Annotation of coherent/a/usr/src/updateprovbyha, revision 1.1

1.1     ! root        1: $�$�$�7�0707070064030053621006440000030000030000011777770507310624600004000000000431/newbits/lib/LIBCobjects/path.o&��(#VW��F���u�����F���F��t�~�:t
��"&s��G������v�}�/t��"&s��G�/�F
        !             2: �F��tD�^��F����F��t
��"&s��G����"&s��vh��z����|����~�t�w�+��_^�path_access_0%%*%7%C%i%v%�7�&%�0�0707070064030053611006440000030000030000011777770507310624600004200000000523/newbits/lib/LIBCobjects/perror.o&TxEVWU��v�;}��㋿��T�thV�����hhe�����hW����hhh�����_^�Bad error number: 
        !             3: errno_fputs__stderr_sys_nerr_sys_errlist_perror_'     '
''$'%7)&'/$275&';7?&'E$H7K&0707070064030053601006440000030000030000011777770507310625200004300000000752/newbits/lib/LIBCobjects/pnmatch.o&b&HVW��v�~
        !             4: �~&u$�<u�A&�F�FPW��FP������t�&�'&��G���F��u�&��F���F��F��f�CC.;��t��.�g$*?[\^�&��,&��~t��N몃~u��~�t�됋�G���F��~�u��~�]u��~�\u�=-u      ��G���F��F�;F�t�=-u�G�ߊ�;F�|��F�;F�|��=t��G�?]u�~�t�1��T�=u�!�N�vWV������t����F�?u��/��G���F��t"�F�;F�u�����~t����<�D��~t�+��_^�pnmatch_00'040D S0b t v x z | ~0�0�0�0�0�0&0
&0&0 &0B&0M&0S&0707070064030053571006440000030000030000011777770507310625200004200000000705/newbits/lib/LIBCobjects/putenv.o&�xAVW��~u������+���^�?=t��^�?u���G��G�6�<tW�4�v�����u�F��}���ߋ�+�.�>�@@����W�������u��+�����ƉF�������^���tG���G��ދF���G�����>�t
        !             5: �6��4����6�6�+��_^�free_putenv_errno_malloc_environ_strncmp_'0'0'<7J'c i7s'�'�%�%�7�'�%�0707070064030053561006440000030000030000011777770507310625300004100000000704/newbits/lib/LIBCobjects/qsort.o&R&(VW�F�v�F��F��^��7�F
        !             6: �G�̓�D�F�;�s�%&�^��7�G�F
        !             7: �n��~
        !             8: s����F�f
        !             9: ljF��v�F
        !            10: ���f�PW����V�F)F��F�P�V���|;v�r�~��PV�V���|;~�r�;~�s�v�v���vV�v��V����F�+�+��v�F���+�+��v)F
        !            11: �F�;F
        !            12: v�F��^��7�G���Y��F��^��?�F
        !            13: �G�F��F
        !            14: �A��F
        !            15: �N
        !            16: =&w���Ƌ��F��F
        !            17: �F��F��N��tW�F&F��F�P�V���}�~���;�t�vVW������F����_^�qsort__memxchg_0'0?7^&7�&0�0�0&7@&&0707070064030053551006440000030000030000011777770507310625300004000000000321/newbits/lib/LIBCobjects/rand.o&N<VWU��F+ңN�P�_^�VWU��jh
f�6P�6N������b��6�N�P�������%�+��_^�&rand_lrmulsrand_$$$!$%7(&$5$90707070064030053541006440000030000030000011777770507310625300004500000000364/newbits/lib/LIBCobjects/shellsort.o&�VW��v�F
        !            18: �.�>��F��~�~\�F��F�;F
        !            19: }L+F����|>��F��n�P���n�P�V���~!�v��F��n�P���n�P���+~���F�묋F���_^�VW��v�~
        !            20: �~t���F���F�����G�F���Nu��_^�shellsort_ 0c0707070064030053531006440000030000030000011777770507310625300004100000000474/newbits/lib/LIBCobjects/sleep.o&�P0VW��vhjj������F�V��������t0�t$;�vW�����j�2���V�+���;�t�;�s�+�j����v�j����W�����_^�VWU��~u�����>�t�����_^�signal_alarm_sleep_pause_ 
        !            21: 77&7.&060O7Z7a&%w7|%�%�0707070064030053521006440000030000030000011777770507310625300004200000002543/newbits/lib/LIBCobjects/strtod.o&B�&VW��v+ɉN��N�N��N�����F��V�+��F�F�F�F��F���F�F䘋؋���&u��=+t
        !            22: =-u
�N�&��F������&u�v�@��&u����0�~�u�t�F�~��ws��~���w��F�tH�v��v��T����N��F�P�v��D����>��;���
        !            23: �5��2�����F��F��F��F��)�v��v�������F��F��F��F�N��F�&�Ǚ�"�F��Ǚ�F�V�jj
        !            24: �v��v������F�V�F��V��F�t�N���F��������.u�F�u�N����F�t0�v��v������|��F�P�v��r����l��i���
        !            25: �c��`�����v��v��R�����F��F��F��F��et��Et��D��F��F����=+t
        !            26: =-u
�N���F������&u�v��+��F�F���&t(�~�u��0t�F�kF�
        !            27: �ȋ��-0�F���F�����у~�~�F�t� ��    F�N�R�F�t�F�)F���F�&F�N�~���N� �/�F�F�H=&|�N���~�t�v��d����^��F�P�W���
        !            28: �~
        !            29: t�^
        !            30: �7�F� t �"�����_�F�t�"�F��}�F�½�F��F��H�F�&t�F��F��F��F��6���F��F��F��F��_^�errno_ddrmul_fpac_dlmul_ctype_dpushdvcvt_pow10_vrmuldraddstrtod_'A'a0j'n0t0�0�7�7�7�7�7�7�7�  '�'�'�'�7�'�'�'&'
        !            31: &75&0Y&7|&7�&7�&7�&7�&7�&7�&   7�&'�&'�&'�&'�&0�&'�&0'7�7�7�&'�'�'�'�'�'�'
        !            32: '''' ')'/'5';0707070064030053511006440000030000030000011777770507310625300004200000001670/newbits/lib/LIBCobjects/strtol.o&z�^VWU��j�v�v
        !            33: �v�!���_^�VWU��j&�v�v
        !            34: �v����_^�VW��v+ɉN��N��N�����F��V���F���F�F昋؋���&u��=+t
        !            35: =-u
�F�&��F�����~u��0t�X&�<xt�<Xu����F�~u��0u�<xt�<Xu�F�F��F�����F0�F�F7�F�FW�F���&t;~�|+��&&t;~�|��&t;~�|�~�t�D���F��� &�~t%�F�RPj�j�������F�V�F�RPj�j����%�F�RPh�j������F�V�F�RPh�j������F�V���&u�;~�}|��0�F��V�;V�wr$;F�r�F��V�;V�u;;F�u6�Ǚ;V�rw,;F�w'�Ǚ�F�V�F�P�F�RP�6���F�V�F��V���F���F�������&t�F
        !            36: ���v�%��&&t;~�}��7�u���&t;~�}��W�c�N�~
        !            37: t�^
        !            38: �7�~�t)�"�~t�������0�~�t+����#�������~�t�F��V����؃���F��V��_^�errno_strtol_lrdivlrrem_ctype_vrdivvrremvlmulstrtoul_00+'d0�'�'�'�0&7)&7?&7O&7f&'s&0y&7�&'�&0�&'�&0'0'40707070064030053471006440000030000030000011777770507310625400004000000000176/newbits/lib/LIBCobjects/swab.o&>VW��v�~
        !            39: �~r(��F���F���G�F���F���^����G�F���n���_^�swab_0707070064030053441006440000030000030000011777770507310625400004300000001700/newbits/lib/LIBCobjects/sys_err.o&�(xRSf�������&&&0&B&N&d&v&�&�&�&�&�&�&�&�&%=J`o{������(not the super userno such file or directoryno such processinterrupted system callI/O errorno such device or addressarg list too longexec format errorbad file numberno childrenno more processesnot enough memorypermission deniedbad addressblock device requiredmount device busyfile existscross-device linkno such devicenot a directoryis a directoryinvalid argumentfile table overflowtoo many open filesnot a typewriterfile busyfile too largeno space left on deviceillegal seekread-only file systemtoo many linksbroken pipemath argumentresult too largeout of kernel spacedriver not loadedbad exec formatdevice needs attentiondevice busysys_nerr_Psys_errlist_$$$$$$
        !            40: $$$$$$$$$$$ $"$$$&$($*$,$.$0$2$4$6$8$:$<$>$@$B$D$F$H$J$L$N0707070064030053411006440000030000030000011777770507310625400004200000000553/newbits/lib/LIBCobjects/system.o&�x1VW�����F��}����n�~�uj�vh�h�h������
        !            41: j�����j&j�������j&j�����F��F�P������;F�t�}��}�v�Wj�����v�j�����F��_^�/bin/shsh-csystem_fork_wait_exit_signal_execl_7&$!$$$'7*727<7H7U7p7{0707070064030053401006440000030000030000011777770507310625400004300000000575/newbits/lib/LIBCobjects/tempnam.o&�x/VWU��j@��������t{�~uh�������F�u�F��~
        !            42: u�F
        !            43: ����vV�����<tF��;�s�|�/t��F�/�v
        !            44: V�����<tF��h�V����W����jW�z���=��u����_^�TMPDIR/tmptXXXXXXstrcpy_access_tempnam_malloc_getenv_mktemp_7$7$,$77@7b$p7t7{7�&0707070064030053371006440000030000030000011777770507310625400004200000000421/newbits/lib/LIBCobjects/tmpnam.o&L@d%VW��v�u�\hLV�����hQV�����hSV�����V������F�jP�����=��uË��_^�/tmp/tXXXXXXstrcpy_access_tmpnam_mktemp_strcat_%$7$7$%7)707<&0707070064030053361006440000030000030000011777770507310625400004300000001113/newbits/lib/LIBCobjects/ttyname.o&&"�AVWU���v����|�&�+��_^�VW�"�F�P�v������|h<&h2&��������u������~�F�F��F��D~�LV�T������*�=
        !            45: t[�D~�LV�T������*�=
        !            46: t=�D~�LV�T������*�=
        !            47: tVjh!&�C����tj
        !            48: h&�4����u�F����4j
        !            49: h&��������F�Ph&�����|
;~�u�F�;F�t�F��L�V������F��_^�/dev/console/etc/ttysrfstat_fclose_stat_ttyname_fttyslot_index_fopen_fgets_0    $7+$5$87;0J$�7�$�7�$�7�$�7�0&7&&0707070064030053351006440000030000030000011777770507310625500004300000000163/newbits/lib/LIBCobjects/ttyslot.o&(VWU��j��������}&F���_^�ttyslot_fttyslot_7&0707070064030053311006440000030000030000011777770507310625500004200000000502/newbits/lib/LIBCobjects/_ctype.o&&@@@@@@@@@PPPPP@@@@@@@@@@@@@@@@@@�                                                                 &&&&&&&&&&&&&&&&&&&&      
        !            50: 
        !            51: 
        !            52: 
        !            53: 
        !            54: 
        !            55:     @_ctype_0707070064030053301006440000030000030000011777770507310625500004400000000120/newbits/lib/LIBCobjects/_tolower.o&VWU��F
 �_^�_tolower_0707070064030053271006440000030000030000011777770507310625500004400000000120/newbits/lib/LIBCobjects/_toupper.o&VWU��F%���_^�_toupper_0707070064030053261006440000030000030000011777770507310625500004300000000157/newbits/lib/LIBCobjects/isalnum.o&(VWU��~��&*�%�_^�isalnum__ctype_'
        !            56: &0707070064030053251006440000030000030000011777770507310625500004300000000157/newbits/lib/LIBCobjects/isalpha.o&(VWU��~��&*�%�_^�isalpha__ctype_'
        !            57: &0707070064030050611006440000030000030000011777770507310625500004300000000130/newbits/lib/LIBCobjects/isascii.o&VWU���F�u�&�+��_^�isascii_0707070064030037561006440000030000030000011777770507310625600004300000000157/newbits/lib/LIBCobjects/iscntrl.o&(VWU��~��&*�%@�_^�iscntrl__ctype_'
        !            58: &0707070064030037551006440000030000030000011777770507310625600004300000000157/newbits/lib/LIBCobjects/isdigit.o&(VWU��~��&*�%�_^�isdigit__ctype_'
        !            59: &0707070064030037541006440000030000030000011777770507310625600004300000000157/newbits/lib/LIBCobjects/isgraph.o&(VWU��~��&*�%'�_^�isgraph__ctype_'
        !            60: &0707070064030037521006440000030000030000011777770507310625600004300000000157/newbits/lib/LIBCobjects/islower.o&(VWU��~��&*�%�_^�_ctype_islower_'
        !            61: 0707070064030030331006440000030000030000011777770507310625600004300000000157/newbits/lib/LIBCobjects/isprint.o&(VWU��~��&*�%��_^�_ctype_isprint_'
        !            62: 0707070064030027151006440000030000030000011777770507310625600004300000000157/newbits/lib/LIBCobjects/ispunct.o&(VWU��~��&*�% �_^�_ctype_ispunct_'
        !            63: 0707070064030027071006440000030000030000011777770507310625600004300000000157/newbits/lib/LIBCobjects/isspace.o&(VWU��~��&*�%�_^�isspace__ctype_'
        !            64: &0707070064030021731006440000030000030000011777770507310625600004300000000157/newbits/lib/LIBCobjects/isupper.o&(VWU��~��&*�%&�_^�_ctype_isupper_'
        !            65: 0707070064030010601006440000030000030000011777770507310625700004400000000157/newbits/lib/LIBCobjects/isxdigit.o&(VWU��~��&*�%�_^�isxdigit__ctype_'
        !            66: &0707070064030010201006440000030000030000011777770507310625700004300000000120/newbits/lib/LIBCobjects/toascii.o&VWU��F%�_^�toascii_0707070064030004221006440000030000030000011777770507310626000004300000000167/newbits/lib/LIBCobjects/tolower.o&(VWU��~��&&t�F
 ��F�_^�_ctype_tolower_'
        !            67: 0707070064030004211006440000030000030000011777770507310626000004300000000167/newbits/lib/LIBCobjects/toupper.o&(VWU��~��&t�F%����F�_^�_ctype_toupper_'
        !            68: 0707070064030004171007550000030000030000011777770507310626000004100000000116/newbits/lib/LIBCobjects/abort.o&VWU��̀��]_^�abort_0707070064030003601007550000030000030000011777770507310626000004100000000112/newbits/lib/LIBCobjects/canon.o&
        !            69: �܋W�G�_canl_0707070064030003571007550000030000030000011777770507310626000003700000000253/newbits/lib/LIBCobjects/div.o&d�܋G�����W���remquotdenom div_numer $
        !            70: 0707070064030003561007550000030000030000011777770507310626000004100000000312/newbits/lib/LIBCobjects/inout.o&&x�܋W�Ë܋W�*�Ë܋W�G�Ë܋W�G*���port       inb_outb_data     in_out_0707070064030003541006440000030000030000011777770507310626000004100000000244/newbits/lib/LIBCobjects/l3tol.o&dVW��v�~
        !            71: �~tM�*䙹�������F��V��E&*�       F�      V��E*䙹������       F�      V����ރ��F��V���W�Nu��_^�l3tol_0707070064030111141007550000030000030000011777770507310626100004000000000426/newbits/lib/LIBCobjects/ldiv.o&bxWVU��F�V
        !            72: �N�^��3����y���ك���y��&���؃������y���߃����&t���؃���b�?�w�G�W��]^_�remfquotbldiv_denom    numer     vdiv74$O0707070064030110331006440000030000030000011777770507310626100004100000000216/newbits/lib/LIBCobjects/ltol3.o&NVW��v�~
        !            73: �~t8�߃���W�F��V����������F��D&�V���������D���Nu��_^�ltol3_0707070064030110321007550000030000030000011777770507310626100004000000001141/newbits/lib/LIBCobjects/modf.o&��EVWU�����v�~�����F���V���*�-��F�+��~�����v������}=8|���r��8�~-|�G���Ȱ��� �N��V�F�v
        !            74: �~��������������
        !            75: �u*����
        !            76: �x���������������n���щ��6�>��t0��t)��V�0�V�~�u�u�u�5����
        !            77: ���������
        !            78: ��]_^��@one�modf__fpac_ip     dlsubd dzerodpushCLAIM     EXP     ��SIGN     ��dladd'40;7C0F'�'�'�'�'�'�#�7�7�'�7�0707070064030110311007550000030000030000011777770507310626100004200000000306/newbits/lib/LIBCobjects/setjmp.o&6dY�܋�/�g�O+���܋G�_�;Nt�n�u�����]_^�g�glongjmp_l0l1+l20setjmp_0707070064030110301006440000030000030000011777770507310626100004300000000505/newbits/lib/LIBCobjects/signame.o&�3"#*49EPXht{������hangupinterruptquitalarm clockterminatedrestartbad system callpipe brokenkilledbreakpointsegmentation violationdivide checkoverflowsignal 14signal 15signal 16signame_$$$$$$
        !            79: $$$$$$$$$$$ 0707070064030110261006440000030000030000011777770507310626100004200000000236/newbits/lib/LIBCobjects/calloc.o&,<
        !            80: VWU��v
        !            81: ���f��V��������t
        !            82: VjW��������_^�calloc_malloc_memset_7&7!0707070064030110251006440000030000030000011777770507310626200004200000001576/newbits/lib/LIBCobjects/malloc.o&<�pVW��>t+���F%��F�;Fs�F�F����v��������=��u�&�~�&v}�n�&�~�s��F��҃>u�
        !            83: �ƉF����/;6u���F��D�F��
        !            84: ��-���E�F��u�
        !            85: �F�-
&���F��-����F��E�&�_^�VW��~u+����F%���F�;Fr�+��6�
        !            86: �F��F��N��t$��N���&u>+��~�t
        !            87: �F�%�����D����;6tjhj��������v������u���t���F�%��&��F��
        !            88: �F�;F�s��롋F�)F��F�=s�%���F����F����F����F���F����
        !            89: �D�_^�VWU��~t@�FHH���<��sjh*j�'����!��&�ρ������;t
        !            90: ��&u�6�_^�Bad pointer in malloc.
        !            91: Bad pointer in free.
        !            92: free_�&__a_first___a_count_
        !            93: write_sbrk_malloc_�__a_scanp_abort_$0$*$-73$A$_$f$p$s$y$�$�$�$�0�$�$�$-&$4&79&7?&0E&$e&$�&$�&$�&$�&$�&7�&7�&$�&$�&$�&0707070064030110241006440000030000030000011777770507310626200004100000000406/newbits/lib/LIBCobjects/memok.o&lPVW�����u�>uP�>uI�&�F�F���F��F��N��t#;6u�F��%���F��t��F���D���Ӄ~�&u;6t�+��_^�__a_first___a_count___a_scanp_memok_'''&'(&'9'b0707070064030110221006440000030000030000011777770507310626200004200000000343/newbits/lib/LIBCobjects/notmem.o&l<VW��~tY��F��tO�^KK�^��?tB�>��O�t)�F�;F�u+��.�^��7�t   ��%�����^��G�F��ЋF�;t�����&�_^�__a_count_notmem___a_scanp_'
'%'\0707070064030110201006440000030000030000011777770507310626200004300000001002/newbits/lib/LIBCobjects/realloc.o&"&x<VW��v�t���v
        !            94: ������&�F
        !            95: %���F�;F
        !            96: s���D��F��^��%����;~�r*+~���=v�F���F�ÉF���
&�^��������F��F��^���F��F�&t[&~��F�;F�vP+F�=v�F��^���F�ÉF��F�+F��^����F�%���F��^���F�ÉF���F�;u��F����v
        !            97: �����F��t+��HHPV�v�����V������F���~
        !            98: t��V�����+��_^�free_realloc___a_count_malloc_memcpy___a_scanp_0700.'h0m'�'�'�7�7�7&0&7&0707070064030110161006440000030000030000011777770507310626200004100000000246/newbits/lib/LIBCobjects/fgetw.o&fVW��v�D~�LV�T������*��=��u����3�D~�LV�T������*�F�=��u�L��ԋF����ȋ���_^�fgetw_0707070064030110151006440000030000030000011777770507310626300004100000000220/newbits/lib/LIBCobjects/fputw.o&PVWU��v
        !            99: �L}�DV�v�T
        !           100: ���   �<��F��L}�DV�F��P�T
        !           101: ����<��F����F�_^�fputw_0707070064030110131006440000030000030000011777770507310626300004000000000246/newbits/lib/LIBCobjects/getw.o&fVW��v�D~�LV�T������*��=��u����3�D~�LV�T������*�F�=��u�L��ԋF����ȋ���_^�getw_0707070064030110111006440000030000030000011777770507310626300004000000000220/newbits/lib/LIBCobjects/putw.o&PVWU��v
        !           102: �L}�DV�v�T
        !           103: ���   �<��F��L}�DV�F��P�T
        !           104: ����<��F����F�_^�putw_0707070064030110071006440000030000030000011777770507310626300004200000000520/newbits/lib/LIBCobjects/_fgetb.o&�x(VWU��vV������t����h�>
        !           105: u   h�������D+DP�t�D
�P�����؉D=&u�>t�L��D밃|u�L@뤋D�D)D�<��*��_^�errno__fgetb__stdout_fflush__fputt_read_7
        !           106: '''!7$'+7B'S0707070064030110061006440000030000030000011777770507310626300004200000000445/newbits/lib/LIBCobjects/_fgetc.o&^x#VW�&�v�>
        !           107: u   h������D�j&�F�P�D
�P�����=��t�t�F�*���>t
        !           108: �L���L@����_^�errno__fgetc__stdout_fflush__fputt_read_''
'7'!71'H0707070064030110051006440000030000030000011777770507310626300004400000000124/newbits/lib/LIBCobjects/_fgeteof.o&VWU��v�D����_^�_fgeteof_0707070064030110041006440000030000030000011777770507310626300004200000001067/newbits/lib/LIBCobjects/_fopen.o&2&�9VW��v�~�F�&�F��F��^
        !           109: �F
        !           110: ��F��F�r�~�rt���F��F�w�^
        !           111: ���F�
        !           112: �t�~�bt�~�+t�F��:F�t���F��}�~�u�v��v�������}9�~�u�~�t-h�&�v�i������|�~�&tW�V����v��v�J������|l�~�t
jjjW�1����uj�%������u  W�����>�D&+��D��D�D�D�D
        !           113: �LjD
����~�wu�F����~�au�F���+��_^�_fpinit_open__fopen_malloc_creat_lseek_close__fginit_010_7w&7�7�7�&7�7�7�'&'&0&0)&0707070064030110031006440000030000030000011777770507310626400004300000000322/newbits/lib/LIBCobjects/_fpseek.o&`<
        !           114: VWU��v�DtV�T���D;w   V������6j&�<+|�ǙRP�D
�P������؋ʃ��u
        !           115: ���u������D�D+��_^�fflush_lseek__fpseek_777&0707070064030110021006440000030000030000011777770507310626400004200000000221/newbits/lib/LIBCobjects/_fputb.o&8(VWU��v�~
        !           116: W������t�����E+EH�E����*�*��_^�_fputb__fpseek_7
&0707070064030110011006440000030000030000011777770507310626400004200000000354/newbits/lib/LIBCobjects/_fputc.o&\PVW�&�v�~
        !           117: �ƈF��E��E�u2W������u'j&�F�P�E
�P�����=&u��*���>t�M�����_^�errno_write__fputc__fpseek_'7$79&'K0707070064030110001006440000030000030000011777770507310626400004200000000252/newbits/lib/LIBCobjects/_fputt.o&L(
        !           118: VWU��v�~
        !           119: �E�E;uW������u���ƈ*�=
        !           120: uW������t������*��_^�fflush__fputt_7760707070064030107771006440000030000030000011777770507310626400004400000000313/newbits/lib/LIBCobjects/_stropen.o&l(VWU��v�F��D�D�F
        !           121: �؉D�|&�}�D��D
        !           122: O��D
        !           123: ;���_^�VWU��v
        !           124: �D����_^�VWU��v
        !           125: �D��<��F�*��_^�_stropen__fgeteof_'& , 30707070064030107761006440000030000030000011777770507310626400004200000000321/newbits/lib/LIBCobjects/fclose.o&FPVWU��v�D&u����/V��������D
�P������|t�Du   �t������D���_^�free_fclose_fflush_close_77"770707070064030107751006440000030000030000011777770507310626400004200000000275/newbits/lib/LIBCobjects/fdopen.o&F<VWU��~|5�~}/���(s&�<t�<�E&u�v�4�v
        !           126: j�����������+��_^�_fp__fopen_fdopen_''72&0707070064030107741006440000030000030000011777770507310626500004200000000341/newbits/lib/LIBCobjects/fflush.o&j<VWU��v�D��D�uI�+D���~W�t�D
�P�������;�t�>u�|�D;u�D����D+���L�����_^�errno_write_fflush_'7.&';0707070064030107721006440000030000030000011777770507310626500004100000000146/newbits/lib/LIBCobjects/fgetc.o&&VWU��v�D~�LV�T����<��*��_^�fgetc_0707070064030107711006440000030000030000011777770507310626500004100000000254/newbits/lib/LIBCobjects/fgets.o&lVW��v
        !           127: �F�F�N~<�^�G~�OS�W����^���F��^��*��=��t�^��F��Lj�=
        !           128: u��^�����u�F�;Fu+���F�_^�fgets_0707070064030107661006440000030000030000011777770507310626500004100000000261/newbits/lib/LIBCobjects/fopen.o&:<VWU����(s&�<t�<�E&uj��4�v
        !           129: �v�����������+��_^�_fp__fopen_fopen_''
        !           130: 7&&0707070064030107651006440000030000030000011777770507310626500004100000000154/newbits/lib/LIBCobjects/fputc.o&,VWU��v
        !           131: �L}�DV�v�T
        !           132: ����<��F�*��_^�fputc_0707070064030107641006440000030000030000011777770507310626500004100000000224/newbits/lib/LIBCobjects/fputs.o&TVW��v�~
        !           133: �<t<�M}�EW��F��P�U
        !           134: ������F���F���^��*�=��u��E�tĸ����&�_^�fputs_0707070064030107621006440000030000030000011777770507310626500004100000000403/newbits/lib/LIBCobjects/fread.o&�(VW��v�~�F�f
        !           135: �F��Et��F�F�W�U���^���N��}u�Eu1�~�tV�E~�MW�U������*�F�=��t5��F��N����v�V�E
�P�����F��~)F���~�u�M@��M��F�f
        !           136: +F�+��v
        !           137: �_^�fread_read_7w&0707070064030107611006440000030000030000011777770507310626500004300000000226/newbits/lib/LIBCobjects/freopen.o&$<
        !           138: VWU���v�����j��v�v
        !           139: �v������_^�freopen__fopen_fclose_7    7&0707070064030107571006440000030000030000011777770507310626600004100000000346/newbits/lib/LIBCobjects/fseek.o&t<
        !           140: VWU��v�~&u�Dt�n
        !           141: &�^V�����=��u����B�v�v�v
        !           142: �D
�P������؋ʉ^
        !           143: �N���u���tӃ|t�F
        !           144: %�&D��D�d�+��_^�fseek_lseek__fpseek_77<&0707070064030107561006440000030000030000011777770507310626600004100000000273/newbits/lib/LIBCobjects/ftell.o&b(VW��vj&jj�D
�P������؋ʉ^��N����u
���u�������(�|t�<+|�Ǚ&F�V��Dt�n�&�^��F��V��_^�lseek_ftell_70707070064030107551006440000030000030000011777770507310626600004200000000361/newbits/lib/LIBCobjects/fwrite.o&�(VW��v�~�F�f
        !           145: �F��EtW�U���}u�EuH�~�t8�M}�EW��F�*�P�U
        !           146: ������F���F�*�^��*�=��t�N��ƒ~�t+���v�V�E
�P�~���;F�t�M���F�_^�write_fwrite_7�0707070064030107531006440000030000030000011777770507310626600004000000000153/newbits/lib/LIBCobjects/getc.o&(VWU���v������_^�getc_fgetc_7       &0707070064030107511006440000030000030000011777770507310626600004300000000236/newbits/lib/LIBCobjects/getchar.o&,(VWU���~�h�����>��*��_^�_stdin_getchar_''
''''!0707070064030107471006440000030000030000011777770507310626600004000000000314/newbits/lib/LIBCobjects/gets.o&Z(VW��v���~�h�������*�F�=��t
�~�
        !           147: t��G�����~��u;�u+�����_^�gets__stdin_'
&'&'&'&'#&''&0707070064030107251006440000030000030000011777770507310626600004100000001634/newbits/lib/LIBCobjects/popen.o&�&(&�VW��F�P������}+����^
        !           148: �?wu�&�~��+��~������F�����^����&�}�v������v�����뽋��ヿ�&ui��&u"�v������
�P�����v������v�� �v��q����
�P�f����v��]����v��T���j�vh�&h�&h�&�@���
        !           149: j&�8�����&u�v��*���h�&�v���v�����h�&�v��
����_^�VW�
        !           150: �^�G
������㋿�&����LJ�&�t�v�����=��u����oj&j&������F�j&j�����F�j&j�����F��F�P�����ȉN�;�t�~�}�~�}�F����v�j&�{����v�j�p����v�j�e����F��_^�/bin/shsh-cwrpopen_pipe_fork_wait_exit_fclose_fdopen_signal__stdin__stdout_pclose_�dup_execl_close_7&076%=7G
7P
%]7k
'q7v
77�
'�    7�
7�7�
$�$�$�7�7�7�
$�7�
$�7�%&%&7#&77&7D&7Q&7^&7�&7�&7�&0707070064030107221006440000030000030000011777770507310626700004000000000157/newbits/lib/LIBCobjects/putc.o&(VWU���v
        !           151: �v������_^�fputc_putc_70707070064030107211006440000030000030000011777770507310626700004300000000244/newbits/lib/LIBCobjects/putchar.o&2(VWU���}�h�v�
        !           152: ����>��F�*��_^�putchar__stdout_'&'
&'&'&' &'$&0707070064030107201006440000030000030000011777770507310626700004000000000433/newbits/lib/LIBCobjects/puts.o&�(AVWU��v�<tE�}�h��F��P�
        !           153: �������F���*�=��uǠ����ǀt�����/�}�hj
        !           154: �
        !           155: ����>��
        !           156: �*�=��tϸ&�_^�_stdout_puts_''''#','0'B'T'Z']'c'l'p0707070064030107171006440000030000030000011777770507310626700004200000000177/newbits/lib/LIBCobjects/rewind.o&&(VWU��vjjjV��������u�d���_^�rewind_fseek_7&0707070064030107161006440000030000030000011777770507310626700004100000005361/newbits/lib/LIBCobjects/scanf.o&&�&VWU��FPh�L���_^�VWU��F
        !           157: P�v�6���_^�VW��F�P�v�����P�v�����F
        !           158: P�F�P����_^�VW�X�F��^
        !           159: �F
        !           160: ��F��^��F������CC.;��u5.�g
        !           161:      
        !           162:  %������v�v� ����P�J������u����^�G~�OS�W����^���F�^�*�ȋ�;�t��vW������^��F�����=*u�&�+��F��~�t�^��F������F���0|"��9kF�
        !           163: �ȋ��-0�F��^��F������ك�lu�&�+��F���hu�&�+��F�~�u�~�t�^��F������ƻ�&�CC.;��uL.�g$%DEFNOX[cdefnorsx���&uu
        !           164: ��&xx
��hh�����
���F��F�
        !           165: ��F��F���F��F���F��F��F�P�v��v��v����F�V�~�u�l�~�t�+��~�t�^
        !           166: �F
        !           167: ���W��~��^
        !           168: �F
        !           169: ��F��F�����F��F�P�v��v������F��F��F��F�~�u�&�~�t����~�t9�^
        !           170: �F
        !           171: ��F��F��F��F���G��G��G��|��^
        !           172: �F
        !           173: ��F��F��F��F���G��O��F��F��^��F�����=^u�&�+��F��~�t�^��F������t��]t�^��F��ƈ���^���F��F��^�G~�OS�W����^���F��^��*���N�~�u�F�&�^�G~�OS�W����^���F��^��*���F�!��v�������F�"�F�&�~�u�^
        !           174: �F
        !           175: ��F��F����t`W�v�������u�&�+�;F�uF�F��~�u
        !           176: �^��F��Lj�N�u����ċ^�G~�OS�W����^���F��^��*��뛃��t
        !           177: �vW�����~�t2�~�t�����cu����^������^
        !           178: �F
        !           179: �7�v����&F�����~�u�^�G@t�����F��_^�VW��v
        !           180: �~�F��F��~�� ~� �^��v�����F��~�-u�&�+��F��u�~�+u-�^�G~�OS�W����^���F�^�*�F��^��^;?|m�ui�~�0t�
        !           181: �^�^�G~�OS�W����^���F�^�*�F��^��;�|+�~�xt�� ��^�G��OS�W���F��^��^;?��F�-W�F�=
        !           182: }!�F�-7�F�=
        !           183: }�F�-0�F��|�~�    ;v���uY�F�F�uQ�F�-x�F��uD�F���F�V�F�P�ƙRP�����+F�V�F��V��^�G~�f��^���F�^�*��\��v�v������~�t�F��V��
�F��V����؃��_^�VW�%+��F߉F݃~
        !           184: ~�~
        !           185:  ~�F
        !           186:  �^��^�;F
        !           187: |�
        !           188: &�^�G~�OS�W����^���Fۋ^ۊ*����CC.;��t��.�g$ 
        !           189:  +-.0123456789Ee444EE[eeeeeeeeeexx�uw�^��^��]��t��uaG�^��F݋ƈ���&'����t
        !           190: ��&t��u��׃�|2��-��ȃ�����t
        !           191: ��t��u�믃�t��u���vV�J����^���F�P�:����_^�VWU��~�E~�MW�^�W����^�?��*��= t׃�
        !           192: t҃�   t͋��_^�Bad format in scanf
        !           193:      
        !           194:  atof__stropen_fscanf_fputs__stderr__fpac_sscanf_,_stdin_ungetc_llmulscanf_index_abort_strlen_'
        !           195: 0
0#7:
7D&0R ~ � � � � �0�7�0�7�0� �& �& �& �& �& �& �& �& �& �& �& �& �& �& �& �& �& �& �&'�&$�&7�&7�&0�&0*0<0E0s0�'�'�'�'�0�0�'�'�'�'�'�'�'�'�0�'�''
        !           196: '''0$�0�$�77m00�0�0�0�0�0�0�7!    0;0O7X0� �0�           " $ & ( * , . 0 20C7�7�0707070064030107151006440000030000030000011777770507310627200004200000000134/newbits/lib/LIBCobjects/setbuf.o&VWU��v�~
        !           197: �|u�|�L�_^�setbuf_0707070064030107141006440000030000030000011777770507310627200004200000001137/newbits/lib/LIBCobjects/ungetc.o&4&�KVWU��v
        !           198: �~�tS�|u"�Dh�D
        !           199: &&�D�L�d��F�D�F�-�|u�D��Ձ|u�D��ǁ|u�D�빸���_^�VWU��v�D�D
        !           200: �D�d��D�_^�VWU��v�D�D
        !           201: �+D�D�~�D+�D�d��D�_^�VWU��v�D�D
        !           202: �D�d��D�_^�VWU��v�D�4�����؉D�D�_^�VWU��v�~
        !           203: W�U���M}
�EWV�U
        !           204: ���
        !           205: ���ƈ*��_^�_fgetb__fgetc__fpinit__fgeteof__fputb__fputc_ungetc_strlen__fginit_'  ': A'H& O'V ]'s'x'�'�'�&'�'�7�0707070064030107131006440000030000030000011777770507310627200004200000003547/newbits/lib/LIBCobjects/_dtefg.o&L>T&]&VW�L�v�^
        !           206: �G��G��G�����F���F���F���F��~}�FhL�v��v��v��v�����
        !           207: �};�F���F���F���F���6���F���F���F���F���F�-�F�P�F�P�F�P�v�v��v��v��v��v�&�����~et�~guT�~�
        !           208: �F��;F�~D�~guj&�jj�vWV�L��
        !           209: ���~�|�v�ht�        �F���Ph{V�����V��������~guj&�j�v��vWV���
        !           210: �_^�VW��v�~
        !           211: �~}��F�0�%��F�F��=t��G����0�^���F�N�uۃ~tP�~t�=tE��F�.�F�N�~5�~t�=t*�F}��F�0�ދ�F�F��=t��G����0�^�������_^�VW�hL�v�v�v�v
        !           212: ����
        !           213: �}>�^�&�F��F��F��F
        !           214: ��6���F��F��F��F
        !           215: ��^�hL�v�v�v�v
        !           216: ����
        !           217: �u
�^�����&�F�P�v�v�v�v
        !           218: ����
        !           219: �F�PhT�N��F�P�v����p��m���
        !           220: �g��d���
        !           221: �v��v��v��v��R����F���P�F����@��F
        !           222: P�9���
        !           223: h\�v�v�v�v
        !           224: �$���
        !           225: �|�F�hd�F
        !           226: P�����F��^��~et�~gu�~�
        !           227: �F��;F�~�F��FF�@�F��~�7�~�u$hl�v�v�v�v
        !           228: ����
        !           229: �~�^������^������~�~�F��v�F�F;�vzhL�v�v�v�v
        !           230: �s���
        !           231: �ta�v�v�v�v
        !           232: �]�������F��0�h\W�G����A��v�v�v�v
        !           233: �2����,��)���
        !           234: ��F��F��F��F
        !           235: �|��hl�v�v�v�v
        !           236: �����
        !           237: �N��;Ft
        !           238: �<0u���F���N;Ft���=9~����^����_^���Kx�TA B�������>�Ae+%02ue-%02u0101ddlmulfrexp_modf_ddrmul_dtefg_dldivilcmp_fpac_idcvtdicvtdlmuldrsubdpushsprintf__dtoa_�&_pow10_strlen_''''!'$'*'0'6$G7V'c'i'o'u'y'}'�'�'�0�0�$&&$&7&
7&05&$�&7�&''      '''''#')'/$>7M$^0a7t&$~7� 7�7�7�7�7�7�7�7�$�7�$�7�$37B$Q0T$^0a$|7�7�$�7�        7�7�7�7�
        !           239: '�'�'�'�0�$�7$E0707070064030107121006440000030000030000011777770507310627300004200000003370/newbits/lib/LIBCobjects/printf.o&��|VWU��FPh�d���_^�VWU��F
        !           240: P�v�N���_^�VW��F�Ph��v������F
        !           241: P�F�P�&���N�}�F��F�Pj�V����       �~��F���_^�VW�^�F
        !           242: �F��^���F�F��^��F����=%t/�u���^�O}
�GSW�W
        !           243: ���ԋ^���F��^��Lj���F� �F����F����^��F������-u�F�&�^��F������F���0u�F�0�^��F������*u'�^��F���F��}
        !           244: �F�&�؉F�^��F�����,�F���0|"��9kF�
        !           245: �ȋ��-0�F�^��F�����ك�.uU�^��F������*u�^��F���F�^��F�����,�F���0|"��9kF�
        !           246: �ȋ��-0�F�^��F�����ك�lu&�^��F������dt��ot
        !           247: ��ut��xu��%�����F��F����F�&�ǻ�CC.;��t��.�gDOUXcdefgorsux����CO����^}��^��F���F�~�}�؉F��F�-j
        !           248: �v�V�������j
        !           249: �^��F��7��j��j��^���W�F�V�F��~�y���؃��F�V��F�-j
        !           250: �v��v�V�5���j
        !           251: �^��w�7V�"�����F��j��j��V�v��v�W�������F��j�F��^���F��u�F���F��F��F�����F�?t�~�|��+F�;F�~�N�-�F���F�F��^��F���^����^��7�v�
        !           252: ����F��F�F�+ƉF��}�F��~�uz�~�tG�~�0uA�^��?-u9�^�O}�GS�^��F���P�^�W
        !           253: ����^���F��^��F����^���F��N��t#�^�O} �GS�v��ŋ^���F��^��F���;v�v;�^�O}�GS�^��F���P�^�W
        !           254: ���ڋ^���F��^��F����^�����~�u�>��F��N��u�1��^�O}�GS�v��W
        !           255: ���܋^���F��^��F�����_^�VW��v
        !           256: �F��F��N��^����+��v���t �N��F��F��+��v�ڊ����^������N��^�������^��?t�F�F�F��F����^���F�_^�VW��v�~�n��N�^���ǙRP�v�v
        !           257: ������F�V��t4�N�F�F�ǙRP�v�v
        !           258: �����؊����^��F�V�F
        !           259: �V��N�F�F�F
        !           260: �؊����^��^�?t
��F�F��F�����_^�{NULL}0123456789ABCDEF_dtefg__stropen_fprintf__stdout_sprintf_,vrdivvrremprintf_'
        !           261: 0
0#7=&0K0� 0 3 5 7 9 ; = ? A C E G I K M0s0{0�0�0�7�#0g0K0X#�#�7"7F#O#u0707070064030107111006440000030000030000011777770507310627300004300000000364/newbits/lib/LIBCobjects/_fdtefg.o&HPVWU��hh�����j&������_^�
        !           262: You must compile with the -f flag to include printf() floating point.
        !           263: _dtefg__stderr_fprintf_exit_$'  &770707070064030107101006440000030000030000011777770507310627300003700000000443/newbits/lib/LIBCobjects/_fp.o&Xx'(8H&&&_fpinit__stderr_H_fp__stdin_(_stdout_8_fginit_$$$'0'2'@'B'P'R0707070064030107071006440000030000030000011777770507310627300004100000001322/newbits/lib/LIBCobjects/finit.o&(&,&RVWU��v�|u9�Du'�D
�P��������t��uh������D�u�D�D
        !           264: �A�Du�t��u�D�D
        !           265: �D��D�D
        !           266: �D
�P���D��D�D�_^�VW�j&jj�v�b����؋ʉ^��N����u      ���u+���F�+�.�6&&���_^�VWU��vV�+���V�T���_^�VWU��v�~
        !           267: W����WV�U
        !           268: ���_^�VWU��&��r�<t�4����������_^�_fgetb__fgetc__fpinit_�_fp_malloc_fclose__fputb__fputc__stdout__fputt_lseek_finit_isatty__finish_&&_fginit_�7''7/'>&'C'S'Z'_       'i'n0v7�
        !           269:  �0�0�'&'&7&0707070064030107061006440000030000030000011777770507310627400004000000000210/newbits/lib/LIBCobjects/exit.o&<
        !           270: VWU������v������_^�exit__exit__finish_77&0707070064030107051006440000030000030000011777770507310627400004300000000112/newbits/lib/LIBCobjects/_finish.o&
        !           271: VWU���_^�_finish_0707070064030124200407550000030000030000011777770507310627400002000000000000/newbits/kernel0707070064030103620407550000030000030000011777770507310627400002700000000000/newbits/kernel/USRSRC0707070064030103630407550000030000030000011777770507310627400003500000000000/newbits/kernel/USRSRC/i80860707070064030103640407550000030000030000011777770507310627400004100000000000/newbits/kernel/USRSRC/i8086/drv0707070064030110711006440000030000030000011777770507310627400005200000024024/newbits/kernel/USRSRC/i8086/drv/Makefile# Makefile for AT specific Coherent drivers
        !           272: 
        !           273: # System utility directory
        !           274: USRSYS=/usr/sys
        !           275: 
        !           276: # Source directory
        !           277: USRSRC=/usr/src/sys
        !           278: 
        !           279: # Loadable driver directory
        !           280: LDRV=$(USRSYS)/ldrv
        !           281: 
        !           282: # Include directories
        !           283: USRINC=/usr/include
        !           284: SYSINC=/usr/include/sys
        !           285: 
        !           286: # Object directory
        !           287: KOBJ=/usr/kobj
        !           288: 
        !           289: ARCHIVES=\
        !           290:        $(USRSYS)/lib/al.a \
        !           291:        $(USRSYS)/lib/at.a \
        !           292:        $(USRSYS)/lib/ati.a \
        !           293:        $(USRSYS)/lib/fl.a \
        !           294:        $(USRSYS)/lib/gr.a \
        !           295:        $(USRSYS)/lib/hs.a \
        !           296:        $(USRSYS)/lib/kb.a \
        !           297:        $(USRSYS)/lib/lp.a \
        !           298:        $(USRSYS)/lib/mm.a \
        !           299:        $(USRSYS)/lib/ms.a \
        !           300:        $(USRSYS)/lib/rm.a \
        !           301:        $(USRSYS)/lib/rs.a \
        !           302:        $(USRSYS)/lib/st.a \
        !           303:        $(USRSYS)/lib/tn.a \
        !           304: 
        !           305: DRVOBJ=\
        !           306:        $(KOBJ)/alx.o \
        !           307:        $(KOBJ)/at.o \
        !           308:        $(KOBJ)/atas.o \
        !           309:        $(KOBJ)/ms.o \
        !           310:        $(KOBJ)/ati.o \
        !           311:        $(KOBJ)/com1.o $(KOBJ)/com2.o \
        !           312:        $(KOBJ)/fdisk.o \
        !           313:        $(KOBJ)/fl.o \
        !           314:        $(KOBJ)/fontw.o \
        !           315:        $(KOBJ)/gr.o $(KOBJ)/gras.o \
        !           316:        $(KOBJ)/hs.o \
        !           317:        $(KOBJ)/kb.o \
        !           318:        $(KOBJ)/mm.o \
        !           319:        $(KOBJ)/lp.o \
        !           320:        $(KOBJ)/mmas.o \
        !           321:        $(KOBJ)/rm.o \
        !           322:        $(KOBJ)/rs0.o $(KOBJ)/rs1.o $(KOBJ)/rsas.o \
        !           323:        $(KOBJ)/st.o \
        !           324:        $(KOBJ)/tn.o $(KOBJ)/tnas.o
        !           325: 
        !           326: DRIVERS=\
        !           327:        $(LDRV)/al0 \
        !           328:        $(LDRV)/al1 \
        !           329:        $(LDRV)/at \
        !           330:        $(LDRV)/fl \
        !           331:        $(LDRV)/gr \
        !           332:        $(LDRV)/hs \
        !           333:        $(LDRV)/lp \
        !           334:        $(LDRV)/mm \
        !           335:        $(LDRV)/ms \
        !           336:        $(LDRV)/rm
        !           337: 
        !           338: install: $(ARCHIVES) $(DRIVERS)
        !           339:        @exec /bin/sync
        !           340: 
        !           341: all:   $(DRVOBJ)
        !           342:        @exec /bin/sync
        !           343: 
        !           344: $(USRSYS)/lib/al.a: $(KOBJ)/com1.o $(KOBJ)/com2.o $(KOBJ)/alx.o
        !           345:        rm -f $@
        !           346:        ar rc $@ $<
        !           347: $(USRSYS)/lib/at.a: $(KOBJ)/at.o $(KOBJ)/atas.o $(KOBJ)/fdisk.o
        !           348:        rm -f $@
        !           349:        ar rc $@ $<
        !           350: $(USRSYS)/lib/ati.a: $(KOBJ)/mm.o $(KOBJ)/ati.o
        !           351:        rm -f $@
        !           352:        ar rc $@ $<
        !           353: $(USRSYS)/lib/fl.a: $(KOBJ)/fl.o
        !           354:        rm -f $(USRSYS)/lib/fl.a
        !           355:        ar rc $(USRSYS)/lib/fl.a $(KOBJ)/fl.o
        !           356: $(USRSYS)/lib/gr.a: $(KOBJ)/mm.o $(KOBJ)/gr.o $(KOBJ)/gras.o \
        !           357:                                $(KOBJ)/fontw.o
        !           358:        rm -f $@
        !           359:        ar rc $@ $<
        !           360: $(USRSYS)/lib/hs.a: $(KOBJ)/hs.o
        !           361:        rm -f $@
        !           362:        ar rc $@ $<
        !           363: $(USRSYS)/lib/kb.a: $(KOBJ)/kb.o
        !           364:        rm -f $@
        !           365:        ar rc $@ $<
        !           366: $(USRSYS)/lib/lp.a: $(KOBJ)/lp.o
        !           367:        rm -f $@
        !           368:        ar rc $@ $<
        !           369: $(USRSYS)/lib/mm.a: $(KOBJ)/mm.o $(KOBJ)/mmas.o
        !           370:        rm -f $@
        !           371:        ar rc $@ $<
        !           372: $(USRSYS)/lib/ms.a: $(KOBJ)/ms.o
        !           373:        rm -f $@
        !           374:        ar rc $@ $<
        !           375: $(USRSYS)/lib/rm.a: $(KOBJ)/rm.o
        !           376:        rm -f $@
        !           377:        ar rc $@ $<
        !           378: $(USRSYS)/lib/rs.a: $(KOBJ)/rs0.o $(KOBJ)/rs1.o $(KOBJ)/rsas.o
        !           379:        rm -f $@
        !           380:        ar rc $@ $<
        !           381: $(USRSYS)/lib/st.a: $(KOBJ)/st.o
        !           382:        rm -f $@
        !           383:        ar rc $@ $<
        !           384: $(USRSYS)/lib/tn.a: $(KOBJ)/tn.o $(KOBJ)/tnas.o
        !           385:        rm -f $@
        !           386:        ar rc $@ $<
        !           387: 
        !           388: $(KOBJ)/alx.o:                         \
        !           389:                $(SYSINC)/clist.h       \
        !           390:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           391:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           392:                                        $(SYSINC)/fun.h \
        !           393:                $(SYSINC)/con.h         \
        !           394:                $(USRINC)/errno.h       \
        !           395:                $(SYSINC)/i8086.h       \
        !           396:                $(SYSINC)/ins8250.h     \
        !           397:                $(SYSINC)/sched.h       \
        !           398:                $(SYSINC)/stat.h        \
        !           399:                $(SYSINC)/timeout.h     \
        !           400:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !           401:                $(SYSINC)/uproc.h       \
        !           402:                alx.c
        !           403:        $(CC) $(CFLAGS) -c -o $@ alx.c
        !           404: 
        !           405: $(KOBJ)/at.o: at.c                     \
        !           406:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           407:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           408:                                        $(SYSINC)/fun.h \
        !           409:                $(SYSINC)/fdisk.h       \
        !           410:                $(SYSINC)/hdioctl.h     \
        !           411:                $(SYSINC)/buf.h         \
        !           412:                $(SYSINC)/con.h         \
        !           413:                $(SYSINC)/devices.h     \
        !           414:                $(SYSINC)/stat.h        \
        !           415:                $(SYSINC)/uproc.h       \
        !           416:                $(USRINC)/errno.h
        !           417:        $(CC) $(CFLAGS) -DVERBOSE=1 -c -o $@ at.c
        !           418: 
        !           419: $(KOBJ)/atas.o: atas.s
        !           420:        $(AS) -go $@ $<
        !           421: 
        !           422: $(KOBJ)/ati.o: ati.m
        !           423:        $(CC) $(CFLAGS) -DATI_132=1 -c -o $@ ati.m
        !           424: 
        !           425: $(KOBJ)/com1.o:                        \
        !           426:                $(SYSINC)/al.h          \
        !           427:                $(SYSINC)/clist.h       \
        !           428:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           429:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           430:                                        $(SYSINC)/fun.h \
        !           431:                $(SYSINC)/con.h         \
        !           432:                $(SYSINC)/devices.h     \
        !           433:                $(USRINC)/errno.h       \
        !           434:                $(SYSINC)/i8086.h       \
        !           435:                $(SYSINC)/ins8250.h     \
        !           436:                $(SYSINC)/sched.h       \
        !           437:                $(SYSINC)/stat.h        \
        !           438:                $(SYSINC)/timeout.h     \
        !           439:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !           440:                $(SYSINC)/uproc.h       \
        !           441:                al.c
        !           442:        $(CC) $(CFLAGS) -DALCOM1=1 -c -o $@ al.c
        !           443: 
        !           444: $(KOBJ)/com2.o:                        \
        !           445:                $(SYSINC)/al.h          \
        !           446:                $(SYSINC)/clist.h       \
        !           447:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           448:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           449:                                        $(SYSINC)/fun.h \
        !           450:                $(SYSINC)/con.h         \
        !           451:                $(SYSINC)/devices.h     \
        !           452:                $(USRINC)/errno.h       \
        !           453:                $(SYSINC)/i8086.h       \
        !           454:                $(SYSINC)/ins8250.h     \
        !           455:                $(SYSINC)/sched.h       \
        !           456:                $(SYSINC)/stat.h        \
        !           457:                $(SYSINC)/timeout.h     \
        !           458:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !           459:                $(SYSINC)/uproc.h       \
        !           460:                al.c
        !           461:        $(CC) $(CFLAGS) -DALCOM2=1 -c -o $@ al.c
        !           462: 
        !           463: $(KOBJ)/fdisk.o:                       \
        !           464:                $(SYSINC)/buf.h         \
        !           465:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           466:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           467:                                        $(SYSINC)/fun.h \
        !           468:                $(SYSINC)/con.h         \
        !           469:                $(USRINC)/errno.h       \
        !           470:                $(SYSINC)/fdisk.h       \
        !           471:                $(SYSINC)/inode.h       \
        !           472:                $(SYSINC)/uproc.h       \
        !           473:                fdisk.c
        !           474:        $(CC) $(CFLAGS) -c -o $@ fdisk.c
        !           475: 
        !           476: $(KOBJ)/fl.o:                          \
        !           477:                $(SYSINC)/buf.h         \
        !           478:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           479:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           480:                                        $(SYSINC)/fun.h \
        !           481:                $(SYSINC)/con.h         \
        !           482:                $(SYSINC)/devices.h     \
        !           483:                $(SYSINC)/dmac.h        \
        !           484:                $(USRINC)/errno.h       \
        !           485:                $(SYSINC)/fdioctl.h     \
        !           486:                $(SYSINC)/i8086.h       \
        !           487:                $(SYSINC)/sched.h       \
        !           488:                $(SYSINC)/stat.h        \
        !           489:                $(SYSINC)/timeout.h     \
        !           490:                $(SYSINC)/uproc.h       \
        !           491:                fl.c
        !           492:        $(CC) $(CFLAGS) -c -o $@ fl.c
        !           493: 
        !           494: $(KOBJ)/fontw.o: tools/fontgen.c
        !           495:        $(CC) -o tools/fontgen tools/fontgen.c
        !           496:        exec tools/fontgen > fontw.s
        !           497:        exec /bin/rm tools/fontgen
        !           498:        $(AS) -gxo $(KOBJ)/fontw.o fontw.s
        !           499:        exec /bin/rm fontw.s
        !           500: 
        !           501: $(KOBJ)/gr.o:                          \
        !           502:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           503:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           504:                                        $(SYSINC)/fun.h \
        !           505:                $(SYSINC)/con.h         \
        !           506:                $(SYSINC)/devices.h     \
        !           507:                $(USRINC)/errno.h       \
        !           508:                $(SYSINC)/sched.h       \
        !           509:                $(SYSINC)/timeout.h     \
        !           510:                $(SYSINC)/types.h       \
        !           511:                $(SYSINC)/uproc.h       \
        !           512:                gr.c
        !           513:        $(CC) $(CFLAGS) -c -o $@ gr.c
        !           514: 
        !           515: $(KOBJ)/gras.o: gras.m
        !           516:        $(CC) $(CFLAGS) -c -o $@ gras.m
        !           517: 
        !           518: $(KOBJ)/hgas.o: gras.s
        !           519:        $(CC) $(CFLAGS) -c -o $@ -DHERCULES gras.m
        !           520: 
        !           521: $(KOBJ)/hs.o:                          \
        !           522:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           523:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           524:                                        $(SYSINC)/fun.h \
        !           525:                $(SYSINC)/con.h         \
        !           526:                $(SYSINC)/devices.h     \
        !           527:                $(USRINC)/errno.h       \
        !           528:                $(SYSINC)/ins8250.h     \
        !           529:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !           530:                $(SYSINC)/stat.h        \
        !           531:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !           532:                $(SYSINC)/uproc.h       \
        !           533:                hs.c
        !           534:        $(CC) $(CFLAGS) -c -o $@ hs.c
        !           535: 
        !           536: $(KOBJ)/kb.o:                          \
        !           537:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           538:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           539:                                        $(SYSINC)/fun.h \
        !           540:                $(SYSINC)/con.h         \
        !           541:                $(SYSINC)/devices.h     \
        !           542:                $(USRINC)/errno.h       \
        !           543:                $(SYSINC)/i8086.h       \
        !           544:                $(SYSINC)/sched.h       \
        !           545:                $(USRINC)/signal.h      \
        !           546:                $(SYSINC)/stat.h        \
        !           547:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !           548:                $(SYSINC)/uproc.h       \
        !           549:                kb.c
        !           550:        $(CC) $(CFLAGS) -c -o $@ kb.c
        !           551: 
        !           552: $(KOBJ)/lp.o:                          \
        !           553:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           554:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           555:                                        $(SYSINC)/fun.h \
        !           556:                $(SYSINC)/con.h         \
        !           557:                $(SYSINC)/devices.h     \
        !           558:                $(USRINC)/errno.h       \
        !           559:                $(SYSINC)/i8086.h       \
        !           560:                $(SYSINC)/io.h          \
        !           561:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !           562:                $(SYSINC)/stat.h        \
        !           563:                $(SYSINC)/timeout.h     \
        !           564:                $(SYSINC)/uproc.h       \
        !           565:                lp.c
        !           566:        $(CC) $(CFLAGS) -c -o $@ lp.c
        !           567: 
        !           568: $(KOBJ)/mm.o:                          \
        !           569:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           570:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           571:                                        $(SYSINC)/fun.h \
        !           572:                $(SYSINC)/sched.h       \
        !           573:                $(USRINC)/errno.h       \
        !           574:                $(SYSINC)/stat.h        \
        !           575:                $(SYSINC)/io.h          \
        !           576:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !           577:                $(SYSINC)/uproc.h       \
        !           578:                $(SYSINC)/timeout.h     \
        !           579:                mm.c
        !           580:        $(CC) $(CFLAGS) -c -o $@ mm.c
        !           581: 
        !           582: $(KOBJ)/mmas.o: mmas.m
        !           583:        $(CC) $(CFLAGS) -c -o $@ mmas.m
        !           584: 
        !           585: $(KOBJ)/ms.o:                          \
        !           586:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           587:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           588:                                        $(SYSINC)/fun.h \
        !           589:                $(SYSINC)/uproc.h       \
        !           590:                $(SYSINC)/con.h         \
        !           591:                $(SYSINC)/devices.h     \
        !           592:                $(SYSINC)/ms.h          \
        !           593:                $(USRINC)/errno.h       \
        !           594:                ms.c
        !           595:        $(CC) $(CFLAGS) -c -o $@ ms.c
        !           596: 
        !           597: $(KOBJ)/rm.o: rm.c                     \
        !           598:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           599:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           600:                                        $(SYSINC)/fun.h \
        !           601:                $(SYSINC)/buf.h         \
        !           602:                $(USRINC)/errno.h       \
        !           603:                $(SYSINC)/uproc.h       \
        !           604:                $(SYSINC)/seg.h         \
        !           605:                $(SYSINC)/con.h         \
        !           606:                $(SYSINC)/devices.h     \
        !           607:                $(SYSINC)/inode.h       \
        !           608:                $(SYSINC)/stat.h
        !           609:        $(CC) $(CFLAGS) -c -o $@ rm.c
        !           610: 
        !           611: $(KOBJ)/rs0.o:                         \
        !           612:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           613:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           614:                                        $(SYSINC)/fun.h \
        !           615:                $(SYSINC)/con.h         \
        !           616:                $(SYSINC)/devices.h     \
        !           617:                $(USRINC)/errno.h       \
        !           618:                $(SYSINC)/ins8250.h     \
        !           619:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !           620:                $(SYSINC)/sched.h       \
        !           621:                $(SYSINC)/stat.h        \
        !           622:                $(USRINC)/termio.h      \
        !           623:                $(SYSINC)/uproc.h       \
        !           624:                rs.c
        !           625:        $(CC) $(CFLAGS) -DRS0 -c -o $@ rs.c
        !           626: 
        !           627: $(KOBJ)/rs1.o:                                 \
        !           628:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           629:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           630:                                        $(SYSINC)/fun.h \
        !           631:                $(SYSINC)/con.h         \
        !           632:                $(SYSINC)/devices.h     \
        !           633:                $(USRINC)/errno.h       \
        !           634:                $(SYSINC)/ins8250.h     \
        !           635:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !           636:                $(SYSINC)/sched.h       \
        !           637:                $(SYSINC)/stat.h        \
        !           638:                $(USRINC)/termio.h      \
        !           639:                $(SYSINC)/uproc.h       \
        !           640:                rs.c
        !           641:        $(CC) $(CFLAGS) -DRS1 -c -o $@ rs.c
        !           642: 
        !           643: $(KOBJ)/rsas.o: rsas.s
        !           644:        $(AS) -gxo $@ rsas.s
        !           645: 
        !           646: $(KOBJ)/st.o:                          \
        !           647:                $(SYSINC)/buf.h         \
        !           648:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           649:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           650:                                        $(SYSINC)/fun.h \
        !           651:                $(SYSINC)/con.h         \
        !           652:                $(SYSINC)/devices.h     \
        !           653:                $(SYSINC)/const.h       \
        !           654:                $(USRINC)/errno.h       \
        !           655:                $(SYSINC)/inode.h       \
        !           656:                $(SYSINC)/mtioctl.h     \
        !           657:                $(SYSINC)/sched.h       \
        !           658:                $(SYSINC)/seg.h         \
        !           659:                $(SYSINC)/stat.h        \
        !           660:                $(SYSINC)/uproc.h       \
        !           661:                st.c
        !           662:        $(CC) $(CFLAGS) -c -o $@ st.c
        !           663: 
        !           664: $(KOBJ)/tn.o:                          \
        !           665:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !           666:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !           667:                                        $(SYSINC)/fun.h \
        !           668:                $(SYSINC)/con.h         \
        !           669:                $(SYSINC)/devices.h     \
        !           670:                $(USRINC)/errno.h       \
        !           671:                $(SYSINC)/sched.h       \
        !           672:                $(SYSINC)/timeout.h     \
        !           673:                $(SYSINC)/types.h       \
        !           674:                $(SYSINC)/uproc.h       \
        !           675:                tn.c
        !           676:        $(CC) $(CFLAGS) -c -o $@ tn.c
        !           677: 
        !           678: $(KOBJ)/tnas.o: tnas.s
        !           679:        $(AS) -gxo $@ tnas.s
        !           680: 
        !           681: # How to make loadable drivers.
        !           682: 
        !           683: $(LDRV)/al0:   $(USRSYS)/lib/al.a
        !           684:        ( cd $(USRSYS); ldconfig al0 )
        !           685: 
        !           686: $(LDRV)/al1:   $(USRSYS)/lib/al.a
        !           687:        ( cd $(USRSYS); ldconfig al1 )
        !           688: 
        !           689: $(LDRV)/at:    $(USRSYS)/lib/at.a
        !           690:        ( cd $(USRSYS); ldconfig at )
        !           691: 
        !           692: $(LDRV)/fl:    $(USRSYS)/lib/fl.a
        !           693:        ( cd $(USRSYS); ldconfig fl )
        !           694: 
        !           695: $(LDRV)/gr:    $(USRSYS)/lib/gr.a
        !           696:        ( cd $(USRSYS); ldconfig gr )
        !           697: 
        !           698: $(LDRV)/hs:    $(USRSYS)/lib/hs.a
        !           699:        ( cd $(USRSYS); ldconfig hs )
        !           700: 
        !           701: $(LDRV)/lp:    $(USRSYS)/lib/lp.a
        !           702:        ( cd $(USRSYS); ldconfig lp )
        !           703: 
        !           704: $(LDRV)/mm:    $(USRSYS)/lib/mm.a
        !           705:        ( cd $(USRSYS); ldconfig mm )
        !           706: 
        !           707: $(LDRV)/ms:    $(USRSYS)/lib/ms.a
        !           708:        ( cd $(USRSYS); ldconfig ms )
        !           709: 
        !           710: $(LDRV)/rm:    $(USRSYS)/lib/rm.a
        !           711:        ( cd $(USRSYS); ldconfig rm )
        !           712: 0707070064030103651006440000030000030000011777770507310627700004700000036064/newbits/kernel/USRSRC/i8086/drv/aha.c/*
        !           713:  * This is the host adaptor specific portion of the
        !           714:  * Adaptec AHA154x driver.
        !           715:  *
        !           716:  * $Log:       /usr/src/sys/i8086/drv/RCS/aha.c,v $
        !           717:  * Revision 1.2        91/05/01  04:54:43      root
        !           718:  * Debug code and kalloc arg fixes.
        !           719:  * 
        !           720:  * Revision 1.1        91/04/30  11:01:41      root
        !           721:  * Shipped with COH 3.1.0
        !           722:  * 
        !           723:  */
        !           724: #include <sys/coherent.h>
        !           725: #include <sys/buf.h>
        !           726: #include <sys/sched.h>
        !           727: 
        !           728: #include <sys/scsiwork.h>
        !           729: #include <sys/aha154x.h>
        !           730: 
        !           731: extern saddr_t sds;            /* System Data Selector */
        !           732: static paddr_t sds_physical;   /* as physical address */
        !           733: static short   aha_i_o_base;
        !           734: static char    aha_loaded;     /* did load() find a host adaptor? */
        !           735: static char    dev_bit_map[8]; /* one byte per SCSI-ID; one bit per LUN */
        !           736: char   drive_info[MAX_SCSI_ID * MAX_LUN]; /* "per drive" info/flags */
        !           737: 
        !           738: void   aha_intr();             /* interrupt service routine */
        !           739: 
        !           740: #define        MIN_MAILBOX     1
        !           741: int    MAX_MAILBOX = { 8 };    /* tunable value */
        !           742: 
        !           743: static scsi_work_t     *scsi_work_queue;
        !           744: static mailentry       *mailbox_in, *mailbox_out;
        !           745: static char            *aha_err_msg = { "no message" };
        !           746: 
        !           747: static long    aha_timeout[] = { 
        !           748: #define        TIMEOUT_PRESENT 0
        !           749:        0x30000L,
        !           750: #define        TIMEOUT_SENDCMD 1
        !           751:        0x10000L,
        !           752: #define        TIMEOUT_POLL    2
        !           753:        0x100L,
        !           754: };
        !           755: 
        !           756: #if    0
        !           757: static
        !           758: OUTB( port, value )
        !           759: short port;
        !           760: {      printf( "<O(%x,%x)>", port, value );
        !           761:        outb( port, value );    }
        !           762: INB( port )
        !           763: short port;
        !           764: {      register i = inb(port);
        !           765:        printf( "<I(%x)=%x>", port, i );
        !           766:        return i;       }
        !           767: #else
        !           768: #define        OUTB( port, value )     outb( port, value )
        !           769: #define        INB(port)       inb(port)
        !           770: #endif
        !           771: 
        !           772: #if    VERBOSE
        !           773: #define        SETMSG(msg)     aha_err_msg = msg
        !           774: 
        !           775: static
        !           776: char   *aha_last_msg()
        !           777: {
        !           778:        return aha_err_msg;
        !           779: }
        !           780: 
        !           781: #else
        !           782: 
        !           783: #define        SETMSG(msg)
        !           784: static
        !           785: char   *aha_last_msg()
        !           786: {
        !           787:        return "error messages not verbose";
        !           788: } 
        !           789: #endif
        !           790: 
        !           791: static
        !           792: int    no_mem()
        !           793: {
        !           794:        printf("aha154x: out of kernel memory\n");
        !           795: }
        !           796: 
        !           797: int    aha_set_base( base )
        !           798: {
        !           799:        register i;
        !           800: 
        !           801:        i = aha_i_o_base;
        !           802:        aha_i_o_base = base;
        !           803:        return i;
        !           804: }
        !           805: 
        !           806: int    aha_get_base()
        !           807: {
        !           808:        return aha_i_o_base;
        !           809: }
        !           810: 
        !           811: aha_process( ccb )
        !           812: ccb_t *ccb;
        !           813: {
        !           814:        register scsi_work_t *sw = ccb->ccb_sw;
        !           815:        register BUF *bp;
        !           816: 
        !           817: #if    VERBOSE
        !           818:        printf( "aha_process: ccb %x ", ccb );
        !           819:        printf("sw=%x bp=%x\n", ccb->ccb_sw, ccb->ccb_sw->sw_bp);
        !           820:        aha_ccb_print( ccb );
        !           821: #endif
        !           822:        if( ccb->ccb_sw == 0 ) {
        !           823: #if    VERBOSE
        !           824:                printf( "process: ccb %x with NULL sw\n", ccb );
        !           825: #endif
        !           826:                ++ccb->opcode;
        !           827:                wakeup( ccb );
        !           828:                return;
        !           829:        }
        !           830: 
        !           831:        bp = sw->sw_bp;
        !           832: #if    VERBOSE
        !           833:        printf( "bp = %x\n", bp );
        !           834: #endif
        !           835:        if( (ccb->hoststatus != 0) || (ccb->targetstatus != 0) ) {
        !           836:                if( --sw->sw_retry > 0
        !           837:                   || (ccb->targetstatus == CHECK_TARGET_STATUS
        !           838:                   && ccb->cmd_status[12] == SENSE_UNIT_ATTENTION)) {
        !           839:                        int s = sphi();
        !           840:                        if( scsi_work_queue->sw_actf == NULL ) {
        !           841:                                scsi_work_queue->sw_actf = sw;
        !           842:                        } else {
        !           843:                                scsi_work_queue->sw_actl->sw_actf = sw;
        !           844:                        }
        !           845:                        scsi_work_queue->sw_actl = sw;
        !           846:                        spl(s);
        !           847:                        aha_start();
        !           848:                        return;
        !           849:                }
        !           850:                bp->b_flag |= BFERR;
        !           851:        } else
        !           852:                bp->b_resid = 0;
        !           853: #if    VERBOSE
        !           854:        printf( "bp flag = %o\n", bp->b_flag );
        !           855: #endif
        !           856:        bdone( bp );
        !           857:        kfree( sw );
        !           858:        kfree( ccb );
        !           859: }
        !           860: 
        !           861: static
        !           862: int    aha_1out( value )
        !           863: {
        !           864:        register i;
        !           865: 
        !           866:        while( (i = INB(aha_i_o_base + AHA_STATUS) & AHA_CDOPFULL) != 0 )
        !           867:                if( (i & AHA_INVDCMD)
        !           868:                 || (INB(aha_i_o_base+AHA_INTERRUPT) & AHA_CMD_DONE) )
        !           869:                        return -1;
        !           870:        OUTB( aha_i_o_base + AHA_WRITE, value );
        !           871:        return 0;
        !           872: }
        !           873: 
        !           874: static
        !           875: int    aha_1in()
        !           876: {
        !           877:        register i;
        !           878: 
        !           879:        while( (i = INB(aha_i_o_base + AHA_STATUS) & AHA_DIPFULL) == 0 )
        !           880:                if( (i & AHA_INVDCMD)
        !           881:                 || (INB(aha_i_o_base+AHA_INTERRUPT) & AHA_CMD_DONE) )
        !           882:                        return -1;
        !           883:        return INB( aha_i_o_base + AHA_READ ) & 0xFF;
        !           884: }
        !           885: 
        !           886: static
        !           887: void   aha_cmd_out( value )
        !           888: {
        !           889:        register long l;
        !           890:        register int i;
        !           891: 
        !           892:        for( l = aha_timeout[TIMEOUT_SENDCMD]; --l > 0; )
        !           893:                if( ((i=INB(aha_i_o_base + AHA_STATUS))
        !           894:                    & AHA_SCSIIDLE ) != 0 ) {
        !           895:                        aha_1out( value );
        !           896:                        return;
        !           897:                }
        !           898: #if    VERBOSE
        !           899:                else
        !           900:                        printf( "aha: cmd_out status = %x\r", i );
        !           901: #endif
        !           902:        SETMSG( "timeout sending cmd byte" );
        !           903:        printf( "aha154x: timeout sending cmd byte\n" );
        !           904: }
        !           905: 
        !           906: static
        !           907: int    aha_poll()
        !           908: {
        !           909:        register i;
        !           910:        register l = aha_timeout[TIMEOUT_POLL];
        !           911:        while( (--l > 0 )
        !           912:          &&  ((i = INB(aha_i_o_base + AHA_INTERRUPT)) & AHA_CMD_DONE) == 0 )
        !           913:                ;
        !           914:        if( l == 0 )
        !           915:                printf( "aha154x: aha_poll timed out\n" );
        !           916: 
        !           917:        i = INB(aha_i_o_base + AHA_STATUS);
        !           918:        OUTB( aha_i_o_base + AHA_CONTROL, AHA_INTRRESET );
        !           919:        return i;
        !           920: }
        !           921: 
        !           922: static
        !           923: void   aha_get_data( vec, cnt )
        !           924: char   *vec;
        !           925: int    cnt;
        !           926: {
        !           927:        while( --cnt >= 0 )
        !           928:                *vec++ = aha_1in();
        !           929:        aha_poll();
        !           930: }
        !           931: 
        !           932: static
        !           933: int    aha_present()
        !           934: {
        !           935:        long    l;
        !           936: 
        !           937:        if( INB(aha_i_o_base) == 0xFF ) {
        !           938:                SETMSG( "no adapter found at io base" );
        !           939:                return -3;
        !           940:        }
        !           941:        for( l = aha_timeout[TIMEOUT_PRESENT];
        !           942:                (--l > 0) && (INB(aha_i_o_base + AHA_STATUS) & AHA_SELFTEST); )
        !           943:                        ;
        !           944:        if( l == 0 ) {
        !           945:                SETMSG( "selftest not completed" );
        !           946:                return -1;
        !           947:        }
        !           948:        if( INB(aha_i_o_base + AHA_STATUS) & AHA_DIAGFAIL ) {
        !           949:                SETMSG( "diagnostics failed" );
        !           950:                return -2;
        !           951:        }
        !           952:        if( INB(aha_i_o_base + AHA_STATUS) & AHA_INITMAIL ) {
        !           953:                SETMSG( "mailbox initialization needed" );
        !           954:                return 1;
        !           955:        }
        !           956:        if( INB(aha_i_o_base + AHA_STATUS) & AHA_SCSIIDLE ) {
        !           957:                SETMSG( "adaptor okay, idle" );
        !           958:                return 0;
        !           959:        }
        !           960:        SETMSG( "unknown status at start" );
        !           961:        return -4;
        !           962: }
        !           963: 
        !           964: static
        !           965: void   aha_l_to_p3( value, vec )
        !           966: paddr_t        value;
        !           967: unsigned char *vec;
        !           968: {
        !           969:        register i;
        !           970: 
        !           971:        for( i = 3; --i >= 0; ) {
        !           972:                vec[i] = value & 0xFF;
        !           973:                value >>= 8;
        !           974:        }
        !           975: }
        !           976: 
        !           977: static
        !           978: char   *aha_p3_to_v( vec )
        !           979: unsigned char *vec;
        !           980: {
        !           981:        paddr_t adr;
        !           982: 
        !           983:        adr = vec[0];
        !           984:        adr <<= 16;
        !           985:        adr |= (vec[1]<<8) | vec[2];
        !           986:        adr -= sds_physical;
        !           987:        return (char *)adr;
        !           988: }
        !           989: 
        !           990: aha_device_info()
        !           991: {
        !           992:        register i;
        !           993:        static char buf[256];
        !           994: 
        !           995:        aha_cmd_out( AHA_DO_GET_DEVICES );
        !           996:        aha_get_data( &buf[0], 8 );
        !           997:        for( i = 0; i < 8; ++i )
        !           998:                if( buf[i] != 0 )
        !           999:                        printf( "[%d] %x ", i, buf[i] );
        !          1000:        printf( "\n" );
        !          1001: }
        !          1002: 
        !          1003: int    aha_unload( ireq )
        !          1004: {
        !          1005: #if    VERBOSE
        !          1006:        printf( "aha_unload: %x\n", ireq );
        !          1007: #endif
        !          1008:        /*
        !          1009:         *      we should really verify that everything
        !          1010:         *      out there gets flushed.
        !          1011:         */
        !          1012:        if (!aha_loaded)
        !          1013:                return;
        !          1014:        if( mailbox_out ) {
        !          1015:                kfree( mailbox_out );
        !          1016:                mailbox_out = 0;
        !          1017:        }
        !          1018:        clrivec( ireq );
        !          1019: }
        !          1020: 
        !          1021: int    aha_load( dma, ireq, base, head )
        !          1022: scsi_work_t *head;
        !          1023: {
        !          1024:        register int    i;
        !          1025:        unsigned char   adr[4];
        !          1026: 
        !          1027: #if    VERBOSE
        !          1028:        printf( "aha_load( %d, %d, 0x%x );\n", dma, ireq, base );
        !          1029: #endif
        !          1030:        aha_set_base(base);
        !          1031:        if( mailbox_out == 0 ) {
        !          1032:                if( (mailbox_out = 
        !          1033:                     kalloc(2 * MAX_MAILBOX * sizeof(mailentry))) == 0 ) {
        !          1034:                        no_mem();
        !          1035:                        return -1;
        !          1036:                } else
        !          1037:                        mailbox_in = &mailbox_out[MAX_MAILBOX];
        !          1038:        }
        !          1039: 
        !          1040:        for( i = 0; i < MAX_MAILBOX; ++i )
        !          1041:                mailbox_out[i].cmd = mailbox_in[i].cmd = 0;
        !          1042: 
        !          1043:        sds_physical = VTOP2( 0, sds );
        !          1044:        aha_l_to_p3( VTOP2( mailbox_out, sds ), &adr[1] );
        !          1045:        adr[0] = MAX_MAILBOX;
        !          1046: 
        !          1047:        /*
        !          1048:         * setup HW
        !          1049:         */
        !          1050:        setivec( ireq, aha_intr );
        !          1051:        outb( 0xD6, 0xC1 );             /* DMA is currently hard coded for */
        !          1052:        outb( 0xD4, 0x01 );             /* DMA channel 5 */
        !          1053: 
        !          1054: 
        !          1055:        OUTB( aha_i_o_base+AHA_CONTROL, AHA_HARDRESET );
        !          1056:        if (aha_present() < 0) {
        !          1057:                printf("aha154x: initialization error or host adaptor not ");
        !          1058:                printf("found at 0x%x\n", aha_i_o_base);
        !          1059:                return -1;
        !          1060:        }
        !          1061:        aha_cmd_out( AHA_DO_MAILBOX_INIT );
        !          1062:        for( i = 0; i < 4; ++i )
        !          1063:                aha_1out( adr[i] );
        !          1064:        scsi_work_queue = head;
        !          1065:        ++aha_loaded;
        !          1066:        return MAX_MAILBOX;
        !          1067: }
        !          1068: 
        !          1069: aha_command( sc )
        !          1070: register scsi_cmd_t *sc;
        !          1071: {
        !          1072:        register i;
        !          1073:        register ccb_t *ccb;
        !          1074: 
        !          1075:        short   count = sc->blklen;
        !          1076:        long    block = sc->block;
        !          1077: 
        !          1078:        ccb = (ccb_t *) kalloc(sizeof (ccb_t));
        !          1079:        if (ccb == (ccb_t *) 0) {
        !          1080:                no_mem();
        !          1081:                return -1;
        !          1082:        }
        !          1083: #if    VERBOSE
        !          1084:        printf( "aha_command( SCSI ID %d, LUN %d, c %x, b %D",
        !          1085:                sc->unit >> 2, sc->unit & 0x3, sc->cmd, sc->block ); 
        !          1086:        printf( " [%d] @%x:%x )\n",
        !          1087:                sc->buflen, sc->buffer );
        !          1088: #endif
        !          1089:        ccb->ccb_sw = 0;
        !          1090:        ccb->opcode = 0;                        /* SCSI_INITIATOR*/
        !          1091:        ccb->target = (sc->unit & 0x1C) << 3;   /* SCSI ID */
        !          1092:        ccb->target |= sc->unit & 0x3;          /* LUN */
        !          1093:        if( (ccb->cmd_status[0] = sc->cmd) == ScmdWRITEXTENDED ) {
        !          1094:                ccb->target |= AHA_CCB_DATA_OUT;
        !          1095:        } else { /* READEXT, READCAP, INQUIRY */
        !          1096:                ccb->target |= AHA_CCB_DATA_IN;
        !          1097:        }
        !          1098:        ccb->cmd_status[1] = 0;
        !          1099:        ccb->cmd_status[2] = block;
        !          1100:        ccb->cmd_status[3] = block >>16;
        !          1101:        ccb->cmd_status[4] = block >> 8;
        !          1102:        ccb->cmd_status[5] = block;
        !          1103:        ccb->cmd_status[6] = 0;
        !          1104:        ccb->cmd_status[7] = count / 512;
        !          1105:        ccb->cmd_status[8] = count;
        !          1106:        ccb->cmd_status[9] = 0;
        !          1107:        ccb->cmdlen = 10;
        !          1108:        ccb->senselen = MAX_SENSEDATA;
        !          1109: 
        !          1110:        aha_l_to_p3( (long)sc->buflen, ccb->datalen );
        !          1111:        aha_l_to_p3( sc->buffer, ccb->dataptr );
        !          1112:        aha_l_to_p3( VTOP2( ccb, sds ), mailbox_out[0].adr );
        !          1113: #if    VERBOSE
        !          1114:        aha_ccb_print( ccb );
        !          1115: #endif
        !          1116:        mailbox_out[0].cmd = MBO_TO_START;
        !          1117:        aha_1out( AHA_DO_SCSI_START );
        !          1118:        while( ccb->opcode == 0 )
        !          1119:                sleep( ccb, CVBLKIO, IVBLKIO, SVBLKIO );
        !          1120:        
        !          1121: #if    VERBOSE
        !          1122:        printf( "done with status = %d, %d\n",
        !          1123:                ccb->hoststatus, ccb->targetstatus );
        !          1124: #endif
        !          1125:        if( (ccb->targetstatus == CHECK_TARGET_STATUS)
        !          1126:           && (ccb->cmd_status[12] != SENSE_UNIT_ATTENTION) ) {
        !          1127:                printf( "aha: SCSI ID %d LUN %d. SCSI sense =",
        !          1128:                (sc->unit >> 2), sc->unit & 0x3 );
        !          1129:                for( i = 0; i < ccb->senselen; ++i )
        !          1130:                        printf( " %x", ccb->cmd_status[10+i] );
        !          1131:                printf( "\n" );
        !          1132:        }
        !          1133:        i = ccb->hoststatus | ccb->targetstatus;
        !          1134:        kfree( ccb );
        !          1135:        return i;
        !          1136: }
        !          1137: 
        !          1138: ccb_t  *buildccb( sw )
        !          1139: register scsi_work_t *sw;
        !          1140: {
        !          1141:        register ccb_t *ccb;
        !          1142:        ccb = (ccb_t *)kalloc(sizeof(ccb_t));
        !          1143: 
        !          1144: #if    VERBOSE
        !          1145:        printf( "build: drv = %x, bno = %D  ",
        !          1146:                sw->sw_drv, sw->sw_bno );
        !          1147: #endif
        !          1148:        ccb->ccb_sw = sw;
        !          1149:        ccb->opcode = 0;                        /* SCSI INITIATOR */
        !          1150:        ccb->target = (sw->sw_drv & 0x1C) << 3; /* SCSI ID */
        !          1151:        ccb->target |= (sw->sw_drv) & 0x3;      /* LUN */
        !          1152:        if( sw->sw_bp->b_req == BREAD ) {
        !          1153:                ccb->target |= AHA_CCB_DATA_IN;
        !          1154:                ccb->cmd_status[0] = ScmdREADEXTENDED;
        !          1155:        } else {
        !          1156:                ccb->target |= AHA_CCB_DATA_OUT;
        !          1157:                ccb->cmd_status[0] = ScmdWRITEXTENDED;
        !          1158:        }
        !          1159:        ccb->cmd_status[2] = 0;
        !          1160:        ccb->cmd_status[3] = sw->sw_bno >>16;
        !          1161:        ccb->cmd_status[4] = sw->sw_bno >> 8;
        !          1162:        ccb->cmd_status[5] = sw->sw_bno;
        !          1163:        ccb->cmd_status[6] = 0;
        !          1164:        ccb->cmd_status[7] = sw->sw_bp->b_count / (512*256L);
        !          1165:        ccb->cmd_status[8] = sw->sw_bp->b_count / 512;
        !          1166:        ccb->cmd_status[9] = 0;
        !          1167:        ccb->cmdlen = 10;
        !          1168:        ccb->senselen = MAX_SENSEDATA;
        !          1169: 
        !          1170:        aha_l_to_p3( (long)sw->sw_bp->b_count, ccb->datalen );
        !          1171:        aha_l_to_p3( vtop(sw->sw_bp->b_faddr), ccb->dataptr );
        !          1172:        return ccb;
        !          1173: #if    0
        !          1174: /* start of ioctl code */
        !          1175:        if( f == SASI_CMD_IN )
        !          1176:                ccb->target |= AHA_CCB_DATA_IN;
        !          1177:        else if( f == SASI_CMD_OUT )
        !          1178:                ccb->target |= AHA_CCB_DATA_OUT;
        !          1179:        else
        !          1180:                ccb->target |=   AHA_CCB_DATA_IN
        !          1181:                                |AHA_CCB_DATA_OUT;
        !          1182: #endif
        !          1183: }
        !          1184: 
        !          1185: aha_start()
        !          1186: {
        !          1187:        register i, s, n = 0;
        !          1188:        scsi_work_t *sw;
        !          1189:        static char locked;
        !          1190: 
        !          1191:        s = sphi();
        !          1192:        if( locked ) {
        !          1193:                spl(s);
        !          1194:                return;
        !          1195:        }
        !          1196:        ++locked;
        !          1197:        spl(s);
        !          1198: 
        !          1199:        while( (sw = scsi_work_queue->sw_actf) != NULL ) {
        !          1200:                for( i = MIN_MAILBOX; i < MAX_MAILBOX; ++i )
        !          1201:                        if( mailbox_out[i].cmd == MBO_IS_FREE ) {
        !          1202:                                register ccb_t *ccb;
        !          1203:                                int s;
        !          1204: 
        !          1205:                                ++n;
        !          1206:                                ccb = buildccb( sw );
        !          1207: #if    VERBOSE
        !          1208:                                aha_ccb_print( ccb );
        !          1209: #endif
        !          1210:                                aha_l_to_p3( VTOP2( ccb, sds ),
        !          1211:                                                mailbox_out[i].adr );
        !          1212:                                mailbox_out[i].cmd = MBO_TO_START;
        !          1213: #if    VERBOSE
        !          1214:                                printf( "MBO[%d] = %x:%x:%x:%x, ccb = %x ",
        !          1215:                                        i, mailbox_out[i].cmd,
        !          1216:                                        mailbox_out[i].adr[0],
        !          1217:                                        mailbox_out[i].adr[1],
        !          1218:                                        mailbox_out[i].adr[2], ccb );
        !          1219:        printf("sw=%x bp=%x\n", ccb->ccb_sw, ccb->ccb_sw->sw_bp);
        !          1220: #endif
        !          1221:                                aha_1out( AHA_DO_SCSI_START );
        !          1222: 
        !          1223:                                s = sphi();
        !          1224:                                sw = scsi_work_queue->sw_actf = sw->sw_actf;
        !          1225:                                if( sw == NULL )
        !          1226:                                        scsi_work_queue->sw_actl = NULL;
        !          1227:                                spl(s);
        !          1228: 
        !          1229:                                if( sw == NULL )
        !          1230:                                        break;
        !          1231:                        }
        !          1232:                if( i == MAX_MAILBOX )
        !          1233:                        break;
        !          1234:        }
        !          1235:        --locked;
        !          1236:        return n;
        !          1237: }
        !          1238: 
        !          1239: int    aha_completed()
        !          1240: {
        !          1241:        register i, n;
        !          1242: 
        !          1243:        for( n = 0, i = 0; i < MAX_MAILBOX; ++i )
        !          1244:                if( mailbox_in[i].cmd != MBI_IS_FREE ) {
        !          1245: #if    VERBOSE
        !          1246:                        printf( "aha: mail[%d] = %x:%x:%x:%x\n",
        !          1247:                                i, mailbox_in[i].cmd,
        !          1248:                                mailbox_in[i].adr[0],
        !          1249:                                mailbox_in[i].adr[1],
        !          1250:                                mailbox_in[i].adr[2] );
        !          1251: #endif
        !          1252:                        defer( aha_process,
        !          1253:                                aha_p3_to_v( mailbox_in[i].adr ) );
        !          1254:                        mailbox_in[i].cmd = MBI_IS_FREE;
        !          1255:                        ++n;
        !          1256:                }
        !          1257:        return n;
        !          1258: }
        !          1259: 
        !          1260: void   aha_intr()
        !          1261: {
        !          1262:        register i;
        !          1263: 
        !          1264: #if    VERBOSE
        !          1265:        printf( "aha_interrupt routine\n" );
        !          1266: #endif
        !          1267:        if( ((i = INB(aha_i_o_base+AHA_INTERRUPT)) & AHA_ANY_INTER) == 0 )
        !          1268:                printf( "aha: spurious interrupt %x\n", i );
        !          1269: #if    VERBOSE
        !          1270:        printf( "aha_interrupt: %x\n", i );
        !          1271: #endif
        !          1272:        switch( i & AHA_ALL_INTERRUPTS ) {
        !          1273:        case AHA_RESETED:
        !          1274: #if    VERBOSE
        !          1275:                printf( "aha: reseted\n" );
        !          1276: #endif
        !          1277:                break;
        !          1278:        case AHA_CMD_DONE:
        !          1279: #if    VERBOSE
        !          1280:                printf( "aha: adapter command completed\n" );
        !          1281: #endif
        !          1282:                break;
        !          1283:        case AHA_MBO_EMPTY:
        !          1284: #if    VERBOSE
        !          1285:                printf( "aha: MAILBOX emptied\n" );
        !          1286: #endif
        !          1287:                defer( aha_start, (char *)0 );
        !          1288:                break;
        !          1289:        case AHA_MBI_STORED:
        !          1290: #if    VERBOSE
        !          1291:                printf( "aha: MAILBOX in stored\n" );
        !          1292: #endif
        !          1293:                aha_completed();
        !          1294:                break;
        !          1295:        default:
        !          1296:                printf( "aha: multiple interrupts not yet handled\n" );
        !          1297:        }
        !          1298:        outb( aha_i_o_base+AHA_CONTROL, AHA_INTRRESET );
        !          1299: }
        !          1300: 
        !          1301: aha_ioctl()
        !          1302: {
        !          1303:        printf( "aha_ioctl: Not implemented\n" );
        !          1304: }
        !          1305: 
        !          1306: #if    VERBOSE
        !          1307: static unsigned char vec[256];
        !          1308: 
        !          1309: static aha_ports_are() {
        !          1310:        printf( "aha_ports_are: %x %x %x\n",
        !          1311:                INB(aha_i_o_base+0),
        !          1312:                INB(aha_i_o_base+1),
        !          1313:                INB(aha_i_o_base+2) );
        !          1314: }
        !          1315: 
        !          1316: static aha_inquiry_is() {
        !          1317:        printf( "aha_inquiry:" );
        !          1318:        printf( "... aha_present = %d, ", aha_present() );
        !          1319:        printf( "%s\n", aha_last_msg() );
        !          1320:        aha_cmd_out( AHA_DO_INQUIRY );
        !          1321: 
        !          1322:        aha_get_data( &vec[0], 4 );
        !          1323:        printf( " board id '%c'", vec[0] );
        !          1324:        printf( ", options '%c'", vec[1] );
        !          1325:        printf( ", HW '%c'", vec[2] );
        !          1326:        printf( ", FW '%c'\n", vec[3] );
        !          1327: }
        !          1328: 
        !          1329: void   aha_setup_is() {
        !          1330:        register i;
        !          1331: 
        !          1332:        printf( "Setup and Data:\n" );
        !          1333:        aha_cmd_out( AHA_DO_GET_SETUP );
        !          1334:        aha_cmd_out( 16 );
        !          1335:        aha_get_data( &vec[0], 16 );
        !          1336:        printf( "  Data Xfer %s Sync (J1)\n", (vec[0]&1) ? "is" : "not" );
        !          1337:        printf( "  Parity %s Enabled (J1)\n", (vec[0]&2) ? "is" : "not" );
        !          1338:        switch( vec[1] ) {
        !          1339:        case AHA_SPEED_5_0_MB:
        !          1340:                printf( "  5.0 Mb/sec.\n" );    break;
        !          1341:        case AHA_SPEED_6_7_MB:
        !          1342:                printf( "  6.7 Mb/sec.\n" );    break;
        !          1343:        case AHA_SPEED_8_0_MB:
        !          1344:                printf( "  8.0 Mb/sec.\n" );    break;
        !          1345:        case AHA_SPEED_10_MB:
        !          1346:                printf( "  10 Mb/sec.\n" );     break;
        !          1347:        case AHA_SPEED_5_7_MB:
        !          1348:                printf( "  5.7 Mb/sec.\n" );    break;
        !          1349:        default:
        !          1350:                if( vec[1] & 0x80 )
        !          1351:                        printf( "  Pulse Read %d, Write %d, Strobe off %d\n",
        !          1352:                                50*(2+(vec[1]>>4)&0x7), 50*(2+(vec[1]&7)),
        !          1353:                                vec[1] & 0x80 ? 150 : 100 );
        !          1354:        }
        !          1355:        printf( "  Bus Time ON %d, OFF %d\n", vec[2], vec[3] );
        !          1356:        printf( "  %d Mailboxes at %x|%x|%x\n", vec[4],
        !          1357:                vec[5], vec[6], vec[7] );
        !          1358:        for( i = 0; i < 8; ++i )
        !          1359:                if( vec[i+8] )
        !          1360:                        printf( "  Target [%d] = Sync Neg %x\n", i, vec[i+8] );
        !          1361: }
        !          1362: 
        !          1363: static aha_mailboxes_are( n, adr )
        !          1364: mailentry *adr;
        !          1365: {
        !          1366:        register i;
        !          1367: 
        !          1368:        printf( "addresses for mailbox is %x:%x\n", (long)adr );
        !          1369:        for( i = 0; i < n; ++i, ++adr )
        !          1370:                printf( "  mbo[%x] = %x %x|%x|%x\n",
        !          1371:                        i, adr->cmd, adr->adr[0], adr->adr[1], adr->adr[2] );
        !          1372:        for( i = 0; i < n; ++i, ++adr )
        !          1373:                printf( "  mbi[%x] = %x %x|%x|%x\n",
        !          1374:                        i, adr->cmd, adr->adr[0], adr->adr[1], adr->adr[2] );
        !          1375: }
        !          1376: 
        !          1377: void   aha_status()
        !          1378: {
        !          1379:        aha_ports_are();
        !          1380:        aha_inquiry_is();
        !          1381:        aha_devices_are();
        !          1382:        aha_setup_is();
        !          1383:        aha_mailboxes_are( MAX_MAILBOX, mailbox_out );
        !          1384: }
        !          1385: 
        !          1386: aha_ccb_print( ccb )
        !          1387: ccb_t  *ccb;
        !          1388: {
        !          1389:        register i;
        !          1390:        register unsigned char *cp;
        !          1391: 
        !          1392:        printf( "ccb @%x, sw @%x, bp @%x, flag %o\n",
        !          1393:                ccb, ccb->ccb_sw, ccb->ccb_sw->sw_bp,
        !          1394:                ccb->ccb_sw->sw_bp->b_flag );
        !          1395:        printf( "op %d, ", ccb->opcode );
        !          1396:        printf( "target ID=%d, ", (ccb->target>>5) & 0x7 );
        !          1397:        printf( "LUN=%d, ", (ccb->target & 0x7) );
        !          1398:        printf( "dir=%s%s\n",   (ccb->target&AHA_CCB_DATA_IN)?"IN":"",
        !          1399:                                (ccb->target&AHA_CCB_DATA_OUT)?"OUT":"" );
        !          1400:        printf( "data len %x|%x|%x, adr %x|%x|%x\n",
        !          1401:                ccb->datalen[0],ccb->datalen[1],ccb->datalen[2],
        !          1402:                ccb->dataptr[0],ccb->dataptr[1],ccb->dataptr[2] );
        !          1403:        printf( "status host=%x, target=%x\n",
        !          1404:                ccb->hoststatus, ccb->targetstatus );
        !          1405:        printf( "cmddata[%d]:", ccb->cmdlen );
        !          1406:        for( i = 0, cp = ccb->cmd_status; i < ccb->cmdlen; ++i )
        !          1407:                printf( " %x", *cp++ );
        !          1408:        printf( "\nrequest sense[%d]:", ccb->senselen );
        !          1409:        for( i = 0; i < ccb->senselen; ++i )
        !          1410:                printf( " %x", *cp++ );
        !          1411:        if( i = cp[-1] ) {
        !          1412:                printf( "\n   + " );
        !          1413:                while( --i >= 0 )
        !          1414:                        printf( " %x", *cp++ );
        !          1415:        }
        !          1416:        printf( "\n" );
        !          1417: }
        !          1418: 
        !          1419: #endif /* VERBOSE */
        !          1420: 
        !          1421: 0707070064030106201006440000030000030000011777770507310630200004600000015324/newbits/kernel/USRSRC/i8086/drv/al.c/* (-lgl
        !          1422:  *     COHERENT Driver Kit Version 1.1.0
        !          1423:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          1424:  *     All rights reserved. May not be copied without permission.
        !          1425:  *
        !          1426:  * $Log:       al.c,v $
        !          1427:  * Revision 1.8  91/08/01  13:47:28  bin
        !          1428:  * updated by hal to include rts/cts handshaking.
        !          1429:  * 
        !          1430:  * Revision 1.4  91/07/31  16:06:33  hal
        !          1431:  * Change include usage.  Use AL[01]_MAJOR.
        !          1432:  * 
        !          1433:  * Revision 1.2        91/02/21  11:21:28      hal
        !          1434:  * Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          1435:  * 
        !          1436:  * Revision 1.1        91/02/21  11:07:36      hal
        !          1437:  * Used in COH Release 3.0.0 - no COM3/COM4
        !          1438:  * 
        !          1439:  -lgl) */
        !          1440: /*
        !          1441:  * Driver for an IBM PC asyncronous
        !          1442:  * line, using interrupts. The interface
        !          1443:  * uses a Natty/WD 8250 chip.
        !          1444:  */
        !          1445: #include <sys/coherent.h>
        !          1446: #include <sys/i8086.h>
        !          1447: #include <sys/con.h>
        !          1448: #include <errno.h>
        !          1449: #include <sys/stat.h>
        !          1450: #include <sys/tty.h>
        !          1451: #include <sys/uproc.h>
        !          1452: #include <sys/clist.h>
        !          1453: #include <sys/ins8250.h>
        !          1454: #include <sys/sched.h>
        !          1455: #include <sys/al.h>
        !          1456: #include <sys/devices.h>
        !          1457: 
        !          1458: #define        minor_st(dev)   (dev & 0x3f)
        !          1459: #define        DEV_TTY         (alttab[minor_st(dev)])
        !          1460: #define ALPORT         (((COM_DDP *)(DEV_TTY.t_ddp))->port)
        !          1461: 
        !          1462: /*
        !          1463:  * This driver can be compiled to drive any possible
        !          1464:  * async port by appropriate definitions of:
        !          1465:  *     ALPORT[ab]      the io port address(es)
        !          1466:  *     ALNUM[ab]       com index number (0..3 for com[1..4])
        !          1467:  *     ALINT   the interrupt level
        !          1468:  *     ALNAME  the xxcon name
        !          1469:  *     ALMAJ   the major device number
        !          1470:  *      ALCNT  number of ports sharing the interrupt
        !          1471:  *
        !          1472:  *     NOTE:   if ALCNT is changed, alttab and alintr will need hacking
        !          1473:  * Common code for the different ports is handled by alx.c
        !          1474:  */
        !          1475: 
        !          1476: #ifdef ALCOM1                  /* COM1_3 definitions */
        !          1477: #define ALPORTa        0x3F8           /* Base of com1 port */
        !          1478: #define ALPORTb        0x3E8           /* Base of com3 port */
        !          1479: #define ALNUMa 0               /* com1 has com number of 0 */
        !          1480: #define ALNUMb 2               /* com3 has com number of 2 */
        !          1481: #define ALINT  4               /* Interrupt level of com1_3 ports */
        !          1482: #define        ALNAME  a0con           /* CON name of com1_3 ports */
        !          1483: #define ALMAJ  AL0_MAJOR       /* Major number of com1_3 port */
        !          1484: #define ALCNT  A0CNT           /* Number of ports for this IRQ */
        !          1485: #define ALSPEEDa C1BAUD                /* Name of patchable variable for com1 speed */
        !          1486: #define ALSPEEDb C3BAUD                /* Name of patchable variable for com3 speed */
        !          1487: #endif
        !          1488: 
        !          1489: #ifdef ALCOM2                  /* COM2_4 definitions */
        !          1490: #define ALPORTa        0x2F8           /* Base of com2 port */
        !          1491: #define ALPORTb        0x2E8           /* Base of com4 port */
        !          1492: #define ALNUMa 1               /* com2 has com number of 1 */
        !          1493: #define ALNUMb 3               /* com4 has com number of 3 */
        !          1494: #define ALINT  3               /* Interrupt level of com2_4 ports */
        !          1495: #define ALNAME a1con           /* CON name of com2_4 ports */
        !          1496: #define ALMAJ  AL1_MAJOR       /* Major number of com2_4 ports */
        !          1497: #define ALCNT  A1CNT           /* Number of ports for this IRQ */
        !          1498: #define ALSPEEDa C2BAUD                /* Name of patchable variable for com2 speed */
        !          1499: #define ALSPEEDb C4BAUD                /* Name of patchable variable for com4 speed */
        !          1500: #endif
        !          1501: 
        !          1502: /*
        !          1503:  * Functions.
        !          1504:  */
        !          1505: int    alxopen();
        !          1506: int    alxclose();
        !          1507: int    alxioctl();
        !          1508: int    alxtimer();
        !          1509: int    alxparam();
        !          1510: int    alxcycle();
        !          1511: int    alxstart();
        !          1512: int    alxbreak();
        !          1513: 
        !          1514: int    alintr();
        !          1515: int    alopen();
        !          1516: int    alclose();
        !          1517: int    alread();
        !          1518: int    alwrite();
        !          1519: int    alioctl();
        !          1520: int    alload();
        !          1521: int    alunload();
        !          1522: int    alpoll();
        !          1523: int    nulldev();
        !          1524: int    nonedev();
        !          1525: 
        !          1526: /*
        !          1527:  * Configuration table.
        !          1528:  */
        !          1529: CON ALNAME ={
        !          1530:        DFCHR|DFPOL,                    /* Flags */
        !          1531:        ALMAJ,                          /* Major index */
        !          1532:        alopen,                         /* Open */
        !          1533:        alclose,                        /* Close */
        !          1534:        nulldev,                        /* Block */
        !          1535:        alread,                         /* Read */
        !          1536:        alwrite,                        /* Write */
        !          1537:        alioctl,                        /* Ioctl */
        !          1538:        nulldev,                        /* Powerfail */
        !          1539:        alxtimer,                       /* Timeout */
        !          1540:        alload,                         /* Load */
        !          1541:        alunload,                       /* Unload */
        !          1542:        alpoll                          /* Poll */
        !          1543: };
        !          1544: 
        !          1545: /*
        !          1546:  * Terminal structures.
        !          1547:  */
        !          1548: static COM_DDP * ddp;
        !          1549: static TTY     * alttab;
        !          1550: static TTY     * irqtty;  /* point to alttab entry which is IRQ-enabled */
        !          1551: 
        !          1552: /*
        !          1553:  * to change default speeds - patch kernel variables C1BAUD..C4BAUD
        !          1554:  *   new value should be one of B0..B9600 in /usr/include/sgtty.h
        !          1555:  */
        !          1556: int ALSPEEDa = B9600;
        !          1557: int ALSPEEDb = B9600;
        !          1558: 
        !          1559: /*
        !          1560:  * to enable com[34], patch here
        !          1561:  *     A0CNT should be 2 if you want com3, 1 otherwise
        !          1562:  *     A1CNT should be 2 if you want com4, 1 otherwise
        !          1563:  */
        !          1564: int ALCNT = 2;
        !          1565: 
        !          1566: static
        !          1567: alload()
        !          1568: {
        !          1569:        register int s;
        !          1570:        static int init;
        !          1571:        extern int albaud[];
        !          1572:        int port, i;
        !          1573: 
        !          1574:        if (init == 0
        !          1575:          && (alttab = (TTY *)kalloc(ALCNT * sizeof(TTY)))
        !          1576:          && (ddp = (COM_DDP *)kalloc(ALCNT * sizeof(COM_DDP)))) {
        !          1577:                kclear(alttab, ALCNT*sizeof(TTY));
        !          1578:                kclear(ddp, ALCNT*sizeof(COM_DDP));
        !          1579:                s = sphi();
        !          1580:                ++init;
        !          1581: 
        !          1582:                alttab[0].t_dispeed = alttab[0].t_dospeed = ALSPEEDa;
        !          1583:                alttab[0].t_ddp = (char *)&ddp[0];
        !          1584:                tp_table[ALNUMa] = alttab; /* set TTY pointers for polling */
        !          1585:                ddp[0].port = ALPORTa;
        !          1586:                ddp[0].com_num = ALNUMa;
        !          1587: 
        !          1588:                if (ALCNT > 1) {
        !          1589:                        alttab[1].t_dispeed = alttab[1].t_dospeed = ALSPEEDb;
        !          1590:                        alttab[1].t_ddp = (char *)&ddp[1];
        !          1591:                        tp_table[ALNUMb] = alttab+1;
        !          1592:                        ddp[1].port = ALPORTb;
        !          1593:                        ddp[1].com_num = ALNUMb;
        !          1594:                }
        !          1595: 
        !          1596:                for (i = 0;  i < ALCNT; i++) {
        !          1597:                        int speed = alttab[i].t_dospeed;
        !          1598: 
        !          1599:                        /* port = base I/O address */
        !          1600:                        port = ((COM_DDP *)(alttab[i].t_ddp))->port;
        !          1601:                        outb(port+IER, 0);      /* disable port interrupts */
        !          1602:                        if (inb(port+IER) == 0) {
        !          1603:                                outb(port+MCR, 0);  /* hangup port */
        !          1604:                                outb(port+LCR, LC_DLAB);
        !          1605:                                outb(port+DLL, albaud[speed]);
        !          1606:                                outb(port+DLH, albaud[speed] >> 8);
        !          1607:                                outb(port+LCR, LC_CS8);
        !          1608:                        }
        !          1609:                        alttab[i].t_start = alxstart;
        !          1610:                        alttab[i].t_param = alxparam;
        !          1611:                        alttab[i].t_cs_sel= cs_sel();
        !          1612:                }
        !          1613: 
        !          1614:                setivec(ALINT, alintr);     /* set interrupt vector */
        !          1615:                spl(s);
        !          1616:        }
        !          1617: }
        !          1618: 
        !          1619: static
        !          1620: alunload()
        !          1621: {
        !          1622:        int port, i;
        !          1623: 
        !          1624:        for (i = 0;  i < ALCNT; i++) {
        !          1625:                port = ((COM_DDP *)(alttab[i].t_ddp))->port;
        !          1626:                outb(port+IER, 0);      /* disable port interrupts */
        !          1627:                outb(port+MCR, 0);      /* hangup port */
        !          1628:                timeout(alttab[i].t_rawtim, 0, NULL, 0);/* cancel timer */
        !          1629:        }
        !          1630:        clrivec(ALINT);                 /* release interrupt vector */
        !          1631:        kfree(alttab);
        !          1632:        kfree(ddp);
        !          1633: }
        !          1634: 
        !          1635: static
        !          1636: alopen(dev, mode)
        !          1637: dev_t  dev;
        !          1638: int    mode;
        !          1639: {
        !          1640:        if (minor_st(dev) < ALCNT) {
        !          1641:                alload();
        !          1642:                alxcycle(&DEV_TTY);
        !          1643:                alxopen(dev, mode, &DEV_TTY, &irqtty);
        !          1644:        } else
        !          1645:                u.u_error = ENXIO;
        !          1646: }
        !          1647: 
        !          1648: static
        !          1649: alclose(dev, mode)
        !          1650: dev_t  dev;
        !          1651: int    mode;
        !          1652: {
        !          1653:        register int s;
        !          1654: 
        !          1655:        if (--DEV_TTY.t_open == 0) {    /* Last open */
        !          1656:                s = sphi();
        !          1657:                alxclose(dev, mode, &DEV_TTY);
        !          1658:                spl(s);
        !          1659:        }
        !          1660: }
        !          1661: 
        !          1662: static
        !          1663: alread(dev, iop)
        !          1664: dev_t  dev;
        !          1665: IO     *iop;
        !          1666: {
        !          1667:        ttread(&DEV_TTY, iop);
        !          1668: }
        !          1669: 
        !          1670: static
        !          1671: alwrite(dev, iop)
        !          1672: dev_t  dev;
        !          1673: register IO    *iop;
        !          1674: {
        !          1675:        register int c;
        !          1676: 
        !          1677:        /*
        !          1678:         * Treat user writes through tty driver.
        !          1679:         */
        !          1680:        if (iop->io_seg != IOSYS) {
        !          1681:                ttwrite(&DEV_TTY, iop);
        !          1682:                return;
        !          1683:        }
        !          1684: 
        !          1685:        /*
        !          1686:         * Treat kernel writes by blocking on transmit buffer.
        !          1687:         */
        !          1688:        while ((c = iogetc(iop)) >= 0) {
        !          1689:                /*
        !          1690:                 * Wait until transmit buffer is empty.
        !          1691:                 * Check twice to prevent critical race with interrupt handler.
        !          1692:                 */
        !          1693:                for (;;) {
        !          1694:                        if (inb(ALPORT+LSR) & LS_TxRDY)
        !          1695:                                if (inb(ALPORT+LSR) & LS_TxRDY)
        !          1696:                                        break;
        !          1697:                }
        !          1698: 
        !          1699:                /*
        !          1700:                 * Output the next character.
        !          1701:                 */
        !          1702:                outb(ALPORT+DREG, c);
        !          1703:        }
        !          1704: }
        !          1705: 
        !          1706: static
        !          1707: alioctl(dev, com, vec)
        !          1708: dev_t  dev;
        !          1709: struct sgttyb *vec;
        !          1710: {
        !          1711:        alxioctl(dev, com, vec, &DEV_TTY);
        !          1712: }
        !          1713: 
        !          1714: static
        !          1715: alpoll(dev, ev, msec)
        !          1716: dev_t dev;
        !          1717: int ev;
        !          1718: int msec;
        !          1719: {
        !          1720:        return ttpoll(&DEV_TTY, ev, msec);
        !          1721: }
        !          1722: 
        !          1723: static
        !          1724: alintr()
        !          1725: {
        !          1726:        alxintr(irqtty);
        !          1727: }
        !          1728: 0707070064030105311006440000030000030000011777770507310630400004700000044563/newbits/kernel/USRSRC/i8086/drv/alx.c/* (-lgl
        !          1729:  *     COHERENT Driver Kit Version 1.1.0
        !          1730:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          1731:  *     All rights reserved. May not be copied without permission.
        !          1732:  *
        !          1733:  * $Log:       alx.c,v $
        !          1734:  * Revision 1.12  91/08/06  10:32:23  bin
        !          1735:  * 2nd rts/cts version form hal
        !          1736:  * 
        !          1737:  * Revision 1.7  91/08/02  07:59:27  hal
        !          1738:  * Raw input silo uses last slot for byte count.
        !          1739:  * Modem control now gives RTS/CTS flow control:
        !          1740:  *     CTS is checked 10x/sec (probably not often enough).
        !          1741:  *     On Rx_INT, check T_ISTOP and rawin silo levels; drop RTS if need to.
        !          1742:  * 
        !          1743:  * Revision 1.6        91/04/03  18:55:07      root
        !          1744:  * alxclose():  do closing state machine BEFORE dropping control lines.
        !          1745:  * alxioctl():  save and restore interrupt enable register.
        !          1746:  * alxopen():   wait for pending last close (fixes SLOW port bug).
        !          1747:  * This version needs al.h 1.3 or later.
        !          1748:  *
        !          1749:  * Revision 1.5        91/04/02  17:53:37      root
        !          1750:  * save MSR delta status; add MS_INTR handling; use al.h 1.2
        !          1751:  *
        !          1752:  * Revision 1.4        91/02/22  09:21:17      root
        !          1753:  * alxintr():  replace repeated use of ALPORT macro by local variable
        !          1754:  *
        !          1755:  * Revision 1.3        91/02/21  14:58:16      root
        !          1756:  * Fix unconditional "hupcl" bug in 3.1.0 version.
        !          1757:  *
        !          1758:  * Revision 1.2        91/02/21  11:21:40      hal
        !          1759:  * Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          1760:  *
        !          1761:  * Revision 1.1        91/02/21  11:08:31      hal
        !          1762:  * Used in COH Release 3.0.0 - no COM3/COM4
        !          1763:  *
        !          1764:  -lgl) */
        !          1765: /*
        !          1766:  * Shared parts of IBM async port drivers.
        !          1767:  */
        !          1768: #include <sys/coherent.h>
        !          1769: #include <sys/i8086.h>
        !          1770: #include <sys/al.h>
        !          1771: #include <sys/con.h>
        !          1772: #include <errno.h>
        !          1773: #include <sys/stat.h>
        !          1774: #include <sys/tty.h>
        !          1775: #include <sys/uproc.h>
        !          1776: #include <sys/timeout.h>
        !          1777: #include <sys/clist.h>
        !          1778: #include <sys/ins8250.h>
        !          1779: #include <sys/sched.h>
        !          1780: 
        !          1781: #define ALPORT (((COM_DDP *)(tp->t_ddp))->port)
        !          1782: #define AL_TIM (((COM_DDP *)(tp->t_ddp))->tim)
        !          1783: #define AL_NUM (((COM_DDP *)(tp->t_ddp))->com_num)
        !          1784: #define AL_MSR_DELTAS  (((COM_DDP *)(tp->t_ddp))->msr_deltas)
        !          1785: #define AL_H_CLOSE     (((COM_DDP *)(tp->t_ddp))->h_close)
        !          1786: 
        !          1787: #define DTRTMOUT  3    /* DTR timeout interval in seconds for close */
        !          1788: #define        IENABLE (IE_RxI+IE_TxI+IE_LSI+IE_MSI)
        !          1789: 
        !          1790: /*
        !          1791:  * For rawin silo (see ktty.h), use last element of si_buf to count the number
        !          1792:  * of characters in the silo.
        !          1793:  */
        !          1794: #define SILO_CHAR_COUNT        si_buf[SI_BUFSIZ-1]
        !          1795: #define SILO_HIGH_MARK (SI_BUFSIZ-SI_BUFSIZ/4)
        !          1796: #define MAX_SILO_INDEX (SI_BUFSIZ-2)
        !          1797: #define MAX_SILO_CHARS (SI_BUFSIZ-1)
        !          1798: 
        !          1799: int    al_sg_set = 0;
        !          1800: int    al_sg_clr = 0;
        !          1801: static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          1802: 
        !          1803: /*
        !          1804:  * functions herein
        !          1805:  */
        !          1806: int    alxopen();
        !          1807: int    alxclose();
        !          1808: int    alxtimer();
        !          1809: int    alxioctl();
        !          1810: int    alxparam();
        !          1811: int    alxcycle();
        !          1812: int    alxstart();
        !          1813: int    alxbreak();
        !          1814: int    alxintr();
        !          1815: static int alxclk();
        !          1816: static set_poll_rate();
        !          1817: 
        !          1818: /*
        !          1819:  * Baud rate table and polling rate table.
        !          1820:  * Indexed by ioctl bit rates.
        !          1821:  */
        !          1822: int albaud[] ={
        !          1823:        0,                              /* 0 */
        !          1824:        2304,                           /* 50 */
        !          1825:        1536,                           /* 75 */
        !          1826:        1047,                           /* 110 */
        !          1827:        857,                            /* 134.5 */
        !          1828:        768,                            /* 150 */
        !          1829:        576,                            /* 200 */
        !          1830:        384,                            /* 300 */
        !          1831:        192,                            /* 600 */
        !          1832:        96,                             /* 1200 */
        !          1833:        64,                             /* 1800 */
        !          1834:        58,                             /* 2000 */
        !          1835:        48,                             /* 2400 */
        !          1836:        32,                             /* 3600 */
        !          1837:        24,                             /* 4800 */
        !          1838:        16,                             /* 7200 */
        !          1839:        12,                             /* 9600 */
        !          1840:        6,                              /* 19200 */
        !          1841:        0,                              /* EXTA */
        !          1842:        0                               /* EXTB */
        !          1843: };
        !          1844: 
        !          1845: /*
        !          1846:  *     alp_rate[] is tied to albaud[] - it gives the minimum polling
        !          1847:  *     rate for the corresponding port speed; it must be a multiple
        !          1848:  *     of 100 (system clock Hz) and >= baud/6
        !          1849:  */
        !          1850: int alp_rate[] ={                      /* baud/6 or zero */
        !          1851:        0,                              /* 0 */
        !          1852:        1*HZ,                           /* 50 */
        !          1853:        1*HZ,                           /* 75 */
        !          1854:        1*HZ,                           /* 110 */
        !          1855:        1*HZ,                           /* 134.5 */
        !          1856:        1*HZ,                           /* 150 */
        !          1857:        1*HZ,                           /* 200 */
        !          1858:        1*HZ,                           /* 300 */
        !          1859:        1*HZ,                           /* 600 */
        !          1860:        2*HZ,                           /* 1200 */
        !          1861:        3*HZ,                           /* 1800 */
        !          1862:        4*HZ,                           /* 2000 */
        !          1863:        4*HZ,                           /* 2400 */
        !          1864:        6*HZ,                           /* 3600 */
        !          1865:        8*HZ,                           /* 4800 */
        !          1866:        12*HZ,                          /* 7200 */
        !          1867:        16*HZ,                          /* 9600 */
        !          1868:        0,                              /* 19200 */
        !          1869:        0,                              /* EXTA */
        !          1870:        0                               /* EXTB */
        !          1871: };
        !          1872: 
        !          1873: /*
        !          1874:  *     the following is for debug only
        !          1875:  */
        !          1876: #if 0
        !          1877: #define CDUMP(text)    cdump(text);
        !          1878: 
        !          1879: cdump(message)
        !          1880: char *message;
        !          1881: {
        !          1882:        int i, b;
        !          1883: 
        !          1884:        for (i = 0; i < NUM_AL_PORTS; i++) {
        !          1885:                b = ((COM_DDP *)(tp_table[i]->t_ddp))->port;
        !          1886:                printf("%x:%x:%x:%x ", i+1, b, inb(b+MCR), inb(b+IER));
        !          1887:        }
        !          1888:        printf("poll=%d ", poll_rate);
        !          1889:        printf("%s\n", message);
        !          1890: }
        !          1891: #else
        !          1892: #define CDUMP(text)
        !          1893: #endif
        !          1894: 
        !          1895: /*
        !          1896:  * alxopen()
        !          1897:  */
        !          1898: alxopen(dev, mode, tp, irqtty)
        !          1899: dev_t  dev;
        !          1900: int    mode;
        !          1901: register TTY   *tp, **irqtty;
        !          1902: {
        !          1903:        register int    s;
        !          1904:        register int    b;
        !          1905:        register int    minor_h;  /* minor device number including high bit */
        !          1906:        unsigned char   msr;
        !          1907: 
        !          1908:        minor_h = minor(dev);     /* complete minor number */
        !          1909: 
        !          1910:        b = ALPORT;
        !          1911: 
        !          1912:        if (inb(b+IER) & ~IENABLE) { /* chip not found */
        !          1913:                u.u_error = ENXIO;
        !          1914:                return;
        !          1915:        }
        !          1916: 
        !          1917:        if ((tp->t_flags & T_EXCL) && !super()) {
        !          1918:                u.u_error = ENODEV;
        !          1919:                return;
        !          1920:        }
        !          1921: 
        !          1922:        if (drvl[major(dev)].d_time != 0) {     /* Modem settling */
        !          1923:                u.u_error = EDBUSY;
        !          1924:                return;
        !          1925:        }
        !          1926: 
        !          1927:        /*
        !          1928:         * Can't open a polled port if another driver is using polling.
        !          1929:         */
        !          1930:        if (dev & CPOLL && poll_owner & ~ POLL_AL) {
        !          1931:                u.u_error = EDBUSY;
        !          1932:                return;
        !          1933:        }
        !          1934: 
        !          1935:        /*
        !          1936:         * exclusion conditions:
        !          1937:         *      can't have same port polled and IRQ at once
        !          1938:         *      can't have both com[13] or both com[24] IRQ at once
        !          1939:         */
        !          1940:        if (dev & CPOLL) {
        !          1941:                if (com_usage[AL_NUM] == COM_IRQ) {
        !          1942:                        u.u_error = EDBUSY;
        !          1943:                        return;
        !          1944:                }
        !          1945:        } else {
        !          1946:                if (com_usage[AL_NUM] == COM_POLLED
        !          1947:                   || com_usage[AL_NUM ^ 2] == COM_IRQ) {
        !          1948:                        u.u_error = EDBUSY;
        !          1949:                        return;
        !          1950:                }
        !          1951:        }
        !          1952: 
        !          1953:        if (tp->t_open == 0) {        /* not already open */
        !          1954:                /*
        !          1955:                 * Wait for pending last close (if any) to finish.
        !          1956:                 */
        !          1957:                while (AL_H_CLOSE) {
        !          1958:                        sleep((char *)(&AL_H_CLOSE), CVTTOUT, IVTTOUT,
        !          1959:                                SVTTOUT);
        !          1960:                }
        !          1961:                s = sphi();
        !          1962:                /*
        !          1963:                 * Raise basic modem control lines even if modem
        !          1964:                 * control hasn't been specified.
        !          1965:                 * MC_OUT2 turns on NON-open-collector IRQ line from the UART.
        !          1966:                 * since we can't have two UART's on same IRQ with MC_OUT2 on
        !          1967:                 */
        !          1968:                if (dev & CPOLL) {
        !          1969:                        outb(b+MCR, MC_RTS|MC_DTR);
        !          1970:                } else {
        !          1971:                        *irqtty = tp_table[AL_NUM];
        !          1972:                        outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          1973:                }
        !          1974: 
        !          1975:                outb(b+IER, IENABLE);        /* enable interrupts */
        !          1976: 
        !          1977:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          1978:                        tp->t_flags |= T_MODC | T_HOPEN | T_STOP;
        !          1979:                        while (1) {     /* wait for carrier */
        !          1980:                                msr = inb(b+MSR);
        !          1981:                                AL_MSR_DELTAS |= msr;
        !          1982:                                if (msr & MS_RLSD)
        !          1983:                                        break;
        !          1984:                                sleep((char *)(&tp->t_open), CVTTOUT, IVTTOUT,
        !          1985:                                        SVTTOUT);       /* wait for carrier */
        !          1986:                                if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          1987:                                        outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          1988:                                        /*
        !          1989:                                         * make sure port is hungup
        !          1990:                                         * disable all ints except for TxI
        !          1991:                                         */
        !          1992:                                        outb(b+IER, IE_TxI);
        !          1993:                                        u.u_error = EINTR;
        !          1994:                                        spl(s);
        !          1995:                                        return;
        !          1996:                                }
        !          1997:                        }
        !          1998:                        tp->t_flags &= ~T_HOPEN; /* no longer hanging in open */
        !          1999:                        if (msr & MS_CTS)
        !          2000:                                tp->t_flags &= ~T_STOP;
        !          2001:                } else {
        !          2002:                        tp->t_flags &= ~T_MODC;         /* no modem control */
        !          2003:                }
        !          2004:                tp->t_flags |= T_CARR;                  /* carrier on */
        !          2005:                ttopen(tp);                             /* stty inits */
        !          2006: 
        !          2007:                /*
        !          2008:                 * Allow custom modification of defaults.
        !          2009:                 */
        !          2010:                tp->t_sgttyb.sg_flags |=  al_sg_set;
        !          2011:                tp->t_sgttyb.sg_flags &= ~al_sg_clr;
        !          2012:                alxparam(tp);
        !          2013:                spl(s);
        !          2014:        } else {                                /* already open */
        !          2015:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          2016:                    if ((tp->t_flags & T_MODC)==0) { /* already not modem control? */
        !          2017:                        u.u_error = ENODEV;     /* yes, don't allow open */
        !          2018:                        return;
        !          2019:                    }
        !          2020:                } else {                         /* don't want modem control */
        !          2021:                        if (tp->t_flags & T_MODC) { /* already modem control? */
        !          2022:                                u.u_error = ENODEV; /* yes, don't allow open */
        !          2023:                                return;
        !          2024:                        }
        !          2025:                }
        !          2026:        }
        !          2027:        tp->t_open++;
        !          2028:        ttsetgrp(tp, dev);
        !          2029: 
        !          2030:        /*
        !          2031:         * now that we've successfully opened, designate port as
        !          2032:         * polled or interrupt driven to avoid future conflicts
        !          2033:         */
        !          2034:        if (dev & CPOLL) {
        !          2035:                com_usage[AL_NUM] = COM_POLLED;
        !          2036:                set_poll_rate();
        !          2037:        } else {                                /* irq-driven port */
        !          2038:                com_usage[AL_NUM] = COM_IRQ;
        !          2039:        }
        !          2040: 
        !          2041:        CDUMP((dev&CPOLL)?"open polled":"open irq")
        !          2042: }
        !          2043: 
        !          2044: /*
        !          2045:  * alxclose()
        !          2046:  *
        !          2047:  *     Called at high priority on last close for the device.
        !          2048:  */
        !          2049: alxclose(dev, mode, tp)
        !          2050: dev_t  dev;
        !          2051: int    mode;
        !          2052: TTY    *tp;
        !          2053: {
        !          2054:        register unsigned holdflags;
        !          2055:        register int b;
        !          2056:        int state, maj;
        !          2057:        int s;
        !          2058: 
        !          2059:        /*
        !          2060:         * Called at high priority by alclose after al_buff is drained
        !          2061:         */
        !          2062:        holdflags = tp->t_flags;        /* save flags */
        !          2063:        AL_H_CLOSE = 1;                 /* disallow reopen til done closing */
        !          2064:        ttclose(tp);                    /* clear flags */
        !          2065:        b = ALPORT;
        !          2066:        /*
        !          2067:         * ttclose() only emptied the output queue tp->t_oq;
        !          2068:         * now wait for the silo tp->rawout to empty
        !          2069:         * and allow a delay for the UART on-chip xmit buffer to empty
        !          2070:         * state 2: waiting for silo to empty
        !          2071:         * state 1: stalling so UART can empty xmit buffer
        !          2072:         * state 0: done!  ok to shut off IRQ for this chip by clearing MC_OUT2
        !          2073:         */
        !          2074:        state = 2;
        !          2075:        while (state) {
        !          2076:                timeout(&AL_TIM, 10, wakeup, (int)&AL_TIM);
        !          2077:                sleep((char *)&AL_TIM, CVTTOUT, IVTTOUT, SVTTOUT);
        !          2078:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          2079:                        state--;
        !          2080:        }
        !          2081: 
        !          2082:        /*
        !          2083:         * If not hanging in open
        !          2084:         */
        !          2085:        if ((holdflags & T_HOPEN) == 0) {
        !          2086:                /*
        !          2087:                 * Disable all ints except TxI
        !          2088:                 */
        !          2089:                outb(b+IER, IE_TxI);
        !          2090:        } else {
        !          2091:                /*
        !          2092:                 * Flags for first open
        !          2093:                 */
        !          2094:                tp->t_flags = T_MODC | T_HOPEN;
        !          2095:        }
        !          2096: 
        !          2097:        /*
        !          2098:         * If hupcls
        !          2099:         */
        !          2100:        if (holdflags & T_HPCL) {
        !          2101:                /*
        !          2102:                 * Hangup port
        !          2103:                 */
        !          2104:                s = sphi();
        !          2105:                outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          2106:                spl(s);
        !          2107: 
        !          2108:                /*
        !          2109:                 * Hold dtr low for timeout
        !          2110:                 */
        !          2111:                maj = major(dev);
        !          2112:                drvl[maj].d_time = 1;
        !          2113:                sleep((char *)&drvl[maj].d_time, CVTTOUT, IVTTOUT, SVTTOUT);
        !          2114:                drvl[maj].d_time = 0;
        !          2115:        }
        !          2116:        s = sphi();
        !          2117:        outb(b+MCR, inb(b+MCR)&(~MC_OUT2));
        !          2118:        spl(s);
        !          2119:        com_usage[AL_NUM] = COM_UNUSED;
        !          2120:        set_poll_rate();
        !          2121:        AL_H_CLOSE = 0;         /* allow reopen - done closing */
        !          2122:        wakeup((char *)&AL_H_CLOSE);
        !          2123:        CDUMP("closed")
        !          2124: }
        !          2125: 
        !          2126: /*
        !          2127:  * Common c_timer routine for async ports.
        !          2128:  */
        !          2129: alxtimer(dev)
        !          2130: dev_t dev;
        !          2131: {
        !          2132:        if (++drvl[major(dev)].d_time > DTRTMOUT)
        !          2133:                wakeup((char *)&drvl[major(dev)].d_time);
        !          2134: }
        !          2135: 
        !          2136: 
        !          2137: /*
        !          2138:  * Common c_ioctl routine for async ports.
        !          2139:  */
        !          2140: alxioctl(dev, com, vec, tp)
        !          2141: dev_t  dev;
        !          2142: struct sgttyb *vec;
        !          2143: register TTY   *tp;
        !          2144: {
        !          2145:        register int    s, b;
        !          2146:        int stat1, stat2;
        !          2147:        unsigned char   msr;
        !          2148:        unsigned char ier_save;
        !          2149: 
        !          2150:        s = sphi();
        !          2151:        b = ALPORT;
        !          2152:        ier_save=inb(b+IER);
        !          2153:        stat1 = inb(b+MCR);             /* get current MCR register status */
        !          2154:        stat2 = inb(b+LCR);             /* get current LCR register status */
        !          2155: 
        !          2156:        switch(com) {
        !          2157:        case TIOCSBRK:                  /* set BREAK */
        !          2158:                outb(b+LCR, stat2|LC_SBRK);
        !          2159:                break;
        !          2160:        case TIOCCBRK:                  /* clear BREAK */
        !          2161:                outb(b+LCR, stat2 & ~LC_SBRK);
        !          2162:                break;
        !          2163:        case TIOCSDTR:                  /* set DTR */
        !          2164:                outb(b+MCR, stat1|MC_DTR);
        !          2165:                break;
        !          2166:        case TIOCCDTR:                  /* clear DTR */
        !          2167:                outb(b+MCR, stat1 & ~MC_DTR);
        !          2168:                break;
        !          2169:        case TIOCSRTS:                  /* set RTS */
        !          2170:                outb(b+MCR, stat1|MC_RTS);
        !          2171:                break;
        !          2172:        case TIOCCRTS:                  /* clear RTS */
        !          2173:                outb(b+MCR, stat1 & ~MC_RTS);
        !          2174:                break;
        !          2175:        case TIOCRSPEED:                /* set "raw" I/O speed divisor */
        !          2176:                outb(b+LCR, stat2|LC_DLAB);  /* set speed latch bit */
        !          2177:                outb(b+DLL, (unsigned) vec);
        !          2178:                outb(b+DLH, (unsigned) vec >> 8);
        !          2179:                outb(b+LCR, stat2);       /* reset latch bit */
        !          2180:                break;
        !          2181:        case TIOCWORDL:         /* set word length and stop bits */
        !          2182:                outb(b+LCR, ((stat2&~0x7) | ((unsigned) vec & 0x7)));
        !          2183:                break;
        !          2184:        case TIOCRMSR:          /* get CTS/DSR/RI/RLSD (MSR) */
        !          2185:                msr = inb(b+MSR);
        !          2186:                AL_MSR_DELTAS |= msr;
        !          2187:                stat1 = msr >> 4;
        !          2188:                kucopy(&stat1, (unsigned *) vec, sizeof(unsigned));
        !          2189:                break;
        !          2190:        default:
        !          2191:                ttioctl(tp, com, vec);
        !          2192:        }
        !          2193:        outb(b+IER, ier_save);
        !          2194:        spl(s);
        !          2195: }
        !          2196: 
        !          2197: alxparam(tp)
        !          2198: TTY    *tp;
        !          2199: {
        !          2200:        register int    b;
        !          2201:        register int    baud;
        !          2202:        int s;
        !          2203: 
        !          2204:        b = ALPORT;
        !          2205: 
        !          2206:        /*
        !          2207:         * error if input speed not the same as output speed
        !          2208:         */
        !          2209:        if (tp->t_sgttyb.sg_ispeed!=tp->t_sgttyb.sg_ospeed) {
        !          2210:                u.u_error = ENODEV;
        !          2211:                return;
        !          2212:        }
        !          2213: 
        !          2214:        if ((baud = albaud[tp->t_sgttyb.sg_ispeed]) == 0) {
        !          2215:                if (tp->t_flags & T_MODC) {  /* modem control? */
        !          2216:                        tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          2217:                        s = sphi();
        !          2218:                        outb(b+MCR, inb(b+MCR) & MC_OUT2); /* hangup */
        !          2219:                        spl(s);
        !          2220:                }
        !          2221:        }
        !          2222: 
        !          2223:        if (baud) {
        !          2224:                unsigned char ier_save;
        !          2225: 
        !          2226:                s=sphi();
        !          2227:                ier_save=inb(b+IER);    /* some chips need this */
        !          2228:                outb(b+LCR, LC_DLAB);
        !          2229:                outb(b+DLL, baud);
        !          2230:                outb(b+DLH, baud >> 8);
        !          2231:                switch (tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW)) {
        !          2232:                case EVENP:
        !          2233:                        outb(b+LCR, LC_CS7 + LC_PARENB + LC_PAREVEN);
        !          2234:                        break;
        !          2235: 
        !          2236:                case ODDP:
        !          2237:                        outb(b+LCR, LC_CS7 + LC_PARENB);
        !          2238:                        break;
        !          2239: 
        !          2240:                default:
        !          2241:                        outb(b+LCR, LC_CS8);
        !          2242:                        break;
        !          2243:                }
        !          2244:                outb(b+IER, ier_save);
        !          2245:                spl(s);
        !          2246:        }
        !          2247:        set_poll_rate();
        !          2248: }
        !          2249: 
        !          2250: /*
        !          2251:  * Middle level processor.
        !          2252:  *
        !          2253:  *     Invoked 10 times per second.
        !          2254:  *     Checks modem status for loss of carrier.
        !          2255:  *     Tranfers rawin buffer [from intr level] to canonical input queue.
        !          2256:  *     Transfers output queue to rawout buffer [for intr level].
        !          2257:  */
        !          2258: alxcycle(tp)
        !          2259: register TTY * tp;
        !          2260: {
        !          2261:        register int b;
        !          2262:        register int n;
        !          2263:        unsigned char msr, mcr;
        !          2264:        int s;
        !          2265: 
        !          2266:        /*
        !          2267:         * Check modem status every ten clock ticks.
        !          2268:         *
        !          2269:         * Modem status interrupts were not enabled due to 8250 hardware bug.
        !          2270:         * Enabling modem status and receive interrupts may cause lockup
        !          2271:         * on older parts.
        !          2272:         *
        !          2273:         * Also check if input silo is nearly full in case we need RTS
        !          2274:         * flow control.
        !          2275:         */
        !          2276:        if (tp->t_flags & T_MODC) {
        !          2277: 
        !          2278:                /*
        !          2279:                 * Get status
        !          2280:                 */
        !          2281:                msr = inb(ALPORT+MSR);
        !          2282:                AL_MSR_DELTAS |= msr;
        !          2283: 
        !          2284:                /*
        !          2285:                 * Carrier changed.
        !          2286:                 */
        !          2287:                if (AL_MSR_DELTAS & MS_DRLSD) {
        !          2288:                        AL_MSR_DELTAS &= ~MS_DRLSD;
        !          2289:                        /*
        !          2290:                         * wakeup open
        !          2291:                         */
        !          2292:                        if (tp->t_open == 0) {
        !          2293:                                wakeup((char *)(&tp->t_open));
        !          2294:                        }
        !          2295: 
        !          2296:                        /*
        !          2297:                         * carrier off?
        !          2298:                         */
        !          2299:                        else if ((msr & MS_RLSD) == 0) {
        !          2300:                                /*
        !          2301:                                 * clear carrier flag; send hangup signal
        !          2302:                                 */
        !          2303:                                s = sphi();
        !          2304:                                tp->t_rawin.si_ox = tp->t_rawin.si_ix;
        !          2305:                                tp->t_rawin.SILO_CHAR_COUNT = 0;
        !          2306:                                spl(s);
        !          2307:                                tthup(tp);
        !          2308:                        }
        !          2309:                }
        !          2310: 
        !          2311:                /*
        !          2312:                 * CTS changed.
        !          2313:                 */
        !          2314:                if (AL_MSR_DELTAS & MS_DCTS) {
        !          2315:                        AL_MSR_DELTAS &= ~MS_DCTS;
        !          2316:                        if (msr & MS_CTS)
        !          2317:                                tp->t_flags &= ~T_STOP;
        !          2318:                        else
        !          2319:                                tp->t_flags |= T_STOP;
        !          2320:                }
        !          2321: 
        !          2322:                /*
        !          2323:                 * If input silo not nearly full, assert RTS.
        !          2324:                 */
        !          2325:                if (tp->t_rawin.SILO_CHAR_COUNT <= SILO_HIGH_MARK) {
        !          2326:                        mcr = inb(ALPORT+MCR);
        !          2327:                        if ((mcr & MC_RTS) == 0) {
        !          2328: printf("%x RTS ON\n", ALPORT);
        !          2329:                                outb(ALPORT+MCR, mcr | MC_RTS);
        !          2330:                        }
        !          2331:                }
        !          2332:        }
        !          2333: 
        !          2334:        /*
        !          2335:         * Empty raw input buffer.
        !          2336:         * If modem control enabled and tt input queue is at high limit
        !          2337:         * (e.g., tp->t_iq.cq_cc >= IHILIM), don't copy from rawin silo
        !          2338:         * to tt input queue.
        !          2339:         */
        !          2340:        if (!(tp->t_flags & T_MODC) || !(tp->t_flags & T_ISTOP))
        !          2341:                while (tp->t_rawin.SILO_CHAR_COUNT > 0) {
        !          2342:                        ttin(tp, tp->t_rawin.si_buf[tp->t_rawin.si_ox]);
        !          2343:                        if (tp->t_rawin.si_ox < MAX_SILO_INDEX)
        !          2344:                                tp->t_rawin.si_ox++;
        !          2345:                        else
        !          2346:                                tp->t_rawin.si_ox = 0;
        !          2347:                        tp->t_rawin.SILO_CHAR_COUNT--;
        !          2348:                }
        !          2349: 
        !          2350:        /*
        !          2351:         * Calculate free output slot count.
        !          2352:         */
        !          2353:        n  = sizeof(tp->t_rawout.si_buf) - 1;
        !          2354:        n += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          2355:        n %= sizeof(tp->t_rawout.si_buf);
        !          2356: 
        !          2357:        /*
        !          2358:         * Fill raw output buffer.
        !          2359:         */
        !          2360:        while ((--n >= 0) && ((b = ttout(tp)) >= 0)) {
        !          2361:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = b;
        !          2362:                if (tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1)
        !          2363:                        tp->t_rawout.si_ix = 0;
        !          2364:                else
        !          2365:                        tp->t_rawout.si_ix++;
        !          2366:        }
        !          2367: 
        !          2368:        /*
        !          2369:         * (Re)start output, wake sleeping processes, etc.
        !          2370:         */
        !          2371:        ttstart(tp);
        !          2372: 
        !          2373:        /*
        !          2374:         * Schedule next cycle.
        !          2375:         */
        !          2376:        timeout(&tp->t_rawtim, HZ/10, alxcycle, tp);
        !          2377: }
        !          2378: 
        !          2379: /*
        !          2380:  * Serial Transmit Start Routine.
        !          2381:  */
        !          2382: alxstart(tp)
        !          2383: register TTY * tp;
        !          2384: {
        !          2385:        register int b;
        !          2386:        register int s;
        !          2387:        extern alxbreak();
        !          2388: 
        !          2389:        /*
        !          2390:         * Read line status register AFTER disabling interrupts.
        !          2391:         */
        !          2392:        s = sphi();
        !          2393:        b = inb(ALPORT+LSR);
        !          2394: 
        !          2395:        /*
        !          2396:         * Process break indication.
        !          2397:         * NOTE: Break indication cleared when line status register was read.
        !          2398:         */
        !          2399:        if (b & LS_BREAK)
        !          2400:                defer(alxbreak, tp);
        !          2401: 
        !          2402:        /*
        !          2403:         * Transmitter is empty, output data is pending.
        !          2404:         */
        !          2405:        if ((b & LS_TxRDY) && (tp->t_rawout.si_ix != tp->t_rawout.si_ox)) {
        !          2406:                outb(   ALPORT+DREG,
        !          2407:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ]);
        !          2408:                if (++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf))
        !          2409:                        tp->t_rawout.si_ox = 0;
        !          2410:        }
        !          2411:        spl(s);
        !          2412: }
        !          2413: 
        !          2414: /*
        !          2415:  * Serial Received Break Handler.
        !          2416:  */
        !          2417: alxbreak(tp)
        !          2418: TTY * tp;
        !          2419: {
        !          2420:        ttsignal(tp, SIGINT);
        !          2421: }
        !          2422: 
        !          2423: /*
        !          2424:  * Serial Interrupt Handler.
        !          2425:  */
        !          2426: alxintr(tp)
        !          2427: register TTY * tp;
        !          2428: {
        !          2429:        register int    b;
        !          2430:        int port = ALPORT;
        !          2431:        unsigned char mcr;
        !          2432: 
        !          2433: rescan:
        !          2434:        switch (inb(port+IIR)) {
        !          2435: 
        !          2436:        case LS_INTR:
        !          2437:                if (inb(port+LSR) & LS_BREAK)
        !          2438:                        defer(alxbreak, tp);
        !          2439:                goto rescan;
        !          2440: 
        !          2441:        case Rx_INTR:
        !          2442:                b = inb(port+DREG);
        !          2443:                if (tp->t_open == 0)
        !          2444:                        goto rescan;
        !          2445:                /*
        !          2446:                 * Must recognize XOFF quickly to avoid transmit overrun.
        !          2447:                 * Recognize XON here as well to avoid race conditions.
        !          2448:                 */
        !          2449:                if ((tp->t_sgttyb.sg_flags & RAWIN) == 0) {
        !          2450:                        /*
        !          2451:                         * XOFF.
        !          2452:                         */
        !          2453:                        if (tp->t_tchars.t_stopc == (b & 0177)) {
        !          2454:                                tp->t_flags |= T_STOP;
        !          2455:                                goto rescan;
        !          2456:                        }
        !          2457: 
        !          2458:                        /*
        !          2459:                         * XON.
        !          2460:                         */
        !          2461:                        if (tp->t_tchars.t_startc == (b & 0177)) {
        !          2462:                                tp->t_flags &= ~T_STOP;
        !          2463:                                goto rescan;
        !          2464:                        }
        !          2465:                }
        !          2466: 
        !          2467:                /*
        !          2468:                 * Save char in raw input buffer.
        !          2469:                 */
        !          2470:                if (tp->t_rawin.SILO_CHAR_COUNT < MAX_SILO_CHARS) {
        !          2471:                        tp->t_rawin.si_buf[tp->t_rawin.si_ix] = b;
        !          2472:                        if (tp->t_rawin.si_ix < MAX_SILO_INDEX)
        !          2473:                                tp->t_rawin.si_ix++;
        !          2474:                        else
        !          2475:                                tp->t_rawin.si_ix = 0;
        !          2476:                        tp->t_rawin.SILO_CHAR_COUNT++;
        !          2477:                }
        !          2478:                if (tp->t_flags & T_MODC)
        !          2479:                        if ((tp->t_flags & T_ISTOP)
        !          2480:                        || (tp->t_rawin.SILO_CHAR_COUNT > SILO_HIGH_MARK)) {
        !          2481:                                mcr = inb(port+MCR);
        !          2482:                                if (mcr & MC_RTS) {
        !          2483:                                        outb(port+MCR, mcr & ~MC_RTS);
        !          2484: printf("%x RTS OFF\n", port);
        !          2485:                                }
        !          2486:                        }
        !          2487:                goto rescan;
        !          2488: 
        !          2489:        case Tx_INTR:
        !          2490:                /*
        !          2491:                 * Do nothing if no raw output data or output is stopped.
        !          2492:                 */
        !          2493:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox) {
        !          2494:                        goto rescan;
        !          2495:                }
        !          2496:                if (tp->t_flags & T_STOP)
        !          2497:                        goto rescan;
        !          2498: 
        !          2499:                /*
        !          2500:                 * Transmit next char in raw output buffer.
        !          2501:                 */
        !          2502:                outb(port+DREG,
        !          2503:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ]);
        !          2504: 
        !          2505:                /*
        !          2506:                 * Adjust raw output buffer output index.
        !          2507:                 */
        !          2508:                if (++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf))
        !          2509:                        tp->t_rawout.si_ox = 0;
        !          2510: 
        !          2511:                /*
        !          2512:                 * Try to fill buffer if now empty.
        !          2513:                 */
        !          2514:                if (tp->t_rawout.si_ox == tp->t_rawout.si_ix) {
        !          2515:                        defer(alxcycle, tp);
        !          2516:                }
        !          2517:                goto rescan;
        !          2518: 
        !          2519:        case MS_INTR:
        !          2520:                AL_MSR_DELTAS |= inb(port+MSR);
        !          2521:                defer(alxcycle, tp);
        !          2522:                goto rescan;
        !          2523:        }
        !          2524: }
        !          2525: 
        !          2526: /*
        !          2527:  * alxclk will be called every time T0 interrupts - if it returns 0,
        !          2528:  * the usual system timer interrupt stuff is done
        !          2529:  */
        !          2530: static int alxclk()
        !          2531: {
        !          2532:        static int count;
        !          2533:        int i;
        !          2534: 
        !          2535:        for (i = 0; i < NUM_AL_PORTS;  i++)
        !          2536:                if (com_usage[i] == COM_POLLED)
        !          2537:                        alxintr(tp_table[i]);
        !          2538:        count++;
        !          2539:        if (count >= poll_divisor)
        !          2540:                count = 0;
        !          2541:        return count;
        !          2542: }
        !          2543: 
        !          2544: /*
        !          2545:  * set_poll_rate is called when a port is opened or closed or changes speed
        !          2546:  * it sets the polling rate only as fast as needed, and shuts off polling
        !          2547:  * whenever possible
        !          2548:  */
        !          2549: static set_poll_rate()
        !          2550: {
        !          2551:        int port_num, max_rate, port_rate;
        !          2552: 
        !          2553:        /*
        !          2554:         * If another driver has the polling clock, do nothing.
        !          2555:         */
        !          2556:        if (poll_owner & ~ POLL_AL)
        !          2557:                return;
        !          2558: 
        !          2559:        /*
        !          2560:         * find highest valid polling rate in units of HZ/10
        !          2561:         */
        !          2562:        max_rate = 0;
        !          2563:        for (port_num = 0; port_num < NUM_AL_PORTS; port_num++) {
        !          2564:                if (com_usage[port_num] == COM_POLLED) {
        !          2565:                        port_rate = alp_rate[(tp_table[port_num])->t_sgttyb.sg_ispeed];
        !          2566:                        if (max_rate < port_rate)
        !          2567:                                max_rate = port_rate;
        !          2568:                }
        !          2569:        }
        !          2570:        /*
        !          2571:         * if max_rate is not current rate, adjust the system clock
        !          2572:         */
        !          2573:        if (max_rate != poll_rate) {
        !          2574:                poll_rate = max_rate;
        !          2575:                poll_divisor = poll_rate/HZ;  /* used in alxclk() */
        !          2576:                altclk_out();           /* stop previous polling */
        !          2577:                poll_owner &= ~ POLL_AL;
        !          2578:                if (max_rate) { /* resume polling at new rate if needed */
        !          2579:                        poll_owner |= POLL_AL;
        !          2580:                        altclk_in(poll_rate, alxclk);
        !          2581:                }
        !          2582:                CDUMP("new rate")
        !          2583:        }
        !          2584: }
        !          2585: 0707070064030050431006440000030000030000011777770507310631100004600000053720/newbits/kernel/USRSRC/i8086/drv/at.c/* (-lgl
        !          2586:  *     COHERENT Driver Kit Version 1.1.0
        !          2587:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          2588:  *     All rights reserved. May not be copied without permission.
        !          2589:  *
        !          2590:  * $Log:       at.c,v $
        !          2591:  * Revision 1.5  91/05/22  15:06:59  hal
        !          2592:  * Don't force 8's bit of control byte.
        !          2593:  * 
        !          2594:  * Revision 1.4        91/03/14  14:22:32      hal
        !          2595:  *
        !          2596:  -lgl) */
        !          2597: /*
        !          2598:  * This is a driver for the
        !          2599:  * hard disk on the AT.
        !          2600:  *
        !          2601:  * Reads drive characteristics from ROM (thru interrupt vector 0x41 and 0x46).
        !          2602:  * Reads partition information from disk.
        !          2603:  */
        !          2604: #include       <sys/coherent.h>
        !          2605: #include       <sys/fdisk.h>
        !          2606: #include       <sys/hdioctl.h>
        !          2607: #include       <sys/buf.h>
        !          2608: #include       <sys/con.h>
        !          2609: #include       <sys/devices.h>
        !          2610: #include       <sys/stat.h>
        !          2611: #include       <sys/uproc.h>
        !          2612: #include       <errno.h>
        !          2613: 
        !          2614: extern saddr_t sds;            /* System Data Selector */
        !          2615: 
        !          2616: /*
        !          2617:  * Configurable parameters
        !          2618:  */
        !          2619: #define        HDIRQ   14                      /* Level 14 */
        !          2620: #define        HDBASE  0x01F0                  /* Port base */
        !          2621: #define NDRIVE 2                       /* only two drives supported */
        !          2622: #define        SOFTLIM 6                       /*  (7) num of retrys before diag */
        !          2623: #define        HARDLIM 8                       /* number of retrys before fail */
        !          2624: #define        BADLIM  100                     /* num to stop recov if flagged bad */
        !          2625: 
        !          2626: #define        BIT(n)          (1 << (n))
        !          2627: 
        !          2628: #define        CMOSA   0x70                    /* write cmos address to this port */
        !          2629: #define        CMOSD   0x71                    /* read cmos data through this port */
        !          2630: 
        !          2631: #ifndef        ATCACHE
        !          2632: #      if VERBOSE > 0
        !          2633: #              define  ATCACHE 2       /* local cache size in blocks */
        !          2634: #      else
        !          2635: #              define  ATCACHE 0       /* no cache for small code */
        !          2636: #      endif
        !          2637: #endif
        !          2638: 
        !          2639: /*
        !          2640:  * Driver configuration.
        !          2641:  */
        !          2642: void   atload();
        !          2643: void   atunload();
        !          2644: void   atopen();
        !          2645: void   atread();
        !          2646: void   atwrite();
        !          2647: int    atioctl();
        !          2648: void   atwatch();
        !          2649: void   atblock();
        !          2650: int    nulldev();
        !          2651: int    nonedev();
        !          2652: 
        !          2653: CON    atcon   = {
        !          2654:        DFBLK|DFCHR,                    /* Flags */
        !          2655:        AT_MAJOR,                       /* Major index */
        !          2656:        atopen,                         /* Open */
        !          2657:        nulldev,                        /* Close */
        !          2658:        atblock,                        /* Block */
        !          2659:        atread,                         /* Read */
        !          2660:        atwrite,                        /* Write */
        !          2661:        atioctl,                        /* Ioctl */
        !          2662:        nulldev,                        /* Powerfail */
        !          2663:        atwatch,                        /* Timeout */
        !          2664:        atload,                         /* Load */
        !          2665:        atunload                        /* Unload */
        !          2666: };
        !          2667: 
        !          2668: /*
        !          2669:  * Forward Referenced Functions.
        !          2670:  */
        !          2671: void   atreset();
        !          2672: int    atdequeue();
        !          2673: void   atstart();
        !          2674: void   atintr();
        !          2675: void   atdefer();
        !          2676: int    aterror();
        !          2677: void   atrecov();
        !          2678: void   atdone();
        !          2679: 
        !          2680: /*
        !          2681:  * I/O Port Addresses
        !          2682:  */
        !          2683: #define        DATA_REG        (HDBASE+0)      /* data (r/w) */
        !          2684: #define        AUX_REG         (HDBASE+1)      /* error(r), write precomp cyl/4 (w) */
        !          2685: #define        NSEC_REG        (HDBASE+2)      /* sector count (r/w) */
        !          2686: #define        SEC_REG         (HDBASE+3)      /* sector number (r/w) */
        !          2687: #define        LCYL_REG        (HDBASE+4)      /* low cylinder (r/w) */
        !          2688: #define        HCYL_REG        (HDBASE+5)      /* high cylinder (r/w) */
        !          2689: #define        HDRV_REG        (HDBASE+6)      /* drive/head (r/w) (D<<4)+(1<<H) */
        !          2690: #define        CSR_REG         (HDBASE+7)      /* status (r), command (w) */
        !          2691: #define        HF_REG          0x3F6
        !          2692: 
        !          2693: /*
        !          2694:  * Error from AUX_REG (r)
        !          2695:  */
        !          2696: #define        DAM_ERR         BIT(0)          /* data address mark not found */
        !          2697: #define        TR0_ERR         BIT(1)          /* track 000 not found */
        !          2698: #define        ABT_ERR         BIT(2)          /* aborted command */
        !          2699: #define        ID_ERR          BIT(4)          /* id not found */
        !          2700: #define        ECC_ERR         BIT(6)          /* data ecc error */
        !          2701: #define        BAD_ERR         BIT(7)          /* bad block detect */
        !          2702: 
        !          2703: /*
        !          2704:  * Status from CSR_REG (r)
        !          2705:  */
        !          2706: #define        ERR_ST          BIT(0)          /* error occurred */
        !          2707: #define        INDEX_ST        BIT(1)          /* index pulse */
        !          2708: #define        SOFT_ST         BIT(2)          /* soft (corrected) ECC error */
        !          2709: #define        DRQ_ST          BIT(3)          /* data request */
        !          2710: #define        SKC_ST          BIT(4)          /* seek complete */
        !          2711: #define        WFLT_ST         BIT(5)          /* improper drive operation */
        !          2712: #define        RDY_ST          BIT(6)          /* drive is ready */
        !          2713: #define        BSY_ST          BIT(7)          /* controller is busy */
        !          2714: 
        !          2715: 
        !          2716: /*
        !          2717:  * Commands to CSR_REG (w)
        !          2718:  */
        !          2719: #define        RESTORE(rate)   (0x10+(rate))   /* X */
        !          2720: #define        SEEK(rate)      (0x70+(rate))   /* X */
        !          2721: #define        READ_CMD        (0x20)          /* X */
        !          2722: #define        WRITE_CMD       (0x30)          /* X */
        !          2723: #define        FORMAT_CMD      (0x50)          /* X */
        !          2724: #define        VERIFY_CMD      (0x40)          /* X */
        !          2725: #define        DIAGNOSE_CMD    (0x90)          /* X */
        !          2726: #define        SETPARM_CMD     (0x91)          /* X */
        !          2727: 
        !          2728: /*
        !          2729:  * Device States.
        !          2730:  */
        !          2731: #define        SIDLE   0                       /* controller idle */
        !          2732: #define        SRETRY  1                       /* seeking */
        !          2733: #define        SREAD   2                       /* reading */
        !          2734: #define        SWRITE  3                       /* writing */
        !          2735: 
        !          2736: /*
        !          2737:  * Drive Parameters - copied from ROM.
        !          2738:  * If patched, use the given values instead of reading from the ROM.
        !          2739:  * NOTE: Exactly duplicates hdparm_s struct.
        !          2740:  */
        !          2741: struct dparm_s {
        !          2742:        unsigned short  d_ncyl;         /* number of cylinders */
        !          2743:        unsigned char   d_nhead;        /* number of heads */
        !          2744:        unsigned short  d_rwcc;         /* reduced write current cyl */
        !          2745:        unsigned short  d_wpcc;         /* write pre-compensation cyl */
        !          2746:        unsigned char   d_eccl;         /* max ecc data length */
        !          2747:        unsigned char   d_ctrl;         /* control byte */
        !          2748:        unsigned char   d_fill2[3];
        !          2749:        unsigned short  d_landc;        /* landing zone cylinder */
        !          2750:        unsigned char   d_nspt;         /* number of sectors per track */
        !          2751:        unsigned char   d_fill3;
        !          2752: 
        !          2753: }      atparm[ NDRIVE ] = {
        !          2754:        0                               /* Initialized to allow patching */
        !          2755: };
        !          2756: 
        !          2757: /*
        !          2758:  * Partition Parameters - copied from disk.
        !          2759:  *
        !          2760:  *     There are NDRIVE * NPARTN positions for the user partitions,
        !          2761:  *     plus NDRIVE additional partitions to span each drive.
        !          2762:  *
        !          2763:  *     Aligning partitions on cylinder boundaries:
        !          2764:  *     Optimal partition size: 2 * 3 * 4 * 5 * 7 * 17 = 14280 blocks
        !          2765:  *     Acceptable partition size:  3 * 4 * 5 * 7 * 17 =  7140 blocks
        !          2766:  */
        !          2767: static
        !          2768: struct fdisk_s pparm[NDRIVE*NPARTN + NDRIVE];
        !          2769: 
        !          2770: /*
        !          2771:  * Per disk controller data.
        !          2772:  * Only one controller; no more, no less.
        !          2773:  */
        !          2774: static
        !          2775: struct at      {
        !          2776:        BUF             *at_actf;       /* Link to first */
        !          2777:        BUF             *at_actl;       /* Link to last */
        !          2778:        faddr_t         at_faddr;       /* Source/Dest virtual address */
        !          2779:        daddr_t         at_bno;         /* Block # on disk */
        !          2780:        unsigned        at_nsec;        /* # of sectors on current transfer */
        !          2781:        unsigned        at_drv;
        !          2782:        unsigned        at_head;
        !          2783:        unsigned        at_cyl;
        !          2784:        unsigned        at_sec;
        !          2785:        unsigned        at_partn;
        !          2786:        unsigned char   at_dtype[ NDRIVE ];     /* drive type, 0 if unused */
        !          2787:        unsigned char   at_tries;
        !          2788:        unsigned char   at_state;
        !          2789:        unsigned char   at_caching;             /* caching in progress */
        !          2790: #if    ATCACHE > 0
        !          2791:        unsigned char   at_cdrv[ ATCACHE ];     /* cached drive */
        !          2792:        daddr_t         at_cbno[ ATCACHE ];     /* cached block number */
        !          2793:        unsigned char * at_cbuf[ ATCACHE ];     /* cached block */
        !          2794: #endif
        !          2795:        unsigned        at_bad_drv;
        !          2796:        unsigned        at_bad_head;
        !          2797:        unsigned        at_bad_cyl;
        !          2798: }      at;
        !          2799: 
        !          2800: static BUF     dbuf;                   /* For raw I/O */
        !          2801: 
        !          2802: int    ATBSYW = 50;                    /* patchable */
        !          2803: static char timeout_msg[] = "at%d: TO\n";
        !          2804: 
        !          2805: /**
        !          2806:  *
        !          2807:  * void
        !          2808:  * atload()    - load routine.
        !          2809:  *
        !          2810:  *     Action: The controller is reset and the interrupt vector is grabbed.
        !          2811:  *             The drive characteristics are set up at this time.
        !          2812:  */
        !          2813: static void
        !          2814: atload()
        !          2815: {
        !          2816:        register int u;
        !          2817:        register struct dparm_s * dp;
        !          2818:        struct { unsigned off, seg; } p;
        !          2819: 
        !          2820:        /*
        !          2821:         * Obtain Drive Types.
        !          2822:         *
        !          2823:         *      High nibble of CMOS 0x12 is drive 0's type.
        !          2824:         *      Low  nibble of CMOS 0x12 is drive 1's type.
        !          2825:         */
        !          2826:        outb( CMOSA, 0x12 );
        !          2827:        /* delay */
        !          2828:        u = inb(CMOSD);
        !          2829:        at.at_dtype[0] = u >> 4;
        !          2830:        at.at_dtype[1] = u & 15;
        !          2831: 
        !          2832:        /*
        !          2833:         * Interrupt Vector 0x41 points to Drive 0 Characteristics.
        !          2834:         */
        !          2835:        pkcopy( (paddr_t) (0x41*4), &p, sizeof p );
        !          2836: 
        !          2837:        /*
        !          2838:         * Obtain Drive Characteristics.
        !          2839:         */
        !          2840:        for ( u = 0, dp = &atparm[0]; u < NDRIVE; ++dp, ++u ) {
        !          2841: 
        !          2842:                if ( dp->d_ncyl == 0 ) {
        !          2843:                        /* Not patched, use the ROM drive table values. */
        !          2844:                        pkcopy( (paddr_t) (p.seg << 4L) + p.off,
        !          2845:                                dp, sizeof(*dp) );
        !          2846:                }
        !          2847:                else {
        !          2848:                        /*
        !          2849:                         * Avoid incomplete patching.
        !          2850:                         */
        !          2851:                        if (at.at_dtype[u] == 0)
        !          2852:                                at.at_dtype[u] = 1;
        !          2853:                        if ( dp->d_nspt == 0 )
        !          2854:                                dp->d_nspt = 17;
        !          2855: #if FORCE_CTRL_8
        !          2856:                        if ( dp->d_nhead > 8 )
        !          2857:                                dp->d_ctrl |= 8;
        !          2858: #endif
        !          2859: 
        !          2860: #if VERBOSE > 0
        !          2861:                        printf(
        !          2862:        "at%d: ncyl=%d nhead=%d wpcc=%d eccl=%d ctrl=%d landc=%d nspt=%d\n",
        !          2863:                                u,
        !          2864:                                dp->d_ncyl,
        !          2865:                                dp->d_nhead,
        !          2866:                                dp->d_wpcc,
        !          2867:                                dp->d_eccl,
        !          2868:                                dp->d_ctrl,
        !          2869:                                dp->d_landc,
        !          2870:                                dp->d_nspt );
        !          2871: #endif
        !          2872:                }
        !          2873: 
        !          2874:                /*
        !          2875:                 * Interrupt Vector 0x46 points to Drive 1 Characteristics.
        !          2876:                 */
        !          2877:                pkcopy( (paddr_t) (0x46*4), &p, sizeof p );
        !          2878:        }
        !          2879: 
        !          2880:        /*
        !          2881:         * Initialize Drive Size.
        !          2882:         */
        !          2883:        for ( u = 0, dp = &atparm[0]; u < NDRIVE; ++dp, ++u ) {
        !          2884: 
        !          2885:                if ( at.at_dtype[u] == 0 )
        !          2886:                        continue;
        !          2887: 
        !          2888:                pparm[NDRIVE*NPARTN + u].p_size =
        !          2889:                        (long) dp->d_ncyl * dp->d_nhead * dp->d_nspt;
        !          2890:        }
        !          2891: 
        !          2892:        /*
        !          2893:         * Initialize Drive Controller.
        !          2894:         */
        !          2895:        atreset();
        !          2896: 
        !          2897:        setivec( HDIRQ, atintr );
        !          2898: 
        !          2899: #if ATCACHE > 0
        !          2900:        at.at_cdrv[0] = -1;
        !          2901:        at.at_cbuf[0] = kalloc( BSIZE );
        !          2902: #endif
        !          2903: 
        !          2904: #if ATCACHE > 1
        !          2905:        at.at_cdrv[1] = -1;
        !          2906:        at.at_cbuf[1] = kalloc( BSIZE );
        !          2907: #endif
        !          2908: 
        !          2909:        at.at_bad_drv = -1;
        !          2910: }
        !          2911: 
        !          2912: /**
        !          2913:  *
        !          2914:  * void
        !          2915:  * atunload()  - unload routine.
        !          2916:  */
        !          2917: static void
        !          2918: atunload()
        !          2919: {
        !          2920:        clrivec( HDIRQ );
        !          2921: }
        !          2922: 
        !          2923: /**
        !          2924:  *
        !          2925:  * void
        !          2926:  * atreset()   -- reset hard disk controller, define drive characteristics.
        !          2927:  */
        !          2928: static void
        !          2929: atreset()
        !          2930: {
        !          2931:        register int u;
        !          2932:        register struct dparm_s * dp;
        !          2933: 
        !          2934:        /*
        !          2935:         * Reset controller for a minimum of 4.8 microseconds.
        !          2936:         */
        !          2937:        outb( HF_REG, 4 );
        !          2938:        for ( u = 100; --u != 0; )
        !          2939:                ;
        !          2940:        outb( HF_REG, atparm[0].d_ctrl & 0x0F );
        !          2941:        myatbsyw(0);
        !          2942:        if ( inb(AUX_REG) != 0x01 )
        !          2943:                printf("at: AT disk controller not present (reset)\n");
        !          2944: 
        !          2945:        /*
        !          2946:         * Initialize drive parameters.
        !          2947:         */
        !          2948:        for ( u = 0, dp = &atparm[0]; u < NDRIVE; ++dp, ++u ) {
        !          2949: 
        !          2950:                if ( at.at_dtype[u] == 0 )
        !          2951:                        continue;
        !          2952: 
        !          2953:                myatbsyw(u);
        !          2954: 
        !          2955:                /*
        !          2956:                 * Set drive characteristics.
        !          2957:                 * 0x1F1 - AUX_REG
        !          2958:                 * 0x1F2 - NSEC_REG
        !          2959:                 * 0x1F3 - SEC_REG
        !          2960:                 * 0x1F4 - LCYL_REG
        !          2961:                 * 0x1F5 - HCYL_REG
        !          2962:                 * 0x1F6 - HDRV_REG
        !          2963:                 * 0x1F7 - CSR_REG
        !          2964:                 */
        !          2965:                outb( HF_REG,   dp->d_ctrl );
        !          2966:                outb( AUX_REG,  dp->d_wpcc / 4 );
        !          2967:                outb( NSEC_REG, dp->d_nspt );
        !          2968:                outb( SEC_REG, 0x01 );
        !          2969:                outb( LCYL_REG, (char)(dp->d_ncyl) );
        !          2970:                outb( HCYL_REG, (char)(dp->d_ncyl >> 8) );
        !          2971:                outb( HDRV_REG, 0xA0 + (u<<4) + dp->d_nhead - 1 );
        !          2972:                outb( CSR_REG,  SETPARM_CMD );
        !          2973:                myatbsyw(u);
        !          2974: 
        !          2975:                /*
        !          2976:                 * Restore heads.
        !          2977:                 */
        !          2978:                outb( CSR_REG, RESTORE(0) );
        !          2979:                myatbsyw(u);
        !          2980:        }
        !          2981: }
        !          2982: 
        !          2983: /**
        !          2984:  *
        !          2985:  * void
        !          2986:  * atopen( dev, mode )
        !          2987:  * dev_t dev;
        !          2988:  * int mode;
        !          2989:  *
        !          2990:  *     Input:  dev = disk device to be opened.
        !          2991:  *             mode = access mode [IPR,IPW, IPR+IPW].
        !          2992:  *
        !          2993:  *     Action: Validate the minor device.
        !          2994:  *             Update the paritition table if necessary.
        !          2995:  */
        !          2996: static void
        !          2997: atopen( dev, mode )
        !          2998: register dev_t dev;
        !          2999: {
        !          3000:        register int d;         /* drive */
        !          3001:        register int p;         /* partition */
        !          3002: 
        !          3003:        p = minor(dev) % (NDRIVE*NPARTN);
        !          3004: 
        !          3005:        if ( minor(dev) & SDEV ) {
        !          3006:                d = minor(dev) % NDRIVE;
        !          3007:                p += NDRIVE * NPARTN;
        !          3008:        }
        !          3009:        else
        !          3010:                d = minor(dev) / NPARTN;
        !          3011: 
        !          3012:        if ( (d >= NDRIVE) || (at.at_dtype[d] == 0) ) {
        !          3013:                u.u_error = ENXIO;
        !          3014:                return;
        !          3015:        }
        !          3016: 
        !          3017:        if ( minor(dev) & SDEV )
        !          3018:                return;
        !          3019: 
        !          3020:        /*
        !          3021:         * If partition not defined read partition characteristics.
        !          3022:         */
        !          3023:        if ( pparm[p].p_size == 0 )
        !          3024:                fdisk( makedev( major(dev), SDEV + d), &pparm[ d * NPARTN ] );
        !          3025: 
        !          3026:        /*
        !          3027:         * Ensure partition lies within drive boundaries and is non-zero size.
        !          3028:         */
        !          3029:        if ((pparm[p].p_base+pparm[p].p_size) > pparm[d+NDRIVE*NPARTN].p_size)
        !          3030:                u.u_error = EBADFMT;
        !          3031:        else if ( pparm[p].p_size == 0 )
        !          3032:                u.u_error = ENODEV;
        !          3033: }
        !          3034: 
        !          3035: /**
        !          3036:  *
        !          3037:  * void
        !          3038:  * atread( dev, iop )  - write a block to the raw disk
        !          3039:  * dev_t dev;
        !          3040:  * IO * iop;
        !          3041:  *
        !          3042:  *     Input:  dev = disk device to be written to.
        !          3043:  *             iop = pointer to source I/O structure.
        !          3044:  *
        !          3045:  *     Action: Invoke the common raw I/O processing code.
        !          3046:  */
        !          3047: static void
        !          3048: atread( dev, iop )
        !          3049: dev_t  dev;
        !          3050: IO     *iop;
        !          3051: {
        !          3052:        ioreq( &dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC );
        !          3053: }
        !          3054: 
        !          3055: /**
        !          3056:  *
        !          3057:  * void
        !          3058:  * atwrite( dev, iop ) - write a block to the raw disk
        !          3059:  * dev_t dev;
        !          3060:  * IO * iop;
        !          3061:  *
        !          3062:  *     Input:  dev = disk device to be written to.
        !          3063:  *             iop = pointer to source I/O structure.
        !          3064:  *
        !          3065:  *     Action: Invoke the common raw I/O processing code.
        !          3066:  */
        !          3067: static void
        !          3068: atwrite( dev, iop )
        !          3069: dev_t  dev;
        !          3070: IO     *iop;
        !          3071: {
        !          3072:        ioreq( &dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC );
        !          3073: }
        !          3074: 
        !          3075: /**
        !          3076:  *
        !          3077:  * int
        !          3078:  * atioctl( dev, cmd, arg )
        !          3079:  * dev_t dev;
        !          3080:  * int cmd;
        !          3081:  * char * vec;
        !          3082:  *
        !          3083:  *     Input:  dev = disk device to be operated on.
        !          3084:  *             cmd = input/output request to be performed.
        !          3085:  *             vec = (pointer to) optional argument.
        !          3086:  *
        !          3087:  *     Action: Validate the minor device.
        !          3088:  *             Update the paritition table if necessary.
        !          3089:  */
        !          3090: static int
        !          3091: atioctl( dev, cmd, vec )
        !          3092: register dev_t dev;
        !          3093: int cmd;
        !          3094: char * vec;
        !          3095: {
        !          3096:        int d;
        !          3097: 
        !          3098:        /*
        !          3099:         * Identify drive number.
        !          3100:         */
        !          3101:        if ( minor(dev) & SDEV )
        !          3102:                d = minor(dev) % NDRIVE;
        !          3103:        else
        !          3104:                d = minor(dev) / NPARTN;
        !          3105: 
        !          3106:        /*
        !          3107:         * Identify input/output request.
        !          3108:         */
        !          3109:        switch ( cmd ) {
        !          3110: 
        !          3111:        case HDGETA:
        !          3112:                /*
        !          3113:                 * Get hard disk attributes.
        !          3114:                 */
        !          3115:                kucopy( &atparm[d], vec, sizeof(atparm[0]) );
        !          3116:                return( 0 );
        !          3117: 
        !          3118:        case HDSETA:
        !          3119:                /* Set hard disk attributes. */
        !          3120:                ukcopy(vec, &atparm[d], sizeof(atparm[0]));
        !          3121:                at.at_dtype[d] = 1;             /* set drive type nonzero */
        !          3122:                pparm[NDRIVE * NPARTN + d].p_size =
        !          3123:                        (long) atparm[d].d_ncyl * atparm[d].d_nhead * atparm[d].d_nspt;
        !          3124:                atreset();
        !          3125:                return 0;
        !          3126: 
        !          3127:        default:
        !          3128:                u.u_error = EINVAL;
        !          3129:                return( -1 );
        !          3130:        }
        !          3131: }
        !          3132: 
        !          3133: /**
        !          3134:  *
        !          3135:  * void
        !          3136:  * atwatch()           - guard against lost interrupt
        !          3137:  *
        !          3138:  *     Action: If drvl[AT_MAJOR] is greater than zero, decrement it.
        !          3139:  *             If it decrements to zero, simulate a hardware interrupt.
        !          3140:  */
        !          3141: static void
        !          3142: atwatch()
        !          3143: {
        !          3144:        register BUF * bp = at.at_actf;
        !          3145:        register int s;
        !          3146: 
        !          3147:        s = sphi();
        !          3148:        if ( --drvl[AT_MAJOR].d_time > 0 ) {
        !          3149:                spl(s);
        !          3150:                return;
        !          3151:        }
        !          3152:        printf("at%d%c: bno=%U head=%u cyl=%u <Watchdog Timeout>\n",
        !          3153:                at.at_drv,
        !          3154:                (bp->b_dev & SDEV) ? 'x' : at.at_partn % NPARTN + 'a',
        !          3155:                bp->b_bno, at.at_head, at.at_cyl );
        !          3156: 
        !          3157:        /*
        !          3158:         * Reset hard disk controller.
        !          3159:         *
        !          3160:         * Mark current cylinder as bad so atstart() will fail.
        !          3161:         * Otherwise would lock up if this track NEVER gives enough IRQ's.
        !          3162:         */
        !          3163:        at.at_bad_drv   = at.at_drv;
        !          3164:        at.at_bad_head  = at.at_head;
        !          3165:        at.at_bad_cyl   = at.at_cyl;
        !          3166:        atreset();
        !          3167:        atstart();
        !          3168:        spl(s);
        !          3169: }
        !          3170: 
        !          3171: /**
        !          3172:  *
        !          3173:  * void
        !          3174:  * atblock( bp )       - queue a block to the disk
        !          3175:  *
        !          3176:  *     Input:  bp = pointer to block to be queued.
        !          3177:  *
        !          3178:  *     Action: Queue a block to the disk.
        !          3179:  *             Make sure that the transfer is within the disk partition.
        !          3180:  */
        !          3181: static void
        !          3182: atblock(bp)
        !          3183: register BUF   *bp;
        !          3184: {
        !          3185:        register struct fdisk_s *pp;
        !          3186:        int partn = minor(bp->b_dev) % (NDRIVE*NPARTN);
        !          3187: 
        !          3188:        bp->b_resid = bp->b_count;
        !          3189: 
        !          3190:        if ( minor(bp->b_dev) & SDEV )
        !          3191:                partn += NDRIVE * NPARTN;
        !          3192: 
        !          3193:        pp = &pparm[ partn ];
        !          3194: 
        !          3195:        /*
        !          3196:         * Check for read at end of partition.
        !          3197:         */
        !          3198:        if ( (bp->b_req == BREAD) && (bp->b_bno == pp->p_size) ) {
        !          3199:                bdone(bp);
        !          3200:                return;
        !          3201:        }
        !          3202: 
        !          3203:        /*
        !          3204:         * Range check disk region.
        !          3205:         */
        !          3206:        if ( ((bp->b_bno + (bp->b_count/BSIZE)) > pp->p_size)
        !          3207:        || (bp->b_count % BSIZE) || bp->b_count == 0) {
        !          3208:                bp->b_flag |= BFERR;
        !          3209:                bdone(bp);
        !          3210:                return;
        !          3211:        }
        !          3212: 
        !          3213:        bp->b_actf = NULL;
        !          3214:        if (at.at_actf == NULL)
        !          3215:                at.at_actf = bp;
        !          3216:        else
        !          3217:                at.at_actl->b_actf = bp;
        !          3218:        at.at_actl = bp;
        !          3219: 
        !          3220:        if ( at.at_state == SIDLE )
        !          3221:                if ( atdequeue() )
        !          3222:                        atstart();
        !          3223: }
        !          3224: 
        !          3225: /**
        !          3226:  *
        !          3227:  * int
        !          3228:  * atdequeue()         - obtain next disk read/write operation
        !          3229:  *
        !          3230:  *     Action: Pull some work from the disk queue.
        !          3231:  *
        !          3232:  *     Return: 0 = no work.
        !          3233:  *             * = work to do.
        !          3234:  */
        !          3235: static int
        !          3236: atdequeue()
        !          3237: {
        !          3238:        register BUF * bp;
        !          3239:        register struct fdisk_s * pp;
        !          3240:        unsigned int nspt;
        !          3241: 
        !          3242:        for (;;) {
        !          3243:                at.at_caching = 0;
        !          3244:                at.at_tries   = 0;
        !          3245: 
        !          3246:                if ( (bp = at.at_actf) == NULL )
        !          3247:                        return (0);
        !          3248: 
        !          3249:                at.at_partn = minor( bp->b_dev ) % (NDRIVE*NPARTN);
        !          3250: 
        !          3251:                if ( minor(bp->b_dev) & SDEV ) {
        !          3252:                        at.at_partn += (NDRIVE*NPARTN);
        !          3253:                        at.at_drv  = minor( bp->b_dev ) % NDRIVE;
        !          3254:                }
        !          3255:                else
        !          3256:                        at.at_drv = minor( bp->b_dev ) / NPARTN;
        !          3257:                nspt = atparm[at.at_drv].d_nspt;
        !          3258: 
        !          3259:                pp = &pparm[ at.at_partn ];
        !          3260:                at.at_bno   = pp->p_base + bp->b_bno;
        !          3261:                at.at_nsec  = bp->b_count / BSIZE;
        !          3262:                at.at_faddr = bp->b_faddr;
        !          3263: 
        !          3264: #if ATCACHE > 0
        !          3265:                if ( bp->b_req == BWRITE ) {
        !          3266: 
        !          3267:                        /*
        !          3268:                         * Invalidate cache if write might overlap.
        !          3269:                         */
        !          3270:                        if ( at.at_nsec > 1 ) {
        !          3271:                                at.at_cdrv[0] = -1;
        !          3272: #if ATCACHE > 1
        !          3273:                                at.at_cdrv[1] = -1;
        !          3274: #endif
        !          3275:                        }
        !          3276:                        else if ( at.at_bno == at.at_cbno[0] )
        !          3277:                                at.at_cdrv[0] = -1;
        !          3278: #if ATCACHE > 1
        !          3279:                        else if ( at.at_bno == at.at_cbno[1] )
        !          3280:                                at.at_cdrv[1] = -1;
        !          3281: #endif
        !          3282:                }
        !          3283:                else if ( at.at_nsec == 1 ) {
        !          3284: 
        !          3285:                        /*
        !          3286:                         * Test for cache hit on block 0.
        !          3287:                         */
        !          3288:                        if ( (at.at_drv == at.at_cdrv[0])
        !          3289:                        &&   (at.at_bno == at.at_cbno[0]) ) {
        !          3290: 
        !          3291:                                kpcopy( at.at_cbuf[0],
        !          3292:                                        bp->b_paddr, BSIZE );
        !          3293:                                at.at_actf  = bp->b_actf;
        !          3294:                                bp->b_resid = 0;
        !          3295:                                bdone(bp);
        !          3296:                                continue;
        !          3297:                        }
        !          3298: 
        !          3299: #if ATCACHE > 1
        !          3300:                        /*
        !          3301:                         * Test for cache hit on block 1.
        !          3302:                         */
        !          3303:                        if ( (at.at_drv == at.at_cdrv[1])
        !          3304:                        &&   (at.at_bno == at.at_cbno[1]) ) {
        !          3305: 
        !          3306:                                kpcopy( at.at_cbuf[1],
        !          3307:                                        bp->b_paddr, BSIZE );
        !          3308:                                at.at_actf  = bp->b_actf;
        !          3309:                                bp->b_resid = 0;
        !          3310:                                bdone(bp);
        !          3311:                                continue;
        !          3312:                        }
        !          3313: #endif
        !          3314: 
        !          3315:                        /*
        !          3316:                         * Enable caching if no backlog for disk i/o.
        !          3317:                         */
        !          3318:                        if ( bp->b_actf == NULL ) {
        !          3319:                                /*
        !          3320:                                 * Enable caching on single block reads
        !          3321:                                 * when at least one block left on same track.
        !          3322:                                 */
        !          3323:                                at.at_caching = nspt - 1 - (at.at_bno % nspt);
        !          3324: #if ATCACHE > 1
        !          3325:                                if ( at.at_caching >= 2 ) {
        !          3326:                                        at.at_caching   = 2;
        !          3327:                                        at.at_cdrv[2-1] = -1;
        !          3328:                                }
        !          3329: #endif
        !          3330: 
        !          3331:                                if ( at.at_caching ) {
        !          3332:                                        at.at_nsec  += at.at_caching;
        !          3333:                                        at.at_cdrv[1-1] = -1;
        !          3334:                                }
        !          3335:                        }
        !          3336:                }
        !          3337: #endif
        !          3338: 
        !          3339:                return (1);
        !          3340:        }
        !          3341: }
        !          3342: 
        !          3343: /**
        !          3344:  *
        !          3345:  * void
        !          3346:  * atstart()   - start or restart next disk read/write operation.
        !          3347:  *
        !          3348:  *     Action: Initiate disk read/write operation.
        !          3349:  */
        !          3350: static void
        !          3351: atstart()
        !          3352: {
        !          3353:        register struct dparm_s *dp;
        !          3354: 
        !          3355:        dp = &atparm[ at.at_drv ];
        !          3356: 
        !          3357:        at.at_cyl  = (at.at_bno / dp->d_nspt) / dp->d_nhead;
        !          3358:        at.at_head = (at.at_bno / dp->d_nspt) % dp->d_nhead;
        !          3359:        at.at_sec  = (at.at_bno % dp->d_nspt) + 1;
        !          3360: 
        !          3361:        /*
        !          3362:         * Check for repeated access to most recently identified bad track.
        !          3363:         */
        !          3364:        if ( (at.at_drv  == at.at_bad_drv )
        !          3365:          && (at.at_cyl  == at.at_bad_cyl )
        !          3366:          && (at.at_head == at.at_bad_head) ) {
        !          3367:                BUF * bp = at.at_actf;
        !          3368:                printf( "at%d%c: bno=%U head=%u cyl=%u <Track Flagged Bad>\n",
        !          3369:                        at.at_drv,
        !          3370:                        (bp->b_dev & SDEV) ? 'x' : at.at_partn % NPARTN + 'a',
        !          3371:                        bp->b_bno,
        !          3372:                        at.at_head,
        !          3373:                        at.at_cyl );
        !          3374:                bp->b_flag |= BFERR;
        !          3375:                atdone(bp);
        !          3376:                return;
        !          3377:        }
        !          3378: 
        !          3379:        myatbsyw(at.at_drv);
        !          3380: 
        !          3381:        outb( HF_REG,   dp->d_ctrl );
        !          3382:        outb( AUX_REG,  dp->d_wpcc / 4 );
        !          3383:        outb( NSEC_REG, at.at_nsec );
        !          3384:        outb( SEC_REG,  at.at_sec );
        !          3385:        outb( LCYL_REG, at.at_cyl );
        !          3386:        outb( HCYL_REG, at.at_cyl >> 8 );
        !          3387:        outb( HDRV_REG, (at.at_drv << 4) + at.at_head + 0xA0 );
        !          3388: 
        !          3389:        if ( at.at_actf->b_req == BWRITE ) {
        !          3390: 
        !          3391:                outb( CSR_REG, WRITE_CMD );
        !          3392: 
        !          3393:                while ( atdrqw() == 0 )
        !          3394:                        printf( timeout_msg, at.at_drv );
        !          3395: 
        !          3396:                atsend( at.at_faddr );
        !          3397:                at.at_state = SWRITE;
        !          3398:        }
        !          3399:        else {
        !          3400:                outb( CSR_REG, READ_CMD );
        !          3401:                at.at_state = SREAD;
        !          3402:        }
        !          3403:        drvl[AT_MAJOR].d_time = 2;
        !          3404: }
        !          3405: 
        !          3406: /**
        !          3407:  *
        !          3408:  * void
        !          3409:  * atintr()    - Interrupt routine.
        !          3410:  *
        !          3411:  */
        !          3412: static void
        !          3413: atintr()
        !          3414: {
        !          3415:        defer( atdefer, 0 );
        !          3416: }
        !          3417: 
        !          3418: /**
        !          3419:  *
        !          3420:  * void
        !          3421:  * atdefer()   - Deferred service of hard disk interrupt.
        !          3422:  *
        !          3423:  *     Action: Service disk interrupt.
        !          3424:  *             Transfer required data.
        !          3425:  *             Update state.
        !          3426:  */
        !          3427: static void
        !          3428: atdefer()
        !          3429: {
        !          3430:        register BUF * bp = at.at_actf;
        !          3431: 
        !          3432:        switch ( at.at_state ) {
        !          3433: 
        !          3434:        case SRETRY:
        !          3435:                atstart();
        !          3436:                break;
        !          3437: 
        !          3438:        case SREAD:
        !          3439:                /*
        !          3440:                 * Check for I/O error before waiting for data.
        !          3441:                 */
        !          3442:                if ( aterror() ) {
        !          3443:                        atrecov();
        !          3444:                        break;
        !          3445:                }
        !          3446: 
        !          3447:                /*
        !          3448:                 * Wait for data, or forever.
        !          3449:                 */
        !          3450:                if ( atdrqw() == 0 )
        !          3451:                        printf( timeout_msg, at.at_drv );
        !          3452: 
        !          3453: #if ATCACHE > 0
        !          3454:                /*
        !          3455:                 * Cache data block.
        !          3456:                 */
        !          3457:                if ( at.at_caching == at.at_nsec )
        !          3458:                        atrecv( at.at_cbuf[ at.at_nsec - 1 ], sds );
        !          3459:                else
        !          3460: #endif
        !          3461: 
        !          3462:                /*
        !          3463:                 * Read data block.
        !          3464:                 */
        !          3465:                        atrecv( at.at_faddr );
        !          3466: 
        !          3467:                /*
        !          3468:                 * Check for I/O error after reading data.
        !          3469:                 */
        !          3470:                if ( aterror() ) {
        !          3471:                        atrecov();
        !          3472:                        break;
        !          3473:                }
        !          3474: 
        !          3475: #if ATCACHE > 0
        !          3476:                /*
        !          3477:                 * Validate cached blocks.
        !          3478:                 */
        !          3479:                if ( at.at_caching == at.at_nsec ) {
        !          3480:                        at.at_cbno[ at.at_nsec - 1 ] = at.at_bno;
        !          3481:                        at.at_cdrv[ at.at_nsec - 1 ] = at.at_drv;
        !          3482:                        at.at_caching--;
        !          3483:                }
        !          3484:                else
        !          3485: #endif
        !          3486:                {
        !          3487:                        FP_OFF(at.at_faddr) += BSIZE;
        !          3488:                        bp->b_resid -= BSIZE;
        !          3489:                }
        !          3490: 
        !          3491:                at.at_tries = 0;
        !          3492:                at.at_bno++;
        !          3493: 
        !          3494:                /*
        !          3495:                 * Check for end of transfer.
        !          3496:                 */
        !          3497:                if ( --at.at_nsec == 0 )
        !          3498:                        atdone( bp );
        !          3499:                break;
        !          3500: 
        !          3501:        case SWRITE:
        !          3502:                /*
        !          3503:                 * Check for I/O error.
        !          3504:                 */
        !          3505:                if ( aterror() ) {
        !          3506:                        atrecov();
        !          3507:                        break;
        !          3508:                }
        !          3509: 
        !          3510:                FP_OFF(at.at_faddr) += BSIZE;
        !          3511:                bp->b_resid -= BSIZE;
        !          3512:                at.at_tries  = 0;
        !          3513:                at.at_bno++;
        !          3514: 
        !          3515:                /*
        !          3516:                 * Check for end of transfer.
        !          3517:                 */
        !          3518:                if ( --at.at_nsec == 0 ) {
        !          3519:                        atdone( bp );
        !          3520:                        break;
        !          3521:                }
        !          3522: 
        !          3523:                /*
        !          3524:                 * Wait for ability to send data, or forever.
        !          3525:                 */
        !          3526:                while ( atdrqw() == 0 )
        !          3527:                        printf( timeout_msg, at.at_drv );
        !          3528: 
        !          3529:                /*
        !          3530:                 * Send data block.
        !          3531:                 */
        !          3532:                atsend( at.at_faddr );
        !          3533:        }
        !          3534: }
        !          3535: 
        !          3536: /**
        !          3537:  *
        !          3538:  * int
        !          3539:  * aterror()
        !          3540:  *
        !          3541:  *     Action: Check for drive error.
        !          3542:  *             If found, increment error count and report it.
        !          3543:  *
        !          3544:  *     Return: 0 = No error found.
        !          3545:  *             1 = Error occurred.
        !          3546:  */
        !          3547: static int
        !          3548: aterror()
        !          3549: {
        !          3550:        register BUF * bp = at.at_actf;
        !          3551:        register int csr;
        !          3552:        register int aux;
        !          3553: 
        !          3554:        if ( (csr = inb(CSR_REG)) & (ERR_ST|WFLT_ST) ) {
        !          3555: 
        !          3556:                aux = inb(AUX_REG);
        !          3557: 
        !          3558:                /*
        !          3559:                 * Don't retry or report failures on cache reads.
        !          3560:                 */
        !          3561: #if ATCACHE > 0
        !          3562:                if ((at.at_state == SREAD) && (at.at_caching == at.at_nsec)) {
        !          3563:                        at.at_tries = BADLIM;
        !          3564:                        return 1;
        !          3565:                }
        !          3566: #endif
        !          3567: 
        !          3568:                if ( aux & BAD_ERR ) {
        !          3569:                        at.at_tries     = BADLIM;
        !          3570:                        at.at_bad_drv   = at.at_drv;
        !          3571:                        at.at_bad_head  = at.at_head;
        !          3572:                        at.at_bad_cyl   = at.at_cyl;
        !          3573:                }
        !          3574:                else if ( ++at.at_tries < SOFTLIM )
        !          3575:                        return 1;
        !          3576: 
        !          3577:                printf( "at%d%c: bno=%U head=%u cyl=%u",
        !          3578:                        at.at_drv,
        !          3579:                        (bp->b_dev & SDEV) ? 'x' : at.at_partn % NPARTN + 'a',
        !          3580:                        (bp->b_count/BSIZE) + bp->b_bno
        !          3581:                                + at.at_caching - at.at_nsec,
        !          3582:                        at.at_head, at.at_cyl );
        !          3583: 
        !          3584: #if VERBOSE > 0
        !          3585:                if ( (csr & RDY_ST) == 0 )
        !          3586:                        printf(" <Drive Not Ready>");
        !          3587:                if ( csr & WFLT_ST )
        !          3588:                        printf(" <Write Fault>");
        !          3589: 
        !          3590:                if ( aux & DAM_ERR )
        !          3591:                        printf(" <No Data Addr Mark>");
        !          3592:                if ( aux & TR0_ERR )
        !          3593:                        printf(" <Track 0 Not Found>" );
        !          3594:                if ( aux & ID_ERR )
        !          3595:                        printf(" <ID Not Found>" );
        !          3596:                if ( aux & ECC_ERR )
        !          3597:                        printf(" <Bad Data Checksum>" );
        !          3598:                if ( aux & ABT_ERR )
        !          3599:                        printf(" <Command Aborted>" );
        !          3600: #else
        !          3601:                if ( (csr & (RDY_ST|WFLT_ST)) != RDY_ST )
        !          3602:                        printf( " csr=%x", csr );
        !          3603:                if ( aux & (DAM_ERR|TR0_ERR|ID_ERR|ECC_ERR|ABT_ERR) )
        !          3604:                        printf( " aux=%x", aux );
        !          3605: #endif
        !          3606:                if ( aux & BAD_ERR )
        !          3607:                        printf(" <Block Flagged Bad>" );
        !          3608: 
        !          3609:                if ( at.at_tries < HARDLIM )
        !          3610:                        printf(" retrying...");
        !          3611:                printf("\n");
        !          3612:                return 1;
        !          3613:        }
        !          3614:        return 0;
        !          3615: }
        !          3616: 
        !          3617: /**
        !          3618:  *
        !          3619:  * void
        !          3620:  * atrecov()
        !          3621:  *
        !          3622:  *     Action: Attempt recovery.
        !          3623:  */
        !          3624: static void
        !          3625: atrecov()
        !          3626: {
        !          3627:        register BUF *bp = at.at_actf;
        !          3628:        register int cmd = SEEK(0);
        !          3629:        register int cyl = at.at_cyl;
        !          3630: 
        !          3631:        switch ( at.at_tries ) {
        !          3632: 
        !          3633:        case 1:
        !          3634:        case 2:
        !          3635:                /*
        !          3636:                 * Move in 1 cylinder, then retry operation
        !          3637:                 */
        !          3638:                if ( --cyl < 0 )
        !          3639:                        cyl += 2;
        !          3640:                break;
        !          3641: 
        !          3642:        case 3:
        !          3643:        case 4:
        !          3644:                /*
        !          3645:                 * Move out 1 cylinder, then retry operation
        !          3646:                 */
        !          3647:                if ( ++cyl >= atparm[ at.at_drv ].d_ncyl )
        !          3648:                        cyl -= 2;
        !          3649:                break;
        !          3650: 
        !          3651:        case 5:
        !          3652:        case 6:
        !          3653:                /*
        !          3654:                 * Seek to cylinder 0, then retry operation
        !          3655:                 */
        !          3656:                cyl = 0;
        !          3657:                break;
        !          3658: 
        !          3659:        default:
        !          3660:                /*
        !          3661:                 * Restore drive, then retry operation
        !          3662:                 */
        !          3663:                cmd = RESTORE(0);
        !          3664:                cyl = 0;
        !          3665:                break;
        !          3666:        }
        !          3667: 
        !          3668:        /*
        !          3669:         * Retry operation [after repositioning head]
        !          3670:         */
        !          3671:        if ( at.at_tries < HARDLIM ) {
        !          3672:                drvl[AT_MAJOR].d_time = (cmd == RESTORE(0)) ? 5 : 2;
        !          3673:                outb( LCYL_REG, cyl );
        !          3674:                outb( HCYL_REG, cyl >> 8 );
        !          3675:                outb( HDRV_REG, (at.at_drv << 4) + 0xA0 );
        !          3676:                outb( CSR_REG, cmd );
        !          3677:                at.at_state = SRETRY;
        !          3678:        }
        !          3679: 
        !          3680:        /*
        !          3681:         * Give up on block.
        !          3682:         */
        !          3683:        else {
        !          3684:                /*
        !          3685:                 * Not a cache-read error.
        !          3686:                 */
        !          3687: #if ATCACHE > 0
        !          3688:                if ( (at.at_state != SREAD) || (at.at_caching != at.at_nsec) )
        !          3689: #endif
        !          3690:                        bp->b_flag |= BFERR;
        !          3691: 
        !          3692:                atdone(bp);
        !          3693:        }
        !          3694: }
        !          3695: 
        !          3696: /**
        !          3697:  *
        !          3698:  * void
        !          3699:  * atdone( bp )
        !          3700:  * BUF * bp;
        !          3701:  *
        !          3702:  *     Action: Release current i/o buffer to the O/S.
        !          3703:  */
        !          3704: static void
        !          3705: atdone( bp )
        !          3706: register BUF * bp;
        !          3707: {
        !          3708:        drvl[AT_MAJOR].d_time = 0;
        !          3709:        at.at_state = SIDLE;
        !          3710:        at.at_actf  = bp->b_actf;
        !          3711:        bdone(bp);
        !          3712: 
        !          3713:        if ( atdequeue() )
        !          3714:                atstart();
        !          3715: }
        !          3716: 
        !          3717: int
        !          3718: myatbsyw(unit) int unit;
        !          3719: {
        !          3720:        register int n, status;
        !          3721: 
        !          3722:        for (n = ATBSYW; n > 0; --n)
        !          3723:                if ((status = atbsyw()) != 0)
        !          3724:                        return status;
        !          3725:        printf(timeout_msg, unit);
        !          3726:        return 0;
        !          3727: }
        !          3728: 0707070064030050451006440000030000030000011777770507310631500005000000004006/newbits/kernel/USRSRC/i8086/drv/atas.s/ (lgl-
        !          3729: /      COHERENT Driver Kit Version 1.1.0
        !          3730: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          3731: /      All rights reserved. May not be copied without permission.
        !          3732: / -lgl)
        !          3733: ////////
        !          3734: /
        !          3735: / AT Hard Disk Assembler Support
        !          3736: /
        !          3737: / atsend( off, seg ) - send 512 bytes from seg:off into hard disk buffer
        !          3738: / atrecv( off, seg ) - receive 512 bytes from hard disk buffer into seg:off.
        !          3739: / DRQ is not checked.  DRQ must be true before atsend/atrecv are called.
        !          3740: /
        !          3741: / atbsyw()          - wait while controller is busy
        !          3742: / atdrqw()          - wait for controller to request data transfer
        !          3743: /
        !          3744: ////////
        !          3745: 
        !          3746:        .globl  atsend_
        !          3747:        .globl  atrecv_
        !          3748:        .globl  atbsyw_
        !          3749:        .globl  atdrqw_
        !          3750: 
        !          3751:        CSR_REG = 0x01F7
        !          3752:        BSY_ST  = 0x80
        !          3753:        DRQ_ST  = 0x08
        !          3754: 
        !          3755: ////////
        !          3756: /
        !          3757: / void
        !          3758: / atsend( fp ) -- send 512 bytes to AT disk controller.
        !          3759: / faddr_t fp;
        !          3760: /
        !          3761: /      Input:  fp = far pointer [sel:off] to data buffer.
        !          3762: /
        !          3763: /      Action: Transfer 512 bytes to AT disk controller from buffer.
        !          3764: /
        !          3765: ////////
        !          3766: 
        !          3767: atsend_:
        !          3768:        push    si
        !          3769:        push    ds
        !          3770:        push    bp
        !          3771:        mov     bp, sp
        !          3772:        lds     si, 8(bp)
        !          3773:        mov     cx, $256
        !          3774:        mov     dx, $0x1F0
        !          3775:        cld
        !          3776:        rep
        !          3777:        outs
        !          3778:        pop     bp
        !          3779:        pop     ds
        !          3780:        pop     si
        !          3781:        ret
        !          3782: 
        !          3783: ////////
        !          3784: /
        !          3785: / void
        !          3786: / atrecv( fp ) -- receive 512 bytes from AT disk controller.
        !          3787: / faddr_t fp;
        !          3788: /
        !          3789: /      Input:  fp = far pointer [sel:off] to data buffer.
        !          3790: /
        !          3791: /      Action: Transfer 512 bytes from AT disk controller to buffer.
        !          3792: /
        !          3793: ////////
        !          3794: 
        !          3795: atrecv_:
        !          3796:        push    di
        !          3797:        push    es
        !          3798:        push    bp
        !          3799:        mov     bp, sp
        !          3800:        les     di, 8(bp)
        !          3801:        mov     cx, $256
        !          3802:        mov     dx, $0x1F0
        !          3803:        cld
        !          3804:        rep
        !          3805:        ins
        !          3806:        pop     bp
        !          3807:        pop     es
        !          3808:        pop     di
        !          3809:        ret
        !          3810: 
        !          3811: ////////
        !          3812: /
        !          3813: / atbsyw()     -- wait for AT disk controller to become not busy
        !          3814: /
        !          3815: /      Return: 0 = timeout
        !          3816: /              * = not busy
        !          3817: /
        !          3818: ////////
        !          3819: 
        !          3820: atbsyw_:
        !          3821:        mov     dx, $CSR_REG
        !          3822:        mov     bx, $4          / add another layer of iteration for 486's
        !          3823: 0:     mov     cx, $-1
        !          3824: 1:     inb     al, dx
        !          3825:        testb   al, $BSY_ST
        !          3826:        loopne  1b
        !          3827:        je      2f              / not busy - return nonzero value
        !          3828:        dec     bx
        !          3829:        jne     0b
        !          3830: 2:     mov     ax, cx
        !          3831:        ret
        !          3832: 
        !          3833: ////////
        !          3834: /
        !          3835: / atdrqw()     -- wait for AT disk controller to initiate data request
        !          3836: /
        !          3837: /      Return: 0 = timeout
        !          3838: /              * = data requested
        !          3839: /
        !          3840: ////////
        !          3841: 
        !          3842: atdrqw_:
        !          3843:        mov     dx, $CSR_REG
        !          3844:        mov     bx, $4
        !          3845: 0:     mov     cx, $-1
        !          3846: 1:     inb     al, dx
        !          3847:        testb   al, $DRQ_ST
        !          3848:        loope   1b
        !          3849:        jne     2f              / not busy - return nonzero value
        !          3850:        dec     bx
        !          3851:        jne     0b
        !          3852: 2:     mov     ax, cx
        !          3853:        ret
        !          3854: 0707070064030050441006440000030000030000011777770507310631600005000000006453/newbits/kernel/USRSRC/i8086/drv/bufq.c/*
        !          3855:  * File:       bufq.c
        !          3856:  *
        !          3857:  * Purpose:
        !          3858:  *     Queueing routines for SCSI driver.
        !          3859:  *     Should be generalizable for other hard drives.
        !          3860:  *
        !          3861:  * $Log:       bufq.c,v $
        !          3862:  * Revision 1.2  91/05/21  23:23:36  hal
        !          3863:  * Enhanced debug printout.
        !          3864:  * 
        !          3865:  * Revision 1.1  91/05/21  13:54:11  root
        !          3866:  * First running version.
        !          3867:  * 
        !          3868:  */
        !          3869: 
        !          3870: /*
        !          3871:  * Includes.
        !          3872:  */
        !          3873: #include <sys/coherent.h>
        !          3874: #include <sys/buf.h>
        !          3875: 
        !          3876: /*
        !          3877:  * Definitions.
        !          3878:  *     Constants.
        !          3879:  *     Macros with argument lists.
        !          3880:  *     Typedefs.
        !          3881:  *     Enums.
        !          3882:  */
        !          3883: typedef struct {
        !          3884:        BUF     * head; /* point to first node */
        !          3885:        BUF     * tail; /* point to last node */
        !          3886:        int     count;  /* number of nodes in the queue */
        !          3887: } bufq_type;
        !          3888: 
        !          3889: /*
        !          3890:  * Global Data.
        !          3891:  *     Import Variables.
        !          3892:  *     Export Variables.
        !          3893:  *     Local Variables.
        !          3894:  */
        !          3895: static int     num_q;          /* number of queues in use */
        !          3896: static bufq_type  * bufq_q;    /* pointer to allocated queue structs */
        !          3897: 
        !          3898: /*
        !          3899:  * Functions.
        !          3900:  *     Import Functions.
        !          3901:  *     Export Functions.
        !          3902:  *     Local Functions.
        !          3903:  */
        !          3904: int bufq_init();
        !          3905: void bufq_rlse();
        !          3906: void bufq_wr_tail();
        !          3907: BUF * bufq_rd_head();
        !          3908: BUF * bufq_rm_head();
        !          3909: 
        !          3910: /*
        !          3911:  * Debug macros.
        !          3912:  */
        !          3913: #if (DEBUG >= 3)
        !          3914: #define QSIZE  printf("Q%d:%d ", s_id, bqp->count)
        !          3915: #else
        !          3916: #if (DEBUG >= 2)
        !          3917: #define QSIZE  {if (bqp->count>1)printf("Q%d:%d ", s_id, bqp->count);}
        !          3918: #else
        !          3919: #define QSIZE
        !          3920: #endif
        !          3921: #endif
        !          3922: 
        !          3923: /*
        !          3924:  * bufq_init()
        !          3925:  *
        !          3926:  * Set up the desired number of queues.
        !          3927:  *
        !          3928:  * Return 1 if ok, 0 if kalloc() failed.
        !          3929:  */
        !          3930: int bufq_init(qcount)
        !          3931: int qcount;
        !          3932: {
        !          3933:        int ret;
        !          3934: 
        !          3935:        if (qcount > 0 && (bufq_q = kalloc(qcount*sizeof(bufq_type)))) {
        !          3936:                ret = 1;
        !          3937:                kclear(bufq_q, qcount*sizeof(bufq_type));
        !          3938:                num_q = qcount;
        !          3939: #if (DEBUG >= 2)
        !          3940: printf("%d queues allocated\n", qcount);
        !          3941: #endif
        !          3942:        } else
        !          3943:                ret = 0;
        !          3944: 
        !          3945:        return ret;
        !          3946: }
        !          3947: 
        !          3948: /*
        !          3949:  * bufq_rlse()
        !          3950:  *
        !          3951:  * Deallocate buffer queue structs.
        !          3952:  */
        !          3953: void bufq_rlse()
        !          3954: {
        !          3955:        num_q = 0;
        !          3956:        if (bufq_q)
        !          3957:                kfree(bufq_q);
        !          3958: }
        !          3959: 
        !          3960: /*
        !          3961:  * bufq_wr_tail()
        !          3962:  *
        !          3963:  * Append a BUF object to the doubly-linked queue.
        !          3964:  * Object to be inserted has been allocated by the caller.
        !          3965:  * Run at high priority.
        !          3966:  */
        !          3967: void bufq_wr_tail(s_id, bp)
        !          3968: int s_id;
        !          3969: BUF * bp;
        !          3970: {
        !          3971:        int s;
        !          3972:        bufq_type * bqp;
        !          3973: 
        !          3974:        if (s_id < num_q) {
        !          3975:                bqp = bufq_q + s_id;
        !          3976:                s = sphi();
        !          3977:                if (bqp->count == 0) {
        !          3978:                        bqp->head = bqp->tail = bp;
        !          3979:                        bp->b_actf = bp->b_actl = NULL;
        !          3980:                } else {
        !          3981:                        bqp->tail->b_actf = bp;
        !          3982:                        bp->b_actf = NULL;
        !          3983:                        bp->b_actl = bqp->tail;
        !          3984:                        bqp->tail = bp;
        !          3985:                }
        !          3986:                bqp->count++;
        !          3987: QSIZE;
        !          3988:                spl(s);
        !          3989:        }
        !          3990: }
        !          3991: 
        !          3992: /*
        !          3993:  * bufq_rd_head()
        !          3994:  *
        !          3995:  * Nondestructively fetch the head entry in the queue - i.e., this routine
        !          3996:  * does not remove an entry from the queue (see ss_rm_head() for that).
        !          3997:  * Return NULL if queue is empty, else return pointer to head item.
        !          3998:  */
        !          3999: BUF * bufq_rd_head(s_id)
        !          4000: int s_id;
        !          4001: {
        !          4002:        bufq_type * bqp;
        !          4003: 
        !          4004:        if (s_id < num_q) {
        !          4005:                bqp = bufq_q + s_id;
        !          4006:                return bqp->head;
        !          4007:        } else
        !          4008:                return NULL;
        !          4009: }
        !          4010: 
        !          4011: /*
        !          4012:  * bufq_rm_head()
        !          4013:  *
        !          4014:  * Delete head item from the queue.  Return a pointer to the node deleted,
        !          4015:  * or NULL if the queue was already empty.
        !          4016:  * Run at high priority.
        !          4017:  *
        !          4018:  * This routine does NOT deallocate the node.  That must be done by the
        !          4019:  * calling function after this routine runs.
        !          4020:  */
        !          4021: BUF * bufq_rm_head(s_id)
        !          4022: int s_id;
        !          4023: {
        !          4024:        BUF * ret;
        !          4025:        int s;
        !          4026:        bufq_type * bqp;
        !          4027: 
        !          4028:        if (s_id < num_q) {
        !          4029:                bqp = bufq_q + s_id;
        !          4030:                s = sphi();
        !          4031:                if (bqp->count > 0) {
        !          4032:                        ret = bqp->head;
        !          4033:                        if (bqp->count == 1) {
        !          4034:                                bqp->head = bqp->tail = NULL;
        !          4035:                        } else {
        !          4036:                                bqp->head = bqp->head->b_actf;
        !          4037:                                bqp->head->b_actl = NULL;
        !          4038:                        }
        !          4039:                        bqp->count--;
        !          4040: QSIZE;
        !          4041:                } else
        !          4042:                        ret = NULL;
        !          4043:                spl(s);
        !          4044:        } else
        !          4045:                ret = NULL;
        !          4046: 
        !          4047:        return ret;
        !          4048: }
        !          4049: 0707070064030050501004440000030000030000011777770507310631700005300000005751/newbits/kernel/USRSRC/i8086/drv/clocked.s////////
        !          4050: /
        !          4051: / Clocked Functions - schedule function 'f' to be periodically invoked.
        !          4052: /                  - invocation is at clock interrupt level
        !          4053: /                  - only one function can be clocked
        !          4054: /
        !          4055: /      clocked( f, hz )
        !          4056: /      void (*f)();
        !          4057: /      int hz;
        !          4058: /
        !          4059: ////////
        !          4060: 
        !          4061:        .globl  clocked_
        !          4062: 
        !          4063: ////////
        !          4064: /
        !          4065: / Hardware Dependant Constants
        !          4066: /
        !          4067: ////////
        !          4068: 
        !          4069:        EOI     = 0x20          / Non-specific End of Interrupt command
        !          4070:        PIC     = 0x20          / 8259 pic   base address
        !          4071:        PIT     = 0x40          / 8253 timer base address
        !          4072: 
        !          4073: ////////
        !          4074: /
        !          4075: / Private Data Declarations
        !          4076: /
        !          4077: ////////
        !          4078: 
        !          4079:        .bssd
        !          4080: stack: .blkb   256             / Run time stack for the clocked function.
        !          4081: stktop:
        !          4082: 
        !          4083:        .shri   / CODE SPACE!
        !          4084: uss:   .word   0               / User stack segment
        !          4085: usp:   .word   0               / User stack pointer
        !          4086: kds:   .word   0               / Kernel data segment
        !          4087: oldclk:        .word   0               / Previous clock interrupt entry point.
        !          4088: reload:        .word   0               / Number of polls per logical clock tick.
        !          4089: resid: .word   0               / Number of polls left in logical clock tick.
        !          4090: cfunc: .word   0               / Clocked function
        !          4091:        .shri
        !          4092: 
        !          4093: ////////
        !          4094: /
        !          4095: / clocked( f, hz )
        !          4096: / void (*f)();
        !          4097: / int hz;
        !          4098: /
        !          4099: /      Input:  f  = function to be clocked.
        !          4100: /              hz = desired clock rate in invocations/second.
        !          4101: /
        !          4102: /      Action: Calculate the number of polls per logical clock tick.
        !          4103: /              Seize the clock hardware interrupt.
        !          4104: /              Preserve the previous clock interrupt handler.
        !          4105: /              Reprogram the hardware clock to the desired rate.
        !          4106: /
        !          4107: /      Return:  0 = clock interrupt seized.
        !          4108: /              -1 = clock interrupt previously seized.
        !          4109: /
        !          4110: /      Notes:  The logical clock rate to the OS will be unchanged.
        !          4111: /
        !          4112: ////////
        !          4113: 
        !          4114: clocked_:
        !          4115:        pop     ax              / Convert IP into PSW,CS,IP so can use iret.
        !          4116:        pushf
        !          4117:        push    cs
        !          4118:        push    ax
        !          4119: 
        !          4120:        mov     cs:kds, ds      / Remember the kernel data segment
        !          4121: 
        !          4122:        cli                     / Disable interrupts
        !          4123: 
        !          4124:        push    es              / Seize clock interrupt vector
        !          4125:        sub     ax, ax
        !          4126:        mov     es, ax
        !          4127:        mov     ax, es:0x0020
        !          4128:        cmp     ax, $clocker
        !          4129:        jne     0f
        !          4130:        mov     ax, $-1
        !          4131:        pop     es
        !          4132:        iret
        !          4133: 
        !          4134: 0:     mov     cs:oldclk, ax
        !          4135:        mov     es:0x0020, $clocker
        !          4136:        pop     es
        !          4137: 
        !          4138:        mov     bx, sp          / Remember the function to be clocked.
        !          4139:        mov     ax, ss:6(bx)
        !          4140:        mov     cs:cfunc, ax
        !          4141: 
        !          4142:        mov     ax, ss:8(bx)    / Compute polling rate relative to 20 hz.
        !          4143:        sub     dx, dx
        !          4144:        mov     cx, $20
        !          4145:        div     cx
        !          4146:        mov     cs:reload, ax
        !          4147:        mov     cs:resid, ax
        !          4148: 
        !          4149:        movb    al, $0x36       / Timer 0, LSB, MSB, mode 3
        !          4150:        outb    PIT+3, al
        !          4151:        mov     ax, $59659
        !          4152:        sub     dx, dx
        !          4153:        div     cs:reload
        !          4154:        outb    PIT, al         / LSB of 59659/reload
        !          4155:        jmp     0f
        !          4156: 0:     movb    al, ah
        !          4157:        outb    PIT, al         / MSB of 59659/reload
        !          4158: 
        !          4159:        sub     ax, ax
        !          4160:        iret
        !          4161: 
        !          4162: ////////
        !          4163: /
        !          4164: /      clocker()       - initiate clocked function.
        !          4165: /
        !          4166: /      Action: Every hardware clock tick, invoke the clocked function.
        !          4167: /              Every 'reload' hardware clock ticks,
        !          4168: /                      simulate a logical clock interrupt to the OS.
        !          4169: /
        !          4170: ////////
        !          4171: 
        !          4172: clocker:
        !          4173:        push    ax              / Save registers.
        !          4174:        push    bx
        !          4175:        push    cx
        !          4176:        push    dx
        !          4177:        push    ds
        !          4178:        push    es
        !          4179: 
        !          4180:        mov     cs:uss, ss      / Save current stack.
        !          4181:        mov     cs:usp, sp
        !          4182: 
        !          4183:        mov     ax, cs:kds      / Remap Data/Extra/Stack Segments into Kernel.
        !          4184:        mov     ds, ax
        !          4185:        mov     es, ax
        !          4186:        mov     ss, ax
        !          4187:        mov     sp, $stktop     / Remap stack pointer onto private intr stack.
        !          4188: 
        !          4189:        icall   cs:cfunc        / Call the clocked function.
        !          4190: 
        !          4191:        mov     ss, cs:uss      / Restore previous stack.
        !          4192:        mov     sp, cs:usp
        !          4193:        
        !          4194:        pop     es              / Restore registers.
        !          4195:        pop     ds
        !          4196:        pop     dx
        !          4197:        pop     cx
        !          4198:        pop     bx
        !          4199: 
        !          4200:        dec     cs:resid
        !          4201:        je      0f
        !          4202:        movb    al, $EOI
        !          4203:        outb    PIC, al
        !          4204:        pop     ax
        !          4205:        iret
        !          4206: 
        !          4207: 0:     mov     ax, cs:reload
        !          4208:        mov     cs:resid, ax
        !          4209:        pop     ax
        !          4210:        ijmp    cs:oldclk
        !          4211: 0707070064030050471004440000030000030000011777770507310631700005300000001525/newbits/kernel/USRSRC/i8086/drv/console.c/* $Header: /usr/src/sys/i8086/drv/RCS/console.c,v 2.1 88/09/03 13:03:39 src Exp $ */
        !          4212: /*
        !          4213:  * Tiny console driver.
        !          4214:  * 8086/8088 Coherent, IBM PC.
        !          4215:  *
        !          4216:  * $Log:       /usr/src/sys/i8086/drv/RCS/console.c,v $
        !          4217:  * Revision 2.1        88/09/03  13:03:39      src
        !          4218:  * *** empty log message ***
        !          4219:  * 
        !          4220:  * Revision 1.1        88/03/24  17:04:25      src
        !          4221:  * Initial revision
        !          4222:  * 
        !          4223:  * 86/11/19    Allan Cornish           /usr/src/sys/i8086/drv/console.c
        !          4224:  * putchar() initializes the (new) (IO).io_flag field to 0.
        !          4225:  */
        !          4226: #include <sys/coherent.h>
        !          4227: #include <sys/inode.h>
        !          4228: #include <sys/stat.h>
        !          4229: #include <sys/con.h>
        !          4230: #include <sys/io.h>
        !          4231: 
        !          4232: dev_t condev = makedev(2,0);
        !          4233: 
        !          4234: putchar(c)
        !          4235: int c;
        !          4236: {
        !          4237:        static coninit;
        !          4238:        IO iob;
        !          4239: 
        !          4240:        if (coninit == 0) {
        !          4241:                ++coninit;
        !          4242:                dopen( condev, IPW, DFCHR );
        !          4243:        }
        !          4244: 
        !          4245:        if (c == '\n')
        !          4246:                putchar('\r');
        !          4247: 
        !          4248:        iob.io_seg  = IOSYS;
        !          4249:        iob.io_ioc  = 1;
        !          4250:        iob.io_base = &c;
        !          4251:        iob.io_flag = 0;
        !          4252:        dwrite( condev, &iob );
        !          4253: }
        !          4254: 0707070064030050521006440000030000030000011777770507310632000004600000032721/newbits/kernel/USRSRC/i8086/drv/dg.c/*
        !          4255:  * dg - device driver for Digiboard PC/Xe intelligent multiport controller
        !          4256:  *
        !          4257:  * $Header: /usr/src/sys/i8086/drv/RCS/dg.c,v 1.3 91/03/05 12:23:42 root Exp $
        !          4258:  *
        !          4259:  * $Log:       /usr/src/sys/i8086/drv/RCS/dg.c,v $
        !          4260:  * Revision 1.3        91/03/05  12:23:42      root
        !          4261:  * Fix cast on dg_ram_base
        !          4262:  * 
        !          4263:  */
        !          4264:  
        !          4265: /*
        !          4266:  * Various notes:
        !          4267:  *
        !          4268:  *     FEP = front-end-processor (the 80186 on the Digiboard)
        !          4269:  *
        !          4270:  *     At port DG_IOB:
        !          4271:  *             the 2's bit is 1 to enable DPRAM, 0 to disable
        !          4272:  *             the 4's bit is 1 to reset FEP, 0 to clear reset 
        !          4273:  *
        !          4274:  *     There is a bug in the current ldlib.a version of setivec and clrivec:
        !          4275:  *     they only work during xxload() and xxunload() due to use of "ucs"
        !          4276:  *     instead of "getcs()" to determine the CS for the interrupt routine.
        !          4277:  */
        !          4278: 
        !          4279: /*
        !          4280:  * Definitions.
        !          4281:  *
        !          4282:  */
        !          4283: #define        DG_RAM_LENGTH   0x10000L
        !          4284: #define DG_MEMORY_SEG  0xF000          /* dual-port ram base on FEP side */
        !          4285: #define DG_BIOS_ADDR   0xF800
        !          4286: #define DG_FEPOS_ADDR  0x2000
        !          4287: #define DG_BIOS_LOADER 0x80            /* minor number to write to BIOS */
        !          4288: #define DG_FEPOS_LOADER        0x40            /* minor number to write to FEPOS */
        !          4289: #define DG_BIOS_LENGTH 0x800           /* PC/Xe BIOS is 2k bytes */
        !          4290: #define DG_BIOS_CONFIRM        0x0C00          /* look for "GD" here */
        !          4291: #define DG_FEP_CONFIRM 0x0D20          /* look for "OS" here */
        !          4292: #define DG_BIOS_REQ    0x0C40          /* Start FEP BIOS requests here */
        !          4293: #define BIOS_GOOD      ('G' + ('D'<<8))        /* "GD" */
        !          4294: #define FEPOS_GOOD     ('O' + ('S'<<8))        /* "OS" */
        !          4295: 
        !          4296: #define CSTART         0x400           /* start addr of command queue */
        !          4297: #define NPORT          0x0C22          /* addr of # of ports */
        !          4298: #define CIN            0x0D10          /* addr for command in pointer */
        !          4299: #define COUT           0x0D12          /* addr for command out pointer */
        !          4300: #define ISTART         0x800           /* start addr of event queue */
        !          4301: #define EIN            0x0D18          /* addr for event in pointer */
        !          4302: #define EOUT           0x0D1A          /* addr for event out pointer */
        !          4303: #define INTERVAL       0x0E04          /* addr for ticks between irpts */
        !          4304: #define EVENT_LEN      4               /* bytes per FEP event */
        !          4305: #define COMMAND_LEN    4               /* bytes per FEP command */
        !          4306: 
        !          4307: /*
        !          4308:  * Includes.
        !          4309:  */
        !          4310: #include "coherent.h" 
        !          4311: #include <sys/io.h>            /* IO */
        !          4312: #include <sys/sched.h>         /* [CIS]VPAUSE */
        !          4313: #include <sys/uproc.h>         /* u.u_error */
        !          4314: #include <sys/proc.h>          /* wakeup();
        !          4315:                                   includes sys/types.h - faddr_t, paddr_t
        !          4316:                                   and sys/timeout.h - TIM
        !          4317:                                   needs coherent.h for KERNEL */
        !          4318: #include <sys/con.h>           /* CON */
        !          4319: #include <sys/stat.h>          /* minor(dev) */
        !          4320: #include <devices.h>           /* device major numbers, including PE_MAJOR */
        !          4321: #include <errno.h>
        !          4322: 
        !          4323: /*
        !          4324:  * Export Functions.
        !          4325:  */
        !          4326: 
        !          4327: /*
        !          4328:  * Export variables - these may be patched in order to configure the driver.
        !          4329:  */
        !          4330: long   DG_RAM = 0xF0000L;      /* segment for 64k of dual-port RAM */
        !          4331: int    DG_IOB = 0x200;         /* address of i/o byte for controller */
        !          4332: int    DG_INT = 15;            /* IRQ number for board's interrupt */
        !          4333: 
        !          4334: /*
        !          4335:  * Import Functions
        !          4336:  */
        !          4337: int    nulldev();
        !          4338: int    nonedev();
        !          4339: 
        !          4340: /*
        !          4341:  * Local functions.
        !          4342:  */
        !          4343: static dgload();
        !          4344: static dgunload();
        !          4345: static dgopen();
        !          4346: static dgclose();
        !          4347: static dgread();
        !          4348: static dgwrite();
        !          4349: static void dgdelay();
        !          4350: static dg_start_timing();
        !          4351: static dg_stop_timing();
        !          4352: static int dginit2();
        !          4353: static int dginit3();
        !          4354: static void dgintr();
        !          4355:  
        !          4356: /*
        !          4357:  * Local variables.
        !          4358:  */
        !          4359: static faddr_t dg_ram_fp;      /* (far *) to access screen */
        !          4360: static paddr_t dg_ram_base;    /* physical address of screen base */
        !          4361: static TIM     delay_tim;      /* needed for calls to timeout() */
        !          4362: static TIM     timeout_tim;    /* needed for calls to timeout() */
        !          4363: static int     dg_expired;     /* TRUE after local timeout */
        !          4364: static int     bios_loading;   /* TRUE if minor device for BIOS load open */
        !          4365: static int     fepos_loading;  /* TRUE if minor device for FEPOS load open */
        !          4366: static int     load_byte_ct;   /* place-holder for BIOS/FEPOS load */
        !          4367: static int     board_ready;    /* TRUE when all board initialization done */
        !          4368: static int     dg_bios_wait;   /* TRUE if waiting for BIOS to be loaded */
        !          4369: static int     dg_fepos_wait;  /* TRUE if waiting for FEPOS to be loaded */
        !          4370: static int     nport;          /* number of ports on the Digiboard */
        !          4371: static int     test_irq;       /* TRUE during startup */
        !          4372: 
        !          4373: /*
        !          4374:  * Configuration table - another export variable.
        !          4375:  */
        !          4376: CON dgcon ={
        !          4377:        DFCHR,                          /* Flags */
        !          4378:        PE_MAJOR,                       /* Major index */
        !          4379:        dgopen,                         /* Open */
        !          4380:        dgclose,                        /* Close */
        !          4381:        nulldev,                        /* Block */
        !          4382:        dgread,                         /* Read */
        !          4383:        dgwrite,                        /* Write */
        !          4384:        nulldev,                        /* Ioctl */
        !          4385:        nulldev,                        /* Powerfail */
        !          4386:        nulldev,                        /* Timeout */
        !          4387:        dgload,                         /* Load */
        !          4388:        dgunload,                       /* Unload */
        !          4389:        nulldev                         /* Poll */
        !          4390: };
        !          4391: 
        !          4392: /*
        !          4393:  * Load Routine.
        !          4394:  */
        !          4395: static dgload()
        !          4396: {
        !          4397:        char v;
        !          4398: 
        !          4399:        setivec(DG_INT, dgintr);
        !          4400:        /*
        !          4401:         * Allocate a selector to map onto the dual-port RAM.  ptov() will
        !          4402:         * return the first available selector of the 8,192 possible.
        !          4403:         */
        !          4404:        dg_ram_base = (paddr_t)((long)(unsigned)DG_RAM << 4);
        !          4405:        dg_ram_fp = ptov(dg_ram_base, (fsize_t)DG_RAM_LENGTH);
        !          4406:        
        !          4407:        /*
        !          4408:         * Reset the board and wait.
        !          4409:         * Actual delay is a tick = 0.01 sec; only need 1msec.
        !          4410:         */
        !          4411:        outb(DG_IOB, 0x04);
        !          4412:        dgdelay(1);
        !          4413:        
        !          4414:        /*
        !          4415:         * Read board ID.
        !          4416:         */
        !          4417:        v = inb(DG_IOB);
        !          4418:        if ((v & 0x01) == 0x01) {
        !          4419:                printf("Error - board type is PC/Xi\n");
        !          4420:                return;
        !          4421:        } else {
        !          4422:                outb(DG_IOB, 0x05);     /* hold FEP reset */
        !          4423:                v = inb(DG_IOB);
        !          4424:                if ((v & 0x01) == 0x01) {
        !          4425:                        printf("Error - board type is PC/Xm\n");
        !          4426:                        return;
        !          4427:                } else
        !          4428:                        printf("PC/Xe ID found\n");
        !          4429:        }
        !          4430:        
        !          4431:        /*
        !          4432:         * Board Reset.
        !          4433:         */
        !          4434:        outb(DG_IOB, 0x04);     /* reset board */
        !          4435:        dg_start_timing(100);   /* start 1-second timer */
        !          4436:        while ((inb(DG_IOB) & 0x0E) != 0x04) {
        !          4437:                if (dg_expired) {
        !          4438:                        printf("Error - PC/Xe failed to reset\n");
        !          4439:                        return;
        !          4440:                }
        !          4441:                dgdelay(10);
        !          4442:        }
        !          4443:        outb(DG_IOB, 0x06);     /* enable memory */
        !          4444:        printf("PC/Xe passed reset\n");
        !          4445: 
        !          4446:        /*
        !          4447:         * Minimal test of PC/Xe's 64k of dual-ported RAM.
        !          4448:         */
        !          4449:        sfword(dg_ram_fp, 0xA55A);              /* store a "far" word */
        !          4450:        sfword(dg_ram_fp + 2, 0x3CC3);
        !          4451:        sfword(dg_ram_fp + 0xFFFC, 0xA55A);
        !          4452:        sfword(dg_ram_fp + 0xFFFE, 0x3CC3);
        !          4453:        if (ffword(dg_ram_fp) != 0xA55A         /* fetch a "far" word */
        !          4454:        ||  ffword(dg_ram_fp + 2) != 0x3CC3
        !          4455:        ||  ffword(dg_ram_fp + 0xFFFC) != 0xA55A
        !          4456:        ||  ffword(dg_ram_fp + 0xFFFE) != 0x3CC3) {
        !          4457:                printf("Error - PC/Xe failed memory test\n");
        !          4458:                return;
        !          4459:        } else
        !          4460:                printf("PC/Xe passed memory test\n");
        !          4461:                
        !          4462:        /*
        !          4463:         * Load and execute the PC/Xe BIOS
        !          4464:         */
        !          4465:        outb(DG_IOB, 0x06);     /* enable memory */
        !          4466:        dg_bios_wait = 1;
        !          4467:        printf("PC/Xe waiting for BIOS load\n");
        !          4468: }
        !          4469: 
        !          4470: static dgunload()
        !          4471: {
        !          4472:        if (board_ready) {
        !          4473:                board_ready = 0;
        !          4474:        }
        !          4475:        
        !          4476:        /*
        !          4477:         * Turn off and unhook interrupts from FEPOS
        !          4478:         */
        !          4479:        sfword(dg_ram_fp+INTERVAL, 0);  /* stop host interrupts */
        !          4480:        outb(DG_IOB, 0x04);             /* Disable DPRAM and hold FEP reset */
        !          4481:        clrivec(DG_INT);
        !          4482: 
        !          4483:        /*
        !          4484:         * We have to free up the selector now that we're done using it.
        !          4485:         */
        !          4486:        vrelse(dg_ram_fp);
        !          4487: }
        !          4488: 
        !          4489: /*
        !          4490:  * Open Routine.
        !          4491:  */
        !          4492: static dgopen( dev, mode )
        !          4493: dev_t dev;
        !          4494: {
        !          4495:        /*
        !          4496:         * If minor number has 128's bit set to 1, this is an attempt to
        !          4497:         * transfer the BIOS to the FEP.
        !          4498:         */
        !          4499:        if (minor(dev) & DG_BIOS_LOADER) {
        !          4500:                if (bios_loading) {
        !          4501:                        u.u_error = EDBUSY;
        !          4502:                        return;
        !          4503:                } else {
        !          4504:                        /*
        !          4505:                         * Only allow BIOS xfer if we are waiting for it.
        !          4506:                         */
        !          4507:                        if (dg_bios_wait) {
        !          4508:                                bios_loading = 1;
        !          4509:                                load_byte_ct = 0;
        !          4510:                        } else {
        !          4511:                                u.u_error = EIO;
        !          4512:                                return;
        !          4513:                        }
        !          4514:                }
        !          4515:        /*
        !          4516:         * If minor number has 64's bit set to 1, this is an attempt to
        !          4517:         * transfer the FEPOS to the FEP.
        !          4518:         */
        !          4519:        } else if (minor(dev) & DG_FEPOS_LOADER) {
        !          4520:                if (fepos_loading) {
        !          4521:                        u.u_error = EDBUSY;
        !          4522:                        return;
        !          4523:                } else {
        !          4524:                        /*
        !          4525:                         * Only allow FEPOS xfer if we are waiting for it.
        !          4526:                         */
        !          4527:                        if (dg_fepos_wait) {
        !          4528:                                fepos_loading = 1;
        !          4529:                                load_byte_ct = 0;
        !          4530:                        } else {
        !          4531:                                u.u_error = EIO;
        !          4532:                                return;
        !          4533:                        }
        !          4534:                }
        !          4535:        } else {
        !          4536:        }
        !          4537: }
        !          4538: 
        !          4539: /*
        !          4540:  * Close Routine.
        !          4541:  */
        !          4542: static dgclose( dev )
        !          4543: dev_t dev;
        !          4544: {
        !          4545:        /*
        !          4546:         * If minor number has 128's bit set to 1, this is an attempt to
        !          4547:         * transfer the BIOS to the FEP.
        !          4548:         */
        !          4549:        if (minor(dev) & DG_BIOS_LOADER) {
        !          4550:                bios_loading = 0;
        !          4551:                /*
        !          4552:                 * Only set dg_fepos_wait if enough bytes got written.
        !          4553:                 */
        !          4554:                if (load_byte_ct == DG_BIOS_LENGTH) {
        !          4555:                        /*
        !          4556:                         * After BIOS is xferred, try to finish
        !          4557:                         * PC/Xe initialization.
        !          4558:                         */
        !          4559:                        if (dginit2()) {
        !          4560:                                dg_bios_wait = 0;
        !          4561:                                dg_fepos_wait = 1;
        !          4562:                                printf("PC/Xe waiting for FEPOS load\n");
        !          4563:                        }
        !          4564:                }
        !          4565:        /*
        !          4566:         * If minor number has 64's bit set to 1, this is an attempt to
        !          4567:         * transfer the FEPOS to the FEP.
        !          4568:         */
        !          4569:        } else if (minor(dev) & DG_FEPOS_LOADER) {
        !          4570:                fepos_loading = 0;
        !          4571:                /*
        !          4572:                 * After BIOS is xferred, try to finish
        !          4573:                 * PC/Xe initialization.
        !          4574:                 */
        !          4575:                if (dginit3()) {
        !          4576:                        dg_fepos_wait = 0;
        !          4577:                        board_ready = 1;
        !          4578:                        printf("PC/Xe ready for use\n");
        !          4579:                }
        !          4580:        } else {
        !          4581:        }
        !          4582: }
        !          4583: 
        !          4584: /*
        !          4585:  * Read Routine.
        !          4586:  */
        !          4587: static dgread( dev, iop )
        !          4588: dev_t dev;
        !          4589: register IO * iop;
        !          4590: {
        !          4591: #if 0
        !          4592:        static int offset;
        !          4593:        int c;
        !          4594:        /*
        !          4595:         * Read a character code from video RAM
        !          4596:         * Start reading RAM just after where previous read ended
        !          4597:         *
        !          4598:         * Note that "offset" is the value of the displacement into
        !          4599:         * the screen RAM. Any expression which results in a value
        !          4600:         * which is less than DG_RAM_LENGTH is OK here.
        !          4601:         */
        !          4602:        while(iop->io_ioc) {
        !          4603:                c = ffbyte(dg_ram_fp + offset); /* fetch a "far" byte */
        !          4604:                if(ioputc(c, iop) == -1)
        !          4605:                        break;
        !          4606:                offset += 2;
        !          4607:                offset %= DG_RAM_LENGTH;
        !          4608:        }
        !          4609: #endif 
        !          4610: }
        !          4611: 
        !          4612: /*
        !          4613:  * Write Routine.
        !          4614:  */
        !          4615: static dgwrite( dev, iop )
        !          4616: dev_t dev;
        !          4617: register IO * iop;
        !          4618: {
        !          4619:        /*
        !          4620:         * If minor number has 128's bit set to 1, this is an attempt to
        !          4621:         * transfer the BIOS to the FEP.
        !          4622:         */
        !          4623:        if (minor(dev) & DG_BIOS_LOADER) {
        !          4624:                int c;
        !          4625: 
        !          4626:                while ((c = iogetc(iop)) >= 0 && load_byte_ct < DG_BIOS_LENGTH) {
        !          4627:                        sfbyte(dg_ram_fp + DG_BIOS_ADDR + load_byte_ct, c);
        !          4628:                        load_byte_ct++;
        !          4629:                }
        !          4630:        /*
        !          4631:         * If minor number has 64's bit set to 1, this is an attempt to
        !          4632:         * transfer the FEPOS to the FEP.
        !          4633:         */
        !          4634:        } else if (minor(dev) & DG_FEPOS_LOADER) {
        !          4635:                int c;
        !          4636: 
        !          4637:                while ((c = iogetc(iop)) >= 0) {
        !          4638:                        sfbyte(dg_ram_fp + DG_FEPOS_ADDR + load_byte_ct, c);
        !          4639:                        load_byte_ct++;
        !          4640:                }
        !          4641:        } else {
        !          4642:        }
        !          4643: }
        !          4644: 
        !          4645: /*
        !          4646:  * Delay for some number of clock ticks.
        !          4647:  * 286/386 kernel ticks are at 100Hz
        !          4648:  * Use kernel function sleep(), which is NOT the system call by that name.
        !          4649:  */
        !          4650: static void dgdelay(ticks)
        !          4651: int ticks;
        !          4652: {
        !          4653:        timeout(&delay_tim, ticks, wakeup, (int)&delay_tim);
        !          4654:        sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
        !          4655: }
        !          4656: 
        !          4657: /*
        !          4658:  * Start a timeout for some number of ticks.
        !          4659:  * Caller knows timer has expired when "dg_expired" goes to 1.
        !          4660:  *
        !          4661:  * Sample invocation:
        !          4662:  *     dg_start_timing(n);
        !          4663:  *     while (check for desired event fails) {
        !          4664:  *             if (dg_expired) {
        !          4665:  *                     ...failure stuff..
        !          4666:  *                     break;
        !          4667:  *             }
        !          4668:  *             dgdelay(m); <= needed to allow kernel to update timers
        !          4669:  *     }
        !          4670:  */
        !          4671: static dg_start_timing(ticks)
        !          4672: int ticks;
        !          4673: {
        !          4674:        dg_expired = 0;
        !          4675:        timeout(&timeout_tim, ticks, dg_stop_timing, 1);
        !          4676: }
        !          4677: 
        !          4678: /*
        !          4679:  * Stub function called only by dg_start_timing()
        !          4680:  */
        !          4681: static dg_stop_timing(flagval)
        !          4682: int flagval;
        !          4683: {
        !          4684:        dg_expired = flagval;
        !          4685: }
        !          4686: 
        !          4687: /*
        !          4688:  * Second part of PC/Xe initialization - done after the BIOS has been
        !          4689:  * written to dual-ported RAM.
        !          4690:  */
        !          4691: static int dginit2()
        !          4692: {
        !          4693:        /*
        !          4694:         * Execute FEP BIOS
        !          4695:         */
        !          4696:        sfword(dg_ram_fp + DG_BIOS_CONFIRM, 0); /* clear confirm word */
        !          4697:        outb(DG_IOB, 0x02);                     /* Release reset */
        !          4698:        dg_start_timing(1000);                  /* start 10-second timer */
        !          4699: 
        !          4700:        while (ffword(dg_ram_fp + DG_BIOS_CONFIRM) != BIOS_GOOD) {
        !          4701:                if (dg_expired) {
        !          4702:                        printf("Error - PC/Xe BIOS won't start\n");
        !          4703:                        return 0;
        !          4704:                }
        !          4705:                dgdelay(10);
        !          4706:        }
        !          4707:        printf("PC/Xe BIOS started\n");
        !          4708: 
        !          4709:        return 1;
        !          4710: }
        !          4711: 
        !          4712: /*
        !          4713:  * Third part of PC/Xe initialization - done after the FEPOS has been
        !          4714:  * written to dual-ported RAM.
        !          4715:  */
        !          4716: static int dginit3()
        !          4717: {
        !          4718:        int cmd;
        !          4719: 
        !          4720:        /*
        !          4721:         * Ask FEP BIOS to move FEPOS into host memory.
        !          4722:         */
        !          4723:        sfword(dg_ram_fp + DG_BIOS_REQ, 0x0002);
        !          4724:        sfword(dg_ram_fp + DG_BIOS_REQ+2, DG_MEMORY_SEG+0x200);
        !          4725:        sfword(dg_ram_fp + DG_BIOS_REQ+4, 0x0000);
        !          4726:        sfword(dg_ram_fp + DG_BIOS_REQ+6, 0x0200);
        !          4727:        sfword(dg_ram_fp + DG_BIOS_REQ+8, 0x0000);
        !          4728:        sfword(dg_ram_fp + DG_BIOS_REQ+0xA, 0x2000);
        !          4729:        outb(DG_IOB, 0x0A);                     /* Toggle interrupt */
        !          4730:        outb(DG_IOB, 0x02);
        !          4731:        dg_start_timing(100);                   /* start 1-second timer */
        !          4732:        while (ffword(dg_ram_fp + DG_BIOS_REQ) != 0) {
        !          4733:                if (dg_expired) {
        !          4734:                        printf("Error - PC/Xe FEPOS move failed\n");
        !          4735:                        return;
        !          4736:                }
        !          4737:                dgdelay(10);
        !          4738:        }
        !          4739:        printf("PC/Xe FEPOS relocated to host RAM\n");
        !          4740: 
        !          4741:        /*
        !          4742:         * Execute FEPOS
        !          4743:         */
        !          4744:        sfword(dg_ram_fp + DG_BIOS_REQ, 0x0001);
        !          4745:        sfword(dg_ram_fp + DG_BIOS_REQ+2, 0x0200);
        !          4746:        sfword(dg_ram_fp + DG_BIOS_REQ+4, 0x0004);
        !          4747:        sfword(dg_ram_fp + DG_FEP_CONFIRM, 0);  /* clear confirm word */
        !          4748:        outb(DG_IOB, 0x0A);                     /* Toggle interrupt */
        !          4749:        outb(DG_IOB, 0x02);
        !          4750:        dg_start_timing(500);                   /* start 5-second timer */
        !          4751:        while (ffword(dg_ram_fp + DG_FEP_CONFIRM) != FEPOS_GOOD) {
        !          4752:                if (dg_expired) {
        !          4753:                        printf("Error - PC/Xe FEPOS won't start\n");
        !          4754:                        printf("Failure code (%x)\n",
        !          4755:                                ffword(dg_ram_fp + DG_BIOS_REQ));
        !          4756:                        return 0;
        !          4757:                }
        !          4758:                dgdelay(10);
        !          4759:        }
        !          4760:        printf("PC/Xe FEPOS started\n");
        !          4761:        nport = ffbyte(dg_ram_fp+NPORT);
        !          4762: 
        !          4763:        /*
        !          4764:         * Enable and test interrupts from FEP
        !          4765:         */
        !          4766:        sfword(dg_ram_fp+INTERVAL, 1);          /* request host interrupts */
        !          4767:        cmd = ffword(dg_ram_fp+CIN);            /* get command pointer */
        !          4768:        sfword(dg_ram_fp+CSTART+cmd, 0xA1FF);   /* send an invalid command */
        !          4769:        sfword(dg_ram_fp+CSTART+cmd+2, 0xC3B2);
        !          4770:        sfword(dg_ram_fp+CIN, (cmd+4)&0x3ff);   /* update command pointer */
        !          4771:        dg_start_timing(100);                   /* start 1-second timer */
        !          4772:        test_irq = 1;
        !          4773:        while (test_irq) {
        !          4774:                if (dg_expired) {
        !          4775:                        printf("Error - PC/Xe no FEPOS interrupts\n");
        !          4776:                        return 0;
        !          4777:                }
        !          4778:                dgdelay(10);
        !          4779:        }
        !          4780:        printf("PC/Xe interrupts working\n");
        !          4781:        
        !          4782:        return 1;
        !          4783: }
        !          4784: 
        !          4785: /*
        !          4786:  * Interrupt handler.
        !          4787:  *
        !          4788:  * No specific action is needed to clear the interrupt
        !          4789:  * as it was a pulse sent from the FEPOS to host's IRQ line.
        !          4790:  */
        !          4791: static void dgintr()
        !          4792: {
        !          4793:        int cin, cout, ein, eout;
        !          4794:        unsigned char event[EVENT_LEN];
        !          4795:        int i;
        !          4796: 
        !          4797:        cin = ffword(dg_ram_fp+CIN);
        !          4798:        cout = ffword(dg_ram_fp+COUT);
        !          4799:        ein = ffword(dg_ram_fp+EIN);
        !          4800:        eout = ffword(dg_ram_fp+EOUT);
        !          4801: 
        !          4802:        if (board_ready) {
        !          4803:                /*
        !          4804:                 * Remove all packets from event queue.
        !          4805:                 */
        !          4806:                while (ffword(dg_ram_fp+EIN) != ffword(dg_ram_fp+EOUT)) {
        !          4807:                        eout = ffword(dg_ram_fp+EOUT);
        !          4808:                        for (i = 0; i < EVENT_LEN; i++)
        !          4809:                                event[i] = ffbyte(dg_ram_fp+ISTART+eout+i);
        !          4810:                        printf("%x %x %x %x\n", event[0],event[1],event[2],event[3]);   
        !          4811:                        sfword(dg_ram_fp+EOUT, (eout+4)&0x3ff);
        !          4812:                }
        !          4813:        } else {        /* e.g., if test_irq is TRUE */
        !          4814:                test_irq = 0;
        !          4815:                /*
        !          4816:                 * Attempt to clear the IRQ condition in the FEP.
        !          4817:                 */
        !          4818:                sfword(dg_ram_fp+EOUT, ffword(dg_ram_fp+EIN));
        !          4819:        }
        !          4820: }
        !          4821: 0707070064030050511004440000030000030000011777770507310632300005200000007617/newbits/kernel/USRSRC/i8086/drv/dmareq.c/* $Header: /usr/src/sys/i8086/drv/RCS/dmareq.c,v 2.1 88/09/03 13:03:47 src Exp $ */
        !          4822: /* (lgl-
        !          4823:  *     The information contained herein is a trade secret of Mark Williams
        !          4824:  *     Company, and  is confidential information.  It is provided  under a
        !          4825:  *     license agreement,  and may be  copied or disclosed  only under the
        !          4826:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          4827:  *     material without the express written authorization of Mark Williams
        !          4828:  *     Company or persuant to the license agreement is unlawful.
        !          4829:  *
        !          4830:  *     COHERENT Version 2.3.37
        !          4831:  *     Copyright (c) 1982, 1983, 1984.
        !          4832:  *     An unpublished work by Mark Williams Company, Chicago.
        !          4833:  *     All rights reserved.
        !          4834:  -lgl) */
        !          4835: 
        !          4836: /*
        !          4837:  * Like ioreq, but guarantee that no DMA straddle occurs.
        !          4838:  * And assume we are called by fl.c, xt.c, dv.c or someone
        !          4839:  * else who obeys the parameter rules that they do.
        !          4840:  *
        !          4841:  * $Log:       /usr/src/sys/i8086/drv/RCS/dmareq.c,v $
        !          4842:  * Revision 2.1        88/09/03  13:03:47      src
        !          4843:  * *** empty log message ***
        !          4844:  * 
        !          4845:  * Revision 1.1        88/03/24  17:04:28      src
        !          4846:  * Initial revision
        !          4847:  * 
        !          4848:  * 87/11/25    Allan Cornish           /usr/src/sys/i8086/drv/dmareq.c
        !          4849:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          4850:  *
        !          4851:  * 87/01/05    Allan Cornish           /usr/src/sys/i8086/drv/dmareq.c
        !          4852:  * dmareq() now wakes &stimer only if the swap timer is active.
        !          4853:  */
        !          4854: #include <sys/coherent.h>
        !          4855: #include <sys/buf.h>
        !          4856: #include <sys/con.h>
        !          4857: #include <errno.h>
        !          4858: #include <sys/io.h>
        !          4859: #include <sys/proc.h>
        !          4860: #include <sys/sched.h>
        !          4861: #include <sys/seg.h>
        !          4862: #include <sys/stat.h>
        !          4863: #include <sys/uproc.h>
        !          4864: #include <sys/dmac.h>
        !          4865: 
        !          4866: dmareq(bp, iop, dev, req)
        !          4867: register BUF *bp;
        !          4868: register IO *iop;
        !          4869: dev_t dev;
        !          4870: {
        !          4871:        register int n;
        !          4872:        register SEG *sp;
        !          4873:        register CON *cp;
        !          4874:        dold_t dold;
        !          4875:        long l;
        !          4876:        BUF *tbp;
        !          4877: 
        !          4878:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          4879:                return;
        !          4880:        lock(bp->b_gate);
        !          4881:        n = cp->c_flag;
        !          4882:        drest(dold);
        !          4883:        if (blocko(iop->io_seek) != 0) {
        !          4884:                u.u_error = EIO;
        !          4885:                goto out;
        !          4886:        }
        !          4887:        if ((sp=iomapvp(iop, bp)) == NULL) {
        !          4888:                u.u_error = EIO;
        !          4889:                goto out;
        !          4890:        }
        !          4891:        bp->b_dev = dev;
        !          4892:        bp->b_flag = 0;
        !          4893:        sp->s_lrefc++;
        !          4894:        bp->b_faddr = ptov( bp->b_paddr, (fsize_t) bp->b_count );
        !          4895:        /*
        !          4896:         * The dma address is 20 bits; 16 bit offset counter from a 4 bit
        !          4897:         * base segment.  Since io_ioc is limited to 32Kb positive, we
        !          4898:         * have at most two raw transfers separated by a block which
        !          4899:         * straddles the segment boundary.
        !          4900:         * Life would be simpler if we assumed io_ioc % BSIZE, but
        !          4901:         * flioctl comes through here with it's short format buffer.
        !          4902:         */
        !          4903:        while (iop->io_ioc > 0 && (bp->b_flag&BFERR) == 0) {
        !          4904:                l = dmaseg(bp->b_paddr+iop->io_ioc-1) - bp->b_paddr;
        !          4905:                if (l < 0)
        !          4906:                        n = iop->io_ioc;
        !          4907:                else
        !          4908:                        n = l & ~((long)BSIZE-1);
        !          4909:                l = blockn(iop->io_seek);
        !          4910:                if (n == 0) {
        !          4911:                        /* Straddle block */
        !          4912:                        tbp = bp;               /* Save the raw buffer */
        !          4913:                        n = BSIZE;
        !          4914:                        if (n > iop->io_ioc)
        !          4915:                                n = iop->io_ioc;
        !          4916:                        bp = bclaim(dev, l);
        !          4917:                        bp->b_count = n;
        !          4918:                        bp->b_req = req;
        !          4919:                        if (req != BREAD)
        !          4920:                                ioread(iop, FP_OFF(bp->b_faddr), n);
        !          4921:                        dmabuf(bp, dev);
        !          4922:                        if ((bp->b_flag&BFERR) == 0) {
        !          4923:                                if (req == BREAD)
        !          4924:                                        iowrite(iop, FP_OFF(bp->b_faddr), n);
        !          4925:                        } else {
        !          4926:                                tbp->b_flag = bp->b_flag;
        !          4927:                                tbp->b_err = bp->b_err;
        !          4928:                                if (req != BREAD)
        !          4929:                                        iop->io_ioc += bp->b_resid;
        !          4930:                        }
        !          4931:                        bp->b_flag |= BFERR;
        !          4932:                        brelease(bp);
        !          4933:                        bp = tbp;               /* Reclaim raw buffer */
        !          4934:                } else {
        !          4935:                        /* Raw transfer */
        !          4936:                        bp->b_count = n;
        !          4937:                        bp->b_req = req;
        !          4938:                        bp->b_bno = l;
        !          4939:                        dmabuf(bp, dev);
        !          4940:                        if ((bp->b_flag&BFERR) != 0)
        !          4941:                                n -= bp->b_resid;
        !          4942:                        iop->io_ioc -= n;       /* cookedio do these */
        !          4943:                        iop->io_base += n;      /* for everyone */
        !          4944:                }
        !          4945:                FP_OFF(bp->b_faddr) += n;
        !          4946:                bp->b_paddr  += n;
        !          4947:                iop->io_seek += n;
        !          4948:                /* And continue for the next chunk */
        !          4949:        }
        !          4950:        vrelse( bp->b_faddr );
        !          4951:        sp->s_lrefc--;
        !          4952:        if ( stimer.t_last != 0 )
        !          4953:                wakeup((char *)&stimer);
        !          4954:        if ((bp->b_flag&BFERR) != 0 && (u.u_error = bp->b_err) == 0)
        !          4955:                u.u_error = EIO;
        !          4956: out:
        !          4957:        unlock(bp->b_gate);
        !          4958: }
        !          4959: 
        !          4960: static
        !          4961: dmabuf(bp, dev)
        !          4962: register BUF *bp;
        !          4963: dev_t dev;
        !          4964: {
        !          4965:        register int s;
        !          4966:        bp->b_flag = BFRAW|BFBLK|BFIOC|BFNTP;
        !          4967:        s = sphi();
        !          4968:        dblock(dev, bp);
        !          4969:        while ((bp->b_flag&BFNTP) != 0)
        !          4970:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          4971:        spl(s);
        !          4972: }
        !          4973: 0707070064030050531006440000030000030000011777770507310632400005100000002600/newbits/kernel/USRSRC/i8086/drv/fdisk.c/* (-lgl
        !          4974:  *     COHERENT Driver Kit Version 1.1.0
        !          4975:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          4976:  *     All rights reserved. May not be copied without permission.
        !          4977:  -lgl) */
        !          4978: /**
        !          4979:  *
        !          4980:  * fdisk( dev, fp )    --      Fixed Disk Configuration
        !          4981:  * dev_t dev;
        !          4982:  * struct fdisk_s *fp;
        !          4983:  *
        !          4984:  *     Input:  dev = special device to read partition information from
        !          4985:  *             fp  = pointer to memory-resident partition info (to update)
        !          4986:  *
        !          4987:  *     Action: Open special device for reading.
        !          4988:  *             Read first block from the device.
        !          4989:  *             If valid signature present on block,
        !          4990:  *                     copy partition information to memory
        !          4991:  *
        !          4992:  *     Return: 1 = partition information successfully updated
        !          4993:  *             0 = failure (could not read block, or bad signature)
        !          4994:  */
        !          4995: 
        !          4996: #include <sys/coherent.h>
        !          4997: #include <sys/uproc.h>
        !          4998: #include <errno.h>
        !          4999: #include <sys/inode.h>
        !          5000: #include <sys/fdisk.h>
        !          5001: #include <sys/buf.h>
        !          5002: #include <sys/con.h>
        !          5003: 
        !          5004: fdisk( dev, fp )
        !          5005: dev_t dev;
        !          5006: register struct fdisk_s *fp;
        !          5007: {
        !          5008:        register struct hdisk_s *hp;
        !          5009:        BUF *bp;
        !          5010:        int s, i;
        !          5011:        int ret = 0;
        !          5012: 
        !          5013:        s = sphi( );
        !          5014:        dopen( dev, IPR, DFBLK );
        !          5015: 
        !          5016:        if ( u.u_error == 0 ) {         /* special device now open */
        !          5017: 
        !          5018:                if (bp = bread(dev, (daddr_t) 0, 1)) {  /* data read */
        !          5019: 
        !          5020:                        /* buffer cache is in kernel data space */
        !          5021:                        hp = FP_OFF(bp->b_faddr);
        !          5022: 
        !          5023:                        if ( hp->hd_sig == HDSIG ) {    /* valid data */
        !          5024: 
        !          5025:                                for (i=0; i < NPARTN; ++i)
        !          5026:                                        *fp++ = hp->hd_partn[i];
        !          5027: 
        !          5028:                                ret   = 1;
        !          5029:                        }
        !          5030:                        brelease( bp );
        !          5031:                }
        !          5032:                dclose( dev );
        !          5033:        }
        !          5034:        spl( s );
        !          5035:        return ret;
        !          5036: }
        !          5037: 0707070064030050541004440000030000030000011777770507310632400004600000057212/newbits/kernel/USRSRC/i8086/drv/fl.c/* (-lgl
        !          5038:  *     COHERENT Driver Kit Version 1.1.0
        !          5039:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          5040:  *     All rights reserved. May not be copied without permission.
        !          5041:  -lgl) */
        !          5042: /*
        !          5043:  * This is a driver for the IBM AT or PC/XT
        !          5044:  * floppy, using interrupts and DMA on
        !          5045:  * the NEC 756 floppy chip. Ugh.
        !          5046:  * Handles single, double and quad
        !          5047:  * density drives, 8, 9, 15 or 18 sectors per track.
        !          5048:  * 15 and 18 sectors per track only available on the IBM_AT.
        !          5049:  *
        !          5050:  * Minor device assignments: xxuuhkkk
        !          5051:  *     uu - unit = 0/1/2/3
        !          5052:  *     kkk - kind, struct fdata infra.
        !          5053:  *     h - alternating head rather than side by side
        !          5054:  *
        !          5055:  */
        !          5056: 
        !          5057: #include       <sys/coherent.h>
        !          5058: #include       <sys/i8086.h>
        !          5059: #include       <sys/buf.h>
        !          5060: #include       <sys/con.h>
        !          5061: #include       <sys/stat.h>
        !          5062: #include       <errno.h>
        !          5063: #include       <sys/uproc.h>
        !          5064: #include       <sys/fdioctl.h>
        !          5065: #include       <sys/sched.h>
        !          5066: #include       <sys/dmac.h>
        !          5067: #include       <sys/devices.h>
        !          5068: 
        !          5069: #define                BIT(n)          (1 << (n))
        !          5070: 
        !          5071: /*
        !          5072:  * Patchable parameters (default to IBM PC/XT values).
        !          5073:  */
        !          5074: 
        !          5075: int    fl_srt = 0xC;   /* Floppy seek step rate, in unit 2 millisec */
        !          5076:                        /* NOT DIRECTLY ENCODED */
        !          5077:                        /* COMPAQ wants 0xD */
        !          5078: int    fl_hlt = 1;     /* Floppy head load time, in unit 4 millisec */
        !          5079: int    fl_hut = 0xF;   /* Floppy head unload time, in unit 32 millisec */
        !          5080: 
        !          5081: int    flload();
        !          5082: int    flunload();
        !          5083: int    flopen();
        !          5084: int    flblock();
        !          5085: int    flread();
        !          5086: int    flwrite();
        !          5087: int    flioctl();
        !          5088: int    fldelay();
        !          5089: int    flintr();
        !          5090: int    fltimeout();
        !          5091: int    nulldev();
        !          5092: int    nonedev();
        !          5093: 
        !          5094: CON    flcon   = {
        !          5095:        DFBLK|DFCHR,                    /* Flags */
        !          5096:        FL_MAJOR,                               /* Major index */
        !          5097:        flopen,                         /* Open */
        !          5098:        nulldev,                        /* Close */
        !          5099:        flblock,                        /* Block */
        !          5100:        flread,                         /* Read */
        !          5101:        flwrite,                        /* Write */
        !          5102:        flioctl,                        /* Ioctl */
        !          5103:        nulldev,                        /* Powerfail */
        !          5104:        fltimeout,                      /* Timeout */
        !          5105:        flload,                         /* Load */
        !          5106:        flunload                        /* Unload */
        !          5107: };
        !          5108: 
        !          5109: #define        MTIMER  5                       /* Motor timeout */
        !          5110: #define        FDCDOR  0x3F2                   /* Digital output */
        !          5111: #define        FDCDAT  0x3F5                   /* Data register */
        !          5112: #define        FDCMSR  0x3F4                   /* Main status register */
        !          5113: #define        FDCRATE 0x3F7                   /* Transfer rate (500,300,250 Kbps) */
        !          5114: 
        !          5115: #define        DORDS   0x03                    /* Drive select bits */
        !          5116: #define        DORNMR  0x04                    /* Not master reset */
        !          5117: #define        DORIEN  0x08                    /* Interrupt, DMA enable */
        !          5118: #define        DORMS   0xF0                    /* Motor enables */
        !          5119: 
        !          5120: #define        MSRDB   0x0F                    /* Drive busy */
        !          5121: #define        MSRCB   0x10                    /* Control busy */
        !          5122: #define        MSRNDMA 0x20                    /* Not DMA */
        !          5123: #define        MSRDIO  0x40                    /* Data direction */
        !          5124: #define        MSRRQM  0x80                    /* Request for master */
        !          5125: 
        !          5126: /*
        !          5127:  * Status Register 0 - Bit Definitions.
        !          5128:  */
        !          5129: #define        ST0_US0 0x01                    /* Unit Select 0 */
        !          5130: #define        ST0_US1 0x02                    /* Unit Select 1 */
        !          5131: #define        ST0_HD  0x04                    /* Head Address */
        !          5132: #define        ST0_NR  0x08                    /* Not Ready */
        !          5133: #define        ST0_EC  0x10                    /* Equipment Check */
        !          5134: #define        ST0_SE  0x20                    /* Seek End */
        !          5135: #define        ST0_IC  0xC0                    /* Interrupt code */
        !          5136: #define        ST0_NT  0x00                    /* Normal Termination */
        !          5137: 
        !          5138: /*
        !          5139:  * Status Register 1 - Bit Definitions.
        !          5140:  */
        !          5141: #define        ST1_MA  0x01                    /* Missing Address Mark */
        !          5142: #define        ST1_NW  0x02                    /* Not writeable */
        !          5143: #define        ST1_ND  0x04                    /* No Data */
        !          5144:        /*      0x08 */                 /* Not used - always 0 */
        !          5145: #define        ST1_OR  0x10                    /* Overrun */
        !          5146: #define        ST1_DE  0x20                    /* Data Error */
        !          5147:        /*      0x40 */                 /* Not used - always 0 */
        !          5148: #define        ST1_EN  0x80                    /* End of Cylinder */
        !          5149: 
        !          5150: /*
        !          5151:  * Status Register 2 - Bit Definitions.
        !          5152:  */
        !          5153: #define        ST2_MD  0x01                    /* Missing Address Mark in Data Field */
        !          5154: #define        ST2_BC  0x02                    /* Bad Cylinder */
        !          5155: #define        ST2_SN  0x04                    /* Scan Not Satisfied */
        !          5156: #define        ST2_SH  0x08                    /* Scan Equal Hit */
        !          5157: #define        ST2_WC  0x10                    /* Wrong Cylinder */
        !          5158: #define        ST2_DD  0x20                    /* Data Error in Data Field */
        !          5159: #define        ST2_CM  0x40                    /* Control Mark */
        !          5160:        /*      0x80 */                 /* Not used - always 0 */
        !          5161: 
        !          5162: /*
        !          5163:  * Status Register 3 - Bit Definitions.
        !          5164:  */
        !          5165: #define        ST3_US0 0x01                    /* Unit Select 0 */
        !          5166: #define        ST3_US1 0x02                    /* Unit Select 1 */
        !          5167: #define        ST3_HD  0x04                    /* Head Address */
        !          5168: #define        ST3_TS  0x08                    /* Two Sides */
        !          5169: #define        ST3_T0  0x10                    /* Track 0 */
        !          5170: #define        ST3_RDY 0x20                    /* Ready */
        !          5171: #define        ST3_WP  0x40                    /* Write Protected */
        !          5172: #define        ST3_FT  0x80                    /* Fault */
        !          5173: 
        !          5174: /*
        !          5175:  * Controller Commands.
        !          5176:  */
        !          5177: #define        CMDSPEC 0x03                    /* Specify */
        !          5178: #define        CMDRCAL 0x07                    /* Recal */
        !          5179: #define        CMDSEEK 0x0F                    /* Seek */
        !          5180: #define        CMDRDAT 0x66                    /* Read data */
        !          5181: #define        CMDWDAT 0x45                    /* Write data */
        !          5182: #define        CMDSINT 0x08                    /* Sense status */
        !          5183: #define        CMDFMT  0x4D                    /* Format track */
        !          5184: 
        !          5185: /*
        !          5186:  * Driver States.
        !          5187:  */
        !          5188: #define        SIDLE   0                       /* Idle */
        !          5189: #define        SSEEK   1                       /* Need seek */
        !          5190: #define        SRDWR   2                       /* Need read/write command */
        !          5191: #define        SENDIO  3                       /* Need end I/O processing */
        !          5192: #define        SDELAY  4                       /* Delay before next disk operation */
        !          5193: #define        SHDLY   5                       /* Head settling delay before r/w */
        !          5194: #define SLOCK  6                       /* Got DMA controller lock */
        !          5195: 
        !          5196: #define funit(x)       (minor(x)>>4)   /* Unit/drive number */
        !          5197: #define fkind(x)       (minor(x)&0x7)  /* Kind of format */
        !          5198: #define        fhbyh(x)        (minor(x)&0x8)  /* 0=Side by side, 1=Head by head */
        !          5199: 
        !          5200: static
        !          5201: struct fdata {
        !          5202:        int     fd_size;        /* Blocks per diskette */
        !          5203:        int     fd_nhds;        /* Heads per drive */
        !          5204:        int     fd_trks;        /* Tracks per side */
        !          5205:        int     fd_offs;        /* Sector base */
        !          5206:        int     fd_nspt;        /* Sectors per track */
        !          5207:        char    fd_GPL[4];      /* Controller gap param (indexed by rate) */
        !          5208:        char    fd_N;           /* Controller size param */
        !          5209:        char    fd_FGPL;        /* Format gap length */
        !          5210: } fdata[] = {
        !          5211: /* 8 sectors per track, surface by surface seek. */
        !          5212:        {  320,1,40,0, 8, { 0x00,0x23,0x2A }, 2,0x50 }, /* Single sided */
        !          5213:        {  640,2,40,0, 8, { 0x00,0x23,0x2A }, 2,0x50 }, /* Double sided */
        !          5214:        { 1280,2,80,0, 8, { 0x00,0x23,0x2A }, 2,0x50 }, /* Quad density */
        !          5215: /* 9 sectors per track, surface by surface seek. */
        !          5216:        {  360,1,40,0, 9, { 0x00,0x23,0x2A }, 2,0x50 }, /* Single sided */
        !          5217:        {  720,2,40,0, 9, { 0x00,0x23,0x2A }, 2,0x50 }, /* Double sided */
        !          5218:        { 1440,2,80,0, 9, { 0x00,0x23,0x2A }, 2,0x50 }, /* Quad density */
        !          5219: /* 15 sectors per track, surface by surface seek. */
        !          5220:        { 2400,2,80,0,15, { 0x1B,0x00,0x00 }, 2,0x54 }, /* High capacity */
        !          5221: /* 18 sectors per track, surface by surface seek. */
        !          5222:        { 2880,2,80,0,18, { 0x1B,0x00,0x00 }, 2,0x54 }  /* 1.44 3.5" */
        !          5223: };
        !          5224: 
        !          5225: 
        !          5226: static
        !          5227: struct fl      {
        !          5228:        BUF     *fl_actf;               /* Queue, forward */
        !          5229:        BUF     *fl_actl;               /* Queue, backward */
        !          5230:        paddr_t fl_addr;                /* Address */
        !          5231:        int     fl_nsec;                /* # of sectors */
        !          5232:        int     fl_secn;                /* Current sector */
        !          5233:        struct  fdata fl_fd;            /* Disk kind data */
        !          5234:        int     fl_fcyl;                /* Floppy cylinder # */
        !          5235:        char    fl_incal[4];            /* Disk in cal flags */
        !          5236:        char    fl_ndsk;                /* # of 5 1/4" drives */
        !          5237:        char    fl_unit;                /* Unit # */
        !          5238:        char    fl_mask;                /* Handy unit mask */
        !          5239:        char    fl_hbyh;                /* 0/1 = Side by side/Head by head */
        !          5240:        char    fl_nerr;                /* Error count */
        !          5241:        int     fl_ncmdstat;            /* Number of cmd status bytes recvd */
        !          5242:        char    fl_cmdstat[8];          /* Command Status buffer */
        !          5243:        int     fl_nintstat;            /* Number of intr status bytes recvd */
        !          5244:        char    fl_intstat[4];          /* Interrupt Status buffer */
        !          5245:        int     fl_fsec;                /* Floppy sector # */
        !          5246:        int     fl_head;                /* Floppy head */
        !          5247:        char    fl_init;                /* FDC init done flag */
        !          5248:        char    fl_state;               /* Processing state */
        !          5249:        char    fl_mstatus;             /* Motor status */
        !          5250:        char    fl_time[4];             /* Motor timeout */
        !          5251:        char    fl_rate;                /* Data rate: 500,300,250,?? kbps */
        !          5252:        char    fl_type[4];             /* Type of drive: 2 = HiCap */
        !          5253:        int     fl_wflag;               /* Write operation  */
        !          5254:        int     fl_recov;               /* Recovery initiated */
        !          5255: }      fl;
        !          5256: 
        !          5257: static BUF     flbuf;
        !          5258: static TIM     fltim;
        !          5259: static TIM     fldmalck;       /* DMA lock deferred function structure.     */
        !          5260: 
        !          5261: /*
        !          5262:  * The load routine asks the
        !          5263:  * switches how many drives are present
        !          5264:  * in the machine, and sets up the field
        !          5265:  * in the floppy database. It also grabs
        !          5266:  * the level 6 interrupt vector.
        !          5267:  */
        !          5268: static
        !          5269: flload()
        !          5270: {
        !          5271:        register int    eflag;
        !          5272:        register int    s;
        !          5273: 
        !          5274:        /*
        !          5275:         * Ensure DMA channel 2 is turned off.
        !          5276:         * The Computerland ROM does not disable DMA channel after autoboot
        !          5277:         * from hard disk.  The Western Digital controller board appears to
        !          5278:         * send a dma burst when the floppy controller chip is reset.
        !          5279:         */
        !          5280:        dmaoff( 2 );
        !          5281: 
        !          5282:        /*
        !          5283:         * Read floppy equipment byte from CMOS ram
        !          5284:         *      drive 0 is in high nibble, drive 1 is in low nibble.
        !          5285:         */
        !          5286:        outb( 0x70, 0x10 );
        !          5287:        /* delay */
        !          5288:        eflag = inb( 0x71 );
        !          5289: 
        !          5290:        /*
        !          5291:         * Flag hardware as an IBM AT if neither equipment byte nibble is
        !          5292:         * greater than 4 (since 5 through 15 are reserved nibble values - see
        !          5293:         * IBM AT Technical Reference manual, page 1-50).  Note that this
        !          5294:         * relies on the fact that in the XT, this byte will "float" high.
        !          5295:         * NOTE: 1.44 Mbyte 3.5 inch drives are type 4
        !          5296:         */
        !          5297:        if ( (eflag & 0x88) == 0 ) {
        !          5298: 
        !          5299:                /*
        !          5300:                 * Reinitialize patchable parameters for IBM AT.
        !          5301:                 */
        !          5302:                fl_srt = 0xD;   /* Floppy seek step rate, in unit 2 ms */
        !          5303:                                /* NOT DIRECTLY ENCODED */
        !          5304:                fl_hlt = 25;    /* Floppy head load time, in unit 4 ms */
        !          5305: 
        !          5306:                /*
        !          5307:                 * Define AT drive information.
        !          5308:                 */
        !          5309:                fl.fl_type[0]   = eflag >> 4;
        !          5310:                fl.fl_type[1]   = eflag & 15;
        !          5311:                fl.fl_rate      = 1; /* Must not be 2 */
        !          5312: 
        !          5313:                /*
        !          5314:                 * Determine number of AT floppy drives.
        !          5315:                 */
        !          5316:                if ( eflag & 0xF0 ) {
        !          5317:                        fl.fl_ndsk++;
        !          5318:                        if ( eflag & 0x0F )
        !          5319:                                fl.fl_ndsk++;
        !          5320:                }
        !          5321:        } else {
        !          5322:                /*
        !          5323:                 * Define XT drive information.
        !          5324:                 */
        !          5325:                eflag           = int11();
        !          5326:                fl.fl_rate      = 2;
        !          5327:                if ( eflag & 1 )
        !          5328:                        fl.fl_ndsk = ((eflag >> 6) & 0x03) + 1;
        !          5329:        }
        !          5330: 
        !          5331:        if ( fl.fl_ndsk ) {
        !          5332: 
        !          5333:                s = sphi();
        !          5334:                outb(FDCDOR, 0);
        !          5335:                setivec(6, &flintr);
        !          5336: 
        !          5337:                outb(FDCDOR, 0);
        !          5338:                outb(FDCDOR, DORNMR);
        !          5339: 
        !          5340:                if ( fl.fl_rate != 2 )
        !          5341:                        outb(FDCRATE, fl.fl_rate );
        !          5342: 
        !          5343:                flput(CMDSPEC);
        !          5344:                flput((fl_srt<<4)|fl_hut);
        !          5345:                flput(fl_hlt<<1);
        !          5346:                spl( s );
        !          5347:        }
        !          5348: }
        !          5349: 
        !          5350: /*
        !          5351:  * Release resources.
        !          5352:  */
        !          5353: flunload()
        !          5354: {
        !          5355:        /*
        !          5356:         * Clear interrupt vector.
        !          5357:         */
        !          5358:        if ( fl.fl_ndsk )
        !          5359:                clrivec(6);
        !          5360: 
        !          5361:        /*
        !          5362:         * Cancel timed function.
        !          5363:         */
        !          5364:        timeout( &fltim, 0, NULL, NULL );
        !          5365: 
        !          5366:        /*
        !          5367:         * Cancel periodic [1 second] invocation.
        !          5368:         */
        !          5369:        drvl[FL_MAJOR].d_time = 0;
        !          5370: 
        !          5371:        /*
        !          5372:         * Turn motors off.
        !          5373:         */
        !          5374:        outb(FDCDOR, DORNMR | DORIEN );
        !          5375: }
        !          5376: 
        !          5377: /*
        !          5378:  * The open routine screens out
        !          5379:  * opens of illegal minor devices and
        !          5380:  * performs the NEC specify command if
        !          5381:  * this is the very first floppy disk
        !          5382:  * open call.
        !          5383:  */
        !          5384: 
        !          5385: static
        !          5386: flopen( dev, mode )
        !          5387: 
        !          5388: dev_t  dev;
        !          5389: int    mode;
        !          5390: 
        !          5391: {
        !          5392:        /*
        !          5393:         * Validate existence and data rate [Gap length != 0].
        !          5394:         */
        !          5395:        if ( ( funit(dev) >= fl.fl_ndsk )
        !          5396:          || ( fdata[ fkind(dev) ].fd_GPL[ flrate(dev) ] == 0 ) ) {
        !          5397: 
        !          5398:                u.u_error = ENXIO;
        !          5399:                return;
        !          5400:        }
        !          5401: }
        !          5402: 
        !          5403: /*
        !          5404:  * The read routine just calls
        !          5405:  * off to the common raw I/O processing
        !          5406:  * code, using a static buffer header in
        !          5407:  * the driver.
        !          5408:  */
        !          5409: 
        !          5410: static
        !          5411: flread( dev, iop )
        !          5412: 
        !          5413: dev_t  dev;
        !          5414: IO     *iop;
        !          5415: 
        !          5416: {
        !          5417:        dmareq(&flbuf, iop, dev, BREAD);
        !          5418: }
        !          5419: 
        !          5420: /*
        !          5421:  * The write routine is just like the
        !          5422:  * read routine, except that the function code
        !          5423:  * is write instead of read.
        !          5424:  */
        !          5425: 
        !          5426: static
        !          5427: flwrite( dev, iop )
        !          5428: 
        !          5429: dev_t  dev;
        !          5430: IO     *iop;
        !          5431: 
        !          5432: {
        !          5433:        dmareq(&flbuf, iop, dev, BWRITE);
        !          5434: }
        !          5435: 
        !          5436: /*
        !          5437:  * The ioctl routine simply queues a format request
        !          5438:  * using flbuf.
        !          5439:  * The only valid command is to format a track.
        !          5440:  * The parameter block contains the header records supplied to the controller.
        !          5441:  */
        !          5442: 
        !          5443: static
        !          5444: flioctl( dev, com, par )
        !          5445: 
        !          5446: dev_t  dev;
        !          5447: int    com;
        !          5448: char   *par;
        !          5449: 
        !          5450: {
        !          5451:        register unsigned s;
        !          5452:        register struct fdata *fdp;
        !          5453:        unsigned hd, cyl;
        !          5454: 
        !          5455:        if (com != FDFORMAT) {
        !          5456:                u.u_error = EINVAL;
        !          5457:                return;
        !          5458:        }
        !          5459: 
        !          5460:        fdp = &fdata[ fkind(dev) ];
        !          5461:        cyl = getubd(par);
        !          5462:        hd  = getubd(par+1);
        !          5463: 
        !          5464:        if (hd > 1 || cyl >= fdp->fd_trks) {
        !          5465:                u.u_error = EINVAL;
        !          5466:                return;
        !          5467:        }
        !          5468: 
        !          5469:        /*
        !          5470:         * The following may need some explanation.
        !          5471:         * dmareq will:
        !          5472:         *      claim the buffer,
        !          5473:         *      bounds check the parameter buffer,
        !          5474:         *      lock the parameter buffer in memory,
        !          5475:         *      convert io_seek to b_bno,
        !          5476:         *      dispatch the request,
        !          5477:         *      wait for completion,
        !          5478:         *      and unlock the parameter buffer.
        !          5479:         * The b_bno is reconverted to hd, cyl in flfsm.
        !          5480:         */
        !          5481: 
        !          5482:        s = fhbyh(dev) ? (cyl * fdp->fd_nhds + hd) : (hd * fdp->fd_trks + cyl);
        !          5483:        s *= fdp->fd_nspt;
        !          5484:        u.u_io.io_seek = ((long)s) * BSIZE;
        !          5485:        u.u_io.io_base = par;
        !          5486:        u.u_io.io_ioc = fdp->fd_nspt * 4;
        !          5487:        dmareq(&flbuf, &u.u_io, dev, FDFORMAT);
        !          5488: }
        !          5489: 
        !          5490: /*
        !          5491:  * Start up block I/O on a
        !          5492:  * buffer. Check that the block number
        !          5493:  * is not out of range, given the style of
        !          5494:  * the disk. Put the buffer header into the
        !          5495:  * device queue. Start up the disk if the
        !          5496:  * device is idle.
        !          5497:  */
        !          5498: 
        !          5499: static
        !          5500: flblock( bp )
        !          5501: 
        !          5502: register BUF   *bp;
        !          5503: 
        !          5504: {
        !          5505:        register int    s;
        !          5506:        register unsigned bno;
        !          5507: 
        !          5508:        bno = bp->b_bno + (bp->b_count >> 9) - 1;
        !          5509:        if ((unsigned)bp->b_bno > fdata[ fkind(bp->b_dev) ].fd_size) {
        !          5510:                bp->b_flag |= BFERR;
        !          5511:                bdone(bp);
        !          5512:                return;
        !          5513:        }
        !          5514:        if (bp->b_req != FDFORMAT && bno >= fdata[ fkind(bp->b_dev) ].fd_size) {
        !          5515:                bp->b_resid = bp->b_count;
        !          5516:                if (bp->b_flag & BFRAW)
        !          5517:                        bp->b_flag |= BFERR;
        !          5518:                bdone(bp);              /* return w/ b_resid != 0 */
        !          5519:                return;
        !          5520:        }
        !          5521: 
        !          5522:        if ((bp->b_count&0x1FF) != 0) {
        !          5523:                if (bp->b_req != FDFORMAT) {
        !          5524:                        bp->b_flag |= BFERR;
        !          5525:                        bdone(bp);
        !          5526:                        return;
        !          5527:                }
        !          5528:        }
        !          5529: 
        !          5530:        bp->b_actf = NULL;
        !          5531:        s = sphi();     /* s was already == sphi() on at least PC/XT. */
        !          5532: 
        !          5533:        if (fl.fl_actf == NULL)
        !          5534:                fl.fl_actf = bp;
        !          5535:        else
        !          5536:                fl.fl_actl->b_actf = bp;
        !          5537: 
        !          5538:        fl.fl_actl = bp;
        !          5539: 
        !          5540:        if (fl.fl_state == SIDLE)
        !          5541:                flfsm();
        !          5542: 
        !          5543:        spl( s );
        !          5544: }
        !          5545: 
        !          5546: /*
        !          5547:  * This finite state machine is
        !          5548:  * responsible for all sequencing on the disk.
        !          5549:  * It builds the commands, does the seeks, spins up
        !          5550:  * the drive motor for 1 second on the first call,
        !          5551:  * and so on.
        !          5552:  * Note that the format command is rather obscurely shoehorned into this.
        !          5553:  */
        !          5554: 
        !          5555: static
        !          5556: flfsm()
        !          5557: {
        !          5558:        register BUF    *bp;
        !          5559:        register int    flcmd;
        !          5560:        register int    i;
        !          5561: 
        !          5562: again:
        !          5563:        bp = fl.fl_actf;
        !          5564: 
        !          5565:        switch (fl.fl_state) {
        !          5566: 
        !          5567:        case SIDLE:
        !          5568:                drvl[FL_MAJOR].d_time = 1;
        !          5569: 
        !          5570:                if ( bp == NULL )
        !          5571:                        break;
        !          5572: 
        !          5573:                fl.fl_fd   = fdata[ fkind(bp->b_dev) ];
        !          5574:                fl.fl_unit = funit( bp->b_dev );
        !          5575:                fl.fl_hbyh = fhbyh( bp->b_dev );
        !          5576: 
        !          5577:                fl.fl_mask = 0x10 << fl.fl_unit;
        !          5578: 
        !          5579:                fl.fl_addr = bp->b_paddr;
        !          5580:                fl.fl_secn = bp->b_bno;
        !          5581:                fl.fl_time[fl.fl_unit] = 0;
        !          5582: 
        !          5583:                if ((fl.fl_nsec = bp->b_count>>9) == 0)
        !          5584:                        fl.fl_nsec = 1;
        !          5585: 
        !          5586:                fl.fl_nerr = 0;
        !          5587: 
        !          5588:                /*
        !          5589:                 * Set data rate if changed.
        !          5590:                 * NOTE: XT never changes data rate.
        !          5591:                 */
        !          5592:                if ( (i = flrate(bp->b_dev)) != fl.fl_rate )
        !          5593:                        outb(FDCRATE, fl.fl_rate = i );
        !          5594: 
        !          5595:                /*
        !          5596:                 * Motor is turned off - turn it on, wait 1 second.
        !          5597:                 */
        !          5598:                if ((fl.fl_mstatus&fl.fl_mask) == 0) {
        !          5599: 
        !          5600:                        fl.fl_mstatus |= fl.fl_mask;
        !          5601:                        outb(FDCDOR, DORNMR|DORIEN|fl.fl_mstatus|fl.fl_unit);
        !          5602:                        flsense();
        !          5603: 
        !          5604:                        timeout( &fltim, HZ, fldelay, SSEEK );
        !          5605:                        fl.fl_time[fl.fl_unit] = 0;
        !          5606:                        fl.fl_state = SDELAY;
        !          5607:                        break;
        !          5608:                }
        !          5609:                /* no break */
        !          5610: 
        !          5611:        case SSEEK:
        !          5612:                fl.fl_time[fl.fl_unit] = 0;
        !          5613:                outb(FDCDOR, DORNMR|DORIEN|fl.fl_mstatus|fl.fl_unit);
        !          5614:                flsense();
        !          5615: 
        !          5616:                /*
        !          5617:                 * Drive is not calibrated - seek to track 0.
        !          5618:                 */
        !          5619:                if (fl.fl_incal[fl.fl_unit] == 0) {
        !          5620:                        ++fl.fl_incal[fl.fl_unit];
        !          5621:                        flput(CMDRCAL);
        !          5622:                        flput(fl.fl_unit);
        !          5623:                        fl.fl_state = SSEEK;
        !          5624:                        break;
        !          5625:                }
        !          5626: 
        !          5627:                fl.fl_fsec = (fl.fl_secn % fl.fl_fd.fd_nspt) + 1;
        !          5628: 
        !          5629:                /*
        !          5630:                 * Seek cylinder by cylinder (XENIX/DOS compatible).
        !          5631:                 */
        !          5632:                if (fl.fl_hbyh) {
        !          5633:                        fl.fl_head = fl.fl_secn / fl.fl_fd.fd_nspt;
        !          5634:                        fl.fl_fcyl = fl.fl_head / fl.fl_fd.fd_nhds;
        !          5635:                        fl.fl_head = fl.fl_head % fl.fl_fd.fd_nhds;
        !          5636:                }
        !          5637:                
        !          5638:                /*
        !          5639:                 * Seek surface by surface.
        !          5640:                 */
        !          5641:                else {
        !          5642:                        fl.fl_fcyl = fl.fl_secn / fl.fl_fd.fd_nspt;
        !          5643:                        fl.fl_head = fl.fl_fcyl / fl.fl_fd.fd_trks;
        !          5644:                        fl.fl_fcyl = fl.fl_fcyl % fl.fl_fd.fd_trks;
        !          5645:                }
        !          5646: 
        !          5647:                flput(CMDSEEK);
        !          5648:                flput((fl.fl_head<<2) | fl.fl_unit);
        !          5649: 
        !          5650:                if ( fl.fl_fd.fd_trks == 80 )
        !          5651:                        flput(fl.fl_fcyl);
        !          5652:                else if ( fl.fl_type[fl.fl_unit] == 2 )
        !          5653:                        flput(fl.fl_fcyl << 1);         /* double step */
        !          5654:                else if ( fl.fl_type[fl.fl_unit] == 4 )
        !          5655:                        flput(fl.fl_fcyl << 1);         /* double step */
        !          5656:                else
        !          5657:                        flput(fl.fl_fcyl);
        !          5658: 
        !          5659:                fl.fl_state = SHDLY;
        !          5660:                break;
        !          5661: 
        !          5662:        case SHDLY:
        !          5663:                /*
        !          5664:                 * Delay for minimum 15 milliseconds after seek before w/fmt.
        !          5665:                 * 2 clock ticks would give 10-20 millisecond [100 Hz clock].
        !          5666:                 * 3 clock ticks gives      20-30 millisecond [100 Hz clock].
        !          5667:                 */
        !          5668:                if ( bp->b_req != BREAD ) {
        !          5669:                        timeout( &fltim, 3, fldelay, SRDWR );
        !          5670:                        fl.fl_state = SDELAY;
        !          5671:                        break;
        !          5672:                }
        !          5673:                /* no break */
        !          5674: 
        !          5675:        case SRDWR:
        !          5676:                /*
        !          5677:                 * Disable watchdog timer while waiting to lock DMA controller.
        !          5678:                 */
        !          5679:                fl.fl_time[fl.fl_unit] = -1;
        !          5680: 
        !          5681:                /*
        !          5682:                 * Next state will be DMA locked state.
        !          5683:                 */
        !          5684:                fl.fl_state = SLOCK;
        !          5685: 
        !          5686:                /*
        !          5687:                 * If DMA controller locked by someone else, exit for now.
        !          5688:                 */
        !          5689:                if ( dmalock( &fldmalck, flfsm, 0 ) != 0 )
        !          5690:                        return;
        !          5691: 
        !          5692:        case SLOCK:
        !          5693:                /*
        !          5694:                 * Reset watchdog timer to restart timeout sequence.
        !          5695:                 */
        !          5696:                fl.fl_time[fl.fl_unit] = 0;
        !          5697: 
        !          5698:                flcmd = CMDRDAT;
        !          5699:                fl.fl_wflag = 0;
        !          5700: 
        !          5701:                if (bp->b_req == BREAD)
        !          5702:                        ;
        !          5703: 
        !          5704:                else if (bp->b_req == BWRITE) {
        !          5705:                        fl.fl_wflag = 1;
        !          5706:                        flcmd = CMDWDAT;
        !          5707:                }
        !          5708:                
        !          5709:                else {
        !          5710:                        fl.fl_wflag = 1;
        !          5711:                        flcmd = CMDFMT;
        !          5712: 
        !          5713:                        if(dmaon(2, fl.fl_addr, bp->b_count, fl.fl_wflag) == 0)
        !          5714:                                goto straddle;
        !          5715: 
        !          5716:                        else
        !          5717:                                goto command;
        !          5718:                }
        !          5719: 
        !          5720:                if (dmaon(2, fl.fl_addr, 512, fl.fl_wflag) == 0) {
        !          5721: straddle:
        !          5722:                        devmsg(bp->b_dev, "fd: DMA page straddle at %x:%x",
        !          5723:                                fl.fl_addr);
        !          5724:                        dmaunlock( &fldmalck );
        !          5725:                        bp->b_flag |= BFERR;
        !          5726:                        fldone( bp );
        !          5727:                        goto again;
        !          5728:                }
        !          5729: command:
        !          5730:                dmago(2);
        !          5731:                flput(flcmd);
        !          5732:                flput((fl.fl_head<<2) | fl.fl_unit);
        !          5733: 
        !          5734:                if (bp->b_req == FDFORMAT) {
        !          5735:                        flput(fl.fl_fd.fd_N);           /* N */
        !          5736:                        flput(fl.fl_fd.fd_nspt);        /* SC */
        !          5737:                        flput(fl.fl_fd.fd_FGPL);        /* GPL */
        !          5738:                        flput(0xF6);                    /* D */
        !          5739:                }
        !          5740:                
        !          5741:                else {
        !          5742:                        flput(fl.fl_fcyl);
        !          5743:                        flput(fl.fl_head);
        !          5744:                        flput(fl.fl_fsec);
        !          5745:                        flput(fl.fl_fd.fd_N);           /* N */
        !          5746:                        flput(fl.fl_fd.fd_nspt);        /* EOT */
        !          5747:                        flput(fl.fl_fd.fd_GPL[fl.fl_rate]); /* GPL */
        !          5748:                        flput(0xFF);                    /* DTL */
        !          5749:                }
        !          5750: 
        !          5751:                fl.fl_state = SENDIO;
        !          5752:                break;
        !          5753: 
        !          5754:        case SENDIO:
        !          5755:                fl.fl_time[fl.fl_unit] = 0;
        !          5756:                dmaoff(2);
        !          5757:                dmaunlock( &fldmalck );
        !          5758: 
        !          5759:                if ((fl.fl_cmdstat[0]&ST0_IC) != ST0_NT) {
        !          5760:                        if (++fl.fl_nerr < 5) {
        !          5761:                                fl.fl_incal[fl.fl_unit] = 0;
        !          5762:                                fl.fl_state = SSEEK;
        !          5763:                        }
        !          5764:                        
        !          5765:                        else {
        !          5766:                                flstatus();
        !          5767:                                bp->b_flag |= BFERR;
        !          5768:                                fldone(bp);
        !          5769:                        }
        !          5770:                }
        !          5771: 
        !          5772:                else if (--fl.fl_nsec == 0) {
        !          5773:                        bp->b_resid = 0;
        !          5774:                        fldone(bp);
        !          5775:                }
        !          5776:                
        !          5777:                else {
        !          5778:                        ++fl.fl_secn;
        !          5779:                        fl.fl_addr += 512;      /* 512 == fl.fl_fd.fd_nbps */
        !          5780:                        fl.fl_state = SSEEK;
        !          5781:                }
        !          5782: 
        !          5783:                /*
        !          5784:                 * Delay for minimum 1.5 msecs after writing before seek.
        !          5785:                 */
        !          5786:                if ( fl.fl_wflag ) {
        !          5787:                        timeout( &fltim, 2, fldelay, fl.fl_state );
        !          5788:                        fl.fl_state = SDELAY;
        !          5789:                        break;
        !          5790:                }
        !          5791: 
        !          5792:                goto again;
        !          5793: 
        !          5794:        case SDELAY:
        !          5795:                /*
        !          5796:                 * Ignore interrupts until timeout occurs.
        !          5797:                 */
        !          5798:                break;
        !          5799: 
        !          5800:        default:
        !          5801:                panic("fds");
        !          5802:        }
        !          5803: }
        !          5804: 
        !          5805: /*
        !          5806:  * Delay before initiating next operation.
        !          5807:  * This allows the floppy motor to turn on,
        !          5808:  * the head to settle before writing,
        !          5809:  * the erase head to turn off after writing, etc.
        !          5810:  */
        !          5811: static
        !          5812: fldelay( state )
        !          5813: int state;
        !          5814: {
        !          5815:        int s;
        !          5816: 
        !          5817:        s = sphi();
        !          5818:        if ( fl.fl_state == SDELAY ) {
        !          5819:                fl.fl_state = state;
        !          5820:                flfsm();
        !          5821:        }
        !          5822:        spl( s );
        !          5823: }
        !          5824: 
        !          5825: /*
        !          5826:  * The flrate function returns the data rate for the flopen and flfsm routines.
        !          5827:  */
        !          5828: static int
        !          5829: flrate( dev )
        !          5830: register dev_t dev;
        !          5831: {
        !          5832:        register int rate;
        !          5833: 
        !          5834:        /*
        !          5835:         * Default is 250 Kbps.
        !          5836:         */
        !          5837:        rate = 2;
        !          5838: 
        !          5839:        /*
        !          5840:         * Check for high capacity drive.
        !          5841:         */
        !          5842:        if ( fl.fl_type[ funit(dev) ] == 2 ) {
        !          5843: 
        !          5844:                /*
        !          5845:                 * 300 Kbps.
        !          5846:                 */
        !          5847:                rate--;
        !          5848: 
        !          5849:                /*                             
        !          5850:                 * Check for high capacity media.
        !          5851:                 */
        !          5852:                if ( fdata[ fkind(dev) ].fd_nspt == 15 ) {
        !          5853: 
        !          5854:                        /*
        !          5855:                         * 500 Kbps.
        !          5856:                         */
        !          5857:                        rate--;
        !          5858:                }
        !          5859:        } else if (fl.fl_type[funit(dev)] == 4 && fkind(dev) == 7)
        !          5860:                rate = 0;
        !          5861: 
        !          5862:        return( rate );
        !          5863: }
        !          5864: 
        !          5865: /*
        !          5866:  * This routine is called by the
        !          5867:  * clock handler every second. If the drive
        !          5868:  * has been idle for a long time it turns off
        !          5869:  * the motor and shuts off the timeouts.
        !          5870:  */
        !          5871: 
        !          5872: static
        !          5873: fltimeout()
        !          5874: {
        !          5875:        register int    unit;
        !          5876:        register int    mask;
        !          5877:        register int    s;
        !          5878: 
        !          5879:        s = sphi();
        !          5880: 
        !          5881:        /*
        !          5882:         * Scan all drives, looking for motor timeouts.
        !          5883:         */
        !          5884:        for ( unit=0, mask=0x10; unit < 4; unit++, mask <<= 1 ) {
        !          5885: 
        !          5886:                /*
        !          5887:                 * Ignore drives which aren't spinning.
        !          5888:                 */
        !          5889:                if ( (fl.fl_mstatus & mask) == 0 )
        !          5890:                        continue;
        !          5891: 
        !          5892:                /*
        !          5893:                 * If timer is disabled (i.e. we are waiting for the DMA
        !          5894:                 * controller), go on to the next drive.
        !          5895:                 */
        !          5896:                if ( fl.fl_time[unit] < 0 )
        !          5897:                        continue;
        !          5898: 
        !          5899:                /*
        !          5900:                 * Leave recently accessed (in last 4 seconds) drives spinning.
        !          5901:                 */
        !          5902:                if ( ++fl.fl_time[unit] < MTIMER )
        !          5903:                        continue;
        !          5904: 
        !          5905:                /*
        !          5906:                 * Timeout drives which have been inactive for 5 seconds.
        !          5907:                 */
        !          5908:                fl.fl_mstatus &= ~mask;
        !          5909: 
        !          5910:                /*
        !          5911:                 * Not selected drive, or selected drive is idle.
        !          5912:                 */
        !          5913:                if ( (unit != fl.fl_unit) || (fl.fl_state == SIDLE) )
        !          5914:                        continue;
        !          5915: 
        !          5916:                /*
        !          5917:                 * Active drive did not complete operation within 5 seconds.
        !          5918:                 * Attempt recovery.
        !          5919:                 */
        !          5920:                flrecov();
        !          5921: 
        !          5922:                /*
        !          5923:                 * Initiate next block request.
        !          5924:                 */
        !          5925:                if ( fl.fl_state == SIDLE )
        !          5926:                        flfsm();
        !          5927:        }
        !          5928: 
        !          5929:        /*
        !          5930:         * Physically turn off drives which timed out.
        !          5931:         */
        !          5932:        outb(FDCDOR, DORNMR | DORIEN | fl.fl_mstatus | fl.fl_unit);
        !          5933: 
        !          5934:        /*
        !          5935:         * Stop checking once all drives have been stopped.
        !          5936:         */
        !          5937:        if ( fl.fl_mstatus == 0 )
        !          5938:                drvl[FL_MAJOR].d_time = 0;
        !          5939: 
        !          5940:        spl(s);
        !          5941: }
        !          5942: 
        !          5943: /*
        !          5944:  * The recovery routine resets and reprograms the floppy controller,
        !          5945:  * and discards any queued requests on the current drive.
        !          5946:  * This is required if the floppy door is open, or diskette is missing.
        !          5947:  */
        !          5948: 
        !          5949: flrecov()
        !          5950: {
        !          5951:        register BUF * bp;
        !          5952:        register dev_t dev;
        !          5953: 
        !          5954:        /*
        !          5955:         * Disable DMA transfer.
        !          5956:         * Reset floppy controller.
        !          5957:         */
        !          5958:        dmaoff( 2 );
        !          5959: 
        !          5960:        /*
        !          5961:         * Unlock the controller if locked by us.
        !          5962:         */
        !          5963:        dmaunlock( &fldmalck );
        !          5964: 
        !          5965:        outb(FDCDOR, 0);
        !          5966:        outb(FDCDOR, DORNMR);
        !          5967: 
        !          5968:        /*
        !          5969:         * Program transfer bps.
        !          5970:         */
        !          5971:        if ( fl.fl_rate != 2 )
        !          5972:                outb( FDCRATE, fl.fl_rate );
        !          5973: 
        !          5974:        /*
        !          5975:         * Program floppy controller.
        !          5976:         */
        !          5977:        flput( CMDSPEC );
        !          5978:        flput( (fl_srt << 4) | fl_hut );
        !          5979:        flput( fl_hlt << 1 );
        !          5980: 
        !          5981:        /*
        !          5982:         * Drives are no longer in calibration.
        !          5983:         */
        !          5984:        fl.fl_incal[0] =
        !          5985:        fl.fl_incal[1] =
        !          5986:        fl.fl_incal[2] =
        !          5987:        fl.fl_incal[3] = 0;
        !          5988: 
        !          5989:        /*
        !          5990:         * Abort all block requests on current drive after 1st recov attempt.
        !          5991:         */
        !          5992:        if ( bp = fl.fl_actf ) {
        !          5993:                printf("fd%d: <Door Open>\n", fl.fl_unit );
        !          5994:                dev = bp->b_dev;
        !          5995:                do {
        !          5996:                        bp->b_flag |= BFERR;
        !          5997:                        fldone( bp );
        !          5998:                } while ( (bp = fl.fl_actf) && (bp->b_dev == dev) );
        !          5999:        }
        !          6000: 
        !          6001:        /*
        !          6002:         * Delay before setting controller state to idle.
        !          6003:         * This gives time for spurious floppy interrupts to occur.
        !          6004:         * NOTE: Can't call flfsm(), since it may call us [future revision].
        !          6005:         */
        !          6006:        timeout( &fltim, HZ/4, fldelay, SIDLE );
        !          6007:        fl.fl_state = SDELAY;
        !          6008: }
        !          6009: 
        !          6010: /*
        !          6011:  * The interrupt routine gets all
        !          6012:  * the status bytes the controller chip
        !          6013:  * will give it, then issues a sense interrupt
        !          6014:  * status command (which is necessary for a seek
        !          6015:  * to complete!) and throws all of the status
        !          6016:  * bytes away.
        !          6017:  */
        !          6018: 
        !          6019: static
        !          6020: flintr()
        !          6021: {
        !          6022:        register int s;
        !          6023: 
        !          6024:        s = sphi();
        !          6025:        flsense();
        !          6026: 
        !          6027:        if (fl.fl_state != SIDLE)
        !          6028:                flfsm();
        !          6029: 
        !          6030:        spl(s);
        !          6031: }
        !          6032: 
        !          6033: /*
        !          6034:  * Fldone() returns current request to operating system.
        !          6035:  */
        !          6036: fldone( bp )
        !          6037: register BUF * bp;
        !          6038: {
        !          6039:        fl.fl_actf  = bp->b_actf;
        !          6040:        fl.fl_state = SIDLE;
        !          6041:        bdone( bp );
        !          6042: }
        !          6043: 
        !          6044: /*
        !          6045:  * Flsense() issues a sense interrupt status command
        !          6046:  * to restore the controller to a quiescent state.
        !          6047:  */
        !          6048: 
        !          6049: static
        !          6050: flsense()
        !          6051: {
        !          6052:        register int    b;
        !          6053:        register int    n;
        !          6054:        register int    i = 0;
        !          6055:        register int    s;
        !          6056: 
        !          6057:        s = sphi();
        !          6058: 
        !          6059:        /*
        !          6060:         * Read all the status bytes the controller will give us.
        !          6061:         */
        !          6062:        n = 0;
        !          6063: 
        !          6064:        for (;;) {
        !          6065:                while (((b=inb(FDCMSR))&MSRRQM) == 0) {
        !          6066:                        if ( --i == 0 ) {
        !          6067:                                printf("flintr: timeout\n");
        !          6068:                                break;
        !          6069:                        }
        !          6070:                }
        !          6071: 
        !          6072:                if ((b&MSRDIO) == 0)
        !          6073:                        break;
        !          6074: 
        !          6075:                b = inb(FDCDAT);
        !          6076:                if ( n < sizeof(fl.fl_cmdstat) )
        !          6077:                        fl.fl_cmdstat[n++] = b;
        !          6078:        }
        !          6079: 
        !          6080:        fl.fl_ncmdstat = n;
        !          6081: 
        !          6082:        /*
        !          6083:         * Issue a sense interrupt command and discard result.
        !          6084:         */
        !          6085:        outb(FDCDAT, CMDSINT);
        !          6086: 
        !          6087:        n = 0;
        !          6088:        for (;;) {
        !          6089:                while (((b=inb(FDCMSR))&MSRRQM) == 0) {
        !          6090:                        if ( --i == 0 ) {
        !          6091:                                printf("flsense: timeout\n");
        !          6092:                                break;
        !          6093:                        }
        !          6094:                }
        !          6095: 
        !          6096:                if ((b&MSRDIO) == 0)
        !          6097:                        break;
        !          6098: 
        !          6099:                b = inb(FDCDAT);
        !          6100:                if ( n < sizeof(fl.fl_intstat) )
        !          6101:                        fl.fl_intstat[n++] = b;
        !          6102:        }
        !          6103:        fl.fl_nintstat = n;
        !          6104: 
        !          6105:        spl( s );
        !          6106: }
        !          6107: 
        !          6108: /*
        !          6109:  * Send a command byte to the
        !          6110:  * NEC chip, first waiting until the chip
        !          6111:  * says that it is ready. No timeout is
        !          6112:  * performed; if the chip dies, we do too!
        !          6113:  */
        !          6114: 
        !          6115: static
        !          6116: flput( b )
        !          6117: 
        !          6118: int    b;
        !          6119: 
        !          6120: {
        !          6121:        register int i = 0;
        !          6122: 
        !          6123:        while ( (inb(FDCMSR) & (MSRRQM|MSRDIO)) != MSRRQM ) {
        !          6124:                if ( --i == 0 ) {
        !          6125:                        printf("flput: timeout\n");
        !          6126:                        return;
        !          6127:                }
        !          6128:        }
        !          6129: 
        !          6130:        outb(FDCDAT, b);
        !          6131: }
        !          6132: 
        !          6133: /*
        !          6134:  * Dissassemble the floppy error status for user reference.
        !          6135:  */
        !          6136: 
        !          6137: static
        !          6138: flstatus()
        !          6139: {
        !          6140:        printf("fd%d: head=%u cyl=%u",
        !          6141:                fl.fl_cmdstat[0] & 3,
        !          6142:                fl.fl_head, fl.fl_fcyl );
        !          6143: 
        !          6144:        /*
        !          6145:         * Report on ST0 bits.
        !          6146:         */
        !          6147:        if ( fl.fl_ncmdstat >= 1 ) {
        !          6148:                if ( fl.fl_cmdstat[0] & ST0_NR )
        !          6149:                        printf(" <Not Ready>");
        !          6150: 
        !          6151:                if ( fl.fl_cmdstat[0] & ST0_EC )
        !          6152:                        printf(" <Equipment Check>");
        !          6153:        }
        !          6154: 
        !          6155:        /*
        !          6156:         * Report on ST1 bits.
        !          6157:         */
        !          6158:        if ( fl.fl_ncmdstat >= 2 ) {
        !          6159:                if ( fl.fl_cmdstat[1] & ST1_MA )
        !          6160:                        printf(" <Missing Address Mark>");
        !          6161: 
        !          6162:                if ( fl.fl_cmdstat[1] & ST1_NW )
        !          6163:                        printf(" <Write Protected>");
        !          6164: 
        !          6165:                if ( fl.fl_cmdstat[1] & ST1_ND )
        !          6166:                        printf(" <No Data>");
        !          6167: 
        !          6168:                if ( fl.fl_cmdstat[1] & ST1_OR )
        !          6169:                        printf(" <Overrun>");
        !          6170: 
        !          6171:                if ( fl.fl_cmdstat[1] & ST1_DE )
        !          6172:                        printf(" <Data Error>");
        !          6173: 
        !          6174:                if ( fl.fl_cmdstat[1] & ST1_EN )
        !          6175:                        printf(" <End of Cyl>");
        !          6176:        }
        !          6177: 
        !          6178:        /*
        !          6179:         * Report on ST2 bits.
        !          6180:         */
        !          6181:        if ( fl.fl_ncmdstat >= 3 ) {
        !          6182:                if ( fl.fl_cmdstat[2] & ST2_MD )
        !          6183:                        printf(" <Missing Data Address Mark>");
        !          6184: 
        !          6185:                if ( fl.fl_cmdstat[2] & ST2_BC )
        !          6186:                        printf(" <Bad Cylinder>");
        !          6187: 
        !          6188:                if ( fl.fl_cmdstat[2] & ST2_WC )
        !          6189:                        printf(" <Wrong Cylinder>");
        !          6190: 
        !          6191:                if ( fl.fl_cmdstat[2] & ST2_DD )
        !          6192:                        printf(" <Bad Data CRC>");
        !          6193: 
        !          6194:                if ( fl.fl_cmdstat[2] & ST2_CM )
        !          6195:                        printf(" <Data Deleted>");
        !          6196:        }
        !          6197: 
        !          6198:        printf("\n");
        !          6199: }
        !          6200: 0707070064030050561006440000030000030000011777770507310633100005300000003427/newbits/kernel/USRSRC/i8086/drv/fontgen.c/*
        !          6201:  * fontgen - generate 16x8 font assembler source on stdout.
        !          6202:  */
        !          6203: 
        !          6204: #define        BIT(n)  (1 << (n))
        !          6205: #define        BITS(n) (((n) >= 4) ? (3 << (((n) - 4) * 2)) : (3 << (((n) + 4) * 2)))
        !          6206: 
        !          6207: unsigned char ibuf[1024];
        !          6208: unsigned char odef[] = "\tB________ = 0000000\n";
        !          6209: unsigned char obuf[] = "\t.word\tB________\n";
        !          6210: 
        !          6211: main()
        !          6212: {
        !          6213:        register unsigned s;
        !          6214:        register unsigned j;
        !          6215:        register unsigned i;
        !          6216:        extern long lseek();
        !          6217: 
        !          6218:        /*
        !          6219:         * Read fonts from /dev/mem at offset 0xFFA6E.
        !          6220:         */
        !          6221:        close(0);
        !          6222:        if (open("/dev/mem", 0) != 0)
        !          6223:                fatal("/dev/mem: can't open\n");
        !          6224:        if (lseek( 0, 0xFFA6EL, 0) != 0xFFA6EL)
        !          6225:                fatal("/dev/mem: can't seek to fonts");
        !          6226:        if (read( 0, ibuf, sizeof ibuf ) != sizeof ibuf)
        !          6227:                fatal("/dev/mem: can't read fonts");
        !          6228: 
        !          6229:        /*
        !          6230:         * Define symbolic constants.
        !          6231:         */
        !          6232:        for (i=0; i < 256; ++i) {
        !          6233:                /* Generate constant's name. */
        !          6234:                s = i;
        !          6235:                for (j=10; --j >= 2; s>>=1)
        !          6236:                        odef[j] = (s&1) ? 'X' : '_';
        !          6237: 
        !          6238:                /* Convert 8 pixel width to 16 pixels */
        !          6239:                s = 0;
        !          6240:                for (j=0; j < 8; ++j)
        !          6241:                        if (i & BIT(j))
        !          6242:                                s |= BITS(j);
        !          6243: 
        !          6244:                /* Generate constant's value */
        !          6245:                for (j=19; j >= 14; --j) {
        !          6246:                        odef[j] = (s & 7) + '0';
        !          6247:                        s >>= 3;
        !          6248:                }
        !          6249: 
        !          6250:                /* Print constant's name and value */
        !          6251:                send( odef );
        !          6252:        }
        !          6253:        send( "\n\t.globl\tfontw_\nfontw_:" );
        !          6254: 
        !          6255:        /*
        !          6256:         * Define fonts for 128 characters.
        !          6257:         */
        !          6258:        for (i=0; i < sizeof ibuf; ++i) {
        !          6259: 
        !          6260:                /* Format and print one pixel line */
        !          6261:                j = 16;
        !          6262:                s = ibuf[i];
        !          6263:                while ( --j >= 8 ) {
        !          6264:                        obuf[j] = (s&1) ? 'X' : '_' ;
        !          6265:                        s >>= 1;
        !          6266:                }
        !          6267:                send( obuf );
        !          6268: 
        !          6269:                /* Insert blank line between characters for readability */
        !          6270:                if ( (i & 7) == 7 )
        !          6271:                        send( "\n" );
        !          6272:        }
        !          6273:        exit( 0 );
        !          6274: }
        !          6275: 
        !          6276: /*
        !          6277:  * Fatal( msg ) - report error, and abort.
        !          6278:  */
        !          6279: 
        !          6280: fatal( msg )
        !          6281: register char *msg;
        !          6282: {
        !          6283:        write( 2, msg, strlen(msg) );
        !          6284:        exit( 1 );
        !          6285: }
        !          6286: 
        !          6287: /*
        !          6288:  * send( s ) - write null-terminated string to standard output.
        !          6289:  */
        !          6290: 
        !          6291: send( s )
        !          6292: register char *s;
        !          6293: {
        !          6294:        write( 1, s, strlen(s) );
        !          6295: }
        !          6296: 0707070064030050571006440000030000030000011777770507310633200004600000022311/newbits/kernel/USRSRC/i8086/drv/gc.c/*
        !          6297:  * Interrupt Driver Multi-Port Device Driver.
        !          6298:  * - supports version 7 compatible ioctl
        !          6299:  */
        !          6300: 
        !          6301: #include "coherent.h"
        !          6302: #include "ins8250.h"
        !          6303: #include <sys/stat.h>
        !          6304: #include <sys/uproc.h>
        !          6305: #include <sys/proc.h>
        !          6306: #include <sys/tty.h>           /* indirectly includes sgtty.h */
        !          6307: #include <sys/con.h>
        !          6308: #include <errno.h>
        !          6309: #include <sys/timeout.h>       /* TIM */
        !          6310: #include <sched.h>             /* CVTTOUT, IVTTOUT, SVTTOUT */
        !          6311: #include <poll_clk.h>
        !          6312: 
        !          6313: /*
        !          6314:  * Definitions.
        !          6315:  *
        !          6316:  * MAX_GCNUM is the maximum number of devices that can be polled
        !          6317:  *   using this driver and can be revised up or down
        !          6318:  * PORT is a convenience macro for the base address of a port
        !          6319:  * port_config is the structure of the initial configuration for each
        !          6320:  *   polled port;  note that "speed" is NOT the actual baud rate, but
        !          6321:  *   the value of the symbol for that baud rate as defined in
        !          6322:  *   /usr/include/sgtty.h
        !          6323:  * GCINT is the IRQ number for the interrupt belonging to the board.
        !          6324:  *   On the AT, IRQ2 is mapped to the same vector as IRQ9.
        !          6325:  */
        !          6326: #define MAX_GCNUM      8
        !          6327: #define        PORT    ((int)(tp->t_ddp))
        !          6328: struct port_config {
        !          6329:        int     addr;   /* base address of the 8250-family UART */
        !          6330:        int     speed;  /* B0..B19200 */
        !          6331: };
        !          6332: #define GCINT          2
        !          6333: 
        !          6334: /*
        !          6335:  * Export Variables - these can be patched without recompiling and linking
        !          6336:  *
        !          6337:  * GCNUM is the actual number of polled serial ports, and should be
        !          6338:  *   less than or equal to MAX_GCNUM
        !          6339:  * GCIRPT is the I/O address of the multiport interrupt register;
        !          6340:  *   a value of 0 in bit 0..3 means a pending interrupt for port 0..3
        !          6341:  * GC_PORTS is an array of address/speed pairs, one for each port
        !          6342:  */
        !          6343: int    GCNUM = 4;
        !          6344: int    GCIRPT = 0x2BF;
        !          6345: /*
        !          6346:  * Defaults are for PC COM4, Enhanced Mode, High Address.
        !          6347:  */
        !          6348: struct port_config GC_PORTS[MAX_GCNUM] = {
        !          6349:        { 0x2A0, B9600 },
        !          6350:        { 0x2A8, B9600 },
        !          6351:        { 0x2B0, B9600 },
        !          6352:        { 0x2B8, B9600 }
        !          6353: };
        !          6354: 
        !          6355: /*
        !          6356:  * Export Functions.
        !          6357:  */
        !          6358: int    gcload();
        !          6359: int    gcopen();
        !          6360: int    gcclose();
        !          6361: int    gcread();
        !          6362: int    gcwrite();
        !          6363: int    gcioctl();
        !          6364: int    gcunload();
        !          6365: int    gcpoll();
        !          6366: 
        !          6367: int    gccycle();
        !          6368: int    gcintr();
        !          6369: int    gcparam();
        !          6370: int    gcstart();
        !          6371: 
        !          6372: /*
        !          6373:  * Import Functions
        !          6374:  */
        !          6375: int    nulldev();
        !          6376: int    nonedev();
        !          6377: 
        !          6378: /*
        !          6379:  * Configuration table.
        !          6380:  */
        !          6381: CON gccon ={
        !          6382:        DFCHR|DFPOL,                    /* Flags */
        !          6383:        GCINT,                          /* Major index */
        !          6384:        gcopen,                         /* Open */
        !          6385:        gcclose,                        /* Close */
        !          6386:        nulldev,                        /* Block */
        !          6387:        gcread,                         /* Read */
        !          6388:        gcwrite,                        /* Write */
        !          6389:        gcioctl,                        /* Ioctl */
        !          6390:        nulldev,                        /* Powerfail */
        !          6391:        nulldev,                        /* Timeout */
        !          6392:        gcload,                         /* Load */
        !          6393:        gcunload,                       /* Unload */
        !          6394:        gcpoll                          /* Poll */
        !          6395: };
        !          6396: 
        !          6397: /*
        !          6398:  * Local variables.
        !          6399:  */
        !          6400: static TTY *hstty;
        !          6401: static TTY *hslimtty;
        !          6402: static TIM hstim;
        !          6403: 
        !          6404: /*
        !          6405:  * Time constant table.
        !          6406:  * Indexed by ioctl baud rate.
        !          6407:  */
        !          6408: static
        !          6409: int timeconst[] = {
        !          6410:        0,                              /* 0 */
        !          6411:        2304,                           /* 50 */
        !          6412:        1536,                           /* 75 */
        !          6413:        1047,                           /* 110 */
        !          6414:        857,                            /* 134.5 */
        !          6415:        768,                            /* 150 */
        !          6416:        576,                            /* 200 */
        !          6417:        384,                            /* 300 */
        !          6418:        192,                            /* 600 */
        !          6419:        96,                             /* 1200 */
        !          6420:        64,                             /* 1800 */
        !          6421:        58,                             /* 2000 */
        !          6422:        48,                             /* 2400 */
        !          6423:        32,                             /* 3600 */
        !          6424:        24,                             /* 4800 */
        !          6425:        16,                             /* 7200 */
        !          6426:        12,                             /* 9600 */
        !          6427:        6,                              /* 19200 */
        !          6428:        6,                              /* EXTA */
        !          6429:        6                               /* EXTB */
        !          6430: };
        !          6431: 
        !          6432: /*
        !          6433:  * Load Routine.
        !          6434:  */
        !          6435: static gcload()
        !          6436: {
        !          6437:        register TTY * tp;
        !          6438:        register int port;
        !          6439:        int i, b, s;
        !          6440: 
        !          6441:        if ((hstty = (TTY *)kalloc(GCNUM*sizeof(TTY))) == 0) {
        !          6442:                printf("gcload: can't allocate tty's\n");
        !          6443:                return;
        !          6444:        }
        !          6445:        kclear(hstty, GCNUM*sizeof(TTY));
        !          6446: 
        !          6447:        s = sphi();
        !          6448:        for (i = 0; i < GCNUM; i++) {
        !          6449:                port = GC_PORTS[i].addr;
        !          6450:                tp = hstty + i;
        !          6451: 
        !          6452:                outb( port+MCR, 0 );
        !          6453:                outb( port+IER, 0 );
        !          6454: 
        !          6455:                if ( inb( port+IER ) )
        !          6456:                        break;
        !          6457: 
        !          6458:                tp->t_cs_sel  = cs_sel();
        !          6459:                tp->t_start   = gcstart;
        !          6460:                tp->t_param   = gcparam;
        !          6461:                tp->t_sgttyb.sg_ospeed = tp->t_sgttyb.sg_ispeed = 
        !          6462:                tp->t_dispeed = tp->t_dospeed = GC_PORTS[i].speed;
        !          6463:                tp->t_ddp     = port;
        !          6464: 
        !          6465:                b = timeconst[ tp->t_sgttyb.sg_ospeed ];
        !          6466:                outb( port+LCR, LC_DLAB );
        !          6467:                outb( port+DLL, b );
        !          6468:                outb( port+DLH, b >> 8);
        !          6469:                outb( port+LCR, LC_CS8);
        !          6470: 
        !          6471:                hslimtty = tp;
        !          6472:        }
        !          6473:        setivec(GCINT, gcintr);
        !          6474:        spl(s);
        !          6475: }
        !          6476: 
        !          6477: static gcunload()
        !          6478: {
        !          6479:        clrivec(GCINT);
        !          6480:        kfree(hstty);
        !          6481: }
        !          6482: 
        !          6483: /*
        !          6484:  * Open Routine.
        !          6485:  */
        !          6486: gcopen( dev, mode )
        !          6487: dev_t dev;
        !          6488: {
        !          6489:        register TTY * tp = &hstty[ dev & 15 ];
        !          6490:        register int b;
        !          6491:        int s;
        !          6492: 
        !          6493:        /*
        !          6494:         * Verify hardware exists.
        !          6495:         */
        !          6496:        if ( (PORT == 0) || (inb(PORT+IER) & ~IE_TxI) ) {
        !          6497:                u.u_error = ENXIO;
        !          6498:                return;
        !          6499:        }
        !          6500: 
        !          6501:        /*
        !          6502:         * Initialize if not already open.
        !          6503:         */
        !          6504:        if ( ++tp->t_open == 1 ) {
        !          6505:                ttopen( tp );
        !          6506: 
        !          6507:                if ( dev & 0x80 ) {
        !          6508:                        s = sphi();
        !          6509:                        b = inb(PORT+MSR);
        !          6510:                        tp->t_flags |= T_MODC + T_STOP;
        !          6511:                        if ( b & MS_CTS )
        !          6512:                                tp->t_flags &= ~T_STOP;
        !          6513:                        if ( b & MS_DSR )
        !          6514:                                tp->t_flags |=  T_CARR;
        !          6515:                        spl( s );
        !          6516:                } else  {
        !          6517:                        tp->t_flags &= ~T_MODC;
        !          6518:                        tp->t_flags |=  T_CARR;
        !          6519:                }
        !          6520:                gccycle( tp );
        !          6521:        }
        !          6522:        ttsetgrp( tp, dev );
        !          6523: }
        !          6524: 
        !          6525: /*
        !          6526:  * Close Routine.
        !          6527:  */
        !          6528: gcclose( dev )
        !          6529: dev_t dev;
        !          6530: {
        !          6531:        register TTY * tp = &hstty[ dev & 15 ];
        !          6532: 
        !          6533:        /*
        !          6534:         * Reset if last close.
        !          6535:         */
        !          6536:        if ( tp->t_open == 1 ) {
        !          6537:                int state;
        !          6538: 
        !          6539:                ttclose( tp );
        !          6540:                /*
        !          6541:                 * ttclose() only emptied the output queue tp->t_oq;
        !          6542:                 * now wait 0.1 sec for the silo tp->rawout to empty
        !          6543:                 * and allow a delay for the UART on-chip xmit buffer to empty
        !          6544:                 *
        !          6545:                 * state 2: waiting for silo to empty
        !          6546:                 * state 1: stalling so UART can empty xmit buffer
        !          6547:                 * state 0: done!
        !          6548:                 */
        !          6549:                state = 2;
        !          6550:                while (state) {
        !          6551:                        timeout(&hstim, 10, wakeup, (int)&hstim);
        !          6552:                        sleep((char *)&hstim, CVTTOUT, IVTTOUT, SVTTOUT);
        !          6553:                        if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          6554:                                state--;
        !          6555:                }
        !          6556:        }
        !          6557: 
        !          6558:        --tp->t_open;
        !          6559: }
        !          6560: 
        !          6561: /*
        !          6562:  * Read Routine.
        !          6563:  */
        !          6564: gcread( dev, iop )
        !          6565: dev_t dev;
        !          6566: register IO * iop;
        !          6567: {
        !          6568:        ttread( &hstty[ dev & 15 ], iop, 0 );
        !          6569: }
        !          6570: 
        !          6571: /*
        !          6572:  * Write Routine.
        !          6573:  */
        !          6574: gcwrite( dev, iop )
        !          6575: dev_t dev;
        !          6576: register IO * iop;
        !          6577: {
        !          6578:        ttwrite( &hstty[ dev & 15 ], iop, 0 );
        !          6579: }
        !          6580: 
        !          6581: /*
        !          6582:  * Ioctl Routine.
        !          6583:  */
        !          6584: gcioctl( dev, com, vec )
        !          6585: dev_t dev;
        !          6586: int com;
        !          6587: struct sgttyb * vec;
        !          6588: {
        !          6589:        ttioctl( &hstty[ dev & 15 ], com, vec );
        !          6590: }
        !          6591: 
        !          6592: /*
        !          6593:  * Polling Routine.
        !          6594:  */
        !          6595: gcpoll( dev, ev, msec )
        !          6596: dev_t dev;
        !          6597: int ev;
        !          6598: int msec;
        !          6599: {
        !          6600:        return ttpoll( &hstty[ dev & 15 ], ev, msec );
        !          6601: }
        !          6602: 
        !          6603: /*
        !          6604:  * Cyclic routine - invoked every clock tick to perform raw input/output.
        !          6605:  *
        !          6606:  *     Notes:  Invoked 10 times per second.
        !          6607:  */
        !          6608: gccycle( tp )
        !          6609: register TTY * tp;
        !          6610: {
        !          6611:        register int resid;
        !          6612:        register int c;
        !          6613: 
        !          6614:        /*
        !          6615:         * Process rawin buf.
        !          6616:         */
        !          6617:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          6618: 
        !          6619:                ttin( tp, tp->t_rawin.si_buf[ tp->t_rawin.si_ox ] );
        !          6620: 
        !          6621:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          6622:                        tp->t_rawin.si_ox = 0;
        !          6623:                else
        !          6624:                        tp->t_rawin.si_ox++;
        !          6625:        }
        !          6626: 
        !          6627:        /*
        !          6628:         * Calculate free output slot count.
        !          6629:         */
        !          6630:        resid  = sizeof(tp->t_rawout.si_buf) - 1;
        !          6631:        resid += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          6632:        resid %= sizeof(tp->t_rawout.si_buf);
        !          6633: 
        !          6634:        /*
        !          6635:         * Fill raw output buffer.
        !          6636:         */
        !          6637:        while ( (--resid >= 0) && ((c = ttout(tp)) >= 0) ) {
        !          6638: 
        !          6639:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = c;
        !          6640: 
        !          6641:                if ( tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1 )
        !          6642:                        tp->t_rawout.si_ix = 0;
        !          6643:                else
        !          6644:                        tp->t_rawout.si_ix++;
        !          6645:        }
        !          6646: 
        !          6647:        /*
        !          6648:         * (Re)start output, waking processes waiting to output, etc.
        !          6649:         */
        !          6650:        ttstart( tp );
        !          6651: 
        !          6652:        /*
        !          6653:         * Schedule next cycle.
        !          6654:         */
        !          6655:        if ( tp->t_open != 0 )
        !          6656:                timeout( &tp->t_rawtim, HZ/10, gccycle, tp );
        !          6657: }
        !          6658: 
        !          6659: /*
        !          6660:  * Interrupt driven Polling routine.
        !          6661:  */
        !          6662: gcintr()
        !          6663: {
        !          6664:        register TTY * tp = &hstty[0];
        !          6665:        register int b;
        !          6666: 
        !          6667:        do {
        !          6668:                if ( tp->t_open == 0 )
        !          6669:                        continue;
        !          6670: 
        !          6671:                /*
        !          6672:                 * Check modem status if modem control is enabled.
        !          6673:                 */
        !          6674:                if ( tp->t_flags & T_MODC ) {
        !          6675: 
        !          6676:                        b = inb( PORT+MSR );
        !          6677: 
        !          6678:                        if ( b & (MS_DCTS|MS_DDSR) ) {
        !          6679: 
        !          6680:                                if ( b & MS_DCTS ) {
        !          6681:                                        if ( b & MS_CTS )
        !          6682:                                                tp->t_flags &= ~T_STOP;
        !          6683:                                        else
        !          6684:                                                tp->t_flags |=  T_STOP;
        !          6685:                                }
        !          6686:                                if ( b & MS_DDSR ) {
        !          6687:                                        if ( b & MS_DSR )
        !          6688:                                                tp->t_flags |=  T_CARR;
        !          6689:                                        else {
        !          6690:                                                tp->t_flags &= ~T_CARR;
        !          6691:                                                tthup( tp );
        !          6692:                                        }
        !          6693:                                }
        !          6694:                        }
        !          6695:                }
        !          6696: 
        !          6697:                b = inb( PORT+LSR );
        !          6698: 
        !          6699:                if ( (b & LS_BREAK) && (tp->t_flags & T_CARR) )
        !          6700:                        ttsignal( tp, SIGINT );
        !          6701: 
        !          6702:                /*
        !          6703:                 * Receive ready.
        !          6704:                 */
        !          6705:                if ( b & LS_RxRDY ) {
        !          6706: 
        !          6707:                        tp->t_rawin.si_buf[tp->t_rawin.si_ix] = inb(PORT+DREG);
        !          6708: 
        !          6709:                        if ( tp->t_flags & T_CARR ) {
        !          6710: 
        !          6711:                                if ( ++(tp->t_rawin.si_ix) >=
        !          6712:                                                sizeof(tp->t_rawin.si_buf) )
        !          6713:                                        tp->t_rawin.si_ix = 0;
        !          6714:                        }
        !          6715:                }
        !          6716: 
        !          6717:                /*
        !          6718:                 * Transmit ready and raw output data exists.
        !          6719:                 */
        !          6720:                if ( (b & LS_TxRDY) && ((tp->t_flags & T_STOP) == 0)
        !          6721:                  && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          6722: 
        !          6723:                        outb(   PORT+DREG,
        !          6724:                                tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          6725: 
        !          6726:                        if ( ++(tp->t_rawout.si_ox) >=
        !          6727:                                        sizeof(tp->t_rawout.si_buf) )
        !          6728:                                tp->t_rawout.si_ox = 0;
        !          6729:                }
        !          6730: 
        !          6731:        } while ( ++tp <= hslimtty );
        !          6732: }
        !          6733: 
        !          6734: /*
        !          6735:  * Set hardware parameters.
        !          6736:  */
        !          6737: gcparam( tp )
        !          6738: register TTY * tp;
        !          6739: {
        !          6740:        register int b;
        !          6741:        int s;
        !          6742: 
        !          6743:        s = sphi();
        !          6744:        /*
        !          6745:         * Assert required modem control lines (DTR, RTS).
        !          6746:         */
        !          6747:        b = 0;
        !          6748:        if ( tp->t_sgttyb.sg_ospeed != B0 )
        !          6749:                b |=  MC_DTR | MC_RTS;
        !          6750:        outb( PORT+MCR, b );
        !          6751: 
        !          6752:        /*
        !          6753:         * Program baud rate.
        !          6754:         */
        !          6755:        if (b = timeconst[ tp->t_sgttyb.sg_ospeed ]) {
        !          6756:                outb( PORT+LCR, LC_DLAB );
        !          6757:                outb( PORT+DLL, b );
        !          6758:                outb( PORT+DLH, b >> 8 );
        !          6759:        }
        !          6760: 
        !          6761:        /*
        !          6762:         * Program character size, parity.
        !          6763:         */
        !          6764:        switch ( tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW) ) {
        !          6765:        case ODDP:              b = LC_CS7|LC_PARENB;            break;
        !          6766:        case EVENP:             b = LC_CS7|LC_PARENB|LC_PAREVEN; break;
        !          6767:        default:                b = LC_CS8;                      break;
        !          6768:        }
        !          6769:        outb( PORT+LCR, b );
        !          6770: 
        !          6771:        /*
        !          6772:         * Enable Transmit Buffer Empty Interrupts.
        !          6773:         */
        !          6774:        outb( PORT+IER, IE_TxI );
        !          6775: 
        !          6776:        spl(s);
        !          6777: }
        !          6778: 
        !          6779: /*
        !          6780:  * Start Routine.
        !          6781:  */
        !          6782: gcstart( tp )
        !          6783: register TTY * tp;
        !          6784: {
        !          6785:        register int s;
        !          6786: 
        !          6787:        /*
        !          6788:         * Transmit buffer is empty, and raw output buffer is not.
        !          6789:         */
        !          6790:        s = sphi();
        !          6791:        if ( (inb( PORT+LSR ) & LS_TxRDY)
        !          6792:          && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          6793: 
        !          6794:                /*
        !          6795:                 * Send next char from raw output buffer.
        !          6796:                 */
        !          6797:                outb( PORT+DREG, tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          6798: 
        !          6799:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          6800:                        tp->t_rawout.si_ox = 0;
        !          6801:        }
        !          6802:        spl( s );
        !          6803: }
        !          6804: 0707070064030050551004440000030000030000011777770507310633400004600000001521/newbits/kernel/USRSRC/i8086/drv/gr.c/* (-lgl
        !          6805:  *     COHERENT Driver Kit Version 1.1.0
        !          6806:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          6807:  *     All rights reserved. May not be copied without permission.
        !          6808:  -lgl) */
        !          6809: /*
        !          6810:  * Graphics Display Driver for PC Color Card
        !          6811:  */
        !          6812: 
        !          6813: #include <sys/coherent.h>
        !          6814: #include <sys/sched.h>
        !          6815: #include <sys/types.h>
        !          6816: #include <sys/uproc.h>
        !          6817: #include <errno.h>
        !          6818: #include <sys/con.h>
        !          6819: #include <sys/devices.h>
        !          6820: 
        !          6821: int grread();
        !          6822: int grwrite();
        !          6823: int nonedev();
        !          6824: int nulldev();
        !          6825: 
        !          6826: /*
        !          6827:  * Driver Configuration.
        !          6828:  */
        !          6829: CON
        !          6830: grcon = {
        !          6831:        DFCHR,                          /* Flags                          */
        !          6832:        GR_MAJOR,                               /* Major Index                    */
        !          6833:        nulldev,                        /* Open                           */
        !          6834:        nulldev,                        /* Close                          */
        !          6835:        nonedev,                        /* Block                          */
        !          6836:        grread,                         /* Read                           */
        !          6837:        grwrite,                        /* Write                          */
        !          6838:        nonedev,                        /* Ioctl                          */
        !          6839:        nulldev,                        /* Power fail                     */
        !          6840:        nulldev,                        /* Timeout                        */
        !          6841:        nulldev,                        /* Load                           */
        !          6842:        nulldev                         /* Unload                         */
        !          6843: };
        !          6844: 0707070064030034631006440000000000000000011777770507310633400005000000074531/newbits/kernel/USRSRC/i8086/drv/mmas.m/ (lgl-
        !          6845: /      COHERENT Driver Kit Version 1.0.0
        !          6846: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          6847: /      All rights reserved. May not be copied without permission.
        !          6848: / -lgl)
        !          6849: ////////
        !          6850: /
        !          6851: /      Memory mapped video driver assembler assist.
        !          6852: /
        !          6853: ////////
        !          6854: /
        !          6855: / State driven code
        !          6856: /
        !          6857: /      Input:  DS:SI - input string
        !          6858: /              ES:DI - current screen location
        !          6859: /              SS:BP - terminal information
        !          6860: /              CX    - input count
        !          6861: /              BP    - references terminal information
        !          6862: /              AH    - character attributes
        !          6863: /              AL    - character
        !          6864: /              BH    - (usually) kept zeroed for efficiency
        !          6865: /              DH    - current row
        !          6866: /              DL    - current column
        !          6867: /
        !          6868: ////////
        !          6869: 
        !          6870:        NCOL    = 80            / number of columns
        !          6871:        NCB     = 2             / number of horizontal bytes per char
        !          6872:        NCR     = 1             / number of horizontal lines per char
        !          6873:        NHB     = 160           / number of horizontal bytes per line
        !          6874:        NRB     = NCR*NHB       / number of bytes per character row
        !          6875: 
        !          6876:        ATTR    = ah            / attribute byte
        !          6877:        ZERO    = bh            / (almost) always zero
        !          6878:        ROW     = dh            / currently active vertical position
        !          6879:        COL     = dl            / currently active horizontal position
        !          6880:        POS     = di            / currently active display address
        !          6881: 
        !          6882:        INTENSE = 0x08          / high intensity attribute bit
        !          6883:        BLINK   = 0x80          / blinking attribute bit
        !          6884:        REVERSE = 0x70          / reverse video
        !          6885: 
        !          6886: ////////
        !          6887: /
        !          6888: / Magic constants from <sys/io.h>
        !          6889: /
        !          6890: ////////
        !          6891: 
        !          6892:        IO_SEG  = 0
        !          6893:        IO_IOC  = 2
        !          6894:        IO_BASE = 8
        !          6895: 
        !          6896:        IOSYS   = 0
        !          6897:        IOUSR   = 1
        !          6898: 
        !          6899: ////////
        !          6900: /
        !          6901: / Data
        !          6902: /
        !          6903: ////////
        !          6904: 
        !          6905: MM_FUNC                = 0             / current state
        !          6906: MM_PORT                = 2             / adapter base i/o port
        !          6907: MM_BASE                = 4             / adapter base memory address
        !          6908: MM_ROW         = 6             / screen row
        !          6909: MM_COL         = 7             / screen column
        !          6910: MM_POS         = 8             / screen position
        !          6911: MM_ATTR                = 10            / attributes
        !          6912: MM_N1          = 11            / numeric argument 1
        !          6913: MM_N2          = 12            / numeric argument 2
        !          6914: MM_BROW                = 13            / base row
        !          6915: MM_EROW                = 14            / end row
        !          6916: MM_LROW                = 15            / legal row limit
        !          6917: MM_SROW                = 16            / saved cursor row
        !          6918: MM_SCOL                = 17            / saved cursor column
        !          6919: MM_IBROW       = 18            / initial base row
        !          6920: MM_IEROW       = 19            / initial end row
        !          6921: MM_INVIS       = 20            / cursor invisible mask
        !          6922: MM_SLOW                = 22            / slow [no flicker] video update
        !          6923: MM_WRAP                = 23            / wrap to start of next line
        !          6924: 
        !          6925: / Characters
        !          6926: AZERO          = 0x30
        !          6927: CLOWER         = 0x63
        !          6928: HLOWER         = 0x68
        !          6929: LLOWER         = 0x6C
        !          6930: SEMIC          = 0x3B
        !          6931: SPACE          = 0x20
        !          6932: 
        !          6933:        .globl  VIDSLOW_        / Patchable kernel variable.
        !          6934:        .prvd
        !          6935: mmdata:        .word   mminit
        !          6936:        .word   0x03B4
        !          6937:        .word   0xB000
        !          6938:        .byte   0, 0
        !          6939:        .word   0
        !          6940:        .byte   0x7, 0, 0, 0, 23, 24, 0, 0, 0, 23
        !          6941:        .word   0
        !          6942: VIDSLOW_:.byte 0
        !          6943:        .byte   1
        !          6944:        .shri
        !          6945: 
        !          6946: ////////
        !          6947: /
        !          6948: / mmgo( iop )
        !          6949: / IO *iop;
        !          6950: /
        !          6951: ////////
        !          6952: 
        !          6953:        .globl  mmgo_
        !          6954: 
        !          6955: mmgo_:
        !          6956:        push    si
        !          6957:        push    di
        !          6958:        push    bp
        !          6959:        mov     bp, sp
        !          6960:        push    ds
        !          6961:        push    es
        !          6962:        cld
        !          6963:        mov     bx, 8(bp)               / iop
        !          6964:        mov     si, IO_BASE(bx)         / iop->io_base
        !          6965:        mov     cx, IO_IOC(bx)          / iop->io_ioc
        !          6966: 
        !          6967:        cmp     IO_SEG(bx), $IOSYS      / user address space
        !          6968:        je      0f
        !          6969:        mov     bx, uds_
        !          6970:        mov     ds, bx
        !          6971: 0:
        !          6972:        mov     bp, $mmdata
        !          6973:        mov     dx, MM_PORT(bp)         / turn video off if color board
        !          6974:        cmp     dx, $0x3B4
        !          6975:        je      3f
        !          6976:        cmpb    MM_SLOW(bp), $0         / check for slow [flicker-free]
        !          6977:        je      2f
        !          6978: 
        !          6979:        mov     dx, $0x3DA
        !          6980: 1:     inb     al, dx                  / wait for vertical retrace
        !          6981:        testb   al, $8
        !          6982:        je      1b
        !          6983: 2:
        !          6984:        mov     dx, $0x3D8              / disable video
        !          6985:        movb    al, $0x25
        !          6986:        outb    dx, al
        !          6987: 3:
        !          6988:        movb    ROW, MM_ROW(bp)
        !          6989:        movb    COL, MM_COL(bp)
        !          6990:        mov     es,  MM_BASE(bp)
        !          6991:        mov     POS, MM_POS(bp)
        !          6992:        sub     bx, bx
        !          6993:        movb    ATTR, MM_ATTR(bp)
        !          6994:        ijmp    MM_FUNC(bp)
        !          6995: 
        !          6996: exit:  pop     bx
        !          6997:        pop     es
        !          6998:        pop     ds
        !          6999:        movb    MM_ATTR(bp), ATTR
        !          7000:        mov     MM_FUNC(bp), bx
        !          7001:        movb    MM_ROW(bp), ROW         / save row,column
        !          7002:        movb    MM_COL(bp), COL
        !          7003:        mov     MM_POS(bp), POS         / save position
        !          7004: 
        !          7005:        mov     dx, MM_PORT(bp)         / adjust cursor location
        !          7006:        mov     bx, POS
        !          7007:        or      bx, MM_INVIS(bp)
        !          7008:        shr     bx, $1
        !          7009: 
        !          7010:        movb    al, $14
        !          7011:        outb    dx, al
        !          7012:        inc     dx
        !          7013:        movb    al, bh
        !          7014:        outb    dx, al
        !          7015:        dec     dx
        !          7016:        movb    al, $15
        !          7017:        outb    dx, al
        !          7018:        inc     dx
        !          7019:        movb    al, bl
        !          7020:        outb    dx, al
        !          7021: 
        !          7022:        mov     dx, MM_PORT(bp)         / turn video on
        !          7023:        add     dx, $4
        !          7024:        movb    al, $0x29
        !          7025:        outb    dx, al
        !          7026:        mov     mmvcnt_, $600           / 600 seconds before video disabled
        !          7027: 
        !          7028:        mov     bp, sp
        !          7029:        mov     bx, 8(bp)
        !          7030:        mov     ax, cx
        !          7031:        xchg    cx, IO_IOC(bx)
        !          7032:        sub     cx, IO_IOC(bx)
        !          7033:        add     IO_BASE(bx), cx
        !          7034:        pop     bp
        !          7035:        pop     di
        !          7036:        pop     si
        !          7037:        ret
        !          7038: 
        !          7039: 
        !          7040: ////////
        !          7041: /
        !          7042: / mminit - initialize screen
        !          7043: /
        !          7044: ////////
        !          7045: 
        !          7046: mminit:        movb    ss:mmesc_, $CLOWER              / schedule keyboard initialization
        !          7047:        call    int11_                  / read equipment status
        !          7048:        and     ax, $0x30               / isolate video bits
        !          7049:        cmp     ax, $0x30               / if not monochrome
        !          7050:        je      0f
        !          7051:        mov     MM_PORT(bp), $0x3D4     /       set color port
        !          7052:        mov     MM_BASE(bp), $0xB800    /       set color base
        !          7053:        mov     es, MM_BASE(bp)         /
        !          7054: 0:                                     /
        !          7055:        mov     dx, MM_PORT(bp)         / turn video off
        !          7056:        add     dx, $4
        !          7057:        movb    al, $0x21
        !          7058:        outb    dx, al
        !          7059: 
        !          7060:        mov     dx, MM_PORT(bp)         / zero display offset
        !          7061:        movb    al, $12
        !          7062:        outb    dx, al
        !          7063:        inc     dx
        !          7064:        subb    al, al
        !          7065:        outb    dx, al
        !          7066:        dec     dx
        !          7067:        movb    al, $13
        !          7068:        outb    dx, al
        !          7069:        inc     dx
        !          7070:        subb    al, al
        !          7071:        outb    dx, al
        !          7072: 
        !          7073:        mov     dx, MM_PORT(bp)         / reset border to black
        !          7074:        add     dx, $5
        !          7075:        subb    al, al
        !          7076:        outb    dx, al
        !          7077: 
        !          7078:        inc     dx                      / reset TECMAR XMSR register
        !          7079:        outb    dx, al
        !          7080: 
        !          7081:        mov     MM_INVIS(bp), $0
        !          7082:        movb    ATTR, $0x07
        !          7083:        movb    MM_ATTR(bp), ATTR
        !          7084:        movb    MM_WRAP(bp), $1
        !          7085:        movb    ROW, MM_IBROW(bp)
        !          7086:        movb    MM_BROW(bp), ROW
        !          7087:        movb    bl, MM_IEROW(bp)
        !          7088:        movb    MM_EROW(bp), bl
        !          7089:        sub     bx, bx
        !          7090:        movb    MM_N1(bp), $2
        !          7091:        jmp     mm_ed
        !          7092: 
        !          7093: ////////
        !          7094: /
        !          7095: / mmspec - schedule special keyboard function
        !          7096: /
        !          7097: ////////
        !          7098: 
        !          7099: mmspec:        movb    ss:mmesc_, al
        !          7100:        jmp     eval
        !          7101: 
        !          7102: ////////
        !          7103: /
        !          7104: / mmbell - schedule beep
        !          7105: /
        !          7106: ////////
        !          7107: 
        !          7108: mmbell:        movb    ss:mmbeeps_, $-1
        !          7109:        jmp     eval
        !          7110: 
        !          7111: ////////
        !          7112: /
        !          7113: / mm_cnl - cursor next line
        !          7114: /
        !          7115: /      Moves the active position to the first column of the next display line.
        !          7116: /      Scrolls the active display if necessary.
        !          7117: /
        !          7118: ////////
        !          7119: 
        !          7120: mm_cnl:        subb    COL, COL
        !          7121:        incb    ROW
        !          7122:        cmpb    ROW, MM_EROW(bp)
        !          7123:        jna     repos
        !          7124:        movb    ROW, MM_EROW(bp)
        !          7125: /      jmp     scrollup
        !          7126: 
        !          7127: ////////
        !          7128: /
        !          7129: / scrollup - scroll display upwards
        !          7130: /
        !          7131: ////////
        !          7132: 
        !          7133: scrollup:
        !          7134:        push    ds
        !          7135:        push    si
        !          7136:        push    cx
        !          7137:        mov     ds, MM_BASE(bp)
        !          7138:        movb    bl, MM_BROW(bp)
        !          7139:        shlb    bl, $1
        !          7140:        mov     di, cs:rowtab(bx)
        !          7141:        mov     si, cs:rowtab+2(bx)
        !          7142:        movb    bl, ROW
        !          7143:        shlb    bl, $1
        !          7144:        mov     cx, cs:rowtab(bx)
        !          7145:        push    cx
        !          7146:        sub     cx, di
        !          7147:        shr     cx, $1
        !          7148:        cld
        !          7149:        rep
        !          7150:        movsw
        !          7151:        movb    al, $SPACE
        !          7152:        pop     di
        !          7153:        mov     cx, $NCOL
        !          7154:        rep
        !          7155:        stosw
        !          7156:        pop     cx
        !          7157:        pop     si
        !          7158:        pop     ds
        !          7159:        movb    bl, COL                 / reposition to ROW and COL
        !          7160:        shlb    bl, $1
        !          7161:        mov     POS, cs:coltab(bx)
        !          7162:        movb    bl, ROW
        !          7163:        shlb    bl, $1
        !          7164:        add     POS, cs:rowtab(bx)
        !          7165:        call    exit
        !          7166:        jmp     eval
        !          7167: 
        !          7168: ////////
        !          7169: /
        !          7170: / repos - reposition cursor
        !          7171: /
        !          7172: ////////
        !          7173: 
        !          7174: repos: movb    bl, COL                 / reposition to ROW and COL
        !          7175:        shlb    bl, $1
        !          7176:        mov     POS, cs:coltab(bx)
        !          7177:        movb    bl, ROW
        !          7178:        shlb    bl, $1
        !          7179:        add     POS, cs:rowtab(bx)
        !          7180: /      jmp     eval
        !          7181: 
        !          7182: ////////
        !          7183: /
        !          7184: / eval - evaluate input character
        !          7185: /
        !          7186: ////////
        !          7187: 
        !          7188: eval:  jcxz    ewait
        !          7189:        dec     cx                              / evaluate next char
        !          7190:        lodsb
        !          7191:        movb    bl, al
        !          7192:        shlb    bl, $1
        !          7193:        jc      mmputc
        !          7194:        ijmp    cs:asctab(bx)
        !          7195: 
        !          7196: ////////
        !          7197: /
        !          7198: / mmputc - put character on screen
        !          7199: /
        !          7200: ////////
        !          7201: 
        !          7202: mmputc:        stosw                           / Update display memory.
        !          7203:        incb    COL
        !          7204:        cmpb    COL, $NCOL              / Past end of line?
        !          7205:        jge     0f
        !          7206:        jcxz    ewait                   / Not past, evaluate next character.
        !          7207:        dec     cx
        !          7208:        lodsb
        !          7209:        movb    bl, al
        !          7210:        shlb    bl, $1
        !          7211:        jc      mmputc
        !          7212:        ijmp    cs:asctab(bx)
        !          7213: 
        !          7214: 0:     cmpb    MM_WRAP(bp), $0         / Yes past, Wrap around?
        !          7215:        jne     0f
        !          7216:        sub     di, $2                  / No wrap, adjust back to end of line.
        !          7217:        decb    COL
        !          7218:        jcxz    ewait                   / Not past, evaluate next character.
        !          7219:        dec     cx
        !          7220:        lodsb
        !          7221:        movb    bl, al
        !          7222:        shlb    bl, $1
        !          7223:        jc      mmputc
        !          7224:        ijmp    cs:asctab(bx)
        !          7225: 
        !          7226: 0:     subb    COL, COL                / Wrap to next line.
        !          7227:        incb    ROW
        !          7228:        cmpb    ROW, MM_EROW(bp)        / Past scrolling region?
        !          7229:        jg      0f
        !          7230:        jcxz    ewait                   / Not past, evaluate next character.
        !          7231:        dec     cx
        !          7232:        lodsb
        !          7233:        movb    bl, al
        !          7234:        shlb    bl, $1
        !          7235:        jc      mmputc
        !          7236:        ijmp    cs:asctab(bx)
        !          7237: 
        !          7238: 0:     movb    ROW, MM_EROW(bp)        / Yes past, scroll up 1 line.
        !          7239:        jmp     scrollup
        !          7240: 
        !          7241: ////////
        !          7242: /
        !          7243: / Ewait - wait for next input char to evaluate
        !          7244: /
        !          7245: ////////
        !          7246: 
        !          7247: ewait: call    exit
        !          7248:        jcxz    ewait
        !          7249:        dec     cx
        !          7250:        lodsb
        !          7251:        movb    bl, al
        !          7252:        shlb    bl, $1
        !          7253:        jc      mmputc
        !          7254:        ijmp    cs:asctab(bx)
        !          7255: 
        !          7256: ////////
        !          7257: /
        !          7258: / mm_cr - carriage return
        !          7259: /
        !          7260: /      Moves the active position to first position of current display line.
        !          7261: /
        !          7262: ////////
        !          7263: 
        !          7264: mm_cr: subb    COL, COL
        !          7265:        movb    bl, ROW
        !          7266:        shlb    bl, $1
        !          7267:        mov     POS, cs:rowtab(bx)
        !          7268:        jcxz    ewait
        !          7269:        dec     cx
        !          7270:        lodsb
        !          7271:        movb    bl, al
        !          7272:        shlb    bl, $1
        !          7273:        jc      mmputc
        !          7274:        ijmp    cs:asctab(bx)
        !          7275: 
        !          7276: ////////
        !          7277: /
        !          7278: / mm_cub - cursor backwards
        !          7279: /
        !          7280: ////////
        !          7281: 
        !          7282: mm_cub:        sub     POS, $2
        !          7283:        decb    COL
        !          7284:        jge     0f
        !          7285:        movb    COL, $NCOL-1
        !          7286:        decb    ROW
        !          7287:        cmpb    ROW, MM_BROW(bp)
        !          7288:        jge     0f
        !          7289:        subb    COL, COL
        !          7290:        movb    ROW, MM_BROW(bp)
        !          7291:        movb    bl, ROW
        !          7292:        shlb    bl, $1
        !          7293:        mov     POS, cs:rowtab(bx)
        !          7294: 0:     jcxz    ewait
        !          7295:        dec     cx
        !          7296:        lodsb
        !          7297:        movb    bl, al
        !          7298:        shlb    bl, $1
        !          7299:        jc      mmputc
        !          7300:        ijmp    cs:asctab(bx)
        !          7301: 
        !          7302: ////////
        !          7303: /
        !          7304: / Esc state - entered when last char was ESC - transient state.
        !          7305: /
        !          7306: ////////
        !          7307: 
        !          7308: 0:     call    exit
        !          7309: mm_esc:        jcxz    0b
        !          7310:        dec     cx
        !          7311:        lodsb
        !          7312:        movb    MM_N1(bp), ZERO
        !          7313:        movb    MM_N2(bp), ZERO
        !          7314:        movb    bl, al
        !          7315:        shlb    bl, $1
        !          7316:        jc      mmputc
        !          7317:        ijmp    cs:esctab(bx)
        !          7318: 
        !          7319: ////////
        !          7320: /
        !          7321: / Csi_n1 state - entered when last two chars were ESC [
        !          7322: /
        !          7323: /      Action: Evaluates numeric chars as numeric parameter 1.
        !          7324: /
        !          7325: ////////
        !          7326: 
        !          7327: 0:     call    exit
        !          7328: csi_n1:        jcxz    0b
        !          7329:        dec     cx
        !          7330:        lodsb
        !          7331:        cmpb    al, $SEMIC
        !          7332:        je      csi_n2
        !          7333:        movb    bl, al
        !          7334:        subb    bl, $AZERO
        !          7335:        cmpb    bl, $9
        !          7336:        ja      csival
        !          7337:        shlb    MM_N1(bp), $1   / n1 * 2
        !          7338:        movb    al, MM_N1(bp)   / n1 * 2
        !          7339:        shlb    al, $1          / n1 * 4
        !          7340:        shlb    al, $1          / n1 * 8
        !          7341:        addb    al, MM_N1(bp)   / n1 * 10
        !          7342:        addb    al, bl          / n1 * 10 + digit
        !          7343:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          7344:        jmp     csi_n1
        !          7345: 
        !          7346: ////////
        !          7347: /
        !          7348: / Csi_n2 state - entered after input sequence ESC [ n ;
        !          7349: /
        !          7350: ////////
        !          7351: 
        !          7352: 0:     call    exit
        !          7353: csi_n2:        jcxz    0b
        !          7354:        dec     cx
        !          7355:        lodsb
        !          7356:        movb    bl, al
        !          7357:        subb    bl, $AZERO
        !          7358:        cmpb    bl, $9
        !          7359:        ja      csival
        !          7360:        shlb    MM_N2(bp), $1   / n2 * 2
        !          7361:        movb    al, MM_N2(bp)   / n2 * 2
        !          7362:        shlb    al, $1          / n2 * 4
        !          7363:        shlb    al, $1          / n2 * 8
        !          7364:        addb    al, MM_N2(bp)   / n2 * 10
        !          7365:        addb    al, bl          / n2 * 10 + digit
        !          7366:        movb    MM_N2(bp), al   / n2 = (n2 * 10) + digit
        !          7367:        jmp     csi_n2
        !          7368: 
        !          7369: csival:        movb    bl, al
        !          7370:        shlb    bl, $1
        !          7371:        jc      mmputc
        !          7372:        ijmp    cs:csitab(bx)
        !          7373: 
        !          7374: ////////
        !          7375: /
        !          7376: / Csi_gt state - entered after input sequence ESC [ >
        !          7377: /      
        !          7378: ////////
        !          7379: 
        !          7380: 0:     call    exit
        !          7381: csi_gt:        jcxz    0b
        !          7382:        dec     cx
        !          7383:        lodsb
        !          7384:        movb    bl, al
        !          7385:        subb    bl, $AZERO
        !          7386:        cmpb    bl, $9
        !          7387:        ja      0f
        !          7388:        shlb    MM_N1(bp), $1   / n1 * 2
        !          7389:        movb    al, MM_N1(bp)   / n1 * 2
        !          7390:        shlb    al, $1          / n1 * 4
        !          7391:        shlb    al, $1          / n1 * 8
        !          7392:        addb    al, MM_N1(bp)   / n1 * 10
        !          7393:        addb    al, bl          / n1 * 10 + digit
        !          7394:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          7395:        jmp     csi_gt
        !          7396: 
        !          7397: 0:     cmpb    al, $HLOWER
        !          7398:        je      mm_cgh
        !          7399:        cmpb    al, $LLOWER
        !          7400:        je      mm_cgl
        !          7401:        jmp     eval
        !          7402: 
        !          7403: ////////
        !          7404: /
        !          7405: / Csi_q state - entered after input sequence ESC [ ?
        !          7406: /      
        !          7407: ////////
        !          7408: 
        !          7409: 0:     call    exit
        !          7410: csi_q: jcxz    0b
        !          7411:        dec     cx
        !          7412:        lodsb
        !          7413:        movb    bl, al
        !          7414:        subb    bl, $AZERO
        !          7415:        cmpb    bl, $9
        !          7416:        ja      0f
        !          7417:        shlb    MM_N1(bp), $1   / n1 * 2
        !          7418:        movb    al, MM_N1(bp)   / n1 * 2
        !          7419:        shlb    al, $1          / n1 * 4
        !          7420:        shlb    al, $1          / n1 * 8
        !          7421:        addb    al, MM_N1(bp)   / n1 * 10
        !          7422:        addb    al, bl          / n1 * 10 + digit
        !          7423:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          7424:        jmp     csi_q
        !          7425: 
        !          7426: 0:     cmpb    al, $HLOWER
        !          7427:        je      mm_cqh
        !          7428:        cmpb    al, $LLOWER
        !          7429:        je      mm_cql
        !          7430:        jmp     eval
        !          7431: 
        !          7432: ////////
        !          7433: /
        !          7434: / mm_cbt - cursor backward tabulation
        !          7435: /
        !          7436: /      Moves the active position horizontally in the backward direction
        !          7437: /      to the preceding in a series of predetermined positions.
        !          7438: /
        !          7439: ////////
        !          7440: 
        !          7441: mm_cbt:        orb     COL, $7                 / calculate next tab stop
        !          7442:        incb    COL
        !          7443:        subb    COL, $16                / step back two tab positions
        !          7444:        jg      0f
        !          7445:        subb    COL, COL                / cannot step past column 0
        !          7446: 0:     jmp     repos                   / reposition cursor
        !          7447: 
        !          7448: ////////
        !          7449: /
        !          7450: / mm_cgh - process ESC [ > N1 h escape sequence
        !          7451: /
        !          7452: /      Recognized sequences:   ESC [ > 13 h    -- Set CRT saver enabled.
        !          7453: /
        !          7454: ////////
        !          7455: 
        !          7456: mm_cgh:        cmpb    MM_N1(bp), $13
        !          7457:        jne     0f
        !          7458:        mov     ss:mmcrtsav_, $1
        !          7459: 0:     jmp     eval
        !          7460: 
        !          7461: ////////
        !          7462: /
        !          7463: / mm_cgl - process ESC [ > N1 l escape sequence
        !          7464: /
        !          7465: /      Recognized sequences:   ESC [ > 13 l    -- Reset CRT saver.
        !          7466: /
        !          7467: ////////
        !          7468: 
        !          7469: mm_cgl:        cmpb    MM_N1(bp), $13
        !          7470:        jne     0f
        !          7471:        mov     ss:mmcrtsav_, $0
        !          7472: 0:     jmp     eval
        !          7473: 
        !          7474: ////////
        !          7475: /
        !          7476: / mm_cha - cursor horizontal absolute
        !          7477: /
        !          7478: /      Advances the active position forward or backward along the active line
        !          7479: /      to the character position specified by the parameter.
        !          7480: /      A parameter value of zero or one moves the active position to the
        !          7481: /      first character position of the active line.
        !          7482: /      A parameter value of N moves the active position to character position
        !          7483: /      N of the active line.
        !          7484: /
        !          7485: ////////
        !          7486: 
        !          7487: mm_cha:        movb    COL, MM_N1(bp)
        !          7488:        decb    COL
        !          7489:        jge     0f
        !          7490:        subb    COL, COL
        !          7491: 0:     cmpb    COL, $NCOL
        !          7492:        jb      0f
        !          7493:        movb    COL, $NCOL-1
        !          7494: 0:     jmp     repos                   / reposition cursor
        !          7495: 
        !          7496: 
        !          7497: ////////
        !          7498: /
        !          7499: / mm_cht - cursor horizontal tabulation
        !          7500: /
        !          7501: /      Advances the active position horizontally to the next or following
        !          7502: /      in a series of predetermined positions.
        !          7503: /
        !          7504: ////////
        !          7505: 
        !          7506: mm_cht:        push    cx
        !          7507:        sub     cx, cx
        !          7508:        movb    cl, COL
        !          7509:        orb     cl, $7
        !          7510:        incb    cl
        !          7511:        subb    cl, COL
        !          7512:        addb    COL, cl
        !          7513:        movb    al, $SPACE
        !          7514:        rep
        !          7515:        stosw
        !          7516:        pop     cx
        !          7517:        cmpb    COL, $NCOL
        !          7518:        jb      0f
        !          7519:        subb    COL, $NCOL
        !          7520:        incb    ROW
        !          7521:        cmpb    ROW, MM_EROW(bp)
        !          7522:        jna     0f
        !          7523:        movb    ROW, MM_EROW(bp)
        !          7524:        jmp     scrollup
        !          7525: 0:     jmp     eval
        !          7526: 
        !          7527: ////////
        !          7528: /
        !          7529: / mm_cpl - cursor preceding line
        !          7530: /
        !          7531: /      Moves the active position to the first position of the preceding
        !          7532: /      display line.
        !          7533: /
        !          7534: ////////
        !          7535: 
        !          7536: mm_cpl:        subb    COL, COL
        !          7537:        decb    ROW
        !          7538:        cmpb    ROW, MM_BROW(bp)
        !          7539:        jnb     0f
        !          7540:        movb    ROW, MM_BROW(bp)
        !          7541:        jmp     scrolldown
        !          7542: 0:     jmp     repos                   / reposition cursor
        !          7543: 
        !          7544: ////////
        !          7545: /
        !          7546: / mm_cqh - process ESC [ ? N1 h escape sequence
        !          7547: /
        !          7548: /      Recognized sequences:   ESC [ ? 4 h     -- Set smooth scroll.
        !          7549: /                              ESC [ ? 7 h     -- Set wraparound.
        !          7550: /
        !          7551: ////////
        !          7552: 
        !          7553: mm_cqh:        cmpb    MM_N1(bp), $4           / Smooth scroll.
        !          7554:        jne     0f
        !          7555:        movb    MM_SLOW(bp), $1
        !          7556: 0:     cmpb    MM_N1(bp), $7           / Wraparound.
        !          7557:        jne     0f
        !          7558:        movb    MM_WRAP(bp), $1
        !          7559: 0:     jmp     eval
        !          7560: 
        !          7561: ////////
        !          7562: /
        !          7563: / mm_cql - process ESC [ ? N1 l escape sequence
        !          7564: /
        !          7565: /      Recognized sequences:   ESC [ ? 4 l     -- Set jump scroll.
        !          7566: /                              ESC [ ? 7 l     -- Reset wraparound.
        !          7567: /
        !          7568: ////////
        !          7569: 
        !          7570: mm_cql:        cmpb    MM_N1(bp), $4           / Jump scroll.
        !          7571:        jne     0f
        !          7572:        movb    MM_SLOW(bp), $0
        !          7573: 0:     cmpb    MM_N1(bp), $7           / No wraparound.
        !          7574:        jne     0f
        !          7575:        movb    MM_WRAP(bp), $0
        !          7576: 0:     jmp     eval
        !          7577: 
        !          7578: ////////
        !          7579: /
        !          7580: / mm_cud - cursor down
        !          7581: /
        !          7582: /      Moves the active position downward without altering the
        !          7583: /      horizontal position.
        !          7584: /
        !          7585: ////////
        !          7586: 
        !          7587: mm_cud:        incb    ROW
        !          7588:        cmpb    ROW, MM_EROW(bp)
        !          7589:        jna     0f
        !          7590:        movb    ROW, MM_EROW(bp)
        !          7591: 0:     jmp     repos                   / reposition cursor
        !          7592: 
        !          7593: ////////
        !          7594: /
        !          7595: / mm_cuf - cursor forward
        !          7596: /
        !          7597: /      Moves the active position in the forward direction.
        !          7598: /
        !          7599: ////////
        !          7600: 
        !          7601: mm_cuf:        incb    COL
        !          7602:        cmpb    COL, $NCOL
        !          7603:        jb      0f
        !          7604:        subb    COL, $NCOL
        !          7605:        incb    ROW
        !          7606:        cmpb    ROW, MM_EROW(bp)
        !          7607:        jna     0f
        !          7608:        movb    ROW, MM_EROW(bp)
        !          7609:        movb    COL, $NCOL-1
        !          7610: 0:     jmp     repos
        !          7611: 
        !          7612: ////////
        !          7613: /
        !          7614: / mm_cup - cursor position
        !          7615: /
        !          7616: /      Moves the active position to the position specified by two parameters.
        !          7617: /      The first parameter (mm_n1) specifies the vertical position (MM_ROW(bp)).
        !          7618: /      The second parameter (mm_n2) specifies the horizontal position (MM_COL(bp)).
        !          7619: /      A parameter value of 0 or 1 for the first or second parameter
        !          7620: /      moves the active position to the first line or column in the
        !          7621: /      display respectively.
        !          7622: /
        !          7623: ////////
        !          7624: 
        !          7625: mm_cup:        movb    ROW, MM_N1(bp)
        !          7626:        decb    ROW
        !          7627:        jg      0f
        !          7628:        subb    ROW, ROW
        !          7629: 0:     addb    ROW, MM_BROW(bp)
        !          7630:        cmpb    ROW, MM_EROW(bp)
        !          7631:        jb      0f
        !          7632:        movb    ROW, MM_EROW(bp)
        !          7633: 0:     movb    COL, MM_N2(bp)
        !          7634:        decb    COL
        !          7635:        jg      0f
        !          7636:        subb    COL, COL
        !          7637: 0:     cmpb    COL, $NCOL
        !          7638:        jb      0f
        !          7639:        movb    COL, $NCOL-1
        !          7640: 0:     jmp     repos                   / reposition cursor
        !          7641: 
        !          7642: ////////
        !          7643: /
        !          7644: / mm_cuu - cursor up
        !          7645: /
        !          7646: /      Moves the active position upward without altering the horizontal
        !          7647: /      position.
        !          7648: /
        !          7649: ////////
        !          7650: 
        !          7651: mm_cuu:        decb    ROW
        !          7652:        cmpb    ROW, MM_BROW(bp)
        !          7653:        jge     0f
        !          7654:        movb    ROW, MM_BROW(bp)
        !          7655: 0:     jmp     repos                   / reposition cursor
        !          7656: 
        !          7657: ////////
        !          7658: /
        !          7659: / mm_dl - delete line
        !          7660: /
        !          7661: /      Removes the contents of the active line.
        !          7662: /      The contents of all following lines are shifted in a block
        !          7663: /      toward the active line.
        !          7664: /
        !          7665: ////////
        !          7666: 
        !          7667: mm_dl: push    ds
        !          7668:        push    si
        !          7669:        push    cx
        !          7670:        mov     ds, MM_BASE(bp)
        !          7671:        movb    bl, ROW
        !          7672:        shlb    bl, $1
        !          7673:        mov     di, cs:rowtab(bx)
        !          7674:        mov     si, cs:rowtab+2(bx)
        !          7675:        movb    bl, MM_EROW(bp)
        !          7676:        shlb    bl, $1
        !          7677:        mov     cx, cs:rowtab(bx)
        !          7678:        sub     cx, di
        !          7679:        jle     0f
        !          7680:        shr     cx, $1
        !          7681:        rep
        !          7682:        movsw
        !          7683:        mov     di, cs:rowtab(bx)
        !          7684:        mov     cx, $NCOL
        !          7685:        movb    al, $SPACE
        !          7686:        rep
        !          7687:        stosw
        !          7688:        subb    COL, COL
        !          7689:        movb    bl, ROW
        !          7690:        shlb    bl, $1
        !          7691:        mov     di, cs:rowtab(bx)
        !          7692: 0:     pop     cx
        !          7693:        pop     si
        !          7694:        pop     ds
        !          7695:        call    exit
        !          7696:        jmp     eval
        !          7697: 
        !          7698: ////////
        !          7699: /
        !          7700: / mm_dmi - disable manual input
        !          7701: /
        !          7702: /      Set flag preventing keyboard input, and causing cursor to vanish.
        !          7703: /
        !          7704: ////////
        !          7705: 
        !          7706: mm_dmi:
        !          7707:        mov     ss:islock_, $1
        !          7708:        jmp     eval
        !          7709: 
        !          7710: ////////
        !          7711: /
        !          7712: / mm_ea - erase in area
        !          7713: /
        !          7714: /      Erase some or all of the characters in the currently active area
        !          7715: /      according to the parameter:
        !          7716: /              0 - erase from active position to end inclusive (default)
        !          7717: /              1 - erase from start to active position inclusive
        !          7718: /              2 - erase all of active area
        !          7719: /
        !          7720: ////////
        !          7721: 
        !          7722: mm_ea: movb    al, MM_N1(bp)
        !          7723:        cmpb    al, $0
        !          7724:        jne     0f
        !          7725:        movb    bl, MM_EROW(bp)
        !          7726:        jmp     mm_e0
        !          7727: 0:     cmpb    al, $1
        !          7728:        jne     0f
        !          7729:        movb    bl, MM_BROW(bp)
        !          7730:        jmp     mm_e1
        !          7731: 0:     subb    COL, COL
        !          7732:        movb    ROW, MM_BROW(bp)
        !          7733:        movb    bl, ROW
        !          7734:        shlb    bl, $1
        !          7735:        mov     POS, cs:rowtab(bx)
        !          7736:        movb    bl, MM_EROW(bp)
        !          7737:        subb    bl, ROW
        !          7738:        jmp     mm_e2
        !          7739: 
        !          7740: 
        !          7741: ////////
        !          7742: /
        !          7743: / mm_ed - erase in display
        !          7744: /
        !          7745: /      Erase some or all of the characters in the display according to the
        !          7746: /      parameter
        !          7747: /              0 - erase from active position to end inclusive (default)
        !          7748: /              1 - erase from start to active position inclusive
        !          7749: /              2 - erase all of display
        !          7750: /
        !          7751: ////////
        !          7752: 
        !          7753: mm_ed: movb    al, MM_N1(bp)
        !          7754:        cmpb    al, $0
        !          7755:        jne     0f
        !          7756:        movb    bl, MM_LROW(bp)
        !          7757:        jmp     mm_e0
        !          7758: 0:     cmpb    al, $1
        !          7759:        jne     0f
        !          7760:        subb    bl, bl
        !          7761:        jmp     mm_e1
        !          7762: 0:     subb    COL, COL
        !          7763:        movb    ROW, MM_BROW(bp)
        !          7764:        sub     POS, POS
        !          7765:        movb    bl, MM_LROW(bp)
        !          7766:        jmp     mm_e2
        !          7767: 
        !          7768: ////////
        !          7769: /
        !          7770: / mm_el - erase in line
        !          7771: /
        !          7772: /      Erase some or all of the characters in the line according to the
        !          7773: /      parameter:
        !          7774: /              0 - erase from active position to end inclusive (default)
        !          7775: /              1 - erase from start to active position inclusive
        !          7776: /              2 - erase entire line
        !          7777: /
        !          7778: ////////
        !          7779: 
        !          7780: mm_el: movb    al, MM_N1(bp)
        !          7781:        movb    bl, ROW
        !          7782:        cmpb    al, $0
        !          7783:        je      mm_e0
        !          7784:        cmpb    al, $1
        !          7785:        je      mm_e1
        !          7786:        shlb    bl, $1
        !          7787:        mov     POS, cs:rowtab(bx)
        !          7788:        subb    COL, COL
        !          7789:        subb    bl, bl
        !          7790: /      jmp     mm_e2
        !          7791: 
        !          7792: mm_e2: push    cx
        !          7793:        movb    al, $SPACE
        !          7794: 0:     mov     cx, $NCOL
        !          7795:        rep
        !          7796:        stosw
        !          7797:        decb    bl
        !          7798:        jge     0b
        !          7799:        pop     cx
        !          7800:        jmp     repos
        !          7801: 
        !          7802: mm_e1: push    cx
        !          7803:        mov     cx, POS
        !          7804:        shlb    bl, $1
        !          7805:        mov     POS, cs:rowtab(bx)
        !          7806:        sub     cx, POS
        !          7807:        jl      0f
        !          7808:        movb    al, $SPACE
        !          7809:        shr     cx, $1
        !          7810:        rep
        !          7811:        stosw
        !          7812: 0:     pop     cx
        !          7813:        jmp     repos
        !          7814: 
        !          7815: mm_e0: push    cx
        !          7816:        shlb    bl, $1
        !          7817:        mov     cx, cs:rowtab+2(bx)
        !          7818:        sub     cx, POS
        !          7819:        jl      0f
        !          7820:        movb    al, $SPACE
        !          7821:        shr     cx, $1
        !          7822:        rep
        !          7823:        stosw
        !          7824: 0:     pop     cx
        !          7825:        jmp     repos
        !          7826: 
        !          7827: ////////
        !          7828: /
        !          7829: / mm_emi - enable manual input
        !          7830: /
        !          7831: /      Clear flag preventing keyboard input.
        !          7832: /
        !          7833: ////////
        !          7834: 
        !          7835: mm_emi:
        !          7836:        mov     ss:islock_, $0
        !          7837:        jmp     eval
        !          7838: 
        !          7839: ////////
        !          7840: /
        !          7841: / mm_il - insert line
        !          7842: /
        !          7843: /      Insert a erased line at the active line by shifting the contents
        !          7844: /      of the active line and all following lines away from the active line.
        !          7845: /      The contents of the last line in the scrolling region are removed.
        !          7846: /
        !          7847: ////////
        !          7848: 
        !          7849: scrolldown:
        !          7850: mm_il: push    ds
        !          7851:        push    si
        !          7852:        push    cx
        !          7853:        mov     ds, MM_BASE(bp)
        !          7854:        movb    bl, MM_EROW(bp)
        !          7855:        shlb    bl, $1
        !          7856:        mov     si, cs:rowtab(bx)
        !          7857:        mov     cx, si
        !          7858:        sub     si, $2
        !          7859:        mov     di, cs:rowtab+2(bx)
        !          7860:        sub     di, $2
        !          7861:        movb    bl, ROW
        !          7862:        shlb    bl, $1
        !          7863:        sub     cx, cs:rowtab(bx)
        !          7864:        jle     0f
        !          7865:        shr     cx, $1
        !          7866:        std
        !          7867:        rep
        !          7868:        movsw
        !          7869:        mov     di, cs:rowtab(bx)
        !          7870:        mov     cx, $NCOL
        !          7871:        movb    al, $SPACE
        !          7872:        cld
        !          7873:        rep
        !          7874:        stosw
        !          7875:        subb    COL, COL
        !          7876:        movb    bl, ROW
        !          7877:        shlb    bl, $1
        !          7878:        mov     di, cs:rowtab(bx)
        !          7879: 0:     pop     cx
        !          7880:        pop     si
        !          7881:        pop     ds
        !          7882:        call    exit
        !          7883:        jmp     eval
        !          7884: 
        !          7885: ////////
        !          7886: /
        !          7887: / mm_hpa - horizontal position absolute
        !          7888: /
        !          7889: /      Moves the active position within the active line to the position
        !          7890: /      specified by the parameter.  A parameter value of zero or one
        !          7891: /      moves the active position to the first position of the active line.
        !          7892: /
        !          7893: ////////
        !          7894: 
        !          7895: mm_hpa:        movb    COL, MM_N1(bp)
        !          7896:        decb    COL
        !          7897:        jg      0f
        !          7898:        subb    COL, COL
        !          7899: 0:     cmpb    COL, $NCOL
        !          7900:        jb      0f
        !          7901:        movb    COL, $NCOL-1
        !          7902: 0:     jmp     repos                   / reposition cursor
        !          7903: 
        !          7904: ////////
        !          7905: /
        !          7906: / mm_hpr - horizontal position relative
        !          7907: /
        !          7908: /      Moves the active position forward the number of positions specified
        !          7909: /      by the parameter.  A parameter value of zero or one indicates a
        !          7910: /      single-position move.
        !          7911: /
        !          7912: ////////
        !          7913: 
        !          7914: mm_hpr:        movb    al, MM_N1(bp)
        !          7915:        orb     al, al
        !          7916:        jne     0f
        !          7917:        incb    al
        !          7918: 0:     addb    COL, al
        !          7919:        cmpb    COL, $NCOL
        !          7920:        jb      0f
        !          7921:        movb    COL, $NCOL-1
        !          7922: 0:     jmp     repos                   / reposition cursor
        !          7923: 
        !          7924: ////////
        !          7925: /
        !          7926: / mm_hvp - horizontal and vertical position
        !          7927: /
        !          7928: /      Moves the active position to the position specified by two parameters.
        !          7929: /      The first parameter specifies the vertical position (MM_ROW(bp)).
        !          7930: /      The second parameter specifies the horizontal position (MM_COL(bp)).
        !          7931: /      A parameter value of zero or one moves the active position to the
        !          7932: /      first line or column in the display.
        !          7933: /
        !          7934: ////////
        !          7935: 
        !          7936: mm_hvp:        movb    ROW, MM_N1(bp)
        !          7937:        decb    ROW
        !          7938:        jg      0f
        !          7939:        subb    ROW, ROW
        !          7940: 0:     cmpb    ROW, MM_LROW(bp)
        !          7941:        jna     0f
        !          7942:        movb    ROW, MM_LROW(bp)
        !          7943: 0:     movb    COL, MM_N2(bp)
        !          7944:        decb    COL
        !          7945:        jg      0f
        !          7946:        subb    COL, COL
        !          7947: 0:     cmpb    COL, $NCOL
        !          7948:        jb      0f
        !          7949:        movb    COL, $NCOL-1
        !          7950: 0:     jmp     repos                   / reposition cursor
        !          7951: 
        !          7952: ////////
        !          7953: /
        !          7954: / mm_ind - index
        !          7955: /
        !          7956: /      Causes the active position to move downward one line without changing
        !          7957: /      the horizontal position.  Scrolling occurs if below scrolling region.
        !          7958: /
        !          7959: ////////
        !          7960: 
        !          7961: mm_ind:        incb    ROW
        !          7962:        cmpb    ROW, MM_EROW(bp)
        !          7963:        jg      0f
        !          7964:        jmp     repos
        !          7965: 0:     movb    ROW, MM_EROW(bp)
        !          7966:        jmp     scrollup
        !          7967: 
        !          7968: ////////
        !          7969: /
        !          7970: / mm_new - save cursor position
        !          7971: /
        !          7972: ////////
        !          7973: 
        !          7974: mm_new:        movb    MM_SCOL(bp), COL
        !          7975:        movb    MM_SROW(bp), ROW
        !          7976:        jmp     eval
        !          7977: 
        !          7978: ////////
        !          7979: /
        !          7980: / mm_old - restore old cursor position
        !          7981: /
        !          7982: ////////
        !          7983: 
        !          7984: mm_old:        movb    COL, MM_SCOL(bp)
        !          7985:        movb    ROW, MM_SROW(bp)
        !          7986:        jmp     repos
        !          7987: 
        !          7988: ////////
        !          7989: /
        !          7990: / mm_ri - reverse index
        !          7991: /
        !          7992: /      Moves the active position to the same horizontal position on the
        !          7993: /      preceding line.  Scrolling occurs if above scrolling region.
        !          7994: /
        !          7995: ////////
        !          7996: 
        !          7997: mm_ri: decb    ROW
        !          7998:        cmpb    ROW, MM_BROW(bp)
        !          7999:        jge     0f
        !          8000:        movb    ROW, MM_BROW(bp)
        !          8001:        jmp     scrolldown
        !          8002: 0:     jmp     repos
        !          8003: 
        !          8004: ////////
        !          8005: /
        !          8006: / mm_scr - select cursor rendition
        !          8007: /
        !          8008: /      Invokes the cursor rendition specified by the parameter.
        !          8009: /
        !          8010: /      Recognized renditions are:      0 - cursor visible
        !          8011: /                                      1 - cursor invisible
        !          8012: ////////
        !          8013: 
        !          8014: mm_scr:        decb     MM_N1(bp)
        !          8015:        je      0f
        !          8016:        jg      1f
        !          8017:        mov     MM_INVIS(bp), $0
        !          8018:        jmp     eval
        !          8019: 
        !          8020: 0:     mov     MM_INVIS(bp), $-1
        !          8021: 1:     jmp     eval
        !          8022: 
        !          8023: ////////
        !          8024: /
        !          8025: / mm_sgr - select graphic rendition
        !          8026: /
        !          8027: /      Invokes the graphic rendition specified by the parameter.
        !          8028: /      All following characters in the data stream are rendered
        !          8029: /      according to the parameters until the next occurrence of
        !          8030: /      SGR in the data stream.
        !          8031: /
        !          8032: /      Recognized renditions are:      1 - high intensity
        !          8033: /                                      4 - underline
        !          8034: /                                      5 - slow blink
        !          8035: /                                      7 - reverse video
        !          8036: /                                      8 - concealed on
        !          8037: /                                      30-37 - foreground color
        !          8038: /                                      40-47 - background color
        !          8039: /                                      50-57 - border color
        !          8040: /
        !          8041: ////////
        !          8042: 
        !          8043: mm_sgr:        movb    al, MM_N1(bp)
        !          8044: 
        !          8045:        cmpb    al, $0                  / reset all = 0
        !          8046:        jne     0f
        !          8047:        movb    ATTR, $0x07
        !          8048: 1:     jmp     eval
        !          8049: 
        !          8050: 0:     cmpb    al, $1                  / bold = 1
        !          8051:        jne     0f
        !          8052:        orb     ATTR, $INTENSE
        !          8053:        jmp     1b
        !          8054: 
        !          8055: 0:     cmpb    al, $4                  / underline = 4
        !          8056:        jne     0f
        !          8057:        cmp     MM_PORT(bp), $0x03D4    / color card?
        !          8058:        je      1b                      / yes, ignore underline
        !          8059:        andb    ATTR, $~0x77
        !          8060:        orb     ATTR, $0x01
        !          8061:        jmp     1b
        !          8062: 
        !          8063: 0:     cmpb    al, $5                  / blinking = 5
        !          8064:        jne     0f
        !          8065:        orb     ATTR, $BLINK
        !          8066:        jmp     1b
        !          8067: 
        !          8068: 0:     cmpb    al, $7                  / reverse video = 7
        !          8069:        jne     0f
        !          8070:        movb    al, $0x70
        !          8071:        cmp     MM_PORT(bp), $0x3D4     / color card?
        !          8072:        jne     2f
        !          8073:        movb    al, ATTR                / yes, exchange foreground/background
        !          8074:        andb    al, $0x77
        !          8075:        rolb    al, $1
        !          8076:        rolb    al, $1
        !          8077:        rolb    al, $1
        !          8078:        rolb    al, $1
        !          8079: 2:     andb    ATTR, $~0x77
        !          8080:        orb     ATTR, al
        !          8081:        jmp     1b
        !          8082: 
        !          8083: 0:     cmpb    al, $8                  / concealed on = 8
        !          8084:        jne     0f
        !          8085:        cmp     MM_PORT(bp), $0x3D4     / color card?
        !          8086:        jne     2f
        !          8087: 
        !          8088:        andb    ATTR, $0x70             / Yes,  Set foreground color
        !          8089:        movb    al, ATTR                /       to background color.
        !          8090:        rorb    al, $1
        !          8091:        rorb    al, $1
        !          8092:        rorb    al, $1
        !          8093:        rorb    al, $1
        !          8094:        orb     ATTR, al
        !          8095:        jmp     1b
        !          8096: 
        !          8097: 2:     andb    ATTR, $0x80             / No, set attributes to non-display.
        !          8098:        jmp     1b                      /       retain blink attribute.
        !          8099: 
        !          8100: 0:     cmp     MM_PORT(bp), $0x03D4    / color card?
        !          8101:        jne     1b                      / no, ignore remaining options
        !          8102: 0:     subb    al, $30                 / foreground color
        !          8103:        jl      1f
        !          8104:        cmpb    al, $7
        !          8105:        jg      0f
        !          8106:        movb    bl, al
        !          8107:        andb    ATTR, $~0x07
        !          8108:        orb     ATTR, cs:fcolor(bx)
        !          8109:        jmp     1f
        !          8110: 0:     subb    al, $10
        !          8111:        jl      1f
        !          8112:        cmpb    al, $7
        !          8113:        jg      0f
        !          8114:        movb    bl, al
        !          8115:        andb    ATTR, $~0x70
        !          8116:        orb     ATTR, cs:bcolor(bx)
        !          8117:        jmp     1f
        !          8118: 0:     subb    al, $10
        !          8119:        jl      1f
        !          8120:        cmpb    al, $7
        !          8121:        jg      0f
        !          8122:        movb    bl, al
        !          8123:        movb    al, cs:fcolor(bx)
        !          8124:        push    dx
        !          8125:        mov     dx, MM_PORT(bp)
        !          8126:        add     dx, $5
        !          8127:        outb    dx, al
        !          8128:        pop     dx
        !          8129: /      jmp     1f
        !          8130: 0:
        !          8131: 1:     jmp     eval
        !          8132: 
        !          8133: ////////
        !          8134: /
        !          8135: / mm_ssr - set scrolling region
        !          8136: /
        !          8137: ////////
        !          8138: 
        !          8139: mm_ssr:        movb    al, MM_N1(bp)
        !          8140:        decb    al
        !          8141:        jge     0f
        !          8142:        subb    al, al
        !          8143: 0:     cmpb    al, MM_LROW(bp)
        !          8144:        ja      1f
        !          8145:        movb    bl, MM_N2(bp)
        !          8146:        decb    bl
        !          8147:        jge     0f
        !          8148:        subb    bl, bl
        !          8149: 0:     cmpb    bl, MM_LROW(bp)
        !          8150:        ja      1f
        !          8151:        cmpb    al, bl
        !          8152:        ja      1f
        !          8153:        movb    MM_BROW(bp), al
        !          8154:        movb    MM_EROW(bp), bl
        !          8155:        movb    ROW, al
        !          8156:        subb    COL, COL
        !          8157: 1:     jmp     repos
        !          8158: 
        !          8159: ////////
        !          8160: /
        !          8161: / mm_vpa - vertical position absolute
        !          8162: /
        !          8163: /      Moves the active position to the line specified by the parameter
        !          8164: /      without changing the horizontal position.
        !          8165: /      A parameter value of 0 or 1 moves the active position vertically
        !          8166: /      to the first line.
        !          8167: /
        !          8168: ////////
        !          8169: 
        !          8170: mm_vpa:        movb    ROW, MM_N1(bp)
        !          8171:        decb    ROW
        !          8172:        jg      0f
        !          8173:        subb    ROW, ROW
        !          8174: 0:     cmpb    ROW, MM_LROW(bp)
        !          8175:        jna     0f
        !          8176:        movb    ROW, MM_LROW(bp)
        !          8177: 0:     jmp     repos                   / reposition cursor
        !          8178: 
        !          8179: ////////
        !          8180: /
        !          8181: / mm_vpr - vertical position relative
        !          8182: /
        !          8183: /      Moves the active position downward the number of lines specified
        !          8184: /      by the parameter without changing the horizontal position.
        !          8185: /      A parameter value of zero or one moves the active position
        !          8186: /      one line downward.
        !          8187: /
        !          8188: ////////
        !          8189: 
        !          8190: mm_vpr:        movb    al, MM_N1(bp)
        !          8191:        orb     al, al
        !          8192:        jne     0f
        !          8193:        incb    al
        !          8194: 0:     addb    ROW, al
        !          8195:        cmpb    ROW, MM_LROW(bp)
        !          8196:        jb      0f
        !          8197:        movb    ROW, MM_LROW(bp)
        !          8198: 0:     jmp     repos                   / reposition cursor
        !          8199: 
        !          8200: ////////
        !          8201: /
        !          8202: / asctab - table of functions indexed by ascii characters
        !          8203: /
        !          8204: ////////
        !          8205: 
        !          8206: asctab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          8207:        .word   eval,   eval,   eval,   mmbell  /* EOT  ENQ  ACK  BEL  */
        !          8208:        .word   mm_cub, mm_cht, mm_cnl, mm_ind  /* BS   HT   LF   VT   */
        !          8209:        .word   eval,   mm_cr,  eval,   eval    /* FF   CR   SO   SI   */
        !          8210:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3  */
        !          8211:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          8212:        .word   eval,   eval,   eval,   mm_esc  /* CAN  EM   SUB  ESC  */
        !          8213:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          8214:        .word   mmputc, mmputc, mmputc, mmputc  /*   ! " # \040 - \043 */
        !          8215:        .word   mmputc, mmputc, mmputc, mmputc  /* $ % & quote \044 - \047 */
        !          8216:        .word   mmputc, mmputc, mmputc, mmputc  /* ( ) * + \050 - \053 */
        !          8217:        .word   mmputc, mmputc, mmputc, mmputc  /* , - . / \054 - \057 */
        !          8218:        .word   mmputc, mmputc, mmputc, mmputc  /* 0 1 2 3 \060 - \063 */
        !          8219:        .word   mmputc, mmputc, mmputc, mmputc  /* 4 5 6 7 \064 - \067 */
        !          8220:        .word   mmputc, mmputc, mmputc, mmputc  /* 8 9 : ; \070 - \073 */
        !          8221:        .word   mmputc, mmputc, mmputc, mmputc  /* < = > ? \074 - \077 */
        !          8222:        .word   mmputc, mmputc, mmputc, mmputc  /* @ A B C \100 - \103 */
        !          8223:        .word   mmputc, mmputc, mmputc, mmputc  /* D E F G \104 - \107 */
        !          8224:        .word   mmputc, mmputc, mmputc, mmputc  /* H I J K \110 - \113 */
        !          8225:        .word   mmputc, mmputc, mmputc, mmputc  /* L M N O \114 - \117 */
        !          8226:        .word   mmputc, mmputc, mmputc, mmputc  /* P Q R S \120 - \123 */
        !          8227:        .word   mmputc, mmputc, mmputc, mmputc  /* T U V W \124 - \127 */
        !          8228:        .word   mmputc, mmputc, mmputc, mmputc  /* X Y Z [ \130 - \133 */
        !          8229:        .word   mmputc, mmputc, mmputc, mmputc  /* \ ] ^ _ \134 - \137 */
        !          8230:        .word   mmputc, mmputc, mmputc, mmputc  /* ` a b c \140 - \143 */
        !          8231:        .word   mmputc, mmputc, mmputc, mmputc  /* d e f g \144 - \147 */
        !          8232:        .word   mmputc, mmputc, mmputc, mmputc  /* h i j k \150 - \153 */
        !          8233:        .word   mmputc, mmputc, mmputc, mmputc  /* l m n o \154 - \157 */
        !          8234:        .word   mmputc, mmputc, mmputc, mmputc  /* p q r s \160 - \163 */
        !          8235:        .word   mmputc, mmputc, mmputc, mmputc  /* t u v w \164 - \167 */
        !          8236:        .word   mmputc, mmputc, mmputc, mmputc  /* x y z { \170 - \173 */
        !          8237:        .word   mmputc, mmputc, mmputc, mmputc  /* | } ~ ? \174 - \177 */
        !          8238: 
        !          8239: ////////
        !          8240: /
        !          8241: / esctab - table of functions indexed by ESC characters.
        !          8242: /
        !          8243: ////////
        !          8244: 
        !          8245: esctab:        .word   mmputc, mmputc, mmputc, mmputc  /* NUL  SOH  STX  ETX  */
        !          8246:        .word   mmputc, mmputc, mmputc, mmputc  /* EOT  ENQ  ACK  BEL  */
        !          8247:        .word   mmputc, mmputc, mmputc, mmputc  /* BS   HT   LF   VT   */
        !          8248:        .word   mmputc, mmputc, mmputc, mmputc  /* FF   CR   SO   SI   */
        !          8249:        .word   mmputc, mmputc, mmputc, mmputc  /* DLE  DC1  DC2  DC3  */
        !          8250:        .word   mmputc, mmputc, mmputc, mmputc  /* DC4  NAK  SYN  ETB  */
        !          8251:        .word   mmputc, mmputc, mmputc, mmputc  /* CAN  EM   SUB  ESC  */
        !          8252:        .word   mmputc, mmputc, mmputc, mmputc  /* FS   GS   RS   US   */
        !          8253:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          8254:        .word   eval,   eval,   eval,   eval    /* $ % & quote \044 - \047 */
        !          8255:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          8256:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          8257:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          8258:        .word   eval,   eval,   eval,   mm_new  /* 4 5 6 7 \064 - \067 */
        !          8259:        .word   mm_old, eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          8260:        .word   eval,   mmspec, mmspec, eval    /* < = > ? \074 - \077 */
        !          8261:        .word   eval,   eval,   eval,   eval    /* @ A B C \100 - \103 */
        !          8262:        .word   mm_ind, mm_cnl, eval,   eval    /* D E F G \104 - \107 */
        !          8263:        .word   eval,   eval,   eval,   eval    /* H I J K \110 - \113 */
        !          8264:        .word   eval,   mm_ri,  eval,   eval    /* L M N O \114 - \117 */
        !          8265:        .word   eval,   eval,   eval,   eval    /* P Q R S \120 - \123 */
        !          8266:        .word   eval,   eval,   eval,   eval    /* T U V W \124 - \127 */
        !          8267:        .word   eval,   eval,   eval,   csi_n1  /* X Y Z [ \130 - \133 */
        !          8268:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          8269:        .word   mm_dmi, eval,   mm_emi, mminit  /* ` a b c \140 - \143 */
        !          8270:        .word   eval,   eval,   eval,   eval    /* d e f g \144 - \147 */
        !          8271:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          8272:        .word   eval,   eval,   eval,   eval    /* l m n o \154 - \157 */
        !          8273:        .word   eval,   eval,   eval,   eval    /* p q r s \160 - \163 */
        !          8274:        .word   mmspec, mmspec, eval,   eval    /* t u v w \164 - \167 */
        !          8275:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          8276:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          8277: 
        !          8278: 
        !          8279: ////////
        !          8280: /
        !          8281: / csitab - table of functions indexed by ESC [ characters.
        !          8282: /
        !          8283: ////////
        !          8284: 
        !          8285: csitab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          8286:        .word   eval,   eval,   eval,   eval    /* EOT  ENQ  ACK  BEL  */
        !          8287:        .word   eval,   eval,   eval,   eval    /* BS   HT   LF   VT   */
        !          8288:        .word   eval,   eval,   eval,   eval    /* FF   CR   SO   SI   */
        !          8289:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3  */
        !          8290:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          8291:        .word   eval,   eval,   eval,   eval    /* CAN  EM   SUB  ESC  */
        !          8292:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          8293:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          8294:        .word   eval,   eval,   eval,   eval    /* $ % & quote \044 - \047 */
        !          8295:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          8296:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          8297:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          8298:        .word   eval,   eval,   eval,   eval    /* 4 5 6 7 \064 - \067 */
        !          8299:        .word   eval,   eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          8300:        .word   eval,   eval,   csi_gt, csi_q   /* < = > ? \074 - \077 */
        !          8301:        .word   eval,   mm_cuu, mm_cud, mm_cuf  /* @ A B C \100 - \103 */
        !          8302:        .word   mm_cub, mm_cnl, mm_cpl, mm_cha  /* D E F G \104 - \107 */
        !          8303:        .word   mm_cup, mm_cht, mm_ed,  mm_el   /* H I J K \110 - \113 */
        !          8304:        .word   mm_il,  mm_dl,  eval,   mm_ea   /* L M N O \114 - \117 */
        !          8305:        .word   eval,   eval,   eval,   mm_ind  /* P Q R S \120 - \123 */
        !          8306:        .word   mm_ri,  eval,   eval,   eval    /* T U V W \124 - \127 */
        !          8307:        .word   eval,   eval,   mm_cbt, eval    /* X Y Z [ \130 - \133 */
        !          8308:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          8309:        .word   mm_hpa, mm_hpr, eval,   eval    /* ` a b c \140 - \143 */
        !          8310:        .word   mm_vpa, mm_vpr, mm_hvp, mm_cup  /* d e f g \144 - \147 */
        !          8311:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          8312:        .word   eval,   mm_sgr, eval,   eval    /* l m n o \154 - \157 */
        !          8313:        .word   eval,   eval,   mm_ssr, eval    /* p q r s \160 - \163 */
        !          8314:        .word   eval,   eval,   mm_scr, eval    /* t u v w \164 - \167 */
        !          8315:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          8316:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          8317: 
        !          8318: ////////
        !          8319: /
        !          8320: / coltab - integer array of offsets to each column
        !          8321: /
        !          8322: ////////
        !          8323: 
        !          8324: coltab:        .word    0*NCB,  1*NCB,  2*NCB,  3*NCB
        !          8325:        .word    4*NCB,  5*NCB,  6*NCB,  7*NCB
        !          8326:        .word    8*NCB,  9*NCB, 10*NCB, 11*NCB
        !          8327:        .word   12*NCB, 13*NCB, 14*NCB, 15*NCB
        !          8328:        .word   16*NCB, 17*NCB, 18*NCB, 19*NCB
        !          8329:        .word   20*NCB, 21*NCB, 22*NCB, 23*NCB
        !          8330:        .word   24*NCB, 25*NCB, 26*NCB, 27*NCB
        !          8331:        .word   28*NCB, 29*NCB, 30*NCB, 31*NCB
        !          8332:        .word   32*NCB, 33*NCB, 34*NCB, 35*NCB
        !          8333:        .word   36*NCB, 37*NCB, 38*NCB, 39*NCB
        !          8334:        .word   40*NCB, 41*NCB, 42*NCB, 43*NCB
        !          8335:        .word   44*NCB, 45*NCB, 46*NCB, 47*NCB
        !          8336:        .word   48*NCB, 49*NCB, 50*NCB, 51*NCB
        !          8337:        .word   52*NCB, 53*NCB, 54*NCB, 55*NCB
        !          8338:        .word   56*NCB, 57*NCB, 58*NCB, 59*NCB
        !          8339:        .word   60*NCB, 61*NCB, 62*NCB, 63*NCB
        !          8340:        .word   64*NCB, 65*NCB, 66*NCB, 67*NCB
        !          8341:        .word   68*NCB, 69*NCB, 70*NCB, 71*NCB
        !          8342:        .word   72*NCB, 73*NCB, 74*NCB, 75*NCB
        !          8343:        .word   76*NCB, 77*NCB, 78*NCB, 79*NCB
        !          8344: 
        !          8345: ////////
        !          8346: /
        !          8347: / rowtab - array of offsets to each row
        !          8348: /
        !          8349: ////////
        !          8350: 
        !          8351: rowtab:        .word    0*NRB,  1*NRB,  2*NRB,  3*NRB
        !          8352:        .word    4*NRB,  5*NRB,  6*NRB,  7*NRB
        !          8353:        .word    8*NRB,  9*NRB, 10*NRB, 11*NRB
        !          8354:        .word   12*NRB, 13*NRB, 14*NRB, 15*NRB
        !          8355:        .word   16*NRB, 17*NRB, 18*NRB, 19*NRB
        !          8356:        .word   20*NRB, 21*NRB, 22*NRB, 23*NRB
        !          8357:        .word   24*NRB, 25*NRB, 26*NRB, 27*NRB
        !          8358:        .word   28*NRB, 29*NRB, 30*NRB, 31*NRB
        !          8359: 
        !          8360: ////////
        !          8361: /
        !          8362: / fcolor - foreground color
        !          8363: / bcolor - background color
        !          8364: /
        !          8365: /      indexed by ansi color (black,red,green,brown,blue,magenta,cyan,white)
        !          8366: /      yields graphics color (black,blue,green,cyan,red,magenta,brown,white)
        !          8367: /              which is properly shifted for installation in attribute byte.
        !          8368: /
        !          8369: ////////
        !          8370: 
        !          8371: fcolor:        .byte   0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07
        !          8372: bcolor:        .byte   0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70
        !          8373: 
        !          8374: ////////
        !          8375: /
        !          8376: / mm_voff()    -- turn video display off
        !          8377: /
        !          8378: ////////
        !          8379:        .globl  mm_voff_
        !          8380: mm_voff_:
        !          8381:        mov     dx, mmdata+MM_PORT
        !          8382:        add     dx, $4
        !          8383:        movb    al, $0x21
        !          8384:        outb    dx, al
        !          8385:        ret
        !          8386: 
        !          8387: ////////
        !          8388: /
        !          8389: / mm_von()     -- turn video display on
        !          8390: /
        !          8391: ////////
        !          8392:        .globl  mm_von_
        !          8393: mm_von_:
        !          8394:        mov     dx, mmdata+MM_PORT      / enable video display
        !          8395:        add     dx, $4
        !          8396:        movb    al, $0x29
        !          8397:        outb    dx, al
        !          8398:        mov     mmvcnt_, $900           / 900 seconds before video disabled
        !          8399:        ret
        !          8400: 0707070064030050601006440000030000030000011777770507310634200004600000026510/newbits/kernel/USRSRC/i8086/drv/hs.c/* (-lgl
        !          8401:  *     COHERENT Driver Kit Version 1.1.0
        !          8402:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          8403:  *     All rights reserved. May not be copied without permission.
        !          8404:  -lgl) */
        !          8405: /*
        !          8406:  * Polled Serial Port Device Driver.
        !          8407:  * - supports version 7 compatible ioctl
        !          8408:  */
        !          8409: 
        !          8410: #include <sys/coherent.h>
        !          8411: #include <sys/ins8250.h>
        !          8412: #include <sys/stat.h>
        !          8413: #include <sys/uproc.h>
        !          8414: #include <sys/proc.h>
        !          8415: #include <sys/tty.h>           /* indirectly includes sgtty.h */
        !          8416: #include <sys/con.h>
        !          8417: #include <sys/devices.h>
        !          8418: #include <errno.h>
        !          8419: #include <sys/sched.h>         /* CVTTOUT, IVTTOUT, SVTTOUT */
        !          8420: #include <sys/poll_clk.h>
        !          8421: 
        !          8422: /*
        !          8423:  * Definitions.
        !          8424:  *
        !          8425:  * HSBAUD is the highest baud rate supported by this driver
        !          8426:  * HS_HZ is the polling rate, i.e. the number of times per second
        !          8427:  *   at which all open ports are checked for input, output, and
        !          8428:  *   line status changes
        !          8429:  * MAX_HSNUM is the maximum number of devices that can be polled
        !          8430:  *   using this driver and can be revised up or down
        !          8431:  * PORT is a convenience macro for the base address of a port
        !          8432:  * port_config is the structure of the initial configuration for each
        !          8433:  *   polled port;  note that "speed" is NOT the actual baud rate, but
        !          8434:  *   the value of the symbol for that baud rate as defined in
        !          8435:  *   /usr/include/sgtty.h
        !          8436:  */
        !          8437: #define        HSBAUD  9600
        !          8438: #define        HS_HZ   (HSBAUD/6)
        !          8439: #define MAX_HSNUM      8
        !          8440: #define        PORT    ((int)(tp->t_ddp))
        !          8441: struct port_config {
        !          8442:        int     addr;   /* base address of the 8250-family UART */
        !          8443:        int     speed;  /* B0..B19200 */
        !          8444: };
        !          8445: 
        !          8446: /*
        !          8447:  * Export Variables - these can be patched without recompiling and linking
        !          8448:  *
        !          8449:  * HSNUM is the actual number of polled serial ports, and should be
        !          8450:  *   less than or equal to MAX_HSNUM
        !          8451:  * HS_PORTS is an array of address/speed pairs, one for each port
        !          8452:  */
        !          8453: int    HSNUM = 4;
        !          8454: struct port_config HS_PORTS[MAX_HSNUM] = {
        !          8455:        { 0x3F8, B9600 },
        !          8456:        { 0x2F8, B9600 },
        !          8457:        { 0x3E8, B9600 },
        !          8458:        { 0x2E8, B9600 }
        !          8459: };
        !          8460: 
        !          8461: /*
        !          8462:  * Export Functions.
        !          8463:  */
        !          8464: int    hsload();
        !          8465: int    hsopen();
        !          8466: int    hsclose();
        !          8467: int    hsread();
        !          8468: int    hswrite();
        !          8469: int    hsioctl();
        !          8470: int    hsunload();
        !          8471: int    hspoll();
        !          8472: 
        !          8473: int    hscycle();
        !          8474: int    hsintr();
        !          8475: int    hsparam();
        !          8476: int    hsstart();
        !          8477: int    hsclk();
        !          8478: int    set_poll_rate();
        !          8479: 
        !          8480: /*
        !          8481:  * Import Functions
        !          8482:  */
        !          8483: int    nulldev();
        !          8484: int    nonedev();
        !          8485: 
        !          8486: /*
        !          8487:  * Configuration table.
        !          8488:  */
        !          8489: CON hscon ={
        !          8490:        DFCHR|DFPOL,                    /* Flags */
        !          8491:        HS_MAJOR,                       /* Major index */
        !          8492:        hsopen,                         /* Open */
        !          8493:        hsclose,                        /* Close */
        !          8494:        nulldev,                        /* Block */
        !          8495:        hsread,                         /* Read */
        !          8496:        hswrite,                        /* Write */
        !          8497:        hsioctl,                        /* Ioctl */
        !          8498:        nulldev,                        /* Powerfail */
        !          8499:        nulldev,                        /* Timeout */
        !          8500:        hsload,                         /* Load */
        !          8501:        hsunload,                       /* Unload */
        !          8502:        hspoll                          /* Poll */
        !          8503: };
        !          8504: 
        !          8505: /*
        !          8506:  * Local variables.
        !          8507:  */
        !          8508: static TTY *hstty;
        !          8509: static TTY *hslimtty;
        !          8510: static TIM hstim;
        !          8511: static int poll_divisor;       /* used in hsclk() and set_poll_rate() */
        !          8512: 
        !          8513: /*
        !          8514:  * Time constant table.
        !          8515:  * Indexed by ioctl baud rate.
        !          8516:  */
        !          8517: static
        !          8518: int timeconst[] = {
        !          8519:        0,                              /* 0 */
        !          8520:        2304,                           /* 50 */
        !          8521:        1536,                           /* 75 */
        !          8522:        1047,                           /* 110 */
        !          8523:        857,                            /* 134.5 */
        !          8524:        768,                            /* 150 */
        !          8525:        576,                            /* 200 */
        !          8526:        384,                            /* 300 */
        !          8527:        192,                            /* 600 */
        !          8528:        96,                             /* 1200 */
        !          8529:        64,                             /* 1800 */
        !          8530:        58,                             /* 2000 */
        !          8531:        48,                             /* 2400 */
        !          8532:        32,                             /* 3600 */
        !          8533:        24,                             /* 4800 */
        !          8534:        16,                             /* 7200 */
        !          8535:        12,                             /* 9600 */
        !          8536:        6,                              /* 19200 */
        !          8537:        6,                              /* EXTA */
        !          8538:        6                               /* EXTB */
        !          8539: };
        !          8540: 
        !          8541: /*
        !          8542:  * poll_hz[] is tied to timeconst[] - it gives the minimum polling
        !          8543:  *     rate for the corresponding port speed; it must be a multiple
        !          8544:  *     of 100 (system clock Hz) and >= baud/6
        !          8545:  */
        !          8546: int poll_hz[] ={
        !          8547:        0,                              /* 0 */
        !          8548:        1*HZ,                           /* 50 */
        !          8549:        1*HZ,                           /* 75 */
        !          8550:        1*HZ,                           /* 110 */
        !          8551:        1*HZ,                           /* 134.5 */
        !          8552:        1*HZ,                           /* 150 */
        !          8553:        1*HZ,                           /* 200 */
        !          8554:        1*HZ,                           /* 300 */
        !          8555:        1*HZ,                           /* 600 */
        !          8556:        2*HZ,                           /* 1200 */
        !          8557:        3*HZ,                           /* 1800 */
        !          8558:        4*HZ,                           /* 2000 */
        !          8559:        4*HZ,                           /* 2400 */
        !          8560:        6*HZ,                           /* 3600 */
        !          8561:        8*HZ,                           /* 4800 */
        !          8562:        12*HZ,                          /* 7200 */
        !          8563:        16*HZ,                          /* 9600 */
        !          8564:        0,                              /* 19200 */
        !          8565:        0,                              /* EXTA */
        !          8566:        0                               /* EXTB */
        !          8567: };
        !          8568: 
        !          8569: /*
        !          8570:  * Load Routine.
        !          8571:  */
        !          8572: static hsload()
        !          8573: {
        !          8574:        register TTY * tp;
        !          8575:        register int port;
        !          8576:        int i, b;
        !          8577: 
        !          8578:        if ((hstty = (TTY *)kalloc(HSNUM*sizeof(TTY))) == 0) {
        !          8579:                printf("hsload: can't allocate tty's\n");
        !          8580:                return;
        !          8581:        }
        !          8582:        kclear(hstty, HSNUM*sizeof(TTY));
        !          8583: 
        !          8584:        for (i = 0; i < HSNUM; i++) {
        !          8585:                port = HS_PORTS[i].addr;
        !          8586:                tp = hstty + i;
        !          8587: 
        !          8588:                outb( port+MCR, 0 );
        !          8589:                outb( port+IER, 0 );
        !          8590: 
        !          8591:                if ( inb( port+IER ) )
        !          8592:                        break;
        !          8593: 
        !          8594:                tp->t_cs_sel  = cs_sel();
        !          8595:                tp->t_start   = hsstart;
        !          8596:                tp->t_param   = hsparam;
        !          8597:                tp->t_sgttyb.sg_ospeed = tp->t_sgttyb.sg_ispeed = 
        !          8598:                tp->t_dispeed = tp->t_dospeed = HS_PORTS[i].speed;
        !          8599:                tp->t_ddp     = port;
        !          8600: 
        !          8601:                b = timeconst[ tp->t_sgttyb.sg_ospeed ];
        !          8602:                outb( port+LCR, LC_DLAB );
        !          8603:                outb( port+DLL, b );
        !          8604:                outb( port+DLH, b >> 8);
        !          8605:                outb( port+LCR, LC_CS8);
        !          8606: 
        !          8607:                hslimtty = tp;
        !          8608:        }
        !          8609: }
        !          8610: 
        !          8611: static hsunload()
        !          8612: {
        !          8613:        if (hstty != (TTY *)0)
        !          8614:                kfree(hstty);
        !          8615: }
        !          8616: 
        !          8617: /*
        !          8618:  * Open Routine.
        !          8619:  */
        !          8620: hsopen( dev, mode )
        !          8621: dev_t dev;
        !          8622: {
        !          8623:        register TTY * tp = &hstty[ dev & 15 ];
        !          8624:        register int b;
        !          8625:        int s;
        !          8626: 
        !          8627:        /*
        !          8628:         * Verify hardware exists.
        !          8629:         */
        !          8630:        if ( (PORT == 0) || (inb(PORT+IER) & ~IE_TxI) ) {
        !          8631:                u.u_error = ENXIO;
        !          8632:                return;
        !          8633:        }
        !          8634: 
        !          8635:        /*
        !          8636:         * Can't open if another driver is using polling
        !          8637:         */
        !          8638:        if (poll_owner & ~ POLL_HS) {
        !          8639:                u.u_error = EDBUSY;
        !          8640:                return;
        !          8641:        }
        !          8642: 
        !          8643:        /*
        !          8644:         * Initialize if not already open.
        !          8645:         */
        !          8646:        if ( ++tp->t_open == 1 ) {
        !          8647:                ttopen( tp );
        !          8648: 
        !          8649:                if ( dev & 0x80 ) {
        !          8650:                        s = sphi();
        !          8651:                        b = inb(PORT+MSR);
        !          8652:                        tp->t_flags |= T_MODC + T_STOP;
        !          8653:                        if ( b & MS_CTS )
        !          8654:                                tp->t_flags &= ~T_STOP;
        !          8655:                        if ( b & MS_DSR )
        !          8656:                                tp->t_flags |=  T_CARR;
        !          8657:                        spl( s );
        !          8658:                } else  {
        !          8659:                        tp->t_flags &= ~T_MODC;
        !          8660:                        tp->t_flags |=  T_CARR;
        !          8661:                }
        !          8662:                hscycle( tp );
        !          8663:        }
        !          8664:        ttsetgrp( tp, dev );
        !          8665:        set_poll_rate();
        !          8666: }
        !          8667: 
        !          8668: /*
        !          8669:  * Close Routine.
        !          8670:  */
        !          8671: hsclose( dev )
        !          8672: dev_t dev;
        !          8673: {
        !          8674:        register TTY * tp = &hstty[ dev & 15 ];
        !          8675: 
        !          8676:        /*
        !          8677:         * Reset if last close.
        !          8678:         */
        !          8679:        if ( tp->t_open == 1 ) {
        !          8680:                int state;
        !          8681: 
        !          8682:                ttclose( tp );
        !          8683:                /*
        !          8684:                 * ttclose() only emptied the output queue tp->t_oq;
        !          8685:                 * now wait 0.1 sec for the silo tp->rawout to empty
        !          8686:                 * and allow a delay for the UART on-chip xmit buffer to empty
        !          8687:                 *
        !          8688:                 * state 2: waiting for silo to empty
        !          8689:                 * state 1: stalling so UART can empty xmit buffer
        !          8690:                 * state 0: done!
        !          8691:                 */
        !          8692:                state = 2;
        !          8693:                while (state) {
        !          8694:                        timeout(&hstim, 10, wakeup, (int)&hstim);
        !          8695:                        sleep((char *)&hstim, CVTTOUT, IVTTOUT, SVTTOUT);
        !          8696:                        if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          8697:                                state--;
        !          8698:                }
        !          8699:        }
        !          8700: 
        !          8701:        --tp->t_open;
        !          8702:        set_poll_rate();
        !          8703: }
        !          8704: 
        !          8705: /*
        !          8706:  * Read Routine.
        !          8707:  */
        !          8708: hsread( dev, iop )
        !          8709: dev_t dev;
        !          8710: register IO * iop;
        !          8711: {
        !          8712:        ttread( &hstty[ dev & 15 ], iop, 0 );
        !          8713: }
        !          8714: 
        !          8715: /*
        !          8716:  * Write Routine.
        !          8717:  */
        !          8718: hswrite( dev, iop )
        !          8719: dev_t dev;
        !          8720: register IO * iop;
        !          8721: {
        !          8722:        ttwrite( &hstty[ dev & 15 ], iop, 0 );
        !          8723: }
        !          8724: 
        !          8725: /*
        !          8726:  * Ioctl Routine.
        !          8727:  */
        !          8728: hsioctl( dev, com, vec )
        !          8729: dev_t dev;
        !          8730: int com;
        !          8731: struct sgttyb * vec;
        !          8732: {
        !          8733:        ttioctl( &hstty[ dev & 15 ], com, vec );
        !          8734: }
        !          8735: 
        !          8736: /*
        !          8737:  * Polling Routine.
        !          8738:  */
        !          8739: hspoll( dev, ev, msec )
        !          8740: dev_t dev;
        !          8741: int ev;
        !          8742: int msec;
        !          8743: {
        !          8744:        return ttpoll( &hstty[ dev & 15 ], ev, msec );
        !          8745: }
        !          8746: 
        !          8747: /*
        !          8748:  * Cyclic routine - invoked every clock tick to perform raw input/output.
        !          8749:  *
        !          8750:  *     Notes:  Invoked 10 times per second.
        !          8751:  */
        !          8752: hscycle( tp )
        !          8753: register TTY * tp;
        !          8754: {
        !          8755:        register int resid;
        !          8756:        register int c;
        !          8757: 
        !          8758:        /*
        !          8759:         * Process rawin buf.
        !          8760:         */
        !          8761:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          8762: 
        !          8763:                ttin( tp, tp->t_rawin.si_buf[ tp->t_rawin.si_ox ] );
        !          8764: 
        !          8765:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          8766:                        tp->t_rawin.si_ox = 0;
        !          8767:                else
        !          8768:                        tp->t_rawin.si_ox++;
        !          8769:        }
        !          8770: 
        !          8771:        /*
        !          8772:         * Calculate free output slot count.
        !          8773:         */
        !          8774:        resid  = sizeof(tp->t_rawout.si_buf) - 1;
        !          8775:        resid += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          8776:        resid %= sizeof(tp->t_rawout.si_buf);
        !          8777: 
        !          8778:        /*
        !          8779:         * Fill raw output buffer.
        !          8780:         */
        !          8781:        while ( (--resid >= 0) && ((c = ttout(tp)) >= 0) ) {
        !          8782: 
        !          8783:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = c;
        !          8784: 
        !          8785:                if ( tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1 )
        !          8786:                        tp->t_rawout.si_ix = 0;
        !          8787:                else
        !          8788:                        tp->t_rawout.si_ix++;
        !          8789:        }
        !          8790: 
        !          8791:        /*
        !          8792:         * (Re)start output, waking processes waiting to output, etc.
        !          8793:         */
        !          8794:        ttstart( tp );
        !          8795: 
        !          8796:        /*
        !          8797:         * Schedule next cycle.
        !          8798:         */
        !          8799:        if ( tp->t_open != 0 )
        !          8800:                timeout( &tp->t_rawtim, HZ/10, hscycle, tp );
        !          8801: }
        !          8802: 
        !          8803: /*
        !          8804:  * Clock Interrupt driven Polling routine.
        !          8805:  */
        !          8806: hsintr()
        !          8807: {
        !          8808:        register TTY * tp = &hstty[0];
        !          8809:        register int b;
        !          8810: 
        !          8811:        do {
        !          8812:                if ( tp->t_open == 0 )
        !          8813:                        continue;
        !          8814: 
        !          8815:                /*
        !          8816:                 * Check modem status if modem control is enabled.
        !          8817:                 */
        !          8818:                if ( tp->t_flags & T_MODC ) {
        !          8819: 
        !          8820:                        b = inb( PORT+MSR );
        !          8821: 
        !          8822:                        if ( b & (MS_DCTS|MS_DDSR) ) {
        !          8823: 
        !          8824:                                if ( b & MS_DCTS ) {
        !          8825:                                        if ( b & MS_CTS )
        !          8826:                                                tp->t_flags &= ~T_STOP;
        !          8827:                                        else
        !          8828:                                                tp->t_flags |=  T_STOP;
        !          8829:                                }
        !          8830:                                if ( b & MS_DDSR ) {
        !          8831:                                        if ( b & MS_DSR )
        !          8832:                                                tp->t_flags |=  T_CARR;
        !          8833:                                        else {
        !          8834:                                                tp->t_flags &= ~T_CARR;
        !          8835:                                                tthup( tp );
        !          8836:                                        }
        !          8837:                                }
        !          8838:                        }
        !          8839:                }
        !          8840: 
        !          8841:                b = inb( PORT+LSR );
        !          8842: 
        !          8843:                if ( (b & LS_BREAK) && (tp->t_flags & T_CARR) )
        !          8844:                        ttsignal( tp, SIGINT );
        !          8845: 
        !          8846:                /*
        !          8847:                 * Receive ready.
        !          8848:                 */
        !          8849:                if ( b & LS_RxRDY ) {
        !          8850: 
        !          8851:                        tp->t_rawin.si_buf[tp->t_rawin.si_ix] = inb(PORT+DREG);
        !          8852: 
        !          8853:                        if ( tp->t_flags & T_CARR ) {
        !          8854: 
        !          8855:                                if ( ++(tp->t_rawin.si_ix) >=
        !          8856:                                                sizeof(tp->t_rawin.si_buf) )
        !          8857:                                        tp->t_rawin.si_ix = 0;
        !          8858:                        }
        !          8859:                }
        !          8860: 
        !          8861:                /*
        !          8862:                 * Transmit ready and raw output data exists.
        !          8863:                 */
        !          8864:                if ( (b & LS_TxRDY) && ((tp->t_flags & T_STOP) == 0)
        !          8865:                  && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          8866: 
        !          8867:                        outb(   PORT+DREG,
        !          8868:                                tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          8869: 
        !          8870:                        if ( ++(tp->t_rawout.si_ox) >=
        !          8871:                                        sizeof(tp->t_rawout.si_buf) )
        !          8872:                                tp->t_rawout.si_ox = 0;
        !          8873:                }
        !          8874: 
        !          8875:        } while ( ++tp <= hslimtty );
        !          8876: }
        !          8877: 
        !          8878: /*
        !          8879:  * Set hardware parameters.
        !          8880:  */
        !          8881: hsparam( tp )
        !          8882: register TTY * tp;
        !          8883: {
        !          8884:        register int b;
        !          8885:        int s;
        !          8886: 
        !          8887:        s = sphi();
        !          8888:        /*
        !          8889:         * Assert required modem control lines (DTR, RTS).
        !          8890:         */
        !          8891:        b = 0;
        !          8892:        if ( tp->t_sgttyb.sg_ospeed != B0 )
        !          8893:                b |=  MC_DTR | MC_RTS;
        !          8894:        outb( PORT+MCR, b );
        !          8895: 
        !          8896:        /*
        !          8897:         * Program baud rate.
        !          8898:         */
        !          8899:        if (b = timeconst[ tp->t_sgttyb.sg_ospeed ]) {
        !          8900:                outb( PORT+LCR, LC_DLAB );
        !          8901:                outb( PORT+DLL, b );
        !          8902:                outb( PORT+DLH, b >> 8 );
        !          8903:        }
        !          8904: 
        !          8905:        /*
        !          8906:         * Program character size, parity.
        !          8907:         */
        !          8908:        switch ( tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW) ) {
        !          8909:        case ODDP:              b = LC_CS7|LC_PARENB;            break;
        !          8910:        case EVENP:             b = LC_CS7|LC_PARENB|LC_PAREVEN; break;
        !          8911:        default:                b = LC_CS8;                      break;
        !          8912:        }
        !          8913:        outb( PORT+LCR, b );
        !          8914: 
        !          8915:        /*
        !          8916:         * Enable Transmit Buffer Empty Interrupts.
        !          8917:         */
        !          8918:        outb( PORT+IER, IE_TxI );
        !          8919: 
        !          8920:        spl(s);
        !          8921:        set_poll_rate();
        !          8922: }
        !          8923: 
        !          8924: /*
        !          8925:  * Start Routine.
        !          8926:  */
        !          8927: hsstart( tp )
        !          8928: register TTY * tp;
        !          8929: {
        !          8930:        register int s;
        !          8931: 
        !          8932:        /*
        !          8933:         * Transmit buffer is empty, and raw output buffer is not.
        !          8934:         */
        !          8935:        s = sphi();
        !          8936:        if ( (inb( PORT+LSR ) & LS_TxRDY)
        !          8937:          && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          8938: 
        !          8939:                /*
        !          8940:                 * Send next char from raw output buffer.
        !          8941:                 */
        !          8942:                outb( PORT+DREG, tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          8943: 
        !          8944:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          8945:                        tp->t_rawout.si_ox = 0;
        !          8946:        }
        !          8947:        spl( s );
        !          8948: }
        !          8949: 
        !          8950: /*
        !          8951:  * hsclk will be called every time T0 interrupts - if it returns 0,
        !          8952:  * the usual system timer interrupt stuff is done
        !          8953:  */
        !          8954: static int hsclk()
        !          8955: {
        !          8956:   static int count;
        !          8957: 
        !          8958:   hsintr();
        !          8959:   count++;
        !          8960:   if (count >= poll_divisor)
        !          8961:     count = 0;
        !          8962:   return count;
        !          8963: }
        !          8964: 
        !          8965: /*
        !          8966:  * set_poll_rate is called when a port is opened or closed or changes speed
        !          8967:  * it sets the polling rate only as fast as needed, and shuts off polling
        !          8968:  * whenever possible
        !          8969:  */
        !          8970: static set_poll_rate()
        !          8971: {
        !          8972:        int port_num, max_rate, port_rate;
        !          8973: 
        !          8974:        /*
        !          8975:         * If another driver has the polling clock, do nothing.
        !          8976:         */
        !          8977:        if (poll_owner & ~ POLL_HS)
        !          8978:                return;
        !          8979: 
        !          8980:        /*
        !          8981:         * find highest valid polling rate in units of HZ/10
        !          8982:         */
        !          8983:        max_rate = 0;
        !          8984:        for (port_num = 0; port_num < HSNUM; port_num++) {
        !          8985:                if (hstty[port_num].t_open) {
        !          8986:                  port_rate = poll_hz[hstty[port_num].t_sgttyb.sg_ispeed];
        !          8987:                  if (max_rate < port_rate)
        !          8988:                        max_rate = port_rate;
        !          8989:                }
        !          8990:        }
        !          8991:        /*
        !          8992:         * if max_rate is not current rate, adjust the system clock
        !          8993:         */
        !          8994:        if (max_rate != poll_rate) {
        !          8995:                poll_rate = max_rate;
        !          8996:                poll_divisor = poll_rate/HZ;  /* used in hsclk() */
        !          8997:                altclk_out();           /* stop previous polling */
        !          8998:                poll_owner &= ~POLL_HS;
        !          8999:                if (max_rate) { /* resume polling at new rate if needed */
        !          9000:                        altclk_in(poll_rate, hsclk);
        !          9001:                        poll_owner |= POLL_HS;
        !          9002:                }
        !          9003:        }
        !          9004: }
        !          9005: 0707070064030050631004440000030000030000011777770507310634500004700000003243/newbits/kernel/USRSRC/i8086/drv/ipc.c/* $Header: /usr/src/sys/i8086/drv/RCS/ipc.c,v 2.1 88/09/03 13:06:15 src Exp $
        !          9006:  *
        !          9007:  *     The  information  contained herein  is a trade secret  of INETCO
        !          9008:  *     Systems, and is confidential information.   It is provided under
        !          9009:  *     a license agreement,  and may be copied or disclosed  only under
        !          9010:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          9011:  *     this  material  without  the express  written  authorization  of
        !          9012:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          9013:  *
        !          9014:  *     Copyright (c) 1985
        !          9015:  *     An unpublished work by INETCO Systems, Ltd.
        !          9016:  *     All rights reserved.
        !          9017:  */
        !          9018: 
        !          9019: /*
        !          9020:  * Inter-Process Communication.
        !          9021:  *
        !          9022:  * $Log:       /usr/src/sys/i8086/drv/RCS/ipc.c,v $
        !          9023:  * Revision 2.1        88/09/03  13:06:15      src
        !          9024:  * *** empty log message ***
        !          9025:  * 
        !          9026:  * Revision 1.1        88/03/24  17:05:02      src
        !          9027:  * Initial revision
        !          9028:  * 
        !          9029:  */
        !          9030: #include <coherent.h>
        !          9031: #include <sys/ipc.h>
        !          9032: #include <sys/uproc.h>
        !          9033: 
        !          9034: /*
        !          9035:  * Determine Inter-Process Communication Access Permissions.
        !          9036:  *
        !          9037:  *     Input:  p = pointer to inter-process communication permission struct.
        !          9038:  *
        !          9039:  *     Action: If super user, permissions are 0600.
        !          9040:  *             If uid is that of the creator or owner of the message id,
        !          9041:  *                     use user permissions.
        !          9042:  *             If gid is that of the creator or owner of the message id,
        !          9043:  *                     use group permissions.
        !          9044:  *             Otherwise, use others permissions.
        !          9045:  *
        !          9046:  *     Output: 0600 = Read/Alter permission.
        !          9047:  *             0400 = Read permission.
        !          9048:  *             0200 = Alter permission.
        !          9049:  *                0 = No permission.
        !          9050:  */
        !          9051: 
        !          9052: ipcaccess( p )
        !          9053: 
        !          9054: register struct ipc_perm * p;
        !          9055: 
        !          9056: {
        !          9057:        if ( u.u_uid == 0 )
        !          9058:                return 0600;
        !          9059: 
        !          9060:        if ((u.u_uid == p->uid) || (u.u_uid == p->cuid))
        !          9061:                return p->mode & 0600;
        !          9062: 
        !          9063:        if ((u.u_gid == p->gid) || (u.u_gid == p->cgid))
        !          9064:                return (p->mode << 3) & 0600;
        !          9065: 
        !          9066:        return (p->mode << 6) & 0600;
        !          9067: }
        !          9068: 0707070064030050641004440000030000030000011777770507310634500005100000007742/newbits/kernel/USRSRC/i8086/drv/ipcas.s/ $Header: /usr/src/sys/i8086/drv/RCS/ipcas.s,v 2.1 88/09/03 13:06:24 src Exp $
        !          9069: /
        !          9070: /      The  information  contained herein  is a trade secret  of INETCO
        !          9071: /      Systems, and is confidential information.   It is provided under
        !          9072: /      a license agreement,  and may be copied or disclosed  only under
        !          9073: /      the terms of that agreement.   Any reproduction or disclosure of
        !          9074: /      this  material  without  the express  written  authorization  of
        !          9075: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          9076: /
        !          9077: /      Copyright (c) 1985, 1984
        !          9078: /      An unpublished work by INETCO Systems, Ltd.
        !          9079: /      All rights reserved.
        !          9080: /
        !          9081: 
        !          9082: ////////
        !          9083: /
        !          9084: / System V Compatible Inter-Process Communication - Assembler Support
        !          9085: /
        !          9086: / ufcopy( base, off, sel, n ) -- copy n bytes from user base to sel:off.
        !          9087: / fucopy( off, sel, base, n ) -- copy n bytes from sel:off to user base.
        !          9088: /
        !          9089: / $Log:        /usr/src/sys/i8086/drv/RCS/ipcas.s,v $
        !          9090: / Revision 2.1 88/09/03  13:06:24      src
        !          9091: / *** empty log message ***
        !          9092: / 
        !          9093: / Revision 1.1 88/03/24  17:05:05      src
        !          9094: / Initial revision
        !          9095: / 
        !          9096: /
        !          9097: / 85/07/19     Allan Cornish
        !          9098: / Inserted code to check user address for validity.
        !          9099: / Functions ufcopy and fucopy now return 0 if user address is invalid.
        !          9100: / Replaced 'jnc .+2;movsb' with 'rcl cx,$1;rep movsb' to improve pipelining.
        !          9101: /
        !          9102: / 85/07/03     Allan Cornish
        !          9103: / Functions renamed: uoscopy --> ufcopy, osucopy --> fucopy (f = far).
        !          9104: / Module moved from msgas.s to ipcas.s, to reflect its shared use.
        !          9105: /
        !          9106: ////////
        !          9107: 
        !          9108:        .globl  ufcopy_
        !          9109:        .globl  fucopy_
        !          9110: 
        !          9111: ////////
        !          9112: /
        !          9113: / ufcopy( base, off, sel, n )  -- copy n bytes from user base to sel:off.
        !          9114: /
        !          9115: /      Input:  base = offset in user memory to copy from
        !          9116: /              off  = offset in the destination segment
        !          9117: /              sel  = selector to access the destination segment
        !          9118: /              n    = number of bytes to copy
        !          9119: /
        !          9120: /      Action: Copy 'n' bytes of data from offset 'base' in user memory
        !          9121: /              to offset 'off' in the segment accessed by selector 'sel'.
        !          9122: /
        !          9123: /      Return: Number of bytes copied, or 0 if invalid user address.
        !          9124: /
        !          9125: ////////
        !          9126: 
        !          9127: ufcopy_:                       / ufcopy( base, off, sel, n )
        !          9128:        push    si              /
        !          9129:        push    di              / unsigned base;
        !          9130:        push    bp              / unsigned off;
        !          9131:        mov     bp, sp          / saddr_t sel;
        !          9132:        push    ds              / unsigned n;
        !          9133:        push    es              /
        !          9134:                                / {
        !          9135:        mov     ax, 8(bp)       /       Validate user address.
        !          9136:        dec     ax              /
        !          9137:        add     ax, 14(bp)      /       Wrap-around error?
        !          9138:        jc      fuerr           /
        !          9139:        cmp     ax, udl_        /       Address out of bounds error?
        !          9140:        ja      fuerr           /
        !          9141:                                /
        !          9142:        mov     bx, uds_        /       Map DS:SI into user (source) addr
        !          9143:        mov     ds, bx          /
        !          9144:        mov     si, 8(bp)       /
        !          9145:        les     di, 10(bp)      /       Map ES:DI into segment (dest) addr
        !          9146:        mov     cx, 14(bp)      /       Transfer count
        !          9147:                                /
        !          9148:        cld                     /       Auto Increment
        !          9149:        clc                     /
        !          9150:        rcr     cx, $1          /       Change byte count into word count
        !          9151:        rep                     /       Transfer data words
        !          9152:        movsw                   /
        !          9153:        rcl     cx, $1          /       If residual byte count
        !          9154:        rep                     /               Transfer last data byte.
        !          9155:        movsb                   /
        !          9156:                                /
        !          9157:        mov     ax, 14(bp)      /       Return transfer count.
        !          9158:        pop     es              / }
        !          9159:        pop     ds
        !          9160:        pop     bp
        !          9161:        pop     di
        !          9162:        pop     si
        !          9163:        ret
        !          9164: 
        !          9165: fuerr: sub     ax, ax
        !          9166:        pop     es
        !          9167:        pop     ds
        !          9168:        pop     bp
        !          9169:        pop     di
        !          9170:        pop     si
        !          9171:        ret
        !          9172: 
        !          9173: ////////
        !          9174: /
        !          9175: / fucopy( off, sel, base, n )  -- copy n bytes from sel:off to user base.
        !          9176: /
        !          9177: /      Input:  off  = offset is the source segment
        !          9178: /              sel  = selector to access the source segment
        !          9179: /              base = offset in user memory to copy to
        !          9180: /              n    = number of bytes to copy
        !          9181: /
        !          9182: /      Action: Copy 'n' bytes of data from offset 'off' in the segment
        !          9183: /              accessed by selector 'sel' to offset 'base' in user memory.
        !          9184: /
        !          9185: /      Return: Number of bytes copied, or 0 if invalid user address.
        !          9186: /
        !          9187: ////////
        !          9188: 
        !          9189: fucopy_:                       / fucopy( off, sel, base, n )
        !          9190:        push    si              /
        !          9191:        push    di              / unsigned off;
        !          9192:        push    bp              / saddr_t  sel;
        !          9193:        mov     bp, sp          / unsigned base;
        !          9194:        push    ds              / unsigned n;
        !          9195:        push    es              /
        !          9196:                                / {
        !          9197:        mov     ax, 12(bp)      /       Validate user address.
        !          9198:        dec     ax              /
        !          9199:        add     ax, 14(bp)      /       Wrap-around error?
        !          9200:        jc      fuerr           /
        !          9201:        cmp     ax, udl_        /       Address out of bounds error?
        !          9202:        ja      fuerr           /
        !          9203:                                /
        !          9204:        mov     es, uds_        /       Map ES:DI into user (dest) address
        !          9205:        mov     di, 12(bp)      /
        !          9206:        lds     si, 8(bp)       /       Map DS:SI into segment (source) addr
        !          9207:        mov     cx, 14(bp)      /       Transfer count
        !          9208:                                /
        !          9209:        cld                     /       Auto Increment
        !          9210:        clc                     /
        !          9211:        rcr     cx, $1          /       Change byte count into word count
        !          9212:        rep                     /
        !          9213:        movsw                   /       Transfer data words
        !          9214:        rcl     cx, $1          /       If residual byte count
        !          9215:        rep                     /               Transfer last data byte.
        !          9216:        movsb                   /
        !          9217:                                /
        !          9218:        mov     ax, 14(bp)      /       Return transfer count.
        !          9219:        pop     es              / }
        !          9220:        pop     ds
        !          9221:        pop     bp
        !          9222:        pop     di
        !          9223:        pop     si
        !          9224:        ret
        !          9225: 0707070064030057001006440000030000030000011777770507310634600004600000043104/newbits/kernel/USRSRC/i8086/drv/kb.c/* (-lgl
        !          9226:  *     COHERENT Driver Kit Version 1.1.0
        !          9227:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          9228:  *     All rights reserved. May not be copied without permission.
        !          9229:  -lgl) */
        !          9230: /*
        !          9231:  * Keyboard/display driver.
        !          9232:  * Coherent, IBM PC/XT/AT.
        !          9233:  */
        !          9234: #include <sys/coherent.h>
        !          9235: #include <sys/i8086.h>
        !          9236: #include <sys/con.h>
        !          9237: #include <sys/devices.h>
        !          9238: #include <errno.h>
        !          9239: #include <sys/stat.h>
        !          9240: #include <sys/tty.h>
        !          9241: #include <sys/uproc.h>
        !          9242: #include <signal.h>
        !          9243: #include <sys/sched.h>
        !          9244: 
        !          9245: #define        SPC     0376                    /* Special encoding */
        !          9246: #define XXX    0377                    /* Non-character */
        !          9247: #define        KBDATA  0x60                    /* Keyboard data */
        !          9248: #define        KBCTRL  0x61                    /* Keyboard control */
        !          9249: #define        KBFLAG  0x80                    /* Keyboard reset flag */
        !          9250: #define        LEDCMD  0xED                    /* status indicator command */
        !          9251: #define        KBACK   0xFA                    /* status indicator acknowledge */
        !          9252: #define        EXTENDED1 0xE1                  /* extended key seq initiator */
        !          9253: 
        !          9254: #define        KEYUP   0x80                    /* Key up change */
        !          9255: #define        KEYSC   0x7F                    /* Key scan code mask */
        !          9256: #define        LSHIFT  0x2A-1                  /* Left shift key */
        !          9257: #define LSHIFTA 0x2B-1                 /* Alternate left-shift key */
        !          9258: #define        RSHIFT  0x36-1                  /* Right shift key */
        !          9259: #define        CTRL    0x1D-1                  /* Control key */
        !          9260: /*-- #define   CAPLOCK 0x1D-1  --*/            /* Control key */
        !          9261: #define        ALT     0x38-1                  /* Alt key */
        !          9262: #define        CAPLOCK 0x3A-1                  /* Caps lock key */
        !          9263: /*-- #define   CTRL    0x3A-1  --*/            /* Caps lock key */
        !          9264: #define        NUMLOCK 0x45-1                  /* Numeric lock key */
        !          9265: #define        DELETE  0x53-1                  /* Del, as in CTRL-ALT-DEL */
        !          9266: #define BACKSP 0x0E-1                  /* Back space */
        !          9267: #define SCRLOCK        0x46-1                  /* Scroll lock */
        !          9268: 
        !          9269: /* Shift flags */
        !          9270: #define        SRS     0x01                    /* Right shift key on */
        !          9271: #define        SLS     0x02                    /* Left shift key on */
        !          9272: #define CTS    0x04                    /* Ctrl key on */
        !          9273: #define ALS    0x08                    /* Alt key on */
        !          9274: #define CPLS   0x10                    /* Caps lock on */
        !          9275: #define NMLS   0x20                    /* Num lock on */
        !          9276: #define AKPS   0x40                    /* Alternate keypad shift */
        !          9277: #define SHFT   0x80                    /* Shift key flag */
        !          9278: 
        !          9279: /* Function key information */
        !          9280: #define        NFKEY   20                      /* Number of settable functions */
        !          9281: #define        NFCHAR  150                     /* Number of characters settable */
        !          9282: #define        NFBUF   (NFKEY*2+NFCHAR+1)      /* Size of buffer */
        !          9283: 
        !          9284: /*
        !          9285:  * Functions.
        !          9286:  */
        !          9287: int    isrint();
        !          9288: int    istime();
        !          9289: void   isbatch();
        !          9290: int    mmstart();
        !          9291: int    isopen();
        !          9292: int    isclose();
        !          9293: int    isread();
        !          9294: int    mmwrite();
        !          9295: int    isioctl();
        !          9296: void   mmwatch();
        !          9297: int    isload();
        !          9298: int    isuload();
        !          9299: int    ispoll();
        !          9300: int    nulldev();
        !          9301: int    nonedev();
        !          9302: 
        !          9303: /*
        !          9304:  * Configuration table.
        !          9305:  */
        !          9306: CON iscon ={
        !          9307:        DFCHR|DFPOL,                    /* Flags */
        !          9308:        KB_MAJOR,                               /* Major index */
        !          9309:        isopen,                         /* Open */
        !          9310:        isclose,                        /* Close */
        !          9311:        nulldev,                        /* Block */
        !          9312:        isread,                         /* Read */
        !          9313:        mmwrite,                        /* Write */
        !          9314:        isioctl,                        /* Ioctl */
        !          9315:        nulldev,                        /* Powerfail */
        !          9316:        mmwatch,                        /* Timeout */
        !          9317:        isload,                         /* Load */
        !          9318:        isuload,                        /* Unload */
        !          9319:        ispoll                          /* Poll */
        !          9320: };
        !          9321: 
        !          9322: /*
        !          9323:  * Flag indicating turbo machine.
        !          9324:  */
        !          9325: int isturbo = 0;
        !          9326: 
        !          9327: /*
        !          9328:  * Terminal structure.
        !          9329:  */
        !          9330: TTY    istty = {
        !          9331:        {0}, {0}, 0, mmstart, NULL, 0, 0
        !          9332: };
        !          9333: 
        !          9334: /*
        !          9335:  * State variables.
        !          9336:  */
        !          9337: int            islock;                 /* Keyboard locked flag */
        !          9338: int            isbusy;                 /* Raw input conversion busy */
        !          9339: static char    shift;                  /* Overall shift state */
        !          9340: static char    scroll;                 /* Scroll lock state */
        !          9341: static  char   lshift = LSHIFT;        /* Left shift alternate state */
        !          9342: static char    isfbuf[NFBUF];          /* Function key values */
        !          9343: static char    *isfval[NFKEY];         /* Function key string pointers */
        !          9344: static int     ledcmd;                 /* LED update command flag */
        !          9345: static int     extended;               /* extended key scan count */
        !          9346: 
        !          9347: /*
        !          9348:  * Tables for converting key code to ASCII.
        !          9349:  * lmaptab specifies unshifted conversion,
        !          9350:  * umaptab specifies shifted conversion,
        !          9351:  * smaptab specifies the shift states which are active.
        !          9352:  * An entry of XXX says the key is dead.
        !          9353:  * An entry of SPC requires further processing.
        !          9354:  *
        !          9355:  * Key codes:
        !          9356:  *     ESC .. <- == 1 .. 14
        !          9357:  *     -> .. \n == 15 .. 28
        !          9358:  *     CTRL .. ` == 29 .. 41
        !          9359:  *     ^Shift .. PrtSc == 42 .. 55
        !          9360:  *     ALT .. CapsLock == 56 .. 58
        !          9361:  *     F1 .. F10 == 59 .. 68
        !          9362:  *     NumLock .. Del == 69 .. 83
        !          9363:  */
        !          9364: static unsigned char lmaptab[] ={
        !          9365:             '\33',  '1',  '2',  '3',  '4',  '5',  '6',         /* 1 - 7 */
        !          9366:         '7',  '8',  '9',  '0',  '-',  '=', '\b', '\t',         /* 8 - 15 */
        !          9367:         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',         /* 16 - 23 */
        !          9368:         'o',  'p',  '[',  ']', '\r',  XXX,  'a',  's',         /* 24 - 31 */
        !          9369:         'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',         /* 32 - 39 */
        !          9370:         '\'', '`',  XXX,  '\\',  'z',  'x',  'c',  'v',        /* 40 - 47 */
        !          9371:         'b',  'n',  'm',  ',',  '.',  '/',  XXX,  '*',         /* 48 - 55 */
        !          9372:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
        !          9373:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
        !          9374:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
        !          9375:         SPC,  SPC,  SPC,  SPC                                  /* 80 - 83 */
        !          9376: };
        !          9377: 
        !          9378: static unsigned char umaptab[] ={
        !          9379:             '\33',  '!',  '@',  '#',  '$',  '%',  '^',         /* 1 - 7 */
        !          9380:         '&',  '*',  '(',  ')',  '_',  '+', '\b', SPC,          /* 8 - 15 */
        !          9381:         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',         /* 16 - 23 */
        !          9382:         'O',  'P',  '{',  '}', '\r',  XXX,  'A',  'S',         /* 24 - 31 */
        !          9383:         'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',         /* 32 - 39 */
        !          9384:         '"',  '~',  XXX,  '|',  'Z',  'X',  'C',  'V',         /* 40 - 47 */
        !          9385:         'B',  'N',  'M',  '<',  '>',  '?',  XXX,  '*',         /* 48 - 55 */
        !          9386:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
        !          9387:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
        !          9388:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
        !          9389:         SPC,  SPC,  SPC,  SPC                                  /* 80 - 83 */
        !          9390: };
        !          9391: 
        !          9392: #define SS0    0                       /* No shift */
        !          9393: #define SS1    (SLS|SRS|CTS)           /* Shift, Ctrl */
        !          9394: #define SES    (SLS|SRS)               /* Shift */
        !          9395: #define LET    (SLS|SRS|CPLS|CTS)      /* Shift, Caps, Ctrl */
        !          9396: #define KEY    (SLS|SRS|NMLS|AKPS)     /* Shift, Num, Alt keypad */
        !          9397: 
        !          9398: static unsigned char smaptab[] ={
        !          9399:               SS0,  SES,  SS1,  SES,  SES,  SES,  SS1,         /* 1 - 7 */
        !          9400:         SES,  SES,  SES,  SES,  SS1,  SES,  CTS,  SES,         /* 8 - 15 */
        !          9401:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  LET,         /* 16 - 23 */
        !          9402:         LET,  LET,  SS1,  SS1,  CTS, SHFT,  LET,  LET,         /* 24 - 31 */
        !          9403:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  SES,         /* 32 - 39 */
        !          9404:         SES,  SS1, SHFT,  SS1,  LET,  LET,  LET,  LET,         /* 40 - 47 */
        !          9405:         LET,  LET,  LET,  SES,  SES,  SES, SHFT,  SES,         /* 48 - 55 */
        !          9406:        SHFT,  SS1, SHFT,  SS0,  SS0,  SS0,  SS0,  SS0,         /* 56 - 63 */
        !          9407:         SS0,  SS0,  SS0,  SS0,  SS0, SHFT,  KEY,  KEY,         /* 64 - 71 */
        !          9408:         KEY,  KEY,  SS0,  KEY,  KEY,  KEY,  SS0,  KEY,         /* 72 - 79 */
        !          9409:         KEY,  KEY,  KEY,  KEY                                  /* 80 - 83 */
        !          9410: };
        !          9411: 
        !          9412: /*
        !          9413:  * Load entry point.
        !          9414:  *  Do reset the keyboard because it gets terribly munged
        !          9415:  *  if you type during the boot.
        !          9416:  */
        !          9417: isload()
        !          9418: {
        !          9419:        register int i;
        !          9420: 
        !          9421:        /*
        !          9422:         * Reset keyboard if NOT an XT turbo.
        !          9423:         */
        !          9424:        if ( ! isturbo ) {
        !          9425:                outb(KBCTRL, 0x0C);             /* Clock low */
        !          9426:                for (i = 10582; --i >= 0; );    /* For 20ms */
        !          9427:                outb(KBCTRL, 0xCC);             /* Clock high */
        !          9428:                for (i = 0; --i != 0; )
        !          9429:                        ;
        !          9430:                i = inb(KBDATA);
        !          9431:                outb(KBCTRL, 0xCC);                     /* Clear keyboard */
        !          9432:                outb(KBCTRL, 0x4D);                     /* Enable keyboard */
        !          9433:        }
        !          9434: 
        !          9435:        /*
        !          9436:         * Enable mmwatch() invocation every second.
        !          9437:         */
        !          9438:        drvl[KB_MAJOR].d_time = 1;
        !          9439: 
        !          9440:        /*
        !          9441:         * Seize keyboard interrupt.
        !          9442:         */
        !          9443:        setivec(1, isrint);
        !          9444: 
        !          9445:        /*
        !          9446:         * Initiailize video display.
        !          9447:         */
        !          9448:        mmstart( &istty );
        !          9449: }
        !          9450: 
        !          9451: /*
        !          9452:  * Unload entry point.
        !          9453:  */
        !          9454: isuload()
        !          9455: {
        !          9456:        clrivec(1);
        !          9457: }
        !          9458: 
        !          9459: /*
        !          9460:  * Default function key strings (terminated by -1 [\377])
        !          9461:  */
        !          9462: static char *deffuncs[] = {
        !          9463:        "\33[1x\377",   /* F1 */
        !          9464:        "\33[2x\377",   /* F2 */
        !          9465:        "\33[3x\377",   /* F3 */
        !          9466:        "\33[4x\377",   /* F4 */
        !          9467:        "\33[5x\377",   /* F5 */
        !          9468:        "\33[6x\377",   /* F6 */
        !          9469:        "\33[7x\377",   /* F7 */
        !          9470:        "\33[8x\377",   /* F8 */
        !          9471:        "\33[9x\377",   /* F9 */
        !          9472:        "\33[0x\377",   /* F10 - historical value */
        !          9473:        "\33[1y\377",   /* F11 */
        !          9474:        "\33[2y\377",   /* F12 */
        !          9475:        "\33[3y\377",   /* F13 */
        !          9476:        "\33[4y\377",   /* F14 */
        !          9477:        "\33[5y\377",   /* F15 */
        !          9478:        "\33[6y\377",   /* F16 */
        !          9479:        "\33[7y\377",   /* F17 */
        !          9480:        "\33[8y\377",   /* F18 */
        !          9481:        "\33[9y\377",   /* F19 */
        !          9482:        "\33[0y\377"    /* F20 */
        !          9483: };
        !          9484: 
        !          9485: /*
        !          9486:  * Open routine.
        !          9487:  */
        !          9488: isopen(dev)
        !          9489: dev_t dev;
        !          9490: {
        !          9491:        register int s;
        !          9492: 
        !          9493:        if (minor(dev) != 0) {
        !          9494:                u.u_error = ENXIO;
        !          9495:                return;
        !          9496:        }
        !          9497:        if ((istty.t_flags&T_EXCL)!=0 && super()==0) {
        !          9498:                u.u_error = ENODEV;
        !          9499:                return;
        !          9500:        }
        !          9501:        ttsetgrp(&istty, dev);
        !          9502: 
        !          9503:        s = sphi();
        !          9504:        if (istty.t_open++ == 0)
        !          9505:        {  initkeys();   /* init function keys */
        !          9506:           istty.t_flags = T_CARR;  /* indicate "carrier" */
        !          9507:           ttopen(&istty);
        !          9508:        }
        !          9509:        spl(s);
        !          9510:        updleds();                      /* update keyboard status LEDS */
        !          9511: }
        !          9512: 
        !          9513: /* Init function keys */
        !          9514: initkeys()
        !          9515: {      register int i;
        !          9516:        register char *cp1, *cp2;
        !          9517: 
        !          9518:        for (i=0; i<NFKEY; i++)
        !          9519:            isfval[i] = 0;          /* clear function key buffer */
        !          9520:        cp2 = isfbuf;               /* pointer to key buffer */   
        !          9521:        for (i=0; i<NFKEY; i++)
        !          9522:        {  isfval[i] = cp2;         /* save pointer to key string */
        !          9523:           cp1 = deffuncs[i];       /* get init string pointer */
        !          9524:           while ((*cp2++ = *cp1++) != -1)  /* copy key data */
        !          9525:             if (cp2 >= &isfbuf[NFBUF-3])   /* overflow? */
        !          9526:                return;
        !          9527:        }
        !          9528: }
        !          9529: 
        !          9530: /*
        !          9531:  * Close a tty.
        !          9532:  */
        !          9533: isclose(dev)
        !          9534: {
        !          9535:        register int s;
        !          9536: 
        !          9537:        s = sphi();
        !          9538:        if (--istty.t_open == 0)
        !          9539:        {       s = sphi();
        !          9540:                ttclose(&istty);
        !          9541:                spl(s);
        !          9542:        }
        !          9543: }
        !          9544: 
        !          9545: /*
        !          9546:  * Read routine.
        !          9547:  */
        !          9548: isread(dev, iop)
        !          9549: dev_t dev;
        !          9550: IO *iop;
        !          9551: {
        !          9552:        ttread(&istty, iop, 0);
        !          9553:        if (istty.t_oq.cq_cc)
        !          9554:                mmtime(&istty);
        !          9555: }
        !          9556: 
        !          9557: /*
        !          9558:  * Ioctl routine.
        !          9559:  */
        !          9560: isioctl(dev, com, vec)
        !          9561: dev_t dev;
        !          9562: struct sgttyb *vec;
        !          9563: {
        !          9564:        register int s;
        !          9565: 
        !          9566:        switch(com) {
        !          9567:        case TIOCSETF:
        !          9568:        case TIOCGETF:
        !          9569:                isfunction(com, (char *)vec);
        !          9570:                return;
        !          9571:        case TIOCSHIFT:   /* switch left-SHIFT and "\" */
        !          9572:                lshift = LSHIFTA;    /* alternate values */
        !          9573:                lmaptab[41] = '\\';
        !          9574:                lmaptab[42] = XXX;
        !          9575:                umaptab[41] = '|';
        !          9576:                umaptab[42] = XXX;
        !          9577:                smaptab[41] = SS1;
        !          9578:                smaptab[42] = SHFT;
        !          9579:                return;
        !          9580:        case TIOCCSHIFT:  /* normal (default) left-SHIFT and "\" */
        !          9581:                lshift = LSHIFT;     /* normal values */
        !          9582:                lmaptab[41] = XXX;
        !          9583:                lmaptab[42] = '\\';
        !          9584:                umaptab[41] = XXX;
        !          9585:                umaptab[42] = '|';
        !          9586:                smaptab[41] = SHFT;
        !          9587:                smaptab[42] = SS1;
        !          9588:                return;
        !          9589:        }
        !          9590:        s = sphi();
        !          9591:        ttioctl(&istty, com, vec);
        !          9592:        spl(s);
        !          9593: }
        !          9594: 
        !          9595: /*
        !          9596:  * Set and receive the function keys.
        !          9597:  */
        !          9598: isfunction(c, v)
        !          9599: int c;
        !          9600: char *v;
        !          9601: {
        !          9602:        register char *cp;
        !          9603:        register int i;
        !          9604: 
        !          9605:        if (c == TIOCGETF) {
        !          9606:                for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++)
        !          9607:                    putubd(v++, *cp);
        !          9608:        } else {
        !          9609:                for (i=0; i<NFKEY; i++)         /* zap current settings */
        !          9610:                        isfval[i] = 0;
        !          9611:                cp = isfbuf;                    /* pointer to key buffer */
        !          9612:                for (i=0; i<NFKEY; i++) {
        !          9613:                        isfval[i] = cp;         /* save pointer to key string */
        !          9614:                        while ((*cp++ = getubd(v++)) != -1)  /* copy key data */
        !          9615:                                if (cp >= &isfbuf[NFBUF-3])  /* overflow? */
        !          9616:                                        return;
        !          9617:                }
        !          9618:        }
        !          9619: }
        !          9620: 
        !          9621: 
        !          9622: /*
        !          9623:  * Poll routine.
        !          9624:  */
        !          9625: ispoll( dev, ev, msec )
        !          9626: dev_t dev;
        !          9627: int ev;
        !          9628: int msec;
        !          9629: {
        !          9630:        /*
        !          9631:         * Priority polls not supported.
        !          9632:         */
        !          9633:        ev &= ~POLLPRI;
        !          9634: 
        !          9635:        /*
        !          9636:         * Input poll failure.
        !          9637:         */
        !          9638:        if ( (ev & POLLIN) && (istty.t_iq.cq_cc == 0) ) {
        !          9639: 
        !          9640:                if ( msec != 0 )
        !          9641:                        pollopen( &istty.t_ipolls );
        !          9642: 
        !          9643:                /*
        !          9644:                 * Second look AFTER enabling monitor, avoiding interrupt race.
        !          9645:                 */
        !          9646:                if ( istty.t_iq.cq_cc == 0 )
        !          9647:                        ev &= ~POLLIN;
        !          9648:        }
        !          9649: 
        !          9650:        return ev;
        !          9651: }
        !          9652: 
        !          9653: /*
        !          9654:  * Receive interrupt.
        !          9655:  */
        !          9656: isrint()
        !          9657: {
        !          9658:        register int    c;
        !          9659:        register int    s;
        !          9660:        register int    r;
        !          9661:        int     savests;
        !          9662:        int     update_leds = 0;
        !          9663: 
        !          9664:        /*
        !          9665:         * Schedule raw input handler if not already active.
        !          9666:         */
        !          9667:        if ( isbusy == 0 ) {
        !          9668:                defer( isbatch, &istty );
        !          9669:                isbusy = 1;
        !          9670:        }
        !          9671: 
        !          9672:        /*
        !          9673:         * Pull character from the data
        !          9674:         * port. Pulse the KBFLAG in the control
        !          9675:         * port to reset the data buffer.
        !          9676:         */
        !          9677:        r = inb(KBDATA) & 0xFF;
        !          9678:        c = inb(KBCTRL);
        !          9679:        outb(KBCTRL, c|KBFLAG);
        !          9680:        outb(KBCTRL, c);
        !          9681: #if    KBDEBUG
        !          9682:        printf("kbd: %d\n", r);                 /* print scan code/direction */
        !          9683: #endif
        !          9684:        if (ledcmd) {
        !          9685:                ledcmd = 0;
        !          9686:                if (r == KBACK) {               /* output to status LEDS */
        !          9687:                        c = scroll & 1;
        !          9688:                        if (shift & NMLS)
        !          9689:                                c |= 2;
        !          9690:                        if (shift & CPLS)
        !          9691:                                c |= 4;
        !          9692:                        outb(KBDATA, c);
        !          9693:                }
        !          9694:                return;
        !          9695:        }
        !          9696:        if (extended > 0) {                     /* if multi-character seq, */
        !          9697:                --extended;                     /* ... ignore this char */
        !          9698:                return;
        !          9699:        }
        !          9700:        if (r == EXTENDED1) {                   /* ignore extended sequences */
        !          9701:                extended = 5;
        !          9702:                return;
        !          9703:        }
        !          9704:        if (r == 0xFF)
        !          9705:                return; /* Overrun */
        !          9706:        c = (r & KEYSC) - 1;
        !          9707:        /*
        !          9708:         * Check for reset.
        !          9709:         */
        !          9710:        if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS))
        !          9711:                boot();
        !          9712: 
        !          9713:        /*
        !          9714:         * Track "shift" keys.
        !          9715:         */
        !          9716:        s = smaptab[c];
        !          9717:        if (s&SHFT) {
        !          9718:                if (r&KEYUP) {                  /* "shift" released */
        !          9719:                        if (c == RSHIFT)
        !          9720:                                shift &= ~SRS;
        !          9721:                        else if (c == lshift)
        !          9722:                                shift &= ~SLS;
        !          9723:                        else if (c == CTRL)
        !          9724:                                shift &= ~CTS;
        !          9725:                        else if (c == ALT)
        !          9726:                                shift &= ~ALS;
        !          9727:                } else {                        /* "shift" pressed */
        !          9728:                        if (c == lshift)
        !          9729:                                shift |= SLS;
        !          9730:                        else if (c == RSHIFT)
        !          9731:                                shift |= SRS;
        !          9732:                        else if (c == CTRL)
        !          9733:                                shift |= CTS;
        !          9734:                        else if (c == ALT)
        !          9735:                                shift |= ALS;
        !          9736:                        else if (c == CAPLOCK) {
        !          9737:                                shift ^= CPLS;  /* toggle cap lock */
        !          9738:                                updleds();
        !          9739:                        } else if (c == NUMLOCK) {
        !          9740:                                shift ^= NMLS;  /* toggle num lock */
        !          9741:                                updleds();
        !          9742:                        }
        !          9743:                }
        !          9744:                return;
        !          9745:        }
        !          9746: 
        !          9747:        /*
        !          9748:         * No other key up codes of interest.
        !          9749:         */
        !          9750:        if (r&KEYUP)
        !          9751:                return;
        !          9752: 
        !          9753:        /*
        !          9754:         * If the tty is not open the character is
        !          9755:         * just tossed away.
        !          9756:         */
        !          9757:        if (istty.t_open == 0)
        !          9758:                return;
        !          9759: 
        !          9760:        /*
        !          9761:         * Map character, based on the
        !          9762:         * current state of the shift, control,
        !          9763:         * meta and lock flags.
        !          9764:         */
        !          9765:        if (shift & CTS) {
        !          9766:                if (s == CTS)                   /* Map Ctrl (BS | NL) */
        !          9767:                        c = (c == BACKSP) ? 0x7F : 0x0A;  
        !          9768:                else if (s==SS1 || s==LET)      /* Normal Ctrl map */
        !          9769:                        c = umaptab[c]&0x1F;    /* Clear bits 5-6 */
        !          9770:                else                            
        !          9771:                        return;                 /* Ignore this char */
        !          9772:        } else if (s &= shift) {
        !          9773:                if (shift & SES) {               /* if shift on */
        !          9774:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
        !          9775:                                c = lmaptab[c];  /* use unshifted */
        !          9776:                        else
        !          9777:                                c = umaptab[c];  /* use shifted */
        !          9778:                } else {                         /* if shift not on */
        !          9779:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
        !          9780:                                c = umaptab[c];  /* use shifted */
        !          9781:                        else
        !          9782:                                c = lmaptab[c];  /* use unshifted */
        !          9783:                }
        !          9784:        } else                                   
        !          9785:                c = lmaptab[c];                  /* use unshifted */
        !          9786: 
        !          9787:        /*
        !          9788:         * Act on character.
        !          9789:         */
        !          9790:        if (c == XXX)                           
        !          9791:                return;                          /* char to ignore */
        !          9792: 
        !          9793:        if (c != SPC) {                  /* not special char? */
        !          9794:                if (shift & ALS)         /* ALT (meta bit)? */
        !          9795:                        c |= 0x80;       /* set meta */
        !          9796:                isin(c);                 /* send the char */
        !          9797:        } else
        !          9798:                update_leds += isspecial(r);     /* special chars */
        !          9799:        if (update_leds) {
        !          9800:                savests = sphi();
        !          9801:                outb(KBDATA, LEDCMD);
        !          9802:                ledcmd = 1;
        !          9803:                spl(savests);
        !          9804:        }
        !          9805: }
        !          9806: 
        !          9807: /*
        !          9808:  * Handle special input sequences.
        !          9809:  * The character passed is the key number.
        !          9810:  *
        !          9811:  * The keypad is translated by the following table,
        !          9812:  * the first entry is the normal sequence, the second the shifted,
        !          9813:  * and the third the alternate keypad sequence.
        !          9814:  */
        !          9815: static char *keypad[][3] = {
        !          9816:        { "\33[H",  "7", "\33?w" },     /* 71 */
        !          9817:        { "\33[A",  "8", "\33?x" },     /* 72 */
        !          9818:        { "\33[V",  "9", "\33?y" },     /* 73 */
        !          9819:        { "\33[D",  "4", "\33?t" },     /* 75 */
        !          9820:        { "\0337",  "5", "\33?u" },     /* 76 */
        !          9821:        { "\33[C",  "6", "\33?v" },     /* 77 */
        !          9822:        { "\33[24H","1", "\33?q" },     /* 79 */
        !          9823:        { "\33[B",  "2", "\33?r" },     /* 80 */
        !          9824:        { "\33[U",  "3", "\33?s" },     /* 81 */
        !          9825:        { "\33[@",  "0", "\33?p" },     /* 82 */
        !          9826:        { "\33[P", ".",  "\33?n" }      /* 83 */
        !          9827: };
        !          9828: 
        !          9829: isspecial(c)
        !          9830: int c;
        !          9831: {
        !          9832:        register char *cp;
        !          9833:        register int s;
        !          9834:        int     update_leds = 0;
        !          9835: 
        !          9836:        cp = 0;
        !          9837: 
        !          9838:        switch (c) {
        !          9839:        case 15:                                        /* cursor back tab */
        !          9840:                cp = "\033[Z";
        !          9841:                break;
        !          9842:        case 59: case 60: case 61: case 62: case 63:    /* Function keys */
        !          9843:        case 64: case 65: case 66: case 67: case 68:
        !          9844:                /* offset to function string */
        !          9845:                if ( shift & ALS )
        !          9846:                        cp = isfval[c-49];
        !          9847:                else
        !          9848:                        cp = isfval[c-59];
        !          9849:                break;
        !          9850: 
        !          9851:        case 70:                /* Scroll Lock -- stop/start output */
        !          9852:        {
        !          9853:                static char cbuf[2];
        !          9854: 
        !          9855:                cp = &cbuf[0];  /* working buffer */
        !          9856:                if (!(istty.t_sgttyb.sg_flags&RAWIN)) { /* not if in RAW mode */
        !          9857:                        ++update_leds;
        !          9858:                        if (istty.t_flags & T_STOP) {   /* output stopped? */
        !          9859:                           cbuf[0] = istty.t_tchars.t_startc;  /* start it */
        !          9860:                           scroll = 0;
        !          9861:                        } else {
        !          9862:                           cbuf[0] = istty.t_tchars.t_stopc;   /* stop output */
        !          9863:                           scroll = 1;
        !          9864:                        }
        !          9865:                }
        !          9866:                break;
        !          9867:        }
        !          9868: 
        !          9869:        case 79:                /* 1/End */
        !          9870:        case 80:                /* 2/DOWN */
        !          9871:        case 81:                /* 3/PgDn */
        !          9872:        case 82:                /* 0/Ins */
        !          9873:        case 83:                /* ./Del */
        !          9874:                --c;            /* adjust code */
        !          9875:        case 75:                /* 4/LEFT */
        !          9876:        case 76:                /* 5 */
        !          9877:        case 77:                /* 6/RIGHT */
        !          9878:                --c;            /* adjust code */
        !          9879:        case 71:                /* 7/Home/Clear */
        !          9880:        case 72:                /* 8/UP */
        !          9881:        case 73:                /* 9/PgUp */
        !          9882:                s = 0;                  /* start off with normal keypad */
        !          9883:                if (shift&NMLS)         /* num lock? */
        !          9884:                        s = 1;          /* set shift pad */
        !          9885:                if (shift&SES)          /* shift? */
        !          9886:                        s ^= 1;         /* toggle shift pad */
        !          9887:                if (shift&AKPS)         /* alternate pad? */
        !          9888:                        s = 2;          /* set alternate pad */         
        !          9889:                cp = keypad[c-71][s];   /* get keypad value */
        !          9890:                break;
        !          9891:        }
        !          9892:        if (cp)                                 /* send string */
        !          9893:                while ((*cp != 0) && (*cp != -1))
        !          9894:                        isin( *cp++ & 0377 );
        !          9895:        return update_leds;
        !          9896: }
        !          9897: 
        !          9898: /**
        !          9899:  *
        !          9900:  * void
        !          9901:  * ismmfunc( c )       -- process keyboard related output escape sequences
        !          9902:  * char c;
        !          9903:  */
        !          9904: void
        !          9905: ismmfunc(c)
        !          9906: register int c;
        !          9907: {
        !          9908:        switch (c) {
        !          9909:        case 't':       /* Enter numlock */
        !          9910:                shift |= NMLS;
        !          9911:                updleds();                      /* update LED status */
        !          9912:                break;
        !          9913:        case 'u':       /* Leave numlock */
        !          9914:                shift &= ~NMLS;
        !          9915:                updleds();                      /* update LED status */
        !          9916:                break;
        !          9917:        case '=':       /* Enter alternate keypad */
        !          9918:                shift |= AKPS;
        !          9919:                break;
        !          9920:        case '>':       /* Exit alternate keypad */
        !          9921:                shift &= ~AKPS;
        !          9922:                break;
        !          9923:        case 'c':       /* Reset terminal */
        !          9924:                islock = 0;
        !          9925:                shift  = 0;
        !          9926:                initkeys();
        !          9927:                updleds();                      /* update LED status */
        !          9928:                break;
        !          9929:        }
        !          9930: }
        !          9931: 
        !          9932: /**
        !          9933:  *
        !          9934:  * void
        !          9935:  * isin( c )   -- append character to raw input silo
        !          9936:  * char c;
        !          9937:  */
        !          9938: static
        !          9939: isin( c )
        !          9940: register int c;
        !          9941: {
        !          9942:        /*
        !          9943:         * Cache received character.
        !          9944:         */
        !          9945:        istty.t_rawin.si_buf[ istty.t_rawin.si_ix ] = c;
        !          9946: 
        !          9947:        if ( ++istty.t_rawin.si_ix >= sizeof(istty.t_rawin.si_buf) )
        !          9948:                istty.t_rawin.si_ix = 0;
        !          9949: }
        !          9950: 
        !          9951: /**
        !          9952:  *
        !          9953:  * void
        !          9954:  * isbatch()   -- raw input conversion routine
        !          9955:  *
        !          9956:  *     Action: Enable the video display.
        !          9957:  *             Canonize the raw input silo.
        !          9958:  *
        !          9959:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
        !          9960:  */
        !          9961: static void
        !          9962: isbatch( tp )
        !          9963: register TTY * tp;
        !          9964: {
        !          9965:        register int c;
        !          9966:        static int lastc;
        !          9967: 
        !          9968:        /*
        !          9969:         * Ensure video display is enabled.
        !          9970:         */
        !          9971:        mm_von();
        !          9972: 
        !          9973:        isbusy = 0;
        !          9974: 
        !          9975:        /*
        !          9976:         * Process all cached characters.
        !          9977:         */
        !          9978:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          9979: 
        !          9980:                /*
        !          9981:                 * Get next cached char.
        !          9982:                 */
        !          9983:                c = tp->t_rawin.si_buf[ tp->t_rawin.si_ox ];
        !          9984: 
        !          9985:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          9986:                        tp->t_rawin.si_ox = 0;
        !          9987:                else
        !          9988:                        tp->t_rawin.si_ox++;
        !          9989: 
        !          9990:                if ( (islock == 0) || ISINTR || ISQUIT ) {
        !          9991:                        ttin( tp, c );
        !          9992:                }
        !          9993: 
        !          9994:                else if ( (c == 'b') && (lastc == '\033') ) {
        !          9995:                        islock = 0;
        !          9996:                        ttin( tp, lastc );
        !          9997:                        ttin( tp, c );
        !          9998:                }
        !          9999: 
        !          10000:                else if ( (c == 'c') && (lastc == '\033') ) {
        !          10001:                        ttin( tp, lastc );
        !          10002:                        ttin( tp, c );
        !          10003:                }
        !          10004: 
        !          10005:                else
        !          10006:                        putchar('\007');
        !          10007: 
        !          10008:                lastc = c;
        !          10009:        }
        !          10010: }
        !          10011: 
        !          10012: /*
        !          10013:  * update the keyboard status LEDS
        !          10014:  */
        !          10015: updleds()
        !          10016: {
        !          10017:        int     s;
        !          10018: 
        !          10019:        s = sphi();
        !          10020:        outb(KBDATA, LEDCMD);
        !          10021:        ledcmd = 1;
        !          10022:        spl(s);
        !          10023: }
        !          10024: 
        !          10025: /*
        !          10026:  * unlock the scroll in case an interrupt character is received
        !          10027:  */
        !          10028: kbunscroll()
        !          10029: {
        !          10030:        scroll = 0;
        !          10031:        updleds();
        !          10032: }
        !          10033: 0707070064030032041006440000030000030000011777770507310635300004700000000260/newbits/kernel/USRSRC/i8086/drv/lgl.h/* (-lgl
        !          10034:  *     COHERENT Driver Kit Version (Beta)
        !          10035:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          10036:  *     All rights reserved. May not be copied without permission.
        !          10037:  -lgl) */
        !          10038: 0707070064030050651006440000030000030000011777770507310635300004600000016111/newbits/kernel/USRSRC/i8086/drv/lp.c/*
        !          10039:  * This is a driver for PC parallel printers.
        !          10040:  * It has been tested on an EPSON MX-80, Printronix P300, HP LaserJet II.
        !          10041:  * Supports up to three line printers.
        !          10042:  */
        !          10043: #include <sys/coherent.h>
        !          10044: #include <sys/i8086.h>
        !          10045: #include <sys/con.h>
        !          10046: #include <sys/devices.h>
        !          10047: #include <errno.h>
        !          10048: #include <sys/io.h>
        !          10049: #include <sys/proc.h>
        !          10050: #include <sys/uproc.h>
        !          10051: #include <sys/stat.h>
        !          10052: 
        !          10053: /*
        !          10054:  * Patchable parameters.
        !          10055:  *
        !          10056:  *     LP0_OK specifies whether LP0 is always THERE.
        !          10057:  *     LPTIME specifies number of ticks between polls.
        !          10058:  *     LPWAIT specifies loop counter to wait in poll.
        !          10059:  *     LPTEST specifies whether or not to test for on-line conditition.
        !          10060:  */
        !          10061: int    LP0_OK = 0;
        !          10062: int    LPTIME = 4;
        !          10063: int    LPWAIT = 400;
        !          10064: int    LPTEST = 1;
        !          10065: 
        !          10066: /*
        !          10067:  * Driver configuration.
        !          10068:  */
        !          10069: int    lpload();
        !          10070: int    lpunload();
        !          10071: int    lpwrite();
        !          10072: int    lpopen();
        !          10073: int    lpclose();
        !          10074: int    lpintr();
        !          10075: int    nulldev();
        !          10076: int    nonedev();
        !          10077: 
        !          10078: CON    lpcon = {
        !          10079:        DFCHR,                          /* Flags */
        !          10080:        LP_MAJOR,                               /* Major index */
        !          10081:        lpopen,                         /* Open */
        !          10082:        lpclose,                        /* Close */
        !          10083:        nulldev,                        /* Block */
        !          10084:        nonedev,                        /* Read */
        !          10085:        lpwrite,                        /* Write */
        !          10086:        nonedev,                        /* Ioctl */
        !          10087:        nulldev,                        /* Powerfail */
        !          10088:        nulldev,                        /* Timeout */
        !          10089:        lpload,                         /* Load */
        !          10090:        lpunload                        /* Unload */
        !          10091: };
        !          10092: 
        !          10093: /*
        !          10094:  * Line Printer Registers.
        !          10095:  */
        !          10096: #define        LPDAT   (0)                     /* Data port, lpbase + 0 */
        !          10097: #define        LPSTR   (1)                     /* Status port, lpbase + 1 */
        !          10098: #define        LPCSR   (2)                     /* Control port, lpbase + 2 */
        !          10099: 
        !          10100: /*
        !          10101:  * LP Flag Bits.
        !          10102:  */
        !          10103: #define        LPTHERE 0x01                    /* Interface actually there */
        !          10104: #define        LPOPEN  0x02                    /* Printer is open */
        !          10105: #define        LPSLEEP 0x04                    /* Sleeping on buffer event */
        !          10106: #define        LPRAW   0x80                    /* Raw mode */
        !          10107: 
        !          10108: /*
        !          10109:  * Printer database.
        !          10110:  * Terminated by lpbase = 0.
        !          10111:  * NLP = # entries - 1.
        !          10112:  */
        !          10113: static struct  lpinfo  {
        !          10114:        int     lpbase;                 /* I/O Base address */
        !          10115:        int     lpflag;                 /* Flags */
        !          10116:        int     lpcol;                  /* Current horizontal position */
        !          10117: }      lpinfo[] = {
        !          10118:        {       0x3BC   },
        !          10119:        {       0x378   },
        !          10120:        {       0x278   },
        !          10121:        {       0x000   }
        !          10122: };
        !          10123: #define        NLP     (sizeof(lpinfo) / sizeof(lpinfo[0]) - 1)
        !          10124: 
        !          10125: /*
        !          10126:  * LP Status Register Bits.
        !          10127:  */
        !          10128: #define        ACK     0x80                    /* Ack (active high) */
        !          10129: #define        BUSY    0x40                    /* Busy (active high) */
        !          10130: #define        NOPAPER 0x20                    /* No paper */
        !          10131: #define        ONLINE  0x10                    /* On line */
        !          10132: #define        NERROR  0x08                    /* Error (active low) */
        !          10133: 
        !          10134: /* IBM cable */
        !          10135: #define        IBMNBSY 0x80                    /* Busy (active low) */
        !          10136: #define        IBMNACK 0x40                    /* Ack (active low) */
        !          10137: 
        !          10138: /*
        !          10139:  * LP Control Register Bits.
        !          10140:  */
        !          10141: #define        IENABLE 0x10                    /* Interrupt enable */
        !          10142: #define        SEL     0x08                    /* Select input */
        !          10143: #define        NINIT   0x04                    /* Initialise printer (active low) */
        !          10144: #define        AFEED   0x02                    /* Auto line feed */
        !          10145: #define        STROBE  0x01                    /* Strobe */
        !          10146: 
        !          10147: /*
        !          10148:  * On load
        !          10149:  * compute the port addresses,
        !          10150:  * reset the printer, and select it.
        !          10151:  */
        !          10152: static
        !          10153: lpload()
        !          10154: {
        !          10155:        register struct lpinfo * p;
        !          10156:        register int delay;
        !          10157:        static int notfirst;
        !          10158: 
        !          10159:        /*
        !          10160:         * Only initialize hardware on first invocation.
        !          10161:         * Necessary if used as console device [condev].
        !          10162:         */
        !          10163:        if ( notfirst )
        !          10164:                return;
        !          10165:        notfirst = 1;
        !          10166: 
        !          10167:        /*
        !          10168:         * Note: since some PC clones lp ports can't be read,
        !          10169:         * their lpflag field has to be patched to 'LPTHERE'.
        !          10170:         */
        !          10171:        if ( LP0_OK & 1 )
        !          10172:                lpinfo[0].lpflag |= LPTHERE;
        !          10173:        if ( LP0_OK & 2 )
        !          10174:                lpinfo[1].lpflag |= LPTHERE;
        !          10175:        if ( LP0_OK & 4 )
        !          10176:                lpinfo[2].lpflag |= LPTHERE;
        !          10177: 
        !          10178:        for ( p = lpinfo; p->lpbase ; ++p ) {
        !          10179: 
        !          10180:                /*
        !          10181:                 * Check printer port existence.
        !          10182:                 */
        !          10183:                if ( (p->lpflag & LPTHERE) == 0 ) {
        !          10184:                        outb( p->lpbase+LPDAT, 0xA5 );
        !          10185:                        delay = LPWAIT; do {
        !          10186:                        } while (--delay);
        !          10187:                        if ( inb(p->lpbase+LPDAT) == 0xA5 )
        !          10188:                                p->lpflag |= LPTHERE;
        !          10189:                }
        !          10190: 
        !          10191:                /*
        !          10192:                 * Initialize and select printer.
        !          10193:                 */
        !          10194:                outb( p->lpbase+LPCSR, SEL );
        !          10195:                delay = LPWAIT; do {
        !          10196:                } while (--delay);
        !          10197:                outb( p->lpbase+LPCSR, SEL|NINIT );
        !          10198:        }
        !          10199: }
        !          10200: 
        !          10201: /*
        !          10202:  * On unload
        !          10203:  * cancel any timed functions.
        !          10204:  */
        !          10205: static
        !          10206: lpunload()
        !          10207: {
        !          10208:        lptimer();
        !          10209: }
        !          10210: 
        !          10211: /*
        !          10212:  * The open routine makes sure that
        !          10213:  * only one process has the printer open
        !          10214:  * at one time, and not too much else.
        !          10215:  */
        !          10216: static
        !          10217: lpopen(dev, mode)
        !          10218: dev_t  dev;
        !          10219: {
        !          10220:        register struct lpinfo * p;
        !          10221: 
        !          10222:        /*
        !          10223:         * Illegal printer port.
        !          10224:         */
        !          10225:        if ( (minor(dev) & ~LPRAW) >= NLP ) {
        !          10226:                u.u_error = ENXIO;
        !          10227:                return;
        !          10228:        }
        !          10229: 
        !          10230:        /*
        !          10231:         * Access attributes.
        !          10232:         */
        !          10233:        p = &lpinfo[ minor(dev) & ~LPRAW ];
        !          10234: 
        !          10235:        /*
        !          10236:         * Attempt initialization if printer port not found.
        !          10237:         */
        !          10238:        if ( (p->lpflag&LPTHERE) == 0 )
        !          10239:                lpload();
        !          10240: 
        !          10241:        /*
        !          10242:         * Printer port not found.
        !          10243:         */
        !          10244:        if ( (p->lpflag&LPTHERE) == 0 ) {
        !          10245:                u.u_error = ENXIO;
        !          10246:                return;
        !          10247:        }
        !          10248: 
        !          10249:        /*
        !          10250:         * Printer port already open.
        !          10251:         */
        !          10252:        if ( (p->lpflag&LPOPEN) != 0 ) {
        !          10253:                u.u_error = EDBUSY;
        !          10254:                return;
        !          10255:        }
        !          10256: 
        !          10257:        /*
        !          10258:         * Printer powered off or off-line
        !          10259:         */
        !          10260:        if (LPTEST && !(inb(p->lpbase+LPSTR) & ONLINE)) {
        !          10261:                u.u_error = EDATTN;
        !          10262:                return;
        !          10263:        }
        !          10264: 
        !          10265:        /*
        !          10266:         * Flag port as being open.
        !          10267:         */
        !          10268:        p->lpflag &= ~LPRAW;
        !          10269:        p->lpflag |= LPOPEN | minor(dev) & LPRAW;
        !          10270: 
        !          10271:        /*
        !          10272:         * Initiate periodic printer scan if user open.
        !          10273:         */
        !          10274:        if ( (SELF != NULL) && (SELF->p_pid != 0) )
        !          10275:                lptimer();
        !          10276: }
        !          10277: 
        !          10278: /*
        !          10279:  * The close routine marks the device as no longer open.
        !          10280:  */
        !          10281: static
        !          10282: lpclose(dev)
        !          10283: dev_t  dev;
        !          10284: {
        !          10285:        lpinfo[ minor(dev) & ~LPRAW ].lpflag &= ~LPOPEN;
        !          10286: }
        !          10287: 
        !          10288: /*
        !          10289:  * The write routine copies the
        !          10290:  * characters from the user buffer to
        !          10291:  * the printer buffer, expanding tabs and
        !          10292:  * keeping track of the current horizontal
        !          10293:  * position of the print head.
        !          10294:  */
        !          10295: static
        !          10296: lpwrite( dev, iop )
        !          10297: dev_t  dev;
        !          10298: IO     *iop;
        !          10299: {
        !          10300:        register struct lpinfo * p;
        !          10301:        register int    c;
        !          10302: 
        !          10303:        p = &lpinfo[ minor(dev) & ~LPRAW ];
        !          10304: 
        !          10305:        /*
        !          10306:         * Writes from kernel are handled via busy-waits instead of timeouts.
        !          10307:         */
        !          10308:        if (iop->io_seg == IOSYS) {
        !          10309: 
        !          10310:                while ( (c=iogetc(iop)) >= 0 ) {
        !          10311: 
        !          10312:                        while ( (inb(p->lpbase+LPSTR) & IBMNBSY) == 0 )
        !          10313:                                ;
        !          10314: 
        !          10315:                        outb( p->lpbase+LPDAT, c );
        !          10316:                        outb( p->lpbase+LPCSR, SEL|NINIT|STROBE );
        !          10317:                        outb( p->lpbase+LPCSR, SEL|NINIT );
        !          10318:                }
        !          10319:                return;
        !          10320:        }
        !          10321: 
        !          10322:        /*
        !          10323:         * Writes from user are handled via lpchar() which uses timeouts.
        !          10324:         */
        !          10325:        while ( (c=iogetc(iop)) >= 0 ) {
        !          10326: 
        !          10327:                if ( (p->lpflag&LPRAW) == 0 ) {
        !          10328: 
        !          10329:                        switch (c) {
        !          10330: 
        !          10331:                        case '\t':
        !          10332:                                do {
        !          10333:                                        lpchar( p, ' ');
        !          10334:                                } while ((++p->lpcol&07) != 0);
        !          10335:                                continue;
        !          10336:        
        !          10337:                        case '\n':
        !          10338:                                lpchar( p, '\r');
        !          10339:                                /* no break */
        !          10340: 
        !          10341:                        case '\r':
        !          10342:                        case '\f':
        !          10343:                                p->lpcol = 0;
        !          10344:                                break;
        !          10345:        
        !          10346:                        case '\b':
        !          10347:                                --p->lpcol;
        !          10348:                                break;
        !          10349:        
        !          10350:                        default:
        !          10351:                                ++p->lpcol;
        !          10352:                        }
        !          10353:                }
        !          10354:                lpchar( p, c );
        !          10355: 
        !          10356:                if ( SELF->p_ssig!=0 && nondsig() ) {
        !          10357:                        u.u_error = EINTR;
        !          10358:                        break;
        !          10359:                }
        !          10360:        }
        !          10361: }
        !          10362: 
        !          10363: /*
        !          10364:  * Put a character into the printer buffer.
        !          10365:  * If the printer doesn't respond ready in a reasonable time
        !          10366:  * sleep for a while.
        !          10367:  */
        !          10368: static
        !          10369: lpchar( p, c )
        !          10370: register struct lpinfo *p;
        !          10371: int c;
        !          10372: {
        !          10373:        register int    s;
        !          10374: 
        !          10375:        s = LPWAIT;
        !          10376:        while ( (inb(p->lpbase+LPSTR) & IBMNBSY) == 0 ) {
        !          10377:                if ( --s == 0 ) {
        !          10378:                        s = sphi();
        !          10379:                        p->lpflag |= LPSLEEP;
        !          10380:                        sleep((char *)p, 0, 0, 0);
        !          10381:                        spl(s);
        !          10382:                        s = LPWAIT;
        !          10383:                }
        !          10384:        }
        !          10385: 
        !          10386:        outb( p->lpbase+LPDAT, c );
        !          10387:        outb( p->lpbase+LPCSR, SEL|NINIT|STROBE );
        !          10388:        outb( p->lpbase+LPCSR, SEL|NINIT );
        !          10389: }
        !          10390: 
        !          10391: /*
        !          10392:  * Poll the line printer interface from the clock.
        !          10393:  * Turn it off when there is nothing left to do.
        !          10394:  */
        !          10395: static
        !          10396: lptimer()
        !          10397: {
        !          10398:        register struct lpinfo *p;
        !          10399:        int isopen = 0;
        !          10400:        static TIM tim;
        !          10401: 
        !          10402:        /*
        !          10403:         * Scan all printers.
        !          10404:         */
        !          10405:        for ( p = lpinfo; p->lpbase; ++p ) {
        !          10406: 
        !          10407:                /*
        !          10408:                 * Ignore unopened printers.
        !          10409:                 */
        !          10410:                if ( (p->lpflag & LPOPEN) == 0 )
        !          10411:                        continue;
        !          10412: 
        !          10413:                ++isopen;
        !          10414: 
        !          10415:                /*
        !          10416:                 * Check for sleeping process on ready printer.
        !          10417:                 */
        !          10418:                if((p->lpflag & LPSLEEP) && (inb(p->lpbase+LPSTR) & IBMNBSY)){
        !          10419:                        p->lpflag &= ~LPSLEEP;
        !          10420:                        wakeup((char *)p);
        !          10421:                }
        !          10422:        }
        !          10423: 
        !          10424:        /*
        !          10425:         * Reschedule timer function if at least 1 printer is still open.
        !          10426:         */
        !          10427:        if ( isopen )
        !          10428:                timeout( &tim, LPTIME, lptimer, &tim );
        !          10429: }
        !          10430: 0707070064030141661004440000030000030000011777770507310635500004600000005773/newbits/kernel/USRSRC/i8086/drv/mm.c/* (-lgl
        !          10431:  *     COHERENT Driver Kit Version 1.1.0
        !          10432:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          10433:  *     All rights reserved. May not be copied without permission.
        !          10434:  -lgl) */
        !          10435: /*
        !          10436:  * Memory Mapped Video
        !          10437:  * High level output routines.
        !          10438:  */
        !          10439: #include <sys/coherent.h>
        !          10440: #include <sys/sched.h>
        !          10441: #include <errno.h>
        !          10442: #include <sys/stat.h>
        !          10443: #include <sys/io.h>
        !          10444: #include <sys/tty.h>
        !          10445: #include <sys/uproc.h>
        !          10446: #include <sys/timeout.h>
        !          10447: 
        !          10448: /* For beeper */
        !          10449: #define        TIMCTL  0x43                    /* Timer control port */
        !          10450: #define        TIMCNT  0x42                    /* Counter timer port */
        !          10451: #define        PORTB   0x61                    /* Port containing speaker enable */
        !          10452: #define        FREQ    ((int)(1193181L/440))   /* Counter for 440 Hz. tone */
        !          10453: 
        !          10454: int mmtime();
        !          10455: 
        !          10456: char mmbeeps;          /* number of ticks remaining on bell */
        !          10457: char mmesc;            /* last unserviced escape character */
        !          10458: int  mmcrtsav = 1;     /* crt saver enabled */
        !          10459: int  mmvcnt   = 900;   /* seconds remaining before crt saver is activated */
        !          10460: 
        !          10461: extern TTY istty;
        !          10462: 
        !          10463: /*
        !          10464:  * Start the output stream.
        !          10465:  * Called from `ttwrite' and `isrint' routines.
        !          10466:  */
        !          10467: TIM mmtim;
        !          10468: 
        !          10469: mmstart(tp)
        !          10470: register TTY *tp;
        !          10471: {
        !          10472:        int c;
        !          10473:        IO iob;
        !          10474:        static int mmbegun;
        !          10475: 
        !          10476:        while ((tp->t_flags&T_STOP) == 0) {
        !          10477:                if ((c = ttout(tp)) < 0)
        !          10478:                        break;
        !          10479:                iob.io_seg  = IOSYS;
        !          10480:                iob.io_ioc  = 1;
        !          10481:                iob.io_base = &c;
        !          10482:                iob.io_flag = 0;
        !          10483:                mmwrite( makedev(2,0), &iob );
        !          10484:        }
        !          10485: 
        !          10486:        if (mmbegun == 0) {
        !          10487:                ++mmbegun;
        !          10488:                timeout(&mmtim, HZ/10, mmtime, (char *)tp);
        !          10489:        }
        !          10490: }
        !          10491: 
        !          10492: mmtime(xp)
        !          10493: char *xp;
        !          10494: {
        !          10495:        register int s;
        !          10496: 
        !          10497:        s = sphi();
        !          10498:        if (mmbeeps < 0) {
        !          10499:                mmbeeps = 2;
        !          10500:                outb(TIMCTL, 0xB6);     /* Timer 2, lsb, msb, binary */
        !          10501:                outb(TIMCNT, FREQ&0xFF);
        !          10502:                outb(TIMCNT, FREQ>>8);
        !          10503:                outb(PORTB, inb(PORTB) | 03);   /* Turn speaker on */
        !          10504:        }
        !          10505:        else if ((mmbeeps > 0) && (--mmbeeps == 0))
        !          10506:                outb( PORTB, inb(PORTB) & ~03 );
        !          10507: 
        !          10508:        if (mmesc) {
        !          10509:                ismmfunc(mmesc);
        !          10510:                mmesc = 0;
        !          10511:        }
        !          10512:        spl(s);
        !          10513: 
        !          10514:        ttstart( (TTY *) xp );
        !          10515: 
        !          10516:        timeout(&mmtim, HZ/10, mmtime, xp);
        !          10517: }
        !          10518: 
        !          10519: /**
        !          10520:  *
        !          10521:  * void
        !          10522:  * mmwatch()   -- turn video display off after 15 minutes inactivity.
        !          10523:  */
        !          10524: void
        !          10525: mmwatch()
        !          10526: {
        !          10527:        if ( (mmcrtsav > 0) && (mmvcnt > 0) && (--mmvcnt == 0) )
        !          10528:                mm_voff();
        !          10529: }
        !          10530: 
        !          10531: mmwrite( dev, iop )
        !          10532: dev_t dev;
        !          10533: register IO *iop;
        !          10534: {
        !          10535:        int ioc;
        !          10536:        int s;
        !          10537: 
        !          10538:        ioc = iop->io_ioc;
        !          10539: 
        !          10540:        /*
        !          10541:         * Kernel writes.
        !          10542:         */
        !          10543:        if (iop->io_seg == IOSYS) {
        !          10544:                while (mmgo(iop))
        !          10545:                        ;
        !          10546:        }
        !          10547: 
        !          10548:        /*
        !          10549:         * Blocking user writes.
        !          10550:         */
        !          10551:        else if ( (iop->io_flag & IONDLY) == 0 ) {
        !          10552:                do {
        !          10553:                        while (istty.t_flags & T_STOP) {
        !          10554:                                s = sphi();
        !          10555:                                istty.t_flags |= T_HILIM;
        !          10556:                                sleep((char*) &istty.t_oq,
        !          10557:                                        CVTTOUT, IVTTOUT, SVTTOUT);
        !          10558:                                spl( s );
        !          10559:                        }
        !          10560:                        /*
        !          10561:                         * Signal received.
        !          10562:                         */
        !          10563:                        if ( SELF->p_ssig && nondsig() ) {
        !          10564:                                kbunscroll();   /* update kbd LEDS */
        !          10565:                                /*
        !          10566:                                 * No data transferred yet.
        !          10567:                                 */
        !          10568:                                if ( ioc == iop->io_ioc )
        !          10569:                                        u.u_error = EINTR;
        !          10570:                                /*
        !          10571:                                 * Transfer remaining data
        !          10572:                                 * without pausing after scrolling.
        !          10573:                                 */
        !          10574:                                else while ( mmgo(iop) )
        !          10575:                                        ;
        !          10576: 
        !          10577:                                return;
        !          10578:                        }
        !          10579:                        mmgo(iop);
        !          10580:                } while ( iop->io_ioc );
        !          10581:        }
        !          10582: 
        !          10583:        /*
        !          10584:         * Non-blocking user writes with output stopped.
        !          10585:         */
        !          10586:        else if ( istty.t_flags & T_STOP ) {
        !          10587:                u.u_error = EAGAIN;
        !          10588:                return;
        !          10589:        }
        !          10590: 
        !          10591:        /*
        !          10592:         * Non-blocking user writes do not pause after scrolling.
        !          10593:         */
        !          10594:        else {
        !          10595:                while ( mmgo(iop) )
        !          10596:                        ;
        !          10597:        }
        !          10598: }
        !          10599: 0707070064030112651006440000000000000000011777770507310635600004700000104560/newbits/kernel/USRSRC/i8086/drv/ati.m/ (lgl-
        !          10600: /      COHERENT Driver Kit Version 1.0.0
        !          10601: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          10602: /      All rights reserved. May not be copied without permission.
        !          10603: / -lgl)
        !          10604: ////////
        !          10605: /
        !          10606: / Array Technologies Inc - Graphics Solution - Device Driver
        !          10607: /
        !          10608: /       Supports 40/80/132 column color text
        !          10609: /                   80/132 column monochrome text
        !          10610: /
        !          10611: / State driven code
        !          10612: /
        !          10613: /      Input:  DS:SI - input string
        !          10614: /              ES:DI - current screen location
        !          10615: /              SS:BP - terminal information
        !          10616: /              CX    - input count
        !          10617: /              BP    - references terminal information
        !          10618: /              AH    - character attributes
        !          10619: /              AL    - character
        !          10620: /              BH    - (usually) kept zeroed for efficiency
        !          10621: /              DH    - current row
        !          10622: /              DL    - current column
        !          10623: /
        !          10624: / 
        !          10625: ////////
        !          10626: 
        !          10627:        NCB     = 2             / number of horizontal bytes per char
        !          10628:        NCR     = 1             / number of horizontal lines per char
        !          10629:        NHB     = 160           / number of horizontal bytes per line
        !          10630:        NRB     = NCR*NHB       / number of bytes per character row
        !          10631: 
        !          10632:        ATTR    = ah            / attribute byte
        !          10633:        ZERO    = bh            / (almost) always zero
        !          10634:        ROW     = dh            / currently active vertical position
        !          10635:        COL     = dl            / currently active horizontal position
        !          10636:        POS     = di            / currently active display address
        !          10637: 
        !          10638:        INTENSE = 0x08          / high intensity attribute bit
        !          10639:        BLINK   = 0x80          / blinking attribute bit
        !          10640:        REVERSE = 0x70          / reverse video
        !          10641: 
        !          10642: ////////
        !          10643: /
        !          10644: / Magic constants from <sys/io.h>
        !          10645: /
        !          10646: ////////
        !          10647: 
        !          10648:        IO_SEG  = 0
        !          10649:        IO_IOC  = 2
        !          10650:        IO_BASE = 8
        !          10651: 
        !          10652:        IOSYS   = 0
        !          10653:        IOUSR   = 1
        !          10654: 
        !          10655: ////////
        !          10656: /
        !          10657: / Data
        !          10658: /
        !          10659: ////////
        !          10660: 
        !          10661: MM_FUNC                = 0             / current state
        !          10662: MM_PORT                = 2             / adapter base i/o port
        !          10663: MM_BASE                = 4             / adapter base memory address
        !          10664: MM_ROW         = 6             / screen row
        !          10665: MM_COL         = 7             / screen column
        !          10666: MM_POS         = 8             / screen position
        !          10667: MM_ATTR                = 10            / attributes
        !          10668: MM_N1          = 11            / numeric argument 1
        !          10669: MM_N2          = 12            / numeric argument 2
        !          10670: MM_BROW                = 13            / base row
        !          10671: MM_EROW                = 14            / end row
        !          10672: MM_LROW                = 15            / legal row limit
        !          10673: MM_SROW                = 16            / saved cursor row
        !          10674: MM_SCOL                = 17            / saved cursor column
        !          10675: MM_IBROW       = 18            / initial base row
        !          10676: MM_IEROW       = 19            / initial end row
        !          10677: MM_INVIS       = 20            / cursor invisible mask
        !          10678: MM_NCOL                = 22            / number of columns
        !          10679: MM_DATA                = 24            / pointer to crt data
        !          10680: MM_MODE                = 26            / mode register [0x21=col80/132,0x20=col40]
        !          10681: 
        !          10682: / ASCII characters
        !          10683: AZERO          = 0x30
        !          10684: CLOWER         = 0x63
        !          10685: SEMIC          = 0x3B
        !          10686: SPACE          = 0x20
        !          10687: 
        !          10688:        .prvd
        !          10689: mmdata:        .word   mminit
        !          10690:        .word   0x03D4
        !          10691:        .word   0xB800
        !          10692:        .byte   0, 0
        !          10693:        .word   0
        !          10694:        .byte   0x7, 0, 0, 0, 23, 24, 0, 0, 0, 23
        !          10695:        .word   0
        !          10696:        .word   80
        !          10697:        .word   creg80
        !          10698:        .byte   0x21, 0x00
        !          10699:        .shri
        !          10700: 
        !          10701: ////////
        !          10702: /
        !          10703: / creg40, creg80, creg132 - crt register values for 40/80/132 column color
        !          10704: /         mreg80, mreg132 - crt register values for 80/132 column monochrome
        !          10705: /
        !          10706: ////////
        !          10707: 
        !          10708: creg40:        .byte   0x38, 0x28, 0x2D, 0x0A, 0x1F, 0x06, 0x19, 0x1C
        !          10709:        .byte   0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          10710: 
        !          10711: creg80:        .byte   0x71, 0x50, 0x5A, 0x0A, 0x1F, 0x06, 0x19, 0x1C
        !          10712:        .byte   0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          10713: 
        !          10714: mreg80:        .byte   0x61, 0x50, 0x52, 0x0F, 0x19, 0x06, 0x19, 0x19
        !          10715:        .byte   0x02, 0x0D, 0x0B, 0x0C, 0x00, 0x00, 0x00, 0x00
        !          10716: 
        !          10717: #ifdef ATI_132
        !          10718:        .globl  creg132
        !          10719: creg132:.byte  0xB5, 0x84, 0x97, 0x0A, 0x1F, 0x06, 0x19, 0x1C
        !          10720:        .byte   0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          10721: 
        !          10722:        .globl  mreg132
        !          10723: mreg132:.byte  0x9F, 0x84, 0x89, 0x0F, 0x19, 0x06, 0x19, 0x19
        !          10724:        .byte   0x02, 0x0D, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          10725: #endif
        !          10726: 
        !          10727: ////////
        !          10728: /
        !          10729: / mmgo( iop )
        !          10730: / IO *iop;
        !          10731: /
        !          10732: ////////
        !          10733: 
        !          10734:        .globl  mmgo_
        !          10735: 
        !          10736: mmgo_:
        !          10737:        push    si
        !          10738:        push    di
        !          10739:        push    bp
        !          10740:        mov     bp, sp
        !          10741:        push    ds
        !          10742:        push    es
        !          10743:        cld
        !          10744:        mov     bx, 8(bp)               / iop
        !          10745:        mov     si, IO_BASE(bx)         / iop->io_base
        !          10746:        mov     cx, IO_IOC(bx)          / iop->io_ioc
        !          10747:        cmp     IO_SEG(bx), $IOSYS
        !          10748:        je      0f
        !          10749:        mov     ds, uds_
        !          10750: 0:     mov     bp, $mmdata
        !          10751: 
        !          10752:        mov     dx, MM_PORT(bp)         / turn video off if color board
        !          10753:        cmp     dx, $0x3B4
        !          10754:        je      0f
        !          10755:        add     dx, $4
        !          10756:        movb    al, MM_MODE(bp)
        !          10757:        outb    dx, al
        !          10758: 0:
        !          10759:        movb    ROW, MM_ROW(bp)
        !          10760:        movb    COL, MM_COL(bp)
        !          10761:        mov     es,  MM_BASE(bp)
        !          10762:        mov     POS, MM_POS(bp)
        !          10763:        sub     bx, bx
        !          10764:        movb    ATTR, MM_ATTR(bp)
        !          10765:        ijmp    MM_FUNC(bp)
        !          10766: 
        !          10767: exit:  pop     bx
        !          10768:        pop     es
        !          10769:        pop     ds
        !          10770:        movb    MM_ATTR(bp), ATTR
        !          10771:        mov     MM_FUNC(bp), bx
        !          10772:        movb    MM_ROW(bp), ROW         / save row,column
        !          10773:        movb    MM_COL(bp), COL
        !          10774:        mov     MM_POS(bp), POS         / save position
        !          10775: 
        !          10776:        mov     dx, MM_PORT(bp)         / adjust cursor location
        !          10777:        mov     bx, POS
        !          10778:        or      bx, MM_INVIS(bp)
        !          10779:        shr     bx, $1
        !          10780: 
        !          10781:        movb    al, $14
        !          10782:        outb    dx, al
        !          10783:        inc     dx
        !          10784:        movb    al, bh
        !          10785:        outb    dx, al
        !          10786:        dec     dx
        !          10787:        movb    al, $15
        !          10788:        outb    dx, al
        !          10789:        inc     dx
        !          10790:        movb    al, bl
        !          10791:        outb    dx, al
        !          10792: 
        !          10793:        mov     dx, MM_PORT(bp)         / turn video on
        !          10794:        add     dx, $4
        !          10795:        movb    al, MM_MODE(bp)
        !          10796:        orb     al, $0x08
        !          10797:        outb    dx, al
        !          10798:        mov     mmvcnt_, $300           / 300 seconds before video disabled
        !          10799: 
        !          10800:        mov     bp, sp
        !          10801:        mov     bx, 8(bp)
        !          10802:        mov     ax, cx
        !          10803:        xchg    cx, IO_IOC(bx)
        !          10804:        sub     cx, IO_IOC(bx)
        !          10805:        add     IO_BASE(bx), cx
        !          10806:        pop     bp
        !          10807:        pop     di
        !          10808:        pop     si
        !          10809:        ret
        !          10810: 
        !          10811: ////////
        !          10812: /
        !          10813: / mminit - initialize screen
        !          10814: /
        !          10815: ////////
        !          10816: 
        !          10817: mminit:        movb    ss:mmesc_, $CLOWER              / schedule keyboard initialization
        !          10818:        mov     MM_NCOL(bp), $80        / set 80 column mode
        !          10819:        movb    MM_MODE(bp), $0x21
        !          10820:        mov     MM_DATA(bp), $creg80
        !          10821: 
        !          10822: #ifdef ATI_132
        !          10823:        mov     dx, $0x3DF              / clear 132 column color
        !          10824:        movb    al, $0x00               / in mode select register
        !          10825:        outb    dx, al
        !          10826: 
        !          10827:        mov     dx, $0x3BA              / clear 132 column monochrome
        !          10828:        movb    al, $0x00               / in mode select register
        !          10829:        outb    dx, al
        !          10830: #endif
        !          10831: 
        !          10832:        call    int11_                  / read equipment status
        !          10833:        andb    al, $0x30               / isolate video bits
        !          10834:        cmpb    al, $0x30               / if monochrome
        !          10835:        jne     0f
        !          10836:        mov     MM_DATA(bp), $mreg80    /       set monochrome register info
        !          10837:        mov     MM_PORT(bp), $0x3B4     /       set monochrome port
        !          10838:        mov     MM_BASE(bp), $0xB000    /       set monochrome base
        !          10839:        mov     es, MM_BASE(bp)         /               and extra segment.
        !          10840: 
        !          10841: 0:     call    newcrt                  / reprogram crt registers
        !          10842: 
        !          10843: reinit:        sub     ax, ax                  / regenerate row table
        !          10844:        mov     bx, $rowtab
        !          10845: 1:     mov     ss:(bx), ax
        !          10846:        add     ax, MM_NCOL(bp)
        !          10847:        add     ax, MM_NCOL(bp)
        !          10848:        add     bx, $2
        !          10849:        cmp     bx, $rowend
        !          10850:        jb      1b
        !          10851: 
        !          10852:        mov     dx, MM_PORT(bp)         / zero display offset
        !          10853:        movb    al, $12
        !          10854:        outb    dx, al
        !          10855:        inc     dx
        !          10856:        subb    al, al
        !          10857:        outb    dx, al
        !          10858:        dec     dx
        !          10859:        movb    al, $13
        !          10860:        outb    dx, al
        !          10861:        inc     dx
        !          10862:        subb    al, al
        !          10863:        outb    dx, al
        !          10864: 
        !          10865:        mov     dx, MM_PORT(bp)         / reset border to black
        !          10866:        add     dx, $5
        !          10867:        subb    al, al
        !          10868:        outb    dx, al
        !          10869: 
        !          10870:        mov     MM_INVIS(bp), $0
        !          10871:        movb    ATTR, $0x07
        !          10872:        movb    MM_ATTR(bp), ATTR
        !          10873:        movb    ROW, MM_IBROW(bp)
        !          10874:        movb    MM_BROW(bp), ROW
        !          10875:        movb    bl, MM_IEROW(bp)
        !          10876:        movb    MM_EROW(bp), bl
        !          10877:        sub     bx, bx
        !          10878:        movb    MM_N1(bp), $2
        !          10879:        jmp     mm_ed
        !          10880: 
        !          10881: ////////
        !          10882: /
        !          10883: / newcrt -- reload crt registers
        !          10884: /
        !          10885: /      Action: Program crt registers with values defined in code space
        !          10886: /              at offset given by MM_DATA(bp).
        !          10887: /
        !          10888: /      Note:   AX, BX, DX, DI trashed on exit.
        !          10889: /
        !          10890: ////////
        !          10891: 
        !          10892: newcrt:        mov     dx, MM_PORT(bp)         / turn video off
        !          10893:        add     dx, $4
        !          10894:        movb    al, MM_MODE(bp)
        !          10895:        outb    dx, al
        !          10896: 
        !          10897:        mov     di, MM_DATA(bp)         / program crt registers, last to first
        !          10898:        mov     bx, $15                 / [delay between i/o]
        !          10899:        mov     dx, MM_PORT(bp)         / [NOTE:DI=obsolete screen offset]
        !          10900: 0:     movb    al, bl
        !          10901:        outb    dx, al
        !          10902:        movb    al, cs:(bx,di)
        !          10903:        inc     dx
        !          10904:        outb    dx, al
        !          10905:        dec     dx
        !          10906:        dec     bx
        !          10907:        jge     0b
        !          10908:        ret
        !          10909: 
        !          10910: ////////
        !          10911: /
        !          10912: / mm_so - stand out - define 40 column attributes
        !          10913: /
        !          10914: ////////
        !          10915: 
        !          10916: mm_so:
        !          10917:        cmp     MM_PORT(bp), $0x3D4     / if color card
        !          10918:        jne     mm_si
        !          10919: 
        !          10920:        mov     MM_NCOL(bp), $40        /       setup for 40 column color
        !          10921:        movb    MM_MODE(bp), $0x20
        !          10922:        mov     MM_DATA(bp), $creg40
        !          10923: 
        !          10924: #ifdef ATI_132
        !          10925:        mov     dx, $0x3DF              /       clear 132 column color
        !          10926:        movb    al, $0x00               /       in mode select register
        !          10927:        outb    dx, al                  /       [delay between i/o]
        !          10928: #endif
        !          10929: 
        !          10930:        call    newcrt                  / program crt registers
        !          10931:        jmp     reinit
        !          10932: 
        !          10933: ////////
        !          10934: /
        !          10935: / mm_si - define 80 column attributes
        !          10936: /
        !          10937: ////////
        !          10938: 
        !          10939: mm_si:
        !          10940:        cmp     MM_PORT(bp), $0x3D4     / if color card
        !          10941:        jne     0f
        !          10942: 
        !          10943:        mov     MM_NCOL(bp), $80
        !          10944:        movb    MM_MODE(bp), $0x21
        !          10945:        mov     MM_DATA(bp), $creg80
        !          10946: 
        !          10947: #ifdef ATI_132
        !          10948:        mov     dx, $0x3DF              /       clear 132 column color
        !          10949:        movb    al, $0x00               /       in mode select register
        !          10950:        outb    dx, al                  /       [delay between i/o]
        !          10951: #endif
        !          10952: 
        !          10953:        call    newcrt                  /       reprogram crt registers.
        !          10954:        jmp     reinit
        !          10955: 
        !          10956: 0:     mov     MM_NCOL(bp), $80
        !          10957:        mov     MM_DATA(bp), $mreg80
        !          10958:        movb    MM_MODE(bp), $0x21
        !          10959: 
        !          10960: #ifdef ATI_132
        !          10961:        mov     dx, $0x3BA              /       clear 132 column monochrome
        !          10962:        movb    al, $0x00               /       in mode select register
        !          10963:        outb    dx, al                  /       [delay between i/o]
        !          10964: #endif
        !          10965: 
        !          10966:        call    newcrt                  /       reprogram crt registers
        !          10967:        jmp     reinit
        !          10968: 
        !          10969: ////////
        !          10970: /
        !          10971: / mm_132 - define 132 column attributes
        !          10972: /
        !          10973: ////////
        !          10974: 
        !          10975: mm_132:
        !          10976:        cmp     MM_PORT(bp), $0x3D4     / if color card
        !          10977:        jne     0f
        !          10978: 
        !          10979: #ifdef ATI_132
        !          10980:        mov     MM_DATA(bp), $creg132   /       set color crt values
        !          10981:        mov     MM_NCOL(bp), $132       /       set columns to 132
        !          10982:        movb    MM_MODE(bp), $0x21
        !          10983: 
        !          10984:        call    newcrt                  /       set 132 column crt values
        !          10985:                                        /       BEFORE setting mode select reg
        !          10986: 
        !          10987:        mov     dx, $0x3DF              /       set 132 columns
        !          10988:        movb    al, $0x10               /               in mode select register
        !          10989:        outb    dx, al
        !          10990: #endif
        !          10991:        jmp     reinit
        !          10992: 
        !          10993: 0:
        !          10994: #ifdef ATI_132
        !          10995:        mov     MM_NCOL(bp), $132       /       set columns to 132
        !          10996:        movb    MM_MODE(bp), $0x21      /       set 80/132 column display mode
        !          10997:        mov     MM_DATA(bp), $mreg132   /       set monochrome crt values
        !          10998: 
        !          10999:        call    newcrt                  /       set 132 column crt values
        !          11000:                                        /       BEFORE setting mode select reg
        !          11001: 
        !          11002:        mov     dx, $0x3BA              /       set 132 columns monochrome
        !          11003:        movb    al, $0x08               /               in mode select register
        !          11004:        outb    dx, al
        !          11005: #endif
        !          11006:        jmp     reinit
        !          11007: 
        !          11008: ////////
        !          11009: /
        !          11010: / mmspec - schedule special keyboard function
        !          11011: /
        !          11012: ////////
        !          11013: 
        !          11014: mmspec:        movb    ss:mmesc_, al
        !          11015:        jmp     eval
        !          11016: 
        !          11017: ////////
        !          11018: /
        !          11019: / mmbell - schedule beep
        !          11020: /
        !          11021: ////////
        !          11022: 
        !          11023: mmbell:        movb    ss:mmbeeps_, $-1
        !          11024:        jmp     eval
        !          11025: 
        !          11026: ////////
        !          11027: /
        !          11028: / mm_cnl - cursor next line
        !          11029: /
        !          11030: /      Moves the active position to the first column of the next display line.
        !          11031: /      Scrolls the active display if necessary.
        !          11032: /
        !          11033: ////////
        !          11034: 
        !          11035: mm_cnl:        subb    COL, COL
        !          11036:        incb    ROW
        !          11037:        cmpb    ROW, MM_EROW(bp)
        !          11038:        jna     repos
        !          11039:        movb    ROW, MM_EROW(bp)
        !          11040: /      jmp     scrollup
        !          11041: 
        !          11042: ////////
        !          11043: /
        !          11044: / scrollup - scroll display upwards
        !          11045: /
        !          11046: ////////
        !          11047: 
        !          11048: scrollup:
        !          11049:        push    ds
        !          11050:        push    si
        !          11051:        push    cx
        !          11052:        mov     ds, MM_BASE(bp)
        !          11053:        movb    bl, MM_BROW(bp)
        !          11054:        shlb    bl, $1
        !          11055:        mov     di, ss:rowtab(bx)
        !          11056:        mov     si, ss:rowtab+2(bx)
        !          11057:        movb    bl, ROW
        !          11058:        shlb    bl, $1
        !          11059:        mov     cx, ss:rowtab(bx)
        !          11060:        push    cx
        !          11061:        sub     cx, di
        !          11062:        shr     cx, $1
        !          11063:        cld
        !          11064:        rep
        !          11065:        movsw
        !          11066:        movb    al, $SPACE
        !          11067:        pop     di
        !          11068:        mov     cx, MM_NCOL(bp)
        !          11069:        rep
        !          11070:        stosw
        !          11071:        pop     cx
        !          11072:        pop     si
        !          11073:        pop     ds
        !          11074:        movb    bl, COL                 / reposition to ROW and COL
        !          11075:        shlb    bl, $1
        !          11076:        mov     POS, cs:coltab(bx)
        !          11077:        movb    bl, ROW
        !          11078:        shlb    bl, $1
        !          11079:        add     POS, ss:rowtab(bx)
        !          11080:        call    exit
        !          11081:        jmp     eval
        !          11082: 
        !          11083: ////////
        !          11084: /
        !          11085: / repos - reposition cursor
        !          11086: /
        !          11087: ////////
        !          11088: 
        !          11089: repos: movb    bl, COL                 / reposition to ROW and COL
        !          11090:        shl     bx, $1                  / [trash BH]
        !          11091:        mov     POS, cs:coltab(bx)
        !          11092:        subb    bh, bh                  / [clear BH]
        !          11093:        movb    bl, ROW
        !          11094:        shlb    bl, $1
        !          11095:        add     POS, ss:rowtab(bx)
        !          11096: /      jmp     eval
        !          11097: 
        !          11098: ////////
        !          11099: /
        !          11100: / eval - evaluate input character
        !          11101: /
        !          11102: ////////
        !          11103: 
        !          11104: eval:  jcxz    ewait
        !          11105:        dec     cx                              / evaluate next char
        !          11106:        lodsb
        !          11107:        movb    bl, al
        !          11108:        shlb    bl, $1
        !          11109:        ijmp    cs:asctab(bx)
        !          11110: 
        !          11111: ////////
        !          11112: /
        !          11113: / mmputc - put character on screen
        !          11114: /
        !          11115: ////////
        !          11116: 
        !          11117: mmputc:        stosw
        !          11118:        incb    COL
        !          11119:        cmpb    COL, MM_NCOL(bp)
        !          11120:        jnb     0f
        !          11121:        jcxz    ewait
        !          11122:        dec     cx
        !          11123:        lodsb
        !          11124:        movb    bl, al
        !          11125:        shlb    bl, $1
        !          11126:        ijmp    cs:asctab(bx)
        !          11127: 
        !          11128: 0:     subb    COL, COL
        !          11129:        incb    ROW
        !          11130:        cmpb    ROW, MM_EROW(bp)
        !          11131:        jg      0f
        !          11132:        jcxz    ewait
        !          11133:        dec     cx
        !          11134:        lodsb
        !          11135:        movb    bl, al
        !          11136:        shlb    bl, $1
        !          11137:        ijmp    cs:asctab(bx)
        !          11138: 
        !          11139: 0:     movb    ROW, MM_EROW(bp)
        !          11140:        jmp     scrollup
        !          11141: 
        !          11142: ////////
        !          11143: /
        !          11144: / Ewait - wait for next input char to evaluate
        !          11145: /
        !          11146: ////////
        !          11147: 
        !          11148: ewait: call    exit
        !          11149:        jcxz    ewait
        !          11150:        dec     cx
        !          11151:        lodsb
        !          11152:        movb    bl, al
        !          11153:        shlb    bl, $1
        !          11154:        ijmp    cs:asctab(bx)
        !          11155: 
        !          11156: ////////
        !          11157: /
        !          11158: / mm_cr - carriage return
        !          11159: /
        !          11160: /      Moves the active position to first position of current display line.
        !          11161: /
        !          11162: ////////
        !          11163: 
        !          11164: mm_cr: subb    COL, COL
        !          11165:        movb    bl, ROW
        !          11166:        shlb    bl, $1
        !          11167:        mov     POS, ss:rowtab(bx)
        !          11168:        jcxz    ewait
        !          11169:        dec     cx
        !          11170:        lodsb
        !          11171:        movb    bl, al
        !          11172:        shlb    bl, $1
        !          11173:        ijmp    cs:asctab(bx)
        !          11174: 
        !          11175: ////////
        !          11176: /
        !          11177: / mm_cub - cursor backwards
        !          11178: /
        !          11179: ////////
        !          11180: 
        !          11181: mm_cub:        sub     POS, $2
        !          11182:        subb    COL, $1
        !          11183:        jnb     0f
        !          11184:        movb    COL, MM_NCOL(bp)
        !          11185:        decb    COL
        !          11186:        decb    ROW
        !          11187:        cmpb    ROW, MM_BROW(bp)
        !          11188:        jge     0f
        !          11189:        subb    COL, COL
        !          11190:        movb    ROW, MM_BROW(bp)
        !          11191:        movb    bl, ROW
        !          11192:        shlb    bl, $1
        !          11193:        mov     POS, ss:rowtab(bx)
        !          11194: 0:     jcxz    ewait
        !          11195:        dec     cx
        !          11196:        lodsb
        !          11197:        movb    bl, al
        !          11198:        shlb    bl, $1
        !          11199:        ijmp    cs:asctab(bx)
        !          11200: 
        !          11201: ////////
        !          11202: /
        !          11203: / Esc state - entered when last char was ESC - transient state.
        !          11204: /
        !          11205: ////////
        !          11206: 
        !          11207: 0:     call    exit
        !          11208: mm_esc:        jcxz    0b
        !          11209:        dec     cx
        !          11210:        lodsb
        !          11211:        movb    MM_N1(bp), ZERO
        !          11212:        movb    MM_N2(bp), ZERO
        !          11213:        movb    bl, al
        !          11214:        shlb    bl, $1
        !          11215:        jc      mmputc
        !          11216:        ijmp    cs:esctab(bx)
        !          11217: 
        !          11218: ////////
        !          11219: /
        !          11220: / Csi_n1 state - entered when last two chars were ESC [
        !          11221: /
        !          11222: /      Action: Evaluates numeric chars as numeric parameter 1.
        !          11223: /
        !          11224: ////////
        !          11225: 
        !          11226: 0:     call    exit
        !          11227: csi_n1:        jcxz    0b
        !          11228:        dec     cx
        !          11229:        lodsb
        !          11230:        cmpb    al, $SEMIC
        !          11231:        je      csi_n2
        !          11232:        movb    bl, al
        !          11233:        subb    bl, $AZERO
        !          11234:        cmpb    bl, $9
        !          11235:        ja      csival
        !          11236:        shlb    MM_N1(bp), $1   / n1 * 2
        !          11237:        movb    al, MM_N1(bp)   / n1 * 2
        !          11238:        shlb    al, $1          / n1 * 4
        !          11239:        shlb    al, $1          / n1 * 8
        !          11240:        addb    al, MM_N1(bp)   / n1 * 10
        !          11241:        addb    al, bl          / n1 * 10 + digit
        !          11242:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          11243:        jmp     csi_n1
        !          11244: 
        !          11245: ////////
        !          11246: /
        !          11247: / Csi_n2 state - entered after input sequence ESC [ n ;
        !          11248: /
        !          11249: ////////
        !          11250: 
        !          11251: 0:     call    exit
        !          11252: csi_n2:        jcxz    0b
        !          11253:        dec     cx
        !          11254:        lodsb
        !          11255:        movb    bl, al
        !          11256:        subb    bl, $AZERO
        !          11257:        cmpb    bl, $9
        !          11258:        ja      csival
        !          11259:        shlb    MM_N2(bp), $1   / n2 * 2
        !          11260:        movb    al, MM_N2(bp)   / n2 * 2
        !          11261:        shlb    al, $1          / n2 * 4
        !          11262:        shlb    al, $1          / n2 * 8
        !          11263:        addb    al, MM_N2(bp)   / n2 * 10
        !          11264:        addb    al, bl          / n2 * 10 + digit
        !          11265:        movb    MM_N2(bp), al   / n2 = (n2 * 10) + digit
        !          11266:        jmp     csi_n2
        !          11267: 
        !          11268: csival:        movb    bl, al
        !          11269:        shlb    bl, $1
        !          11270:        ijmp    cs:csitab(bx)
        !          11271: 
        !          11272: ////////
        !          11273: /
        !          11274: / Csi_gt state - entered after input sequence ESC [ >
        !          11275: /      
        !          11276: ////////
        !          11277: 
        !          11278: 0:     call    exit
        !          11279: csi_gt:        jcxz    0b
        !          11280:        dec     cx
        !          11281:        lodsb
        !          11282:        movb    bl, al
        !          11283:        subb    bl, $AZERO
        !          11284:        cmpb    bl, $9
        !          11285:        ja      1f
        !          11286:        shlb    MM_N1(bp), $1   / n1 * 2
        !          11287:        movb    al, MM_N1(bp)   / n1 * 2
        !          11288:        shlb    al, $1          / n1 * 4
        !          11289:        shlb    al, $1          / n1 * 8
        !          11290:        addb    al, MM_N1(bp)   / n1 * 10
        !          11291:        addb    al, bl          / n1 * 10 + digit
        !          11292:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          11293:        jmp     csi_gt
        !          11294: 
        !          11295: 1:     movb    bl, al
        !          11296:        shlb    bl, $1
        !          11297:        ijmp    cs:csgtab(bx)
        !          11298: 
        !          11299: ////////
        !          11300: /
        !          11301: / mm_cbt - cursor backward tabulation
        !          11302: /
        !          11303: /      Moves the active position horizontally in the backward direction
        !          11304: /      to the preceding in a series of predetermined positions.
        !          11305: /
        !          11306: ////////
        !          11307: 
        !          11308: mm_cbt:        orb     COL, $7                 / calculate next tab stop
        !          11309:        incb    COL
        !          11310:        subb    COL, $16                / step back two tab positions
        !          11311:        jnb     0f
        !          11312:        subb    COL, COL                / cannot step past column 0
        !          11313: 0:     jmp     repos                   / reposition cursor
        !          11314: 
        !          11315: ////////
        !          11316: /
        !          11317: / mm_cgh - process ESC [ > N1 h escape sequence
        !          11318: /
        !          11319: /      Recognized sequences:   ESC [ > 13 h    -- Set CRT saver enabled.
        !          11320: /
        !          11321: ////////
        !          11322: 
        !          11323: mm_cgh:        cmpb    MM_N1(bp), $13
        !          11324:        jne     0f
        !          11325:        mov     ss:mmcrtsav_, $1
        !          11326: 0:     jmp     eval
        !          11327: 
        !          11328: ////////
        !          11329: /
        !          11330: / mm_cgl - process ESC [ > N1 l escape sequence
        !          11331: /
        !          11332: /      Recognized sequences:   ESC [ > 13 l    -- Reset CRT saver.
        !          11333: /
        !          11334: ////////
        !          11335: 
        !          11336: mm_cgl:        cmpb    MM_N1(bp), $13
        !          11337:        jne     0f
        !          11338:        mov     ss:mmcrtsav_, $0
        !          11339: 0:     jmp     eval
        !          11340: 
        !          11341: ////////
        !          11342: /
        !          11343: / mm_cha - cursor horizontal absolute
        !          11344: /
        !          11345: /      Advances the active position forward or backward along the active line
        !          11346: /      to the character position specified by the parameter.
        !          11347: /      A parameter value of zero or one moves the active position to the
        !          11348: /      first character position of the active line.
        !          11349: /      A parameter value of N moves the active position to character position
        !          11350: /      N of the active line.
        !          11351: /
        !          11352: ////////
        !          11353: 
        !          11354: mm_cha:        movb    COL, MM_N1(bp)
        !          11355:        orb     COL, COL
        !          11356:        je      0f
        !          11357:        decb    COL
        !          11358: 0:     cmpb    COL, MM_NCOL(bp)
        !          11359:        jb      0f
        !          11360:        movb    COL, MM_NCOL(bp)
        !          11361:        decb    COL
        !          11362: 0:     jmp     repos                   / reposition cursor
        !          11363: 
        !          11364: 
        !          11365: ////////
        !          11366: /
        !          11367: / mm_cht - cursor horizontal tabulation
        !          11368: /
        !          11369: /      Advances the active position horizontally to the next or following
        !          11370: /      in a series of predetermined positions.
        !          11371: /
        !          11372: ////////
        !          11373: 
        !          11374: mm_cht:        push    cx
        !          11375:        sub     cx, cx
        !          11376:        movb    cl, COL
        !          11377:        orb     cl, $7
        !          11378:        incb    cl
        !          11379:        subb    cl, COL
        !          11380:        addb    COL, cl
        !          11381:        movb    al, $SPACE
        !          11382:        rep
        !          11383:        stosw
        !          11384:        pop     cx
        !          11385:        cmpb    COL, MM_NCOL(bp)
        !          11386:        jb      0f
        !          11387:        subb    COL, MM_NCOL(bp)
        !          11388:        incb    ROW
        !          11389:        cmpb    ROW, MM_EROW(bp)
        !          11390:        jna     0f
        !          11391:        movb    ROW, MM_EROW(bp)
        !          11392:        jmp     scrollup
        !          11393: 0:     jmp     eval
        !          11394: 
        !          11395: ////////
        !          11396: /
        !          11397: / mm_cpl - cursor preceding line
        !          11398: /
        !          11399: /      Moves the active position to the first position of the preceding
        !          11400: /      display line.
        !          11401: /
        !          11402: ////////
        !          11403: 
        !          11404: mm_cpl:        subb    COL, COL
        !          11405:        decb    ROW
        !          11406:        cmpb    ROW, MM_BROW(bp)
        !          11407:        jnb     0f
        !          11408:        movb    ROW, MM_BROW(bp)
        !          11409:        jmp     scrolldown
        !          11410: 0:     jmp     repos                   / reposition cursor
        !          11411: 
        !          11412: ////////
        !          11413: /
        !          11414: / mm_cud - cursor down
        !          11415: /
        !          11416: /      Moves the active position downward without altering the
        !          11417: /      horizontal position.
        !          11418: /
        !          11419: ////////
        !          11420: 
        !          11421: mm_cud:        incb    ROW
        !          11422:        cmpb    ROW, MM_EROW(bp)
        !          11423:        jna     0f
        !          11424:        movb    ROW, MM_EROW(bp)
        !          11425: 0:     jmp     repos                   / reposition cursor
        !          11426: 
        !          11427: ////////
        !          11428: /
        !          11429: / mm_cuf - cursor forward
        !          11430: /
        !          11431: /      Moves the active position in the forward direction.
        !          11432: /
        !          11433: ////////
        !          11434: 
        !          11435: mm_cuf:        incb    COL
        !          11436:        cmpb    COL, MM_NCOL(bp)
        !          11437:        jb      0f
        !          11438:        subb    COL, MM_NCOL(bp)
        !          11439:        incb    ROW
        !          11440:        cmpb    ROW, MM_EROW(bp)
        !          11441:        jna     0f
        !          11442:        movb    ROW, MM_EROW(bp)
        !          11443:        movb    COL, MM_NCOL(bp)
        !          11444:        decb    COL
        !          11445: 0:     jmp     repos
        !          11446: 
        !          11447: ////////
        !          11448: /
        !          11449: / mm_cup - cursor position
        !          11450: /
        !          11451: /      Moves the active position to the position specified by two parameters.
        !          11452: /      The 1st parameter (mm_n1) specifies the vertical   position MM_ROW(bp).
        !          11453: /      The 2nd parameter (mm_n2) specifies the horizontal position MM_COL(bp).
        !          11454: /      A parameter value of 0 or 1 for the first or second parameter
        !          11455: /      moves the active position to the first line or column in the
        !          11456: /      display respectively.
        !          11457: /
        !          11458: ////////
        !          11459: 
        !          11460: mm_cup:        movb    ROW, MM_N1(bp)
        !          11461:        orb     ROW, ROW
        !          11462:        je      0f
        !          11463:        decb    ROW
        !          11464: 0:     addb    ROW, MM_BROW(bp)
        !          11465:        cmpb    ROW, MM_EROW(bp)
        !          11466:        jb      0f
        !          11467:        movb    ROW, MM_EROW(bp)
        !          11468: 0:     movb    COL, MM_N2(bp)
        !          11469:        orb     COL, COL
        !          11470:        je      0f
        !          11471:        decb    COL
        !          11472: 0:     cmpb    COL, MM_NCOL(bp)
        !          11473:        jb      0f
        !          11474:        movb    COL, MM_NCOL(bp)
        !          11475:        decb    COL
        !          11476: 0:     jmp     repos                   / reposition cursor
        !          11477: 
        !          11478: ////////
        !          11479: /
        !          11480: / mm_cuu - cursor up
        !          11481: /
        !          11482: /      Moves the active position upward without altering the horizontal
        !          11483: /      position.
        !          11484: /
        !          11485: ////////
        !          11486: 
        !          11487: mm_cuu:        decb    ROW
        !          11488:        cmpb    ROW, MM_BROW(bp)
        !          11489:        jge     0f
        !          11490:        movb    ROW, MM_BROW(bp)
        !          11491: 0:     jmp     repos                   / reposition cursor
        !          11492: 
        !          11493: ////////
        !          11494: /
        !          11495: / mm_dl - delete line
        !          11496: /
        !          11497: /      Removes the contents of the active line.
        !          11498: /      The contents of all following lines are shifted in a block
        !          11499: /      toward the active line.
        !          11500: /
        !          11501: ////////
        !          11502: 
        !          11503: mm_dl: push    ds
        !          11504:        push    si
        !          11505:        push    cx
        !          11506:        mov     ds, MM_BASE(bp)
        !          11507:        movb    bl, ROW
        !          11508:        shlb    bl, $1
        !          11509:        mov     di, ss:rowtab(bx)
        !          11510:        mov     si, ss:rowtab+2(bx)
        !          11511:        movb    bl, MM_EROW(bp)
        !          11512:        shlb    bl, $1
        !          11513:        mov     cx, ss:rowtab(bx)
        !          11514:        sub     cx, di
        !          11515:        jle     0f
        !          11516:        shr     cx, $1
        !          11517:        rep
        !          11518:        movsw
        !          11519:        mov     di, ss:rowtab(bx)
        !          11520:        mov     cx, MM_NCOL(bp)
        !          11521:        movb    al, $SPACE
        !          11522:        rep
        !          11523:        stosw
        !          11524:        subb    COL, COL
        !          11525:        movb    bl, ROW
        !          11526:        shlb    bl, $1
        !          11527:        mov     di, ss:rowtab(bx)
        !          11528: 0:     pop     cx
        !          11529:        pop     si
        !          11530:        pop     ds
        !          11531:        call    exit
        !          11532:        jmp     eval
        !          11533: 
        !          11534: ////////
        !          11535: /
        !          11536: / mm_dmi - disable manual input
        !          11537: /
        !          11538: /      Set flag preventing keyboard input, and causing cursor to vanish.
        !          11539: /
        !          11540: ////////
        !          11541: 
        !          11542: mm_dmi:
        !          11543:        mov     ss:islock_, $1
        !          11544:        jmp     eval
        !          11545: 
        !          11546: ////////
        !          11547: /
        !          11548: / mm_ea - erase in area
        !          11549: /
        !          11550: /      Erase some or all of the characters in the currently active area
        !          11551: /      according to the parameter:
        !          11552: /              0 - erase from active position to end inclusive (default)
        !          11553: /              1 - erase from start to active position inclusive
        !          11554: /              2 - erase all of active area
        !          11555: /
        !          11556: ////////
        !          11557: 
        !          11558: mm_ea: movb    al, MM_N1(bp)
        !          11559:        cmpb    al, $0
        !          11560:        jne     0f
        !          11561:        movb    bl, MM_EROW(bp)
        !          11562:        jmp     mm_e0
        !          11563: 0:     cmpb    al, $1
        !          11564:        jne     0f
        !          11565:        movb    bl, MM_BROW(bp)
        !          11566:        jmp     mm_e1
        !          11567: 0:     subb    COL, COL
        !          11568:        movb    ROW, MM_BROW(bp)
        !          11569:        movb    bl, ROW
        !          11570:        shlb    bl, $1
        !          11571:        mov     POS, ss:rowtab(bx)
        !          11572:        movb    bl, MM_EROW(bp)
        !          11573:        subb    bl, ROW
        !          11574:        jmp     mm_e2
        !          11575: 
        !          11576: 
        !          11577: ////////
        !          11578: /
        !          11579: / mm_ed - erase in display
        !          11580: /
        !          11581: /      Erase some or all of the characters in the display according to the
        !          11582: /      parameter
        !          11583: /              0 - erase from active position to end inclusive (default)
        !          11584: /              1 - erase from start to active position inclusive
        !          11585: /              2 - erase all of display
        !          11586: /
        !          11587: ////////
        !          11588: 
        !          11589: mm_ed: movb    al, MM_N1(bp)
        !          11590:        cmpb    al, $0
        !          11591:        jne     0f
        !          11592:        movb    bl, MM_LROW(bp)
        !          11593:        jmp     mm_e0
        !          11594: 0:     cmpb    al, $1
        !          11595:        jne     0f
        !          11596:        subb    bl, bl
        !          11597:        jmp     mm_e1
        !          11598: 0:     subb    COL, COL
        !          11599:        movb    ROW, MM_BROW(bp)
        !          11600:        sub     POS, POS
        !          11601:        movb    bl, MM_LROW(bp)
        !          11602:        jmp     mm_e2
        !          11603: 
        !          11604: ////////
        !          11605: /
        !          11606: / mm_el - erase in line
        !          11607: /
        !          11608: /      Erase some or all of the characters in the line according to the
        !          11609: /      parameter:
        !          11610: /              0 - erase from active position to end inclusive (default)
        !          11611: /              1 - erase from start to active position inclusive
        !          11612: /              2 - erase entire line
        !          11613: /
        !          11614: ////////
        !          11615: 
        !          11616: mm_el: movb    al, MM_N1(bp)
        !          11617:        movb    bl, ROW
        !          11618:        cmpb    al, $0
        !          11619:        je      mm_e0
        !          11620:        cmpb    al, $1
        !          11621:        je      mm_e1
        !          11622:        shlb    bl, $1
        !          11623:        mov     POS, ss:rowtab(bx)
        !          11624:        subb    COL, COL
        !          11625:        subb    bl, bl
        !          11626: /      jmp     mm_e2
        !          11627: 
        !          11628: mm_e2: push    cx
        !          11629:        movb    al, $SPACE
        !          11630: 0:     mov     cx, MM_NCOL(bp)
        !          11631:        rep
        !          11632:        stosw
        !          11633:        decb    bl
        !          11634:        jge     0b
        !          11635:        pop     cx
        !          11636:        jmp     repos
        !          11637: 
        !          11638: mm_e1: push    cx
        !          11639:        mov     cx, POS
        !          11640:        shlb    bl, $1
        !          11641:        mov     POS, ss:rowtab(bx)
        !          11642:        sub     cx, POS
        !          11643:        jl      0f
        !          11644:        movb    al, $SPACE
        !          11645:        shr     cx, $1
        !          11646:        rep
        !          11647:        stosw
        !          11648: 0:     pop     cx
        !          11649:        jmp     repos
        !          11650: 
        !          11651: mm_e0: push    cx
        !          11652:        shlb    bl, $1
        !          11653:        mov     cx, ss:rowtab+2(bx)
        !          11654:        sub     cx, POS
        !          11655:        jl      0f
        !          11656:        movb    al, $SPACE
        !          11657:        shr     cx, $1
        !          11658:        rep
        !          11659:        stosw
        !          11660: 0:     pop     cx
        !          11661:        jmp     repos
        !          11662: 
        !          11663: ////////
        !          11664: /
        !          11665: / mm_emi - enable manual input
        !          11666: /
        !          11667: /      Clear flag preventing keyboard input.
        !          11668: /
        !          11669: ////////
        !          11670: 
        !          11671: mm_emi:
        !          11672:        mov     ss:islock_, $0
        !          11673:        jmp     eval
        !          11674: 
        !          11675: ////////
        !          11676: /
        !          11677: / mm_il - insert line
        !          11678: /
        !          11679: /      Insert a erased line at the active line by shifting the contents
        !          11680: /      of the active line and all following lines away from the active line.
        !          11681: /      The contents of the last line in the scrolling region are removed.
        !          11682: /
        !          11683: ////////
        !          11684: 
        !          11685: scrolldown:
        !          11686: mm_il: push    ds
        !          11687:        push    si
        !          11688:        push    cx
        !          11689:        mov     ds, MM_BASE(bp)
        !          11690:        movb    bl, MM_EROW(bp)
        !          11691:        shlb    bl, $1
        !          11692:        mov     si, ss:rowtab(bx)
        !          11693:        mov     cx, si
        !          11694:        sub     si, $2
        !          11695:        mov     di, ss:rowtab+2(bx)
        !          11696:        sub     di, $2
        !          11697:        movb    bl, ROW
        !          11698:        shlb    bl, $1
        !          11699:        sub     cx, ss:rowtab(bx)
        !          11700:        jle     0f
        !          11701:        shr     cx, $1
        !          11702:        std
        !          11703:        rep
        !          11704:        movsw
        !          11705:        mov     di, ss:rowtab(bx)
        !          11706:        mov     cx, MM_NCOL(bp)
        !          11707:        movb    al, $SPACE
        !          11708:        cld
        !          11709:        rep
        !          11710:        stosw
        !          11711:        subb    COL, COL
        !          11712:        movb    bl, ROW
        !          11713:        shlb    bl, $1
        !          11714:        mov     di, ss:rowtab(bx)
        !          11715: 0:     pop     cx
        !          11716:        pop     si
        !          11717:        pop     ds
        !          11718:        call    exit
        !          11719:        jmp     eval
        !          11720: 
        !          11721: ////////
        !          11722: /
        !          11723: / mm_hpa - horizontal position absolute
        !          11724: /
        !          11725: /      Moves the active position within the active line to the position
        !          11726: /      specified by the parameter.  A parameter value of zero or one
        !          11727: /      moves the active position to the first position of the active line.
        !          11728: /
        !          11729: ////////
        !          11730: 
        !          11731: mm_hpa:        movb    COL, MM_N1(bp)
        !          11732:        orb     COL, COL
        !          11733:        je      0f
        !          11734:        decb    COL
        !          11735: 0:     cmpb    COL, MM_NCOL(bp)
        !          11736:        jb      0f
        !          11737:        movb    COL, MM_NCOL(bp)
        !          11738:        decb    COL
        !          11739: 0:     jmp     repos                   / reposition cursor
        !          11740: 
        !          11741: ////////
        !          11742: /
        !          11743: / mm_hpr - horizontal position relative
        !          11744: /
        !          11745: /      Moves the active position forward the number of positions specified
        !          11746: /      by the parameter.  A parameter value of zero or one indicates a
        !          11747: /      single-position move.
        !          11748: /
        !          11749: ////////
        !          11750: 
        !          11751: mm_hpr:        movb    al, MM_N1(bp)
        !          11752:        orb     al, al
        !          11753:        jne     0f
        !          11754:        incb    al
        !          11755: 0:     addb    COL, al
        !          11756:        cmpb    COL, MM_NCOL(bp)
        !          11757:        jb      0f
        !          11758:        movb    COL, MM_NCOL(bp)
        !          11759:        decb    COL
        !          11760: 0:     jmp     repos                   / reposition cursor
        !          11761: 
        !          11762: ////////
        !          11763: /
        !          11764: / mm_hvp - horizontal and vertical position
        !          11765: /
        !          11766: /      Moves the active position to the position specified by two parameters.
        !          11767: /      The first parameter specifies the vertical position (MM_ROW(bp)).
        !          11768: /      The second parameter specifies the horizontal position (MM_COL(bp)).
        !          11769: /      A parameter value of zero or one moves the active position to the
        !          11770: /      first line or column in the display.
        !          11771: /
        !          11772: ////////
        !          11773: 
        !          11774: mm_hvp:        movb    ROW, MM_N1(bp)
        !          11775:        orb     ROW, ROW
        !          11776:        je      0f
        !          11777:        decb    ROW
        !          11778: 0:     cmpb    ROW, MM_LROW(bp)
        !          11779:        jna     0f
        !          11780:        movb    ROW, MM_LROW(bp)
        !          11781: 0:     movb    COL, MM_N2(bp)
        !          11782:        orb     COL, COL
        !          11783:        je      0f
        !          11784:        decb    COL
        !          11785: 0:     cmpb    COL, MM_NCOL(bp)
        !          11786:        jb      0f
        !          11787:        movb    COL, MM_NCOL(bp)
        !          11788:        decb    COL
        !          11789: 0:     jmp     repos                   / reposition cursor
        !          11790: 
        !          11791: ////////
        !          11792: /
        !          11793: / mm_ind - index
        !          11794: /
        !          11795: /      Causes the active position to move downward one line without changing
        !          11796: /      the horizontal position.  Scrolling occurs if below scrolling region.
        !          11797: /
        !          11798: ////////
        !          11799: 
        !          11800: mm_ind:        incb    ROW
        !          11801:        cmpb    ROW, MM_EROW(bp)
        !          11802:        jg      0f
        !          11803:        jmp     repos
        !          11804: 0:     movb    ROW, MM_EROW(bp)
        !          11805:        jmp     scrollup
        !          11806: 
        !          11807: ////////
        !          11808: /
        !          11809: / mm_new - save cursor position
        !          11810: /
        !          11811: ////////
        !          11812: 
        !          11813: mm_new:        movb    MM_SCOL(bp), COL
        !          11814:        movb    MM_SROW(bp), ROW
        !          11815:        jmp     eval
        !          11816: 
        !          11817: ////////
        !          11818: /
        !          11819: / mm_old - restore old cursor position
        !          11820: /
        !          11821: ////////
        !          11822: 
        !          11823: mm_old:        movb    COL, MM_SCOL(bp)
        !          11824:        movb    ROW, MM_SROW(bp)
        !          11825:        jmp     repos
        !          11826: 
        !          11827: ////////
        !          11828: /
        !          11829: / mm_ri - reverse index
        !          11830: /
        !          11831: /      Moves the active position to the same horizontal position on the
        !          11832: /      preceding line.  Scrolling occurs if above scrolling region.
        !          11833: /
        !          11834: ////////
        !          11835: 
        !          11836: mm_ri: decb    ROW
        !          11837:        cmpb    ROW, MM_BROW(bp)
        !          11838:        jge     0f
        !          11839:        movb    ROW, MM_BROW(bp)
        !          11840:        jmp     scrolldown
        !          11841: 0:     jmp     repos
        !          11842: 
        !          11843: ////////
        !          11844: /
        !          11845: / mm_scr - select cursor rendition
        !          11846: /
        !          11847: /      Invokes the cursor rendition specified by the parameter.
        !          11848: /
        !          11849: /      Recognized renditions are:      0 - cursor visible
        !          11850: /                                      1 - cursor invisible
        !          11851: ////////
        !          11852: 
        !          11853: mm_scr:        decb     MM_N1(bp)
        !          11854:        je      0f
        !          11855:        jg      1f
        !          11856:        mov     MM_INVIS(bp), $0
        !          11857:        jmp     eval
        !          11858: 
        !          11859: 0:     mov     MM_INVIS(bp), $-1
        !          11860: 1:     jmp     eval
        !          11861: 
        !          11862: ////////
        !          11863: /
        !          11864: / mm_sgr - select graphic rendition
        !          11865: /
        !          11866: /      Invokes the graphic rendition specified by the parameter.
        !          11867: /      All following characters in the data stream are rendered
        !          11868: /      according to the parameters until the next occurrence of
        !          11869: /      SGR in the data stream.
        !          11870: /
        !          11871: /      Recognized renditions are:      1 - high intensity
        !          11872: /                                      4 - underline
        !          11873: /                                      5 - slow blink
        !          11874: /                                      7 - reverse video
        !          11875: /                                      30-37 - foreground color
        !          11876: /                                      40-47 - background color
        !          11877: /                                      50-57 - border color
        !          11878: /
        !          11879: ////////
        !          11880: 
        !          11881: mm_sgr:        movb    al, MM_N1(bp)
        !          11882:        cmpb    al, $0
        !          11883:        jne     0f
        !          11884:        movb    ATTR, $0x07
        !          11885: 1:     jmp     eval
        !          11886: 0:     cmpb    al, $1          / bold
        !          11887:        jne     0f
        !          11888:        orb     ATTR, $INTENSE
        !          11889:        jmp     1b
        !          11890: 0:     cmpb    al, $4          / underline
        !          11891:        jne     0f
        !          11892:        cmp     MM_PORT(bp), $0x03D4    / color card?
        !          11893:        je      1b                      / yes, ignore underline
        !          11894:        andb    ATTR, $~0x77
        !          11895:        orb     ATTR, $0x01
        !          11896:        jmp     1b
        !          11897: 0:     cmpb    al, $5          / blinking
        !          11898:        jne     0f
        !          11899:        orb     ATTR, $BLINK
        !          11900:        jmp     1b
        !          11901: 0:     cmpb    al, $7          / reverse video
        !          11902:        jne     0f
        !          11903:        movb    al, $0x70
        !          11904:        cmp     MM_PORT(bp), $0x3D4     / color card?
        !          11905:        jne     2f
        !          11906:        movb    al, ah                  / yes, exchange foreground/background
        !          11907:        andb    al, $0x77
        !          11908:        rolb    al, $1
        !          11909:        rolb    al, $1
        !          11910:        rolb    al, $1
        !          11911:        rolb    al, $1
        !          11912: 2:     andb    ATTR, $~0x77
        !          11913:        orb     ATTR, al
        !          11914:        jmp     1b
        !          11915: 0:     cmp     MM_PORT(bp), $0x03D4    / color card?
        !          11916:        jne     1b                      / no, ignore remaining options
        !          11917: 0:     subb    al, $30         / foreground color
        !          11918:        jl      1f
        !          11919:        cmpb    al, $7
        !          11920:        jg      0f
        !          11921:        movb    bl, al
        !          11922:        andb    ATTR, $~0x07
        !          11923:        orb     ATTR, cs:fcolor(bx)
        !          11924:        jmp     1f
        !          11925: 0:     subb    al, $10
        !          11926:        jl      1f
        !          11927:        cmpb    al, $7
        !          11928:        jg      0f
        !          11929:        movb    bl, al
        !          11930:        andb    ATTR, $~0x70
        !          11931:        orb     ATTR, cs:bcolor(bx)
        !          11932:        jmp     1f
        !          11933: 0:     subb    al, $10
        !          11934:        jl      1f
        !          11935:        cmpb    al, $7
        !          11936:        jg      0f
        !          11937:        movb    bl, al
        !          11938:        movb    al, cs:fcolor(bx)
        !          11939:        push    dx
        !          11940:        mov     dx, MM_PORT(bp)
        !          11941:        add     dx, $5
        !          11942:        outb    dx, al
        !          11943:        pop     dx
        !          11944: /      jmp     1f
        !          11945: 0:
        !          11946: 1:     jmp     eval
        !          11947: 
        !          11948: ////////
        !          11949: /
        !          11950: / mm_ssr - set scrolling region
        !          11951: /
        !          11952: ////////
        !          11953: 
        !          11954: mm_ssr:        movb    al, MM_N1(bp)
        !          11955:        decb    al
        !          11956:        jge     0f
        !          11957:        subb    al, al
        !          11958: 0:     cmpb    al, MM_LROW(bp)
        !          11959:        ja      1f
        !          11960:        movb    bl, MM_N2(bp)
        !          11961:        decb    bl
        !          11962:        jge     0f
        !          11963:        subb    bl, bl
        !          11964: 0:     cmpb    bl, MM_LROW(bp)
        !          11965:        ja      1f
        !          11966:        cmpb    al, bl
        !          11967:        ja      1f
        !          11968:        movb    MM_BROW(bp), al
        !          11969:        movb    MM_EROW(bp), bl
        !          11970:        movb    ROW, al
        !          11971:        subb    COL, COL
        !          11972: 1:     jmp     repos
        !          11973: 
        !          11974: ////////
        !          11975: /
        !          11976: / mm_vpa - vertical position absolute
        !          11977: /
        !          11978: /      Moves the active position to the line specified by the parameter
        !          11979: /      without changing the horizontal position.
        !          11980: /      A parameter value of 0 or 1 moves the active position vertically
        !          11981: /      to the first line.
        !          11982: /
        !          11983: ////////
        !          11984: 
        !          11985: mm_vpa:        movb    ROW, MM_N1(bp)
        !          11986:        decb    ROW
        !          11987:        jg      0f
        !          11988:        subb    ROW, ROW
        !          11989: 0:     cmpb    ROW, MM_LROW(bp)
        !          11990:        jna     0f
        !          11991:        movb    ROW, MM_LROW(bp)
        !          11992: 0:     jmp     repos                   / reposition cursor
        !          11993: 
        !          11994: ////////
        !          11995: /
        !          11996: / mm_vpr - vertical position relative
        !          11997: /
        !          11998: /      Moves the active position downward the number of lines specified
        !          11999: /      by the parameter without changing the horizontal position.
        !          12000: /      A parameter value of zero or one moves the active position
        !          12001: /      one line downward.
        !          12002: /
        !          12003: ////////
        !          12004: 
        !          12005: mm_vpr:        movb    al, MM_N1(bp)
        !          12006:        orb     al, al
        !          12007:        jne     0f
        !          12008:        incb    al
        !          12009: 0:     addb    ROW, al
        !          12010:        cmpb    ROW, MM_LROW(bp)
        !          12011:        jb      0f
        !          12012:        movb    ROW, MM_LROW(bp)
        !          12013: 0:     jmp     repos                   / reposition cursor
        !          12014: 
        !          12015: ////////
        !          12016: /
        !          12017: / asctab - table of functions indexed by ascii characters
        !          12018: /
        !          12019: ////////
        !          12020: 
        !          12021: asctab:        .word   eval,   eval,   eval,   eval    /       NUL  SOH  STX  ETX
        !          12022:        .word   eval,   eval,   eval,   mmbell  /       EOT  ENQ  ACK  BEL
        !          12023:        .word   mm_cub, mm_cht, mm_cnl, mm_ind  /       BS   HT   LF   VT
        !          12024:        .word   eval,   mm_cr,  mm_so,  mm_si   /       FF   CR   SO   SI
        !          12025:        .word   eval,   eval,   eval,   eval    /       DLE  DC1  DC2  DC3
        !          12026: / DEBUG: mm_132 is only inserted temporarily, for testing - 86/05/26
        !          12027:        .word   eval,   eval,   eval,   mm_132  /       DC4  NAK  SYN  ETB
        !          12028:        .word   eval,   eval,   eval,   mm_esc  /       CAN  EM   SUB  ESC
        !          12029:        .word   eval,   eval,   eval,   eval    /       FS   GS   RS   US
        !          12030:        .word   mmputc, mmputc, mmputc, mmputc  /         ! dquote # \040 - \043
        !          12031:        .word   mmputc, mmputc, mmputc, mmputc  /       $ % & quote \044 - \047
        !          12032:        .word   mmputc, mmputc, mmputc, mmputc  /       ( ) * + \050 - \053
        !          12033:        .word   mmputc, mmputc, mmputc, mmputc  /       , - . / \054 - \057
        !          12034:        .word   mmputc, mmputc, mmputc, mmputc  /       0 1 2 3 \060 - \063
        !          12035:        .word   mmputc, mmputc, mmputc, mmputc  /       4 5 6 7 \064 - \067
        !          12036:        .word   mmputc, mmputc, mmputc, mmputc  /       8 9 : ; \070 - \073
        !          12037:        .word   mmputc, mmputc, mmputc, mmputc  /       < = > ? \074 - \077
        !          12038:        .word   mmputc, mmputc, mmputc, mmputc  /       @ A B C \100 - \103
        !          12039:        .word   mmputc, mmputc, mmputc, mmputc  /       D E F G \104 - \107
        !          12040:        .word   mmputc, mmputc, mmputc, mmputc  /       H I J K \110 - \113
        !          12041:        .word   mmputc, mmputc, mmputc, mmputc  /       L M N O \114 - \117
        !          12042:        .word   mmputc, mmputc, mmputc, mmputc  /       P Q R S \120 - \123
        !          12043:        .word   mmputc, mmputc, mmputc, mmputc  /       T U V W \124 - \127
        !          12044:        .word   mmputc, mmputc, mmputc, mmputc  /       X Y Z [ \130 - \133
        !          12045:        .word   mmputc, mmputc, mmputc, mmputc  /       \ ] ^ _ \134 - \137
        !          12046:        .word   mmputc, mmputc, mmputc, mmputc  /       ` a b c \140 - \143
        !          12047:        .word   mmputc, mmputc, mmputc, mmputc  /       d e f g \144 - \147
        !          12048:        .word   mmputc, mmputc, mmputc, mmputc  /       h i j k \150 - \153
        !          12049:        .word   mmputc, mmputc, mmputc, mmputc  /       l m n o \154 - \157
        !          12050:        .word   mmputc, mmputc, mmputc, mmputc  /       p q r s \160 - \163
        !          12051:        .word   mmputc, mmputc, mmputc, mmputc  /       t u v w \164 - \167
        !          12052:        .word   mmputc, mmputc, mmputc, mmputc  /       x y z { \170 - \173
        !          12053:        .word   mmputc, mmputc, mmputc, mmputc  /       | } ~ ? \174 - \177
        !          12054: 
        !          12055: ////////
        !          12056: /
        !          12057: / esctab - table of functions indexed by escape characters.
        !          12058: /
        !          12059: ////////
        !          12060: 
        !          12061: esctab:        .word   mmputc, mmputc, mmputc, mmputc  /       NUL  SOH  STX  ETX
        !          12062:        .word   mmputc, mmputc, mmputc, mmputc  /       EOT  ENQ  ACK  BEL
        !          12063:        .word   mmputc, mmputc, mmputc, mmputc  /       BS   HT   LF   VT
        !          12064:        .word   mmputc, mmputc, mmputc, mmputc  /       FF   CR   SO   SI
        !          12065:        .word   mmputc, mmputc, mmputc, mmputc  /       DLE  DC1  DC2  DC3
        !          12066:        .word   mmputc, mmputc, mmputc, mmputc  /       DC4  NAK  SYN  ETB
        !          12067:        .word   mmputc, mmputc, mmputc, mmputc  /       CAN  EM   SUB  ESC
        !          12068:        .word   mmputc, mmputc, mmputc, mmputc  /       FS   GS   RS   US
        !          12069:        .word   eval,   eval,   eval,   eval    /         ! dquote # \040 - \043
        !          12070:        .word   eval,   eval,   eval,   eval    /       $ % & quote \044 - \047
        !          12071:        .word   eval,   eval,   eval,   eval    /       ( ) * + \050 - \053
        !          12072:        .word   eval,   eval,   eval,   eval    /       , - . / \054 - \057
        !          12073:        .word   eval,   eval,   eval,   eval    /       0 1 2 3 \060 - \063
        !          12074:        .word   eval,   eval,   eval,   mm_new  /       4 5 6 7 \064 - \067
        !          12075:        .word   mm_old, eval,   eval,   eval    /       8 9 : ; \070 - \073
        !          12076:        .word   eval,   mmspec, mmspec, eval    /       < = > ? \074 - \077
        !          12077:        .word   eval,   eval,   eval,   eval    /       @ A B C \100 - \103
        !          12078:        .word   mm_ind, mm_cnl, eval,   eval    /       D E F G \104 - \107
        !          12079:        .word   eval,   eval,   eval,   eval    /       H I J K \110 - \113
        !          12080:        .word   eval,   mm_ri,  eval,   eval    /       L M N O \114 - \117
        !          12081:        .word   eval,   eval,   eval,   eval    /       P Q R S \120 - \123
        !          12082:        .word   eval,   eval,   eval,   eval    /       T U V W \124 - \127
        !          12083:        .word   eval,   eval,   eval,   csi_n1  /       X Y Z [ \130 - \133
        !          12084:        .word   eval,   eval,   eval,   eval    /       \ ] ^ _ \134 - \137
        !          12085:        .word   mm_dmi, eval,   mm_emi, mminit  /       ` a b c \140 - \143
        !          12086:        .word   eval,   eval,   eval,   eval    /       d e f g \144 - \147
        !          12087:        .word   eval,   eval,   eval,   eval    /       h i j k \150 - \153
        !          12088:        .word   eval,   eval,   eval,   eval    /       l m n o \154 - \157
        !          12089:        .word   eval,   eval,   eval,   eval    /       p q r s \160 - \163
        !          12090:        .word   mmspec, mmspec, eval,   eval    /       t u v w \164 - \167
        !          12091:        .word   eval,   eval,   eval,   eval    /       x y z { \170 - \173
        !          12092:        .word   eval,   eval,   eval,   eval    /       | } ~ ? \174 - \177
        !          12093: 
        !          12094: ////////
        !          12095: /
        !          12096: / csitab - table of functions indexed by ESC [ characters.
        !          12097: /
        !          12098: ////////
        !          12099: 
        !          12100: csitab:        .word   eval,   eval,   eval,   eval    /       NUL  SOH  STX  ETX
        !          12101:        .word   eval,   eval,   eval,   eval    /       EOT  ENQ  ACK  BEL
        !          12102:        .word   eval,   eval,   eval,   eval    /       BS   HT   LF   VT
        !          12103:        .word   eval,   eval,   eval,   eval    /       FF   CR   SO   SI
        !          12104:        .word   eval,   eval,   eval,   eval    /       DLE  DC1  DC2  DC3
        !          12105:        .word   eval,   eval,   eval,   eval    /       DC4  NAK  SYN  ETB
        !          12106:        .word   eval,   eval,   eval,   eval    /       CAN  EM   SUB  ESC
        !          12107:        .word   eval,   eval,   eval,   eval    /       FS   GS   RS   US
        !          12108:        .word   eval,   eval,   eval,   eval    /         ! dquote # \040 - \043
        !          12109:        .word   eval,   eval,   eval,   eval    /       $ % & quote \044 - \047
        !          12110:        .word   eval,   eval,   eval,   eval    /       ( ) * + \050 - \053
        !          12111:        .word   eval,   eval,   eval,   eval    /       , - . / \054 - \057
        !          12112:        .word   eval,   eval,   eval,   eval    /       0 1 2 3 \060 - \063
        !          12113:        .word   eval,   eval,   eval,   eval    /       4 5 6 7 \064 - \067
        !          12114:        .word   eval,   eval,   eval,   eval    /       8 9 : ; \070 - \073
        !          12115:        .word   eval,   eval,   csi_gt, eval    /       < = > ? \074 - \077
        !          12116:        .word   eval,   mm_cuu, mm_cud, mm_cuf  /       @ A B C \100 - \103
        !          12117:        .word   mm_cub, mm_cnl, mm_cpl, mm_cha  /       D E F G \104 - \107
        !          12118:        .word   mm_cup, mm_cht, mm_ed,  mm_el   /       H I J K \110 - \113
        !          12119:        .word   mm_il,  mm_dl,  eval,   mm_ea   /       L M N O \114 - \117
        !          12120:        .word   eval,   eval,   eval,   mm_ind  /       P Q R S \120 - \123
        !          12121:        .word   mm_ri,  eval,   eval,   eval    /       T U V W \124 - \127
        !          12122:        .word   eval,   eval,   mm_cbt, eval    /       X Y Z [ \130 - \133
        !          12123:        .word   eval,   eval,   eval,   eval    /       \ ] ^ _ \134 - \137
        !          12124:        .word   mm_hpa, mm_hpr, eval,   eval    /       ` a b c \140 - \143
        !          12125:        .word   mm_vpa, mm_vpr, mm_hvp, mm_cup  /       d e f g \144 - \147
        !          12126:        .word   eval,   eval,   eval,   eval    /       h i j k \150 - \153
        !          12127:        .word   eval,   mm_sgr, eval,   eval    /       l m n o \154 - \157
        !          12128:        .word   eval,   eval,   mm_ssr, eval    /       p q r s \160 - \163
        !          12129:        .word   eval,   eval,   mm_scr, eval    /       t u v w \164 - \167
        !          12130:        .word   eval,   eval,   eval,   eval    /       x y z { \170 - \173
        !          12131:        .word   eval,   eval,   eval,   eval    /       | } ~ ? \174 - \177
        !          12132: 
        !          12133: ////////
        !          12134: /
        !          12135: / csgtab - table of functions indexed by ESC [ > characters.
        !          12136: /
        !          12137: ////////
        !          12138: 
        !          12139: csgtab:        .word   eval,   eval,   eval,   eval    /       NUL  SOH  STX  ETX
        !          12140:        .word   eval,   eval,   eval,   eval    /       EOT  ENQ  ACK  BEL
        !          12141:        .word   eval,   eval,   eval,   eval    /       BS   HT   LF   VT
        !          12142:        .word   eval,   eval,   eval,   eval    /       FF   CR   SO   SI
        !          12143:        .word   eval,   eval,   eval,   eval    /       DLE  DC1  DC2  DC3
        !          12144:        .word   eval,   eval,   eval,   eval    /       DC4  NAK  SYN  ETB
        !          12145:        .word   eval,   eval,   eval,   eval    /       CAN  EM   SUB  ESC
        !          12146:        .word   eval,   eval,   eval,   eval    /       FS   GS   RS   US
        !          12147:        .word   eval,   eval,   eval,   eval    /         ! dquote # \040 - \043
        !          12148:        .word   eval,   eval,   eval,   eval    /       $ % & quote \044 - \047
        !          12149:        .word   eval,   eval,   eval,   eval    /       ( ) * + \050 - \053
        !          12150:        .word   eval,   eval,   eval,   eval    /       , - . / \054 - \057
        !          12151:        .word   eval,   eval,   eval,   eval    /       0 1 2 3 \060 - \063
        !          12152:        .word   eval,   eval,   eval,   eval    /       4 5 6 7 \064 - \067
        !          12153:        .word   eval,   eval,   eval,   eval    /       8 9 : ; \070 - \073
        !          12154:        .word   eval,   eval,   eval,   eval    /       < = > ? \074 - \077
        !          12155:        .word   eval,   eval,   eval,   eval    /       @ A B C \100 - \103
        !          12156:        .word   eval,   eval,   eval,   eval    /       D E F G \104 - \107
        !          12157:        .word   eval,   eval,   eval,   eval    /       H I J K \110 - \113
        !          12158:        .word   eval,   eval,   eval,   eval    /       L M N O \114 - \117
        !          12159:        .word   eval,   eval,   eval,   eval    /       P Q R S \120 - \123
        !          12160:        .word   eval,   eval,   eval,   eval    /       T U V W \124 - \127
        !          12161:        .word   eval,   eval,   eval,   eval    /       X Y Z [ \130 - \133
        !          12162:        .word   eval,   eval,   eval,   eval    /       \ ] ^ _ \134 - \137
        !          12163:        .word   eval,   eval,   eval,   eval    /       ` a b c \140 - \143
        !          12164:        .word   eval,   eval,   eval,   eval    /       d e f g \144 - \147
        !          12165:        .word   mm_cgh, eval,   eval,   eval    /       h i j k \150 - \153
        !          12166:        .word   mm_cgl, eval,   eval,   eval    /       l m n o \154 - \157
        !          12167:        .word   eval,   eval,   eval,   eval    /       p q r s \160 - \163
        !          12168:        .word   eval,   eval,   eval,   eval    /       t u v w \164 - \167
        !          12169:        .word   eval,   eval,   eval,   eval    /       x y z { \170 - \173
        !          12170:        .word   eval,   eval,   eval,   eval    /       | } ~ ? \174 - \177
        !          12171: 
        !          12172: ////////
        !          12173: /
        !          12174: / coltab - integer array of offsets to each column - up to 132 columns
        !          12175: /
        !          12176: ////////
        !          12177: 
        !          12178: coltab:        .word     0*NCB,   1*NCB,   2*NCB,   3*NCB
        !          12179:        .word     4*NCB,   5*NCB,   6*NCB,   7*NCB
        !          12180:        .word     8*NCB,   9*NCB,  10*NCB,  11*NCB
        !          12181:        .word    12*NCB,  13*NCB,  14*NCB,  15*NCB
        !          12182:        .word    16*NCB,  17*NCB,  18*NCB,  19*NCB
        !          12183:        .word    20*NCB,  21*NCB,  22*NCB,  23*NCB
        !          12184:        .word    24*NCB,  25*NCB,  26*NCB,  27*NCB
        !          12185:        .word    28*NCB,  29*NCB,  30*NCB,  31*NCB
        !          12186:        .word    32*NCB,  33*NCB,  34*NCB,  35*NCB
        !          12187:        .word    36*NCB,  37*NCB,  38*NCB,  39*NCB
        !          12188:        .word    40*NCB,  41*NCB,  42*NCB,  43*NCB
        !          12189:        .word    44*NCB,  45*NCB,  46*NCB,  47*NCB
        !          12190:        .word    48*NCB,  49*NCB,  50*NCB,  51*NCB
        !          12191:        .word    52*NCB,  53*NCB,  54*NCB,  55*NCB
        !          12192:        .word    56*NCB,  57*NCB,  58*NCB,  59*NCB
        !          12193:        .word    60*NCB,  61*NCB,  62*NCB,  63*NCB
        !          12194:        .word    64*NCB,  65*NCB,  66*NCB,  67*NCB
        !          12195:        .word    68*NCB,  69*NCB,  70*NCB,  71*NCB
        !          12196:        .word    72*NCB,  73*NCB,  74*NCB,  75*NCB
        !          12197:        .word    76*NCB,  77*NCB,  78*NCB,  79*NCB
        !          12198:        .word    80*NCB,  81*NCB,  82*NCB,  83*NCB
        !          12199:        .word    84*NCB,  85*NCB,  86*NCB,  87*NCB
        !          12200:        .word    88*NCB,  89*NCB,  90*NCB,  91*NCB
        !          12201:        .word    92*NCB,  93*NCB,  94*NCB,  95*NCB
        !          12202:        .word    96*NCB,  97*NCB,  98*NCB,  99*NCB
        !          12203:        .word   100*NCB, 101*NCB, 102*NCB, 103*NCB
        !          12204:        .word   104*NCB, 105*NCB, 106*NCB, 107*NCB
        !          12205:        .word   108*NCB, 109*NCB, 110*NCB, 111*NCB
        !          12206:        .word   112*NCB, 113*NCB, 114*NCB, 115*NCB
        !          12207:        .word   116*NCB, 117*NCB, 118*NCB, 119*NCB
        !          12208:        .word   120*NCB, 121*NCB, 122*NCB, 123*NCB
        !          12209:        .word   124*NCB, 125*NCB, 126*NCB, 127*NCB
        !          12210:        .word   128*NCB, 129*NCB, 130*NCB, 131*NCB
        !          12211: 
        !          12212: ////////
        !          12213: /
        !          12214: / rowtab - array of offsets to each row - up to 44 rows
        !          12215: /         automatically regenerated by reinit().
        !          12216: /
        !          12217: /      NOTE: In kernel data space to allow modification in protected mode.
        !          12218: /
        !          12219: ////////
        !          12220: 
        !          12221:        .shrd
        !          12222: rowtab:        .word    0*NRB,  1*NRB,  2*NRB,  3*NRB
        !          12223:        .word    4*NRB,  5*NRB,  6*NRB,  7*NRB
        !          12224:        .word    8*NRB,  9*NRB, 10*NRB, 11*NRB
        !          12225:        .word   12*NRB, 13*NRB, 14*NRB, 15*NRB
        !          12226:        .word   16*NRB, 17*NRB, 18*NRB, 19*NRB
        !          12227:        .word   20*NRB, 21*NRB, 22*NRB, 23*NRB
        !          12228:        .word   24*NRB, 25*NRB, 26*NRB, 27*NRB
        !          12229:        .word   28*NRB, 29*NRB, 30*NRB, 31*NRB
        !          12230:        .word   32*NRB, 33*NRB, 34*NRB, 35*NRB
        !          12231:        .word   36*NRB, 37*NRB, 38*NRB, 39*NRB
        !          12232:        .word   40*NRB, 41*NRB, 42*NRB, 43*NRB
        !          12233: rowend:
        !          12234:        .shri
        !          12235: 
        !          12236: ////////
        !          12237: /
        !          12238: / fcolor - foreground color
        !          12239: / bcolor - background color
        !          12240: /
        !          12241: /      indexed by ansi color (black,red,green,brown,blue,magenta,cyan,white)
        !          12242: /      yields graphics color (black,blue,green,cyan,red,magenta,brown,white)
        !          12243: /              which is properly shifted for installation in attribute byte.
        !          12244: /
        !          12245: ////////
        !          12246: 
        !          12247: fcolor:        .byte   0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07
        !          12248: bcolor:        .byte   0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70
        !          12249: 
        !          12250: ////////
        !          12251: /
        !          12252: / mm_voff()    -- Disable video display.
        !          12253: /
        !          12254: ////////
        !          12255:        .globl  mm_voff_
        !          12256: mm_voff_:
        !          12257:        mov     dx, mmdata+MM_PORT
        !          12258:        add     dx, $4
        !          12259:        movb    al, mmdata+MM_MODE
        !          12260:        outb    dx, al
        !          12261:        ret
        !          12262: 
        !          12263: ////////
        !          12264: /
        !          12265: / mm_von()     -- Enable video display
        !          12266: /
        !          12267: ////////
        !          12268:        .globl  mm_von_
        !          12269: mm_von_:
        !          12270:        mov     dx, mmdata+MM_PORT      / enable video display
        !          12271:        add     dx, $4
        !          12272:        movb    al, mmdata+MM_MODE
        !          12273:        orb     al, $0x08
        !          12274:        outb    dx, al
        !          12275:        mov     mmvcnt_, $300           / 300 seconds before video disabled
        !          12276:        ret
        !          12277: 0707070064030140061004440000030000030000011777770507310636500004600000020135/newbits/kernel/USRSRC/i8086/drv/ms.c/* (-lgl
        !          12278:  *     COHERENT Driver Kit Version 1.1.0
        !          12279:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          12280:  *     All rights reserved. May not be copied without permission.
        !          12281:  -lgl) */
        !          12282: /*
        !          12283:  *     Microsoft bus mouse (rodent) driver.
        !          12284:  */
        !          12285: 
        !          12286: #include <sys/coherent.h>
        !          12287: #include <sys/uproc.h>
        !          12288: #include <sys/con.h>
        !          12289: #include <sys/devices.h>
        !          12290: #include <sys/ms.h>
        !          12291: #include <errno.h>
        !          12292: 
        !          12293: #define Help(fmt, p)           printf(fmt, p)
        !          12294: #define Help2(fmt, p, q)       printf(fmt, p, q)
        !          12295: #define Diag(fmt, p)           /* Help(fmt, p) */
        !          12296: #define Diag2(fmt, p, q)       /* Help2(fmt, p, q) */
        !          12297: 
        !          12298: /*
        !          12299:  *     global patchable definitions
        !          12300:  */
        !          12301: unsigned MSPORT  = 0x23C;      /* mouse 8255A registers: */
        !          12302:                                /* modified mouse is 0x23C */
        !          12303:                                /* Geac modified mouse is 0x230 */
        !          12304: unsigned MSIRQ   = 2;          /* mouse interrupt # */
        !          12305: 
        !          12306: /*
        !          12307:  *     driver function definitions
        !          12308:  */
        !          12309: int    msload();
        !          12310: int    msunload();
        !          12311: int    msopen();
        !          12312: int    msclose();
        !          12313: int    msioctl();
        !          12314: int    mspoll();
        !          12315: int    msintr();
        !          12316: int    nulldev();
        !          12317: int    nonedev();
        !          12318: 
        !          12319: /*
        !          12320:  *     configuration table
        !          12321:  */
        !          12322: CON mscon = {
        !          12323:        DFCHR|DFPOL,                    /* flags        */
        !          12324:        MS_MAJOR,                       /* major index  */
        !          12325:        msopen,                         /* open         */
        !          12326:        msclose,                        /* close        */
        !          12327:        nonedev,                        /* block        */
        !          12328:        nonedev,                        /* read         */
        !          12329:        nonedev,                        /* write        */
        !          12330:        msioctl,                        /* ioctl        */
        !          12331:        nulldev,                        /* power fail   */
        !          12332:        nulldev,                        /* timeout      */
        !          12333:        msload,                         /* load         */
        !          12334:        msunload,                       /* unload       */
        !          12335:        mspoll                          /* poll         */
        !          12336: };
        !          12337: 
        !          12338: /*
        !          12339:  *     ioctl function definitions
        !          12340:  */
        !          12341: 
        !          12342: int    ms_setup();
        !          12343: int    ms_setcrs();
        !          12344: int    ms_readcrs();
        !          12345: int    ms_setmick();
        !          12346: int    ms_readmick();
        !          12347: int    ms_readbtns();
        !          12348: int    ms_readstat();
        !          12349: int    ms_wait();
        !          12350: 
        !          12351: int (*ioctls[])() = {
        !          12352:   /*      0         1           2           3            4             */
        !          12353:        ms_setup, ms_setcrs, ms_readcrs, ms_setmick, ms_readmick,
        !          12354: 
        !          12355:   /*        5           6         7                                    */
        !          12356:        ms_readbtns, ms_readstat, ms_wait
        !          12357: };
        !          12358: 
        !          12359: /*
        !          12360:  *     hardware constants
        !          12361:  */
        !          12362: static int     porta;                  /*      port A (read/write) */
        !          12363: static int     portb;                  /*      port B (read/write) */
        !          12364: static int     portc;                  /*      port C (read/write) */
        !          12365: static int     portcm;                 /*      control port (write only) */
        !          12366: 
        !          12367: static int     u_stts  =  0;           /* changed-status flags */
        !          12368: static int     u_mask  =  0;           /* user condition mask */
        !          12369: 
        !          12370: static event_t ipolls;
        !          12371: 
        !          12372: static struct msparms parms, initparm = {
        !          12373:        2, -16, 655, -16, 215, 8, 16
        !          12374: };
        !          12375: 
        !          12376: static struct mspos crsr, csav, initcrsr = { 320, 100 };
        !          12377: 
        !          12378: static struct msmick mick, initmick = { 0, 0 };
        !          12379: 
        !          12380: static struct msbuts buttons, initbuttons = {
        !          12381:        0,
        !          12382:        {       {0, {320, 100}},
        !          12383:                {0, {320, 100}},
        !          12384:                {0, {320, 100}},
        !          12385:                {0, {320, 100}}
        !          12386:        }
        !          12387: };
        !          12388: 
        !          12389: static int     ms_inuse = 0;           /* is mouse in use ? */
        !          12390: 
        !          12391: msload()
        !          12392: {
        !          12393:        int s;
        !          12394: 
        !          12395:        porta  = MSPORT;
        !          12396:        portb  = MSPORT + 1;
        !          12397:        portc  = MSPORT + 2;
        !          12398:        portcm = MSPORT + 3;
        !          12399: 
        !          12400:        s = sphi();
        !          12401:        outb( portcm, 0x91 );           /* set 8255A mode 9 */
        !          12402:        outb( portc,  0x10 );           /* disable interrupt */
        !          12403:        setivec( MSIRQ, msintr );       /* set up irq vector */
        !          12404:        spl(s);
        !          12405: 
        !          12406:        return 0;
        !          12407: }
        !          12408: 
        !          12409: /*
        !          12410:  * Unload function.
        !          12411:  */
        !          12412: msunload()
        !          12413: {
        !          12414:        clrivec( MSIRQ );               /* release irq vector */
        !          12415:        outb( portcm, 0x91 );           /* set 8255A mode 9 */
        !          12416:        outb( portc,  0x10 );           /* disable interrupt */
        !          12417: }
        !          12418: 
        !          12419: msopen(dev, mode)
        !          12420: dev_t  dev;
        !          12421: {
        !          12422:        int     s;
        !          12423: 
        !          12424:        s = sphi(s);
        !          12425:        if (ms_inuse) {
        !          12426:                u.u_error = EDBUSY;
        !          12427:                spl(s);
        !          12428:                return( -1 );
        !          12429:        }
        !          12430: 
        !          12431:        outb( portcm, 0x91 );                   /* set 8255A mode 9 */
        !          12432:        outb( portb,  0x5a );
        !          12433: 
        !          12434:        if( inb( portb ) != 0x5a) {             /* hardware installed? */
        !          12435:                u.u_error = ENXIO;
        !          12436:                spl(s);
        !          12437:                return( -1 );
        !          12438:        }
        !          12439: 
        !          12440:        outb( portc, 0x90 );
        !          12441:        inb( porta );
        !          12442:        outb( portc, 0xb0 );
        !          12443:        inb( porta );
        !          12444:        outb( portc, 0xd0 );
        !          12445:        inb( porta );
        !          12446:        outb( portc, 0xf0 );
        !          12447:        inb( porta );
        !          12448:        outb( portc, 0 );               /* clear all mouse registers */
        !          12449: 
        !          12450: /* set things */
        !          12451:        parms = initparm;
        !          12452:        crsr = csav = initcrsr;
        !          12453:        mick = initmick;
        !          12454:        buttons = initbuttons;
        !          12455:        u_stts = u.u_error = 0;
        !          12456:        ms_inuse = 1;
        !          12457:        spl(s);
        !          12458: 
        !          12459:        return( 0 );
        !          12460: }
        !          12461: 
        !          12462: msclose()
        !          12463: {
        !          12464:        int s;
        !          12465: 
        !          12466:        s = sphi();
        !          12467:        outb( portc, 0x10 );                    /* disable interrupt */
        !          12468:        ms_inuse = u.u_error = 0;
        !          12469:        spl(s);
        !          12470:        return( 0 );
        !          12471: }
        !          12472: 
        !          12473: msioctl( dev, com, vec )
        !          12474: dev_t  dev;
        !          12475: int    com;
        !          12476: char   *vec;
        !          12477: {
        !          12478:        int s;
        !          12479: 
        !          12480:        s = sphi();
        !          12481:        if (com >= 0 && com < sizeof(ioctls)/sizeof(ioctls[0])) {
        !          12482:                (*ioctls[com])(vec);    /* indirect func call */
        !          12483:                u.u_error = 0;
        !          12484:        } else
        !          12485:                u.u_error = EINVAL;
        !          12486:        spl(s);
        !          12487:        if (u.u_error)
        !          12488:                return( -1 );
        !          12489: 
        !          12490:        return( 0 );
        !          12491: }
        !          12492: 
        !          12493: /*
        !          12494:  * Polling routine.
        !          12495:  * [System V.3 Compatible].
        !          12496:  */
        !          12497: mspoll( dev, ev, msec )
        !          12498: dev_t dev;
        !          12499: int ev;
        !          12500: int msec;
        !          12501: {
        !          12502:        ev &= ~POLLPRI;
        !          12503:        ev &= ~POLLOUT;
        !          12504: 
        !          12505:        /*
        !          12506:         * No input.
        !          12507:         */
        !          12508:        if ( (u_stts & u_mask) == 0 ) {
        !          12509:                /*
        !          12510:                 * Enable monitor if blocking poll.
        !          12511:                 */
        !          12512:                if ( msec != 0 ) 
        !          12513:                        pollopen( &ipolls );
        !          12514:                /*
        !          12515:                 * Look again to avoid interrupt race.
        !          12516:                 */
        !          12517:                if ( (u_stts & u_mask) == 0 )
        !          12518:                        ev &= ~POLLIN;
        !          12519:        }
        !          12520: 
        !          12521:        return ev;
        !          12522: }
        !          12523: 
        !          12524: /*
        !          12525:  *     write setup structure
        !          12526:  */
        !          12527: ms_setup( newparm )
        !          12528: struct msparms *newparm;
        !          12529: {
        !          12530:        ukcopy(newparm, &parms, sizeof(struct msparms));
        !          12531:        if (parms.h_mpr == 0)
        !          12532:                parms.h_mpr = 1;
        !          12533:        if (parms.v_mpr == 0)
        !          12534:                parms.v_mpr = 1;
        !          12535: }
        !          12536: 
        !          12537: /*
        !          12538:  *     write cursor position
        !          12539:  */
        !          12540: ms_setcrs( pos )
        !          12541: struct mspos *pos;
        !          12542: {
        !          12543:        ukcopy(pos, &crsr, sizeof(struct mspos));
        !          12544:        u_stts &= ~MS_S_MOVE;           /* clear u_stts pos bit */
        !          12545: }
        !          12546: 
        !          12547: /*
        !          12548:  *     read cursor postion
        !          12549:  */
        !          12550: ms_readcrs( pos )
        !          12551: struct mspos *pos;
        !          12552: {
        !          12553:        kucopy(&crsr, pos, sizeof(struct mspos));
        !          12554:        u_stts &= ~MS_S_MOVE;           /* clear u_stts pos bit */
        !          12555: }
        !          12556: 
        !          12557: /*
        !          12558:  *     write mickey postion
        !          12559:  */
        !          12560: ms_setmick( pos )
        !          12561: struct msmick *pos;
        !          12562: {
        !          12563:        ukcopy(pos, &mick, sizeof(struct msmick));
        !          12564: }
        !          12565: 
        !          12566: /*
        !          12567:  *     read mickey postion
        !          12568:  */
        !          12569: ms_readmick( pos )
        !          12570: struct msmick *pos;
        !          12571: {
        !          12572:        kucopy(&mick, pos, sizeof(struct msmick));
        !          12573: }
        !          12574: 
        !          12575: /*
        !          12576:  *     read button status
        !          12577:  */
        !          12578: ms_readbtns( btns )
        !          12579: struct msbuts *btns;
        !          12580: {
        !          12581:        kucopy(&buttons, btns, sizeof(struct msbuts));
        !          12582:        u_stts &= ~MS_S_BUTTONS;                /* clear u_stts button bits */
        !          12583: }
        !          12584: 
        !          12585: /*
        !          12586:  *     read "changed status" mask
        !          12587:  */
        !          12588: ms_readstat( stat )
        !          12589: int *stat;
        !          12590: {
        !          12591:        kucopy(&u_stts, stat, sizeof(int));
        !          12592: }
        !          12593: 
        !          12594: /*
        !          12595:  *     wait on "changed status" mask
        !          12596:  */
        !          12597: ms_wait( flag )
        !          12598: int *flag;
        !          12599: {
        !          12600:        ukcopy(flag, &u_mask, sizeof(int));
        !          12601:        while ((u_mask & u_stts) == 0)  /* wait until any bit is on */
        !          12602:                sleep(&u_stts, 0x7fff, 0x7fff, 0);
        !          12603:        u_mask = 0;
        !          12604: }
        !          12605: 
        !          12606: /*
        !          12607:  *     mouse interrupt service routine
        !          12608:  */
        !          12609: msintr()
        !          12610: {
        !          12611:        static  int h_fpix =  0;                        /* fractional pixel */
        !          12612:        static  int v_fpix = 0;                         /* ditto */
        !          12613:        int     s, n_l, n_h, h_diff, v_diff, tmp, left, right;
        !          12614: 
        !          12615:        if (!ms_inuse)                  /* dev not open - ignore interrupts */
        !          12616:                return;
        !          12617:        
        !          12618:        s = sphi();
        !          12619:        outb( portc, 0x90 );            /* get horizontal change */
        !          12620:        n_l = inb( porta );
        !          12621:        outb( portc, 0xb0 );
        !          12622:        n_h = inb( porta );
        !          12623:        h_diff = (char) ((n_l & 0x0f) | (n_h << 4));
        !          12624: 
        !          12625:        outb( portc, 0xd0 );            /* get vertical change */
        !          12626:        n_l = inb( porta );
        !          12627:        outb( portc, 0xf0 );
        !          12628:        n_h = inb( porta );
        !          12629:        v_diff = (char) ((n_l & 0x0f) | (n_h << 4));
        !          12630: 
        !          12631:        outb( portc, 0 );
        !          12632:        left = right = 0;                               /* set button status */
        !          12633:        if (!(n_h & 0x80)) left = MS_L_DOWN;            /* left button.. */
        !          12634:        if ((buttons.bbstat & MS_L_DOWN) ^ left) {
        !          12635:                if (left)
        !          12636:                        button(MS_B_L_PRESS,   MS_S_L_PRESS);
        !          12637:                else
        !          12638:                        button(MS_B_L_RELEASE, MS_S_L_RELEASE);
        !          12639:        }
        !          12640:        if (!(n_h & 0x20))                              /* right button.. */
        !          12641:                right = MS_R_DOWN;
        !          12642:        if ((buttons.bbstat & MS_R_DOWN) ^ right) {
        !          12643:                if (right)
        !          12644:                        button(MS_B_R_PRESS,   MS_S_R_PRESS);
        !          12645:                else
        !          12646:                        button(MS_B_R_RELEASE, MS_S_R_RELEASE);
        !          12647:        }
        !          12648: 
        !          12649:        buttons.bbstat = left | right;          /* set new button status */
        !          12650: 
        !          12651:        if (h_diff || v_diff) {                 /* any motion? */
        !          12652:                mick.h_mick += h_diff;          /* yes - update positions */
        !          12653:                mick.v_mick += v_diff;
        !          12654:                if ((abs(h_diff) > parms.accel_t) || (abs(v_diff) > parms.accel_t)) {
        !          12655:                        h_diff *= 2;
        !          12656:                        v_diff *= 2;
        !          12657:                }
        !          12658: 
        !          12659:                if (h_diff) {                   /* horizontal change */
        !          12660:                        tmp   = h_fpix + 8 * h_diff;
        !          12661:                        h_fpix = tmp % parms.h_mpr;
        !          12662:                        tmp    = crsr.h_crsr + tmp / parms.h_mpr;
        !          12663:                        crsr.h_crsr = c_range(tmp, parms.h_cmin, parms.h_cmax);
        !          12664:                }
        !          12665: 
        !          12666:                if (v_diff) {                   /* vertical change */                                                                                                                                                                                           
        !          12667:                        tmp   = v_fpix + 8 * v_diff;
        !          12668:                        v_fpix = tmp % parms.v_mpr;
        !          12669:                        tmp    = crsr.v_crsr + tmp / parms.v_mpr;
        !          12670:                        crsr.v_crsr = c_range(tmp, parms.v_cmin, parms.v_cmax);
        !          12671:                }
        !          12672: 
        !          12673:                if ((crsr.h_crsr != csav.h_crsr) || (crsr.v_crsr != csav.v_crsr)) {
        !          12674:                        u_stts |= MS_S_MOVE;
        !          12675:                        csav = crsr;
        !          12676:                }
        !          12677:        }
        !          12678: 
        !          12679:        if (u_stts & u_mask) {
        !          12680:                wakeup(&u_stts);
        !          12681:                if ( ipolls.e_procp )
        !          12682:                        pollwake( &ipolls );
        !          12683:        }
        !          12684: 
        !          12685:        spl(s);
        !          12686: }
        !          12687: 
        !          12688: /*
        !          12689:  *     update button-press/release data
        !          12690:  */
        !          12691: button( bp, sbit )
        !          12692: int bp;
        !          12693: unsigned sbit;
        !          12694: {
        !          12695:        ++buttons.buts[bp].cnt;
        !          12696:        buttons.buts[bp].bpos = crsr;
        !          12697:        u_stts |= sbit;
        !          12698: }
        !          12699: 
        !          12700: /*
        !          12701:  *     force return value to be within specified range
        !          12702:  */
        !          12703: c_range(c, cmin, cmax)
        !          12704: int    c, cmin, cmax;
        !          12705: {
        !          12706:        if( c < cmin )
        !          12707:                c = cmin;
        !          12708:        else if( c > cmax )
        !          12709:                c = cmax;
        !          12710:        return( c );
        !          12711: }
        !          12712: 
        !          12713: abs(i)
        !          12714: int i;
        !          12715: {
        !          12716:        if (i < 0)
        !          12717:                return (-i);
        !          12718:        return i;
        !          12719: }
        !          12720: 0707070064030034521004440000030000030000011777770507310636700004700000044047/newbits/kernel/USRSRC/i8086/drv/msg.c/* $Header: /usr/src/sys/i8086/drv/RCS/msg.c,v 2.1 88/09/03 13:09:07 src Exp $
        !          12721:  *
        !          12722:  *     The  information  contained herein  is a trade secret  of INETCO
        !          12723:  *     Systems, and is confidential information.   It is provided under
        !          12724:  *     a license agreement,  and may be copied or disclosed  only under
        !          12725:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          12726:  *     this  material  without  the express  written  authorization  of
        !          12727:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          12728:  *
        !          12729:  *     Copyright (c) 1987, 1986, 1985, 1984.
        !          12730:  *     An unpublished work by INETCO Systems, Ltd.
        !          12731:  *     All rights reserved.
        !          12732:  */
        !          12733: 
        !          12734: /*
        !          12735:  * System V Compatible Messaging
        !          12736:  *
        !          12737:  *     This module provides System V compatible messaging operations.
        !          12738:  *
        !          12739:  *                     Author: Allan Cornish, INETCO Systems Ltd., Oct 1984
        !          12740:  *
        !          12741:  * $Log:       /usr/src/sys/i8086/drv/RCS/msg.c,v $
        !          12742:  * Revision 2.1        88/09/03  13:09:07      src
        !          12743:  * *** empty log message ***
        !          12744:  * 
        !          12745:  * Revision 1.2        88/08/02  16:49:52      src
        !          12746:  * Bug:        msgget with IPC_CREAT could fail if message queue already
        !          12747:  *     existed, and queue permissions were not an exact match
        !          12748:  *     for requested permissions.
        !          12749:  * Fix:        Permission checking made more rigorous.
        !          12750:  * 
        !          12751:  * Revision 1.1        88/03/24  17:05:44      src
        !          12752:  * Initial revision
        !          12753:  * 
        !          12754:  * 87/04/24    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          12755:  * Msgctl() IPC_STAT check of polled devices modified.
        !          12756:  *
        !          12757:  * 87/04/01    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          12758:  * Msgctl() now correctly reports polling events on an IPC_STAT operation.
        !          12759:  *
        !          12760:  * 87/03/20    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          12761:  * Msgpoll() now correctly reports POLLOUT events.
        !          12762:  *
        !          12763:  * 87/01/20    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          12764:  * msginit() is now more paranoid about validating NMSC, NMSG, NMSQID.
        !          12765:  *
        !          12766:  * 87/01/05    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          12767:  * msginit() now allocates message buffers in high memory.
        !          12768:  *
        !          12769:  * 86/12/12    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          12770:  * Added 3rd argument to msgpoll() to support non-blocking polls.
        !          12771:  *
        !          12772:  * 86/11/21    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          12773:  * Added support for System V.3 compatible polls.
        !          12774:  * Added msgpoll() routine and xmsqid_ds structure.
        !          12775:  *
        !          12776:  * 85/08/06    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          12777:  * Msg.c split into configuration (msgcon.c) and implementation (msg.c).
        !          12778:  *
        !          12779:  * 85/07/22    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          12780:  * Msgget, msgctl, msgsnd, msgrcv now return immediately if u.u_error is set.
        !          12781:  *
        !          12782:  * 85/07/19    Allan Cornish
        !          12783:  * Msgrcv() now reports E2BIG if message is larger than size requested.
        !          12784:  * Msgfree() integrated into msginit() and msgrcv() functions.
        !          12785:  * Msgsnd() now checks for queue removal after waking from sleep.
        !          12786:  * Msgsnd() and msgrcv() now detect address faults and report EFAULT.
        !          12787:  *
        !          12788:  * 85/07/03    Allan Cornish
        !          12789:  * Replaced use of EDOM with EIDRM.
        !          12790:  * Replaced msgaccess() by calls to ipcaccess(), increasing shared ipc code.
        !          12791:  * Eliminated many calls to sphi() and spl().  They are not really required,
        !          12792:  * since system calls are synchronous unless they sleep or are interrupted.
        !          12793:  * Sleeps cause no problem, and interrupts do not affect messaging state.
        !          12794:  *
        !          12795:  * 85/06/19    Allan Cornish
        !          12796:  * Added code to msgctl to allow the owner of a queue to reduce msg_qbytes.
        !          12797:  * Previously only the super-user could modify msg_qbytes.
        !          12798:  *
        !          12799:  * 85/06/18    Allan Cornish
        !          12800:  * Added code to msgsnd to check for full queue (msg_cbytes >= msg_qbytes).
        !          12801:  * Integrated msgalloc function into msgsnd, since only called from there.
        !          12802:  * Fixed bug in msgrcv when msgtyp < 0, to treat msg_type as mesg priority.
        !          12803:  *
        !          12804:  * 85/05/10    Allan Cornish
        !          12805:  * C compiler bug in msginit caused 'mp->msg_spot = (wanted -= NMSC)' to fail.
        !          12806:  * For NMSG=10, NMSC=640, msg_spot always set to 0x1900 or 0xE980.
        !          12807:  * Code changed to 'wanted -= NMSC; mp->msg_spot = wanted'.
        !          12808:  *
        !          12809:  * 85/04/01    Allan Cornish
        !          12810:  * fixed qp->msg_last bug in msgrcv().
        !          12811:  */
        !          12812: 
        !          12813: #include <coherent.h>
        !          12814: #include <sched.h>
        !          12815: #include <types.h>
        !          12816: #include <uproc.h>
        !          12817: #include <errno.h>
        !          12818: #include <stat.h>
        !          12819: #include <con.h>
        !          12820: #include <seg.h>
        !          12821: #include <msg.h>
        !          12822: 
        !          12823: #ifndef        EIDRM
        !          12824: #define        EIDRM   EDOM
        !          12825: #endif
        !          12826: 
        !          12827: /*
        !          12828:  * Extended message queue id data structure.
        !          12829:  *     - extended to support System V.3 compatible polls.
        !          12830:  */
        !          12831: struct xmsqid_ds {
        !          12832:        struct msqid_ds msq;
        !          12833:        struct event    ipolls;
        !          12834:        struct event    opolls;
        !          12835: };
        !          12836: 
        !          12837: /*
        !          12838:  *     Message Information
        !          12839:  */
        !          12840: 
        !          12841: struct xmsqid_ds *msqs = 0;    /* Pointer to array of message queues */
        !          12842:                                /* (first queue contains free message list) */
        !          12843: 
        !          12844: struct msg * msgs = 0;         /* Pointer to array of message headers */
        !          12845: 
        !          12846: static SEG * msgsp;            /* Segment containing messages */
        !          12847: #define        msgsel FP_SEL(msgsp->s_faddr)
        !          12848: 
        !          12849: /*
        !          12850:  *     Global Message Parameters
        !          12851:  */
        !          12852: 
        !          12853: unsigned NMSQID = 9;   /* allocated number of message queues */
        !          12854: unsigned NMSQB  = 2048;        /* default maximum queue size in bytes */
        !          12855: unsigned NMSG = 10;    /* allocated messages: (NMSG * NMSC) < 2^16 */
        !          12856: unsigned NMSC = 640;   /* maximum message text size */
        !          12857: 
        !          12858: /*
        !          12859:  * Message Device Initialization.
        !          12860:  *
        !          12861:  *     Initialize message ids.
        !          12862:  */
        !          12863: 
        !          12864: msginit()
        !          12865: {
        !          12866:        register struct xmsqid_ds *qp;
        !          12867:        register struct msg *mp;
        !          12868:        long wanted;
        !          12869:        int i;
        !          12870: 
        !          12871:        if ( NMSG == 0 )
        !          12872:                NMSQID = 0;
        !          12873:        if ( NMSC == 0 )
        !          12874:                NMSQID = 0;
        !          12875:        if ( NMSQID == 0 )
        !          12876:                return 0;
        !          12877: 
        !          12878:        if ( NMSQID > 128 )
        !          12879:                NMSQID = 128;
        !          12880: 
        !          12881:        /*
        !          12882:         * Allocate message queues and message headers.
        !          12883:         */
        !          12884:        wanted = (NMSQID * (long) sizeof(struct xmsqid_ds)) +
        !          12885:                (NMSG * (long) sizeof(struct msg));
        !          12886:        if (wanted > 16384) {
        !          12887:                printf("invalid NMSQID or NMSG kernel variable\n");
        !          12888:                NMSQID=0;
        !          12889:                return;
        !          12890:        }
        !          12891: 
        !          12892:        if ( msqs = kalloc( (unsigned) wanted) ) {
        !          12893: 
        !          12894:                /*
        !          12895:                 * Ensure allocated space is cleared.
        !          12896:                 */
        !          12897:                memset( msqs, 0, (unsigned) wanted );
        !          12898: 
        !          12899:                /*
        !          12900:                 * Message headers are contiguous to message queues.
        !          12901:                 */
        !          12902:                msgs = (struct msg *) (&msqs[NMSQID]);
        !          12903: 
        !          12904:                /*
        !          12905:                 * Allocate message buffers.
        !          12906:                 */
        !          12907:                wanted = (long) NMSG * NMSC;
        !          12908:                if ( wanted > 0xFFFFL ) {
        !          12909:                        printf("invalid NMSG or NMSC kernel variable\n");
        !          12910:                        kfree( msqs );
        !          12911:                        NMSQID = 0;
        !          12912:                        msqs   = 0;
        !          12913:                        return;
        !          12914:                }
        !          12915: 
        !          12916:                msgsp = salloc( (size_t) wanted, SFHIGH|SFNSWP|SFNCLR );
        !          12917: 
        !          12918:                if ( msgsp == 0 ) {
        !          12919:                        printf("could not salloc %u messages\n", NMSG);
        !          12920:                        kfree( msqs );
        !          12921:                        NMSQID = 0;
        !          12922:                        msqs   = 0;
        !          12923:                        return;
        !          12924:                }
        !          12925: 
        !          12926:                /*
        !          12927:                 * Initialize message queues.
        !          12928:                 */
        !          12929:                for ( qp = msqs, i = 0; i < NMSQID; i++, qp++ ) {
        !          12930: 
        !          12931:                        qp->msq.msg_perm.seq  = i * 256;
        !          12932: 
        !          12933:                        qp->ipolls.e_dnext =
        !          12934:                        qp->ipolls.e_dlast = &qp->ipolls;
        !          12935: 
        !          12936:                        qp->opolls.e_dnext =
        !          12937:                        qp->opolls.e_dlast = &qp->opolls;
        !          12938:                }
        !          12939: 
        !          12940:                /*
        !          12941:                 * Initialize message headers, place on free queue.
        !          12942:                 */
        !          12943:                for ( qp = msqs, mp = &msgs[NMSG]; --mp >= msgs; ) {
        !          12944:                        wanted -= NMSC;
        !          12945:                        mp->msg_spot  = wanted;
        !          12946:                        mp->msg_next  = qp->msq.msg_first;
        !          12947:                        qp->msq.msg_first = mp;
        !          12948:                }
        !          12949:        }
        !          12950:        else {
        !          12951:                printf("could not kalloc %u message ids\n", NMSQID);
        !          12952:                NMSQID = 0;
        !          12953:        }
        !          12954: }
        !          12955: 
        !          12956: 
        !          12957: /*
        !          12958:  * Msgctl - Message Control Operations.
        !          12959:  */
        !          12960: 
        !          12961: umsgctl( qid, cmd, buf )
        !          12962: 
        !          12963: int qid;
        !          12964: int cmd;
        !          12965: struct msqid_ds *buf;
        !          12966: 
        !          12967: {
        !          12968:        register struct xmsqid_ds *qp;
        !          12969:        register struct msg *mp;
        !          12970:        unsigned n;
        !          12971: 
        !          12972:        /*
        !          12973:         * Validate queue identifier.
        !          12974:         */
        !          12975:        if ( (qid <= 0) || (qid/256 >= NMSQID) || (msqs == 0) ) {
        !          12976:                u.u_error = EINVAL;
        !          12977:                return -1;
        !          12978:        }
        !          12979: 
        !          12980:        qp = &msqs[ qid / 256 ];
        !          12981: 
        !          12982:        /*
        !          12983:         * Validate queue existence.
        !          12984:         */
        !          12985:        if ( (qp == 0) || ((qp->msq.msg_perm.mode & IPC_ALLOC) == 0) ) {
        !          12986:                u.u_error = EINVAL;
        !          12987:                return -1;
        !          12988:        }
        !          12989: 
        !          12990:        /*
        !          12991:         * Validate qid for all commands except for IPC_STAT.
        !          12992:         */
        !          12993:        if ( (cmd != IPC_STAT) && (qp->msq.msg_perm.seq != qid) ) {
        !          12994:                u.u_error = EINVAL;
        !          12995:                return -1;
        !          12996:        }
        !          12997: 
        !          12998:        switch ( cmd ) {
        !          12999: 
        !          13000:        case IPC_STAT:
        !          13001:                /*
        !          13002:                 * Validate access authority.
        !          13003:                 */
        !          13004:                if ( (ipcaccess(&qp->msq.msg_perm) & MSG_R) == 0 ) {
        !          13005:                        u.u_error = EACCES;
        !          13006:                        break;
        !          13007:                }
        !          13008: 
        !          13009:                /*
        !          13010:                 * Copy queue info to user.
        !          13011:                 */
        !          13012:                kucopy( qp, buf, sizeof(struct msqid_ds) );
        !          13013: 
        !          13014:                /*
        !          13015:                 * Include input polls in receive waiting.
        !          13016:                 */
        !          13017:                if ( (qp->ipolls.e_dnext != NULL)
        !          13018:                  && (qp->ipolls.e_dnext != &qp->ipolls) ) {
        !          13019:                        putuwd( &buf->msg_perm.mode,
        !          13020:                                getuwd( &buf->msg_perm.mode ) | MSG_RWAIT );
        !          13021:                }
        !          13022: 
        !          13023:                /*
        !          13024:                 * Include output polls in write waiting.
        !          13025:                 */
        !          13026:                if ( (qp->opolls.e_dnext != NULL)
        !          13027:                  && (qp->opolls.e_dnext != &qp->opolls) ) {
        !          13028:                        putuwd( &buf->msg_perm.mode,
        !          13029:                                getuwd( &buf->msg_perm.mode ) | MSG_WWAIT );
        !          13030:                }
        !          13031: 
        !          13032:                /*
        !          13033:                 * Validate qid.
        !          13034:                 * Doing it now lets user get info on message queue.
        !          13035:                 */
        !          13036:                if ( qp->msq.msg_perm.seq != qid )
        !          13037:                        u.u_error = EINVAL;
        !          13038:                break;
        !          13039: 
        !          13040:        case IPC_SET:
        !          13041:                /*
        !          13042:                 * Validate modify authority.
        !          13043:                 */
        !          13044:                if ( (u.u_uid != 0) && (u.u_uid != qp->msq.msg_perm.uid) ) {
        !          13045:                        u.u_error = EPERM;
        !          13046:                        break;
        !          13047:                }
        !          13048: 
        !          13049:                /*
        !          13050:                 * Get desired queue size.
        !          13051:                 */
        !          13052:                n = getuwd( &(buf->msg_qbytes) );
        !          13053:                if (u.u_error)
        !          13054:                        break;
        !          13055: 
        !          13056:                /*
        !          13057:                 * Only super-user can increase queue size.
        !          13058:                 */
        !          13059:                if ( (u.u_uid != 0) && (n > qp->msq.msg_qbytes) ) {
        !          13060:                        u.u_error = EPERM;
        !          13061:                        break;
        !          13062:                }
        !          13063: 
        !          13064:                /*
        !          13065:                 * Set queue parameters.
        !          13066:                 */
        !          13067:                qp->msq.msg_perm.uid   = getuwd( &(buf->msg_perm.uid ) );
        !          13068:                qp->msq.msg_perm.gid   = getuwd( &(buf->msg_perm.gid ) );
        !          13069:                qp->msq.msg_perm.mode &= ~0777;
        !          13070:                qp->msq.msg_perm.mode |= getuwd( &(buf->msg_perm.mode) ) & 0777;
        !          13071:                qp->msq.msg_qbytes     = n;
        !          13072:                break;
        !          13073: 
        !          13074:        case IPC_RMID:
        !          13075:                /*
        !          13076:                 * Validate removal authority.
        !          13077:                 */
        !          13078:                if ( (u.u_uid != 0) && (u.u_uid != qp->msq.msg_perm.uid) ) {
        !          13079:                        u.u_error = EPERM;
        !          13080:                        break;
        !          13081:                }
        !          13082: 
        !          13083:                /*
        !          13084:                 * Free all messages on the queue being removed.
        !          13085:                 */
        !          13086:                while ( mp = qp->msq.msg_first ) {
        !          13087:                        qp->msq.msg_first   = mp->msg_next;
        !          13088:                        mp->msg_next        = msqs->msq.msg_first;
        !          13089:                        msqs->msq.msg_first = mp;
        !          13090:                }
        !          13091: 
        !          13092:                /*
        !          13093:                 * Wakeup processes waiting for free message buffers.
        !          13094:                 */
        !          13095:                if ( msqs->msq.msg_perm.mode & MSG_RWAIT ) {
        !          13096:                        msqs->msq.msg_perm.mode &= ~MSG_RWAIT;
        !          13097:                        wakeup( msqs );
        !          13098:                }
        !          13099:                if ( msqs->ipolls.e_procp )
        !          13100:                        pollwake( &msqs->ipolls );
        !          13101: 
        !          13102:                /*
        !          13103:                 * Initialize queue parameters.
        !          13104:                 */
        !          13105:                qp->msq.msg_last   = 0;
        !          13106:                qp->msq.msg_qnum   = 0;
        !          13107:                qp->msq.msg_cbytes = 0;
        !          13108:                if ( (qp->msq.msg_perm.seq & 0x00FF) == 0x00FF )
        !          13109:                        qp->msq.msg_perm.seq &= 0x7F00;
        !          13110:                qp->msq.msg_perm.seq++;
        !          13111: 
        !          13112:                /*
        !          13113:                 * Wakeup processes sleeping on the removed message queue.
        !          13114:                 */
        !          13115:                if ( qp->msq.msg_perm.mode & (MSG_RWAIT|MSG_WWAIT) )
        !          13116:                        wakeup( qp );
        !          13117:                if ( qp->ipolls.e_procp )
        !          13118:                        pollwake( &qp->ipolls );
        !          13119:                if ( qp->opolls.e_procp )
        !          13120:                        pollwake( &qp->opolls );
        !          13121: 
        !          13122:                qp->msq.msg_perm.mode = 0;
        !          13123:                break;
        !          13124: 
        !          13125:        default:
        !          13126:                u.u_error = EINVAL;
        !          13127:        }
        !          13128: 
        !          13129:        if ( u.u_error )
        !          13130:                return -1;
        !          13131: 
        !          13132:        return 0;
        !          13133: }
        !          13134: 
        !          13135: /*
        !          13136:  * Msgget - Get set of messages
        !          13137:  */
        !          13138: 
        !          13139: umsgget( mykey, msgflg )
        !          13140: 
        !          13141: key_t mykey;
        !          13142: int msgflg;
        !          13143: 
        !          13144: {
        !          13145:        register struct xmsqid_ds *qp;
        !          13146:        register struct xmsqid_ds *freeidp = 0;
        !          13147:        int rwmode;
        !          13148:        
        !          13149:        if ( msqs == 0 ) {
        !          13150: 
        !          13151:                msginit();
        !          13152: 
        !          13153:                if ( msqs == 0 ) {
        !          13154:                        u.u_error = ENOMEM;
        !          13155:                        return;
        !          13156:                }
        !          13157:        }
        !          13158: 
        !          13159:        /*
        !          13160:         * Extract desired access mode from flags.
        !          13161:         */
        !          13162:        rwmode = msgflg & 0777;
        !          13163: 
        !          13164:        /*
        !          13165:         * Search for desired message queue [also for first free queue].
        !          13166:         */
        !          13167:        for ( qp = &msqs[NMSQID]; --qp > msqs; ) {
        !          13168: 
        !          13169:                if ( (qp->msq.msg_perm.mode & IPC_ALLOC) == 0 ) {
        !          13170: 
        !          13171:                        if ((freeidp == 0) ||
        !          13172:                            (freeidp->msq.msg_ctime > qp->msq.msg_ctime))
        !          13173:                                freeidp = qp;
        !          13174:                        continue;
        !          13175:                }
        !          13176: 
        !          13177:                if (mykey == IPC_PRIVATE)
        !          13178:                        continue;
        !          13179: 
        !          13180:                if ( mykey == qp->msq.msg_perm.key ) {          /* found! */
        !          13181: 
        !          13182:                        if ( (msgflg & IPC_CREAT) && (msgflg & IPC_EXCL) ) {
        !          13183:                                u.u_error = EEXIST;
        !          13184:                                return -1;
        !          13185:                        }
        !          13186: 
        !          13187:                        if ( (qp->msq.msg_perm.mode & rwmode) != rwmode ) {
        !          13188:                                u.u_error = EACCES;
        !          13189:                                return -1;
        !          13190:                        }
        !          13191: 
        !          13192:                        return qp->msq.msg_perm.seq;
        !          13193:                }
        !          13194:        }
        !          13195: 
        !          13196:        if ( ! (msgflg & IPC_CREAT) ) {
        !          13197:                u.u_error = ENOENT;
        !          13198:                return -1;
        !          13199:        }
        !          13200: 
        !          13201:        if ( (qp = freeidp) == 0 ) {
        !          13202:                u.u_error = ENOSPC;
        !          13203:                return -1;
        !          13204:        }
        !          13205: 
        !          13206:        qp->msq.msg_first  = 0;
        !          13207:        qp->msq.msg_last   = 0;
        !          13208:        qp->msq.msg_cbytes = 0;
        !          13209:        qp->msq.msg_qnum   = 0;
        !          13210:        qp->msq.msg_qbytes = NMSQB;
        !          13211:        qp->msq.msg_lspid  = 0;
        !          13212:        qp->msq.msg_lrpid  = 0;
        !          13213:        qp->msq.msg_stime  = 0;
        !          13214:        qp->msq.msg_rtime  = 0;
        !          13215:        qp->msq.msg_ctime  = timer.t_time;
        !          13216: 
        !          13217:        qp->msq.msg_perm.cuid = qp->msq.msg_perm.uid = u.u_uid;
        !          13218:        qp->msq.msg_perm.cgid = qp->msq.msg_perm.gid = u.u_gid;
        !          13219:        qp->msq.msg_perm.mode = rwmode | IPC_ALLOC;
        !          13220:        qp->msq.msg_perm.key  = mykey;
        !          13221: 
        !          13222:        return qp->msq.msg_perm.seq;
        !          13223: }
        !          13224: 
        !          13225: /*
        !          13226:  * Send a Message
        !          13227:  */
        !          13228: 
        !          13229: umsgsnd( qid, bufp, msgsz, msgflg )
        !          13230: 
        !          13231: int qid;
        !          13232: struct msgbuf *bufp;
        !          13233: unsigned msgsz, msgflg;
        !          13234: 
        !          13235: {
        !          13236:        register struct xmsqid_ds * qp;
        !          13237:        register struct msg      * mp;
        !          13238: 
        !          13239:        /*
        !          13240:         * Validate queue identifier.
        !          13241:         */
        !          13242:        if ((qid <= 0) || (qid/256 >= NMSQID) || (msgsz > NMSC) || (msqs==0)) {
        !          13243:                u.u_error = EINVAL;
        !          13244:                return -1;
        !          13245:        }
        !          13246: 
        !          13247:        qp = &msqs[ qid / 256 ];
        !          13248: 
        !          13249:        /*
        !          13250:         * Validate queue existence.
        !          13251:         */
        !          13252:        if ( (qp->msq.msg_perm.seq != qid)
        !          13253:          || ((qp->msq.msg_perm.mode & IPC_ALLOC) == 0) ) {
        !          13254:                u.u_error = EINVAL;
        !          13255:                return -1;
        !          13256:        }
        !          13257: 
        !          13258:        if ((ipcaccess(&qp->msq.msg_perm) & MSG_W) == 0){ /* can't send mesg */
        !          13259:                u.u_error = EACCES;
        !          13260:                return -1;
        !          13261:        }
        !          13262: 
        !          13263:        /*
        !          13264:         * Wait for a free message buffer
        !          13265:         */
        !          13266:        while ( (msqs->msq.msg_first == 0)
        !          13267:             || (qp->msq.msg_qbytes <= qp->msq.msg_cbytes)) {
        !          13268: 
        !          13269:                if ( msgflg & IPC_NOWAIT ) {
        !          13270:                        u.u_error = EAGAIN;
        !          13271:                        return -1;
        !          13272:                }
        !          13273: 
        !          13274:                if (qp->msq.msg_qbytes <= qp->msq.msg_cbytes) {
        !          13275:                        qp->msq.msg_perm.mode |= MSG_WWAIT;
        !          13276:                        sleep( qp, CVTTOUT, IVTTOUT, SVTTOUT );
        !          13277:                }
        !          13278:                else {
        !          13279:                        msqs->msq.msg_perm.mode |= MSG_RWAIT;
        !          13280:                        sleep( msqs, CVTTOUT, IVTTOUT, SVTTOUT );
        !          13281:                }
        !          13282: 
        !          13283:                /*
        !          13284:                 * Abort if a signal was received
        !          13285:                 */
        !          13286:                if (SELF->p_ssig && nondsig() ) {
        !          13287:                        u.u_error = EINTR;
        !          13288:                        return -1;
        !          13289:                }
        !          13290: 
        !          13291:                /*
        !          13292:                 * Abort if the message queue was removed.
        !          13293:                 */
        !          13294:                if ( qid != qp->msq.msg_perm.seq ) {
        !          13295:                        u.u_error = EIDRM;
        !          13296:                        return -1;
        !          13297:                }
        !          13298:        }
        !          13299: 
        !          13300:        /*
        !          13301:         * Use first message on free message queue
        !          13302:         */
        !          13303:        mp = msqs->msq.msg_first;
        !          13304:        mp->msg_ts = msgsz;
        !          13305: 
        !          13306:        /*
        !          13307:         * Transfer the message type and text.
        !          13308:         */
        !          13309:        ukcopy( &(bufp->mtype), &(mp->msg_type), sizeof(mp->msg_type) );
        !          13310:        if ( ufcopy( &bufp->mtext[0], mp->msg_spot, msgsel, msgsz ) != msgsz )
        !          13311:                        u.u_error = EFAULT;
        !          13312: 
        !          13313:        /*
        !          13314:         * Abort if address fault occured during transfer.
        !          13315:         */
        !          13316:        if ( u.u_error )
        !          13317:                return -1;
        !          13318: 
        !          13319:        /*
        !          13320:         * Move the message to the desired queue.
        !          13321:         */
        !          13322:        msqs->msq.msg_first = mp->msg_next;
        !          13323:        mp->msg_next = 0;
        !          13324: 
        !          13325:        if ( qp->msq.msg_last )
        !          13326:                qp->msq.msg_last->msg_next = mp;
        !          13327:        else
        !          13328:                qp->msq.msg_first = mp;
        !          13329:        qp->msq.msg_last = mp;
        !          13330: 
        !          13331:        /*
        !          13332:         * Update queue statistics.
        !          13333:         */
        !          13334:        qp->msq.msg_cbytes += msgsz;
        !          13335:        qp->msq.msg_qnum++;
        !          13336:        qp->msq.msg_lspid = SELF->p_pid;
        !          13337:        qp->msq.msg_stime = timer.t_time;
        !          13338: 
        !          13339:        /*
        !          13340:         * Wake processes waiting to receive.
        !          13341:         */
        !          13342:        if ( qp->msq.msg_perm.mode & MSG_RWAIT ) {
        !          13343:                qp->msq.msg_perm.mode &= ~MSG_RWAIT;
        !          13344:                wakeup( qp );
        !          13345:        }
        !          13346:        if ( qp->ipolls.e_procp )
        !          13347:                pollwake( &qp->ipolls );
        !          13348: 
        !          13349:        return 0;
        !          13350: }
        !          13351: 
        !          13352: /*
        !          13353:  * Receive A Message
        !          13354:  */
        !          13355: 
        !          13356: umsgrcv( qid, bufp, msgsz, msgtyp, msgflg )
        !          13357: 
        !          13358: int qid;
        !          13359: struct msgbuf *bufp;
        !          13360: unsigned msgsz;
        !          13361: long msgtyp;
        !          13362: unsigned msgflg;
        !          13363: 
        !          13364: {
        !          13365:        register struct xmsqid_ds *qp;
        !          13366:        register struct msg *mp;
        !          13367:        register struct msg *prev;
        !          13368: 
        !          13369:        /*
        !          13370:         * Validate queue identifier.
        !          13371:         */
        !          13372:        if ( (qid <= 0) || (qid/256 >= NMSQID) || (msqs == 0) ) {
        !          13373:                u.u_error = EINVAL;
        !          13374:                return -1;
        !          13375:        }
        !          13376: 
        !          13377:        qp = &msqs[ qid / 256 ];
        !          13378: 
        !          13379:        /*
        !          13380:         * Validate queue existence.
        !          13381:         */
        !          13382:        if ( (qp->msq.msg_perm.seq != qid)
        !          13383:          || ((qp->msq.msg_perm.mode & IPC_ALLOC) == 0) ) {
        !          13384:                u.u_error = EINVAL;
        !          13385:                return -1;
        !          13386:        }
        !          13387: 
        !          13388:        /*
        !          13389:         * Permission denied
        !          13390:         */
        !          13391:        if ( (ipcaccess(&qp->msq.msg_perm) & MSG_R) == 0 ) {
        !          13392:                u.u_error = EACCES;
        !          13393:                return -1;
        !          13394:        }
        !          13395: 
        !          13396:        /*
        !          13397:         * Wait for message
        !          13398:         */
        !          13399:        for (;;) {
        !          13400: 
        !          13401:                mp   = qp->msq.msg_first;
        !          13402:                prev = 0;
        !          13403: 
        !          13404:                /*
        !          13405:                 * Find mesg of type <= abs(msgtyp)
        !          13406:                 */
        !          13407:                if ( msgtyp < 0 ) {
        !          13408: 
        !          13409:                        struct msg *xp, *xprev;
        !          13410:                        
        !          13411:                        xp     = 0;
        !          13412:                        xprev  = 0;
        !          13413:                        msgtyp = -msgtyp;
        !          13414: 
        !          13415:                        for ( ; mp != 0 ; prev = mp, mp = mp->msg_next ) {
        !          13416: 
        !          13417:                                if (mp->msg_type > msgtyp)
        !          13418:                                        continue;
        !          13419: 
        !          13420:                                if ((xp==0) || (mp->msg_type < xp->msg_type)) {
        !          13421:                                        xp    = mp;
        !          13422:                                        xprev = prev;
        !          13423:                                }
        !          13424:                        }
        !          13425:                        mp     = xp;
        !          13426:                        prev   = xprev;
        !          13427:                        msgtyp = -msgtyp;
        !          13428:                }
        !          13429: 
        !          13430:                /*
        !          13431:                 * Find message of type == msgtyp
        !          13432:                 */
        !          13433:                else if ( msgtyp > 0 ) {
        !          13434: 
        !          13435:                        while ( (mp != 0) && (mp->msg_type != msgtyp) ) {
        !          13436:                                prev = mp;
        !          13437:                                mp = mp->msg_next;
        !          13438:                        }
        !          13439:                }
        !          13440: 
        !          13441:                /*
        !          13442:                 * Else take first message
        !          13443:                 */
        !          13444: 
        !          13445:                if ( mp )
        !          13446:                        break;
        !          13447: 
        !          13448:                /*
        !          13449:                 * Can't wait to receive mesg
        !          13450:                 */
        !          13451:                if ( msgflg & IPC_NOWAIT ) {
        !          13452:                        u.u_error = EAGAIN;
        !          13453:                        return -1;
        !          13454:                }
        !          13455: 
        !          13456:                qp->msq.msg_perm.mode |= MSG_RWAIT;
        !          13457:                sleep( qp, CVTTOUT, IVTTOUT, SVTTOUT );
        !          13458: 
        !          13459:                /*
        !          13460:                 * Signal received
        !          13461:                 */
        !          13462:                if ( SELF->p_ssig && nondsig() ) {
        !          13463:                        u.u_error = EINTR;
        !          13464:                        return -1;
        !          13465:                }
        !          13466: 
        !          13467:                /*
        !          13468:                 * Not same q anymore
        !          13469:                 */
        !          13470:                if ( qid != qp->msq.msg_perm.seq ) {
        !          13471:                        u.u_error = EIDRM;
        !          13472:                        return -1;
        !          13473:                }
        !          13474:        }
        !          13475: 
        !          13476:        /*
        !          13477:         * Ensure entire message can be transferred, or MSG_NOERROR asserted.
        !          13478:         */
        !          13479:        if ( (msgsz < mp->msg_ts) && ((msgflg & MSG_NOERROR) == 0) ) {
        !          13480:                u.u_error = E2BIG;
        !          13481:                return -1;
        !          13482:        }
        !          13483: 
        !          13484:        /*
        !          13485:         * Transfer message data
        !          13486:         */
        !          13487:        if ( msgsz > mp->msg_ts )
        !          13488:                msgsz = mp->msg_ts;
        !          13489: 
        !          13490:        kucopy( &(mp->msg_type), &(bufp->mtype), sizeof(mp->msg_type) );
        !          13491:        if (fucopy( mp->msg_spot, msgsel, &(bufp->mtext[0]), msgsz ) != msgsz)
        !          13492:                u.u_error = EFAULT;
        !          13493: 
        !          13494:        /*
        !          13495:         * Abort if address fault occurred during transfer.
        !          13496:         */
        !          13497:        if ( u.u_error )
        !          13498:                return -1;
        !          13499: 
        !          13500:        /*
        !          13501:         * Remove message from queue
        !          13502:         */
        !          13503:        if ( prev )
        !          13504:                prev->msg_next = mp->msg_next;
        !          13505:        else
        !          13506:                qp->msq.msg_first = mp->msg_next;
        !          13507: 
        !          13508:        if ( qp->msq.msg_last == mp )
        !          13509:                qp->msq.msg_last = prev;
        !          13510: 
        !          13511:        /*
        !          13512:         * Update queue statistics
        !          13513:         */
        !          13514:        qp->msq.msg_cbytes -= mp->msg_ts;
        !          13515:        qp->msq.msg_qnum--;
        !          13516:        qp->msq.msg_lrpid = SELF->p_pid;
        !          13517:        qp->msq.msg_rtime = timer.t_time;
        !          13518: 
        !          13519:        /*
        !          13520:         * Wakeup processes waiting to send.
        !          13521:         */
        !          13522:        if (qp->msq.msg_perm.mode & MSG_WWAIT) {
        !          13523:                qp->msq.msg_perm.mode &= ~MSG_WWAIT;
        !          13524:                wakeup( qp );
        !          13525:        }
        !          13526:        if ( qp->opolls.e_procp )
        !          13527:                pollwake( &qp->opolls );
        !          13528: 
        !          13529:        /*
        !          13530:         * Place message buffer on free message queue
        !          13531:         */
        !          13532:        qp = msqs;
        !          13533:        mp->msg_next = qp->msq.msg_first;
        !          13534:        qp->msq.msg_first = mp;
        !          13535: 
        !          13536:        /*
        !          13537:         * Wakeup processes waiting for empty message buffer
        !          13538:         */
        !          13539:        if ( qp->msq.msg_perm.mode & MSG_RWAIT ) {
        !          13540:                qp->msq.msg_perm.mode &= ~MSG_RWAIT;
        !          13541:                wakeup( qp );
        !          13542:        }
        !          13543:        if ( msqs->ipolls.e_procp )
        !          13544:                pollwake( &msqs->ipolls );
        !          13545: 
        !          13546:        return msgsz;
        !          13547: }
        !          13548: 
        !          13549: /*
        !          13550:  * Msgpoll - Message Queue Polling.
        !          13551:  */
        !          13552: msgpoll( qid, ev, msec )
        !          13553: int qid;
        !          13554: int ev;
        !          13555: int msec;
        !          13556: {
        !          13557:        register struct xmsqid_ds * qp;
        !          13558: 
        !          13559:        /*
        !          13560:         * Validate queue identifier.
        !          13561:         */
        !          13562:        if ( (qid <= 0) || (qid/256 >= NMSQID) || (msqs == 0) )
        !          13563:                return POLLNVAL;
        !          13564: 
        !          13565:        qp = &msqs[ qid / 256 ];
        !          13566: 
        !          13567:        /*
        !          13568:         * Validate queue existence.
        !          13569:         */
        !          13570:        if ( ((qp->msq.msg_perm.mode & IPC_ALLOC) == 0)
        !          13571:          || (qp->msq.msg_perm.seq != qid) )
        !          13572:                return POLLHUP;
        !          13573: 
        !          13574:        /*
        !          13575:         * Priority polls not supported.
        !          13576:         */
        !          13577:        ev &= ~POLLPRI;
        !          13578: 
        !          13579:        /*
        !          13580:         * Input poll.
        !          13581:         */
        !          13582:        if ( ev & POLLIN ) {
        !          13583: 
        !          13584:                /*
        !          13585:                 * No messages on queue.
        !          13586:                 */
        !          13587:                if ( qp->msq.msg_qnum == 0 ) {
        !          13588:                        /*
        !          13589:                         * Enable input monitor.
        !          13590:                         */
        !          13591:                        if ( msec != 0 )
        !          13592:                                pollopen( &qp->ipolls );
        !          13593:                        ev &= ~POLLIN;
        !          13594:                }
        !          13595: 
        !          13596:                /*
        !          13597:                 * Prevent output monitor.
        !          13598:                 */
        !          13599:                else
        !          13600:                        msec = 0;
        !          13601:        }
        !          13602: 
        !          13603:        /*
        !          13604:         * Output poll.
        !          13605:         */
        !          13606:        if ( ev & POLLOUT ) {
        !          13607: 
        !          13608:                /*
        !          13609:                 * Queue full.
        !          13610:                 */
        !          13611:                if ( qp->msq.msg_cbytes >= qp->msq.msg_qbytes ) {
        !          13612:                        if ( msec != 0 )
        !          13613:                                pollopen( &qp->opolls );
        !          13614:                        ev &= ~POLLOUT;
        !          13615:                }
        !          13616: 
        !          13617:                /*
        !          13618:                 * No free message buffers.
        !          13619:                 */
        !          13620:                else if ( msqs->msq.msg_first == NULL ) {
        !          13621:                        if ( msec != 0 )
        !          13622:                                pollopen( &msqs->ipolls );
        !          13623:                        ev &= ~POLLOUT;
        !          13624:                }
        !          13625:        }
        !          13626: 
        !          13627:        return ev;
        !          13628: }
        !          13629: 0707070064030034531004440000030000030000011777770507310637300005200000006107/newbits/kernel/USRSRC/i8086/drv/msgcon.c/* $Header: /usr/src/sys/i8086/drv/RCS/msgcon.c,v 2.1 88/09/03 13:09:32 src Exp $
        !          13630:  *
        !          13631:  *     The  information  contained herein  is a trade secret  of INETCO
        !          13632:  *     Systems, and is confidential information.   It is provided under
        !          13633:  *     a license agreement,  and may be copied or disclosed  only under
        !          13634:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          13635:  *     this  material  without  the express  written  authorization  of
        !          13636:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          13637:  *
        !          13638:  *     Copyright (c) 1987, 1985, 1984.
        !          13639:  *     An unpublished work by INETCO Systems, Ltd.
        !          13640:  *     All rights reserved.
        !          13641:  */
        !          13642: 
        !          13643: /*
        !          13644:  * System V Compatible Message Device Driver
        !          13645:  *
        !          13646:  *     This device driver provides System V compatible messaging operations.
        !          13647:  *     Operations are performed through the message device (/dev/msg).
        !          13648:  *     and are implemented as ioctl calls from msgctl, msgget, msgsnd, msgrcv
        !          13649:  *     utilities.
        !          13650:  *
        !          13651:  *                     Author: Allan Cornish, INETCO Systems Ltd., Oct 1984
        !          13652:  *
        !          13653:  * $Log:       /usr/src/sys/i8086/drv/RCS/msgcon.c,v $
        !          13654:  * Revision 2.1        88/09/03  13:09:32      src
        !          13655:  * *** empty log message ***
        !          13656:  * 
        !          13657:  * Revision 1.1        88/03/24  17:05:49      src
        !          13658:  * Initial revision
        !          13659:  * 
        !          13660:  * 87/03/02    Allan Cornish           /usr/src/sys/i8086/drv/msgcon.c
        !          13661:  * Msgioctl() now supports long key [was short] on MSGGET operations.
        !          13662:  * This allows compatability with System V.
        !          13663:  *
        !          13664:  * 85/08/06    Allan Cornish
        !          13665:  * Msg.c split into configuration (msgcon.c) and implementation (msg.c).
        !          13666:  *
        !          13667:  * 85/07/03    Allan Cornish
        !          13668:  * Simplified msgopen by ignoring minor device, which previously had to be 0.
        !          13669:  *
        !          13670:  * 84/01/30    Allan Cornish
        !          13671:  * Initial revision.
        !          13672:  */
        !          13673: 
        !          13674: #include <coherent.h>
        !          13675: #include <types.h>
        !          13676: #include <uproc.h>
        !          13677: #include <errno.h>
        !          13678: #include <con.h>
        !          13679: #include <msg.h>
        !          13680: 
        !          13681: /*
        !          13682:  * Functions.
        !          13683:  */
        !          13684: 
        !          13685: int msgopen();
        !          13686: int msgioctl();
        !          13687: int nulldev();
        !          13688: int nonedev();
        !          13689: 
        !          13690: /*
        !          13691:  * Device Configuration.
        !          13692:  */
        !          13693: 
        !          13694: CON msgcon = {
        !          13695:        DFCHR,                  /* Flags                        */
        !          13696:        25,                     /* Major Index                  */
        !          13697:        msgopen,                /* Open                         */
        !          13698:        nulldev,                /* Close                        */
        !          13699:        nonedev,                /* Block                        */
        !          13700:        nonedev,                /* Read                         */
        !          13701:        nonedev,                /* Write                        */
        !          13702:        msgioctl,               /* Ioctl                        */
        !          13703:        nulldev,                /* Power fail                   */
        !          13704:        nulldev,                /* Timeout                      */
        !          13705:        nulldev,                /* Load                         */
        !          13706:        nulldev                 /* Unload                       */
        !          13707: };
        !          13708: 
        !          13709: /*
        !          13710:  * Message Device Open.
        !          13711:  */
        !          13712: 
        !          13713: static
        !          13714: msgopen( dev, mode )
        !          13715: 
        !          13716: dev_t dev;
        !          13717: int mode;
        !          13718: 
        !          13719: {
        !          13720:        extern struct msqid_ds * msqs; /* Pointer to array of message queues */
        !          13721: 
        !          13722:        if ( ! msqs )                   /* message queues not initialized */
        !          13723:                msginit();
        !          13724: 
        !          13725:        if ( ! msqs )                   /* no message queues */
        !          13726:                u.u_error = ENODEV;
        !          13727: }
        !          13728: 
        !          13729: /*
        !          13730:  * Message Device Ioctl.
        !          13731:  */
        !          13732: 
        !          13733: static
        !          13734: msgioctl( dev, com, vec )
        !          13735: 
        !          13736: dev_t dev;
        !          13737: int com;
        !          13738: register int *vec;
        !          13739: 
        !          13740: {
        !          13741:        switch ( com ) {
        !          13742: 
        !          13743:        case MSGCTL:
        !          13744:                putuwd( vec+0,
        !          13745:                        umsgctl(getuwd( vec+1 ),
        !          13746:                                getuwd( vec+2 ),
        !          13747:                                getuwd( vec+3 ) ));
        !          13748:                return;
        !          13749: 
        !          13750:        case MSGGET:
        !          13751:                putuwd( vec+0,
        !          13752:                        umsgget(getuwd( vec+1 ),
        !          13753:                                getuwd( vec+2 ),
        !          13754:                                getuwd( vec+3 ) ));
        !          13755:                return;
        !          13756: 
        !          13757:        case MSGSND:
        !          13758:                putuwd( vec+0,
        !          13759:                        umsgsnd(getuwd( vec+1 ),
        !          13760:                                getuwd( vec+2 ),
        !          13761:                                getuwd( vec+3 ),
        !          13762:                                getuwd( vec+4 ) ));
        !          13763:                return;
        !          13764: 
        !          13765:        case MSGRCV:
        !          13766:                putuwd( vec+0,
        !          13767:                        umsgrcv(getuwd( vec+1 ),
        !          13768:                                getuwd( vec+2 ),
        !          13769:                                getuwd( vec+3 ),
        !          13770:                                getuwd( vec+4 ),
        !          13771:                                getuwd( vec+5 ),
        !          13772:                                getuwd( vec+6 ) ));
        !          13773:                return;
        !          13774: 
        !          13775:        default:
        !          13776:                u.u_error = EINVAL;
        !          13777:                return;
        !          13778:        }
        !          13779: }
        !          13780: 0707070064030073621006440000030000030000011777770507310637400005100000003246/newbits/kernel/USRSRC/i8086/drv/msgop.c/*
        !          13781:  * User Message Functions.
        !          13782:  *
        !          13783:  *     Note: msgget() must be first function called.
        !          13784:  *
        !          13785:  *     91/02/07        Hal Snyder      mwchwc!/u/libc/sys/msgop.c
        !          13786:  *     msgget():  sizeof(key_t) is 4, not 2.
        !          13787:  */
        !          13788: #include <sys/msg.h>
        !          13789: #include <errno.h>
        !          13790: 
        !          13791: static int  msgfno   = -1;
        !          13792: static char msgdev[] = "/dev/msg";
        !          13793: 
        !          13794: /*
        !          13795:  * Message Control Operations.
        !          13796:  */
        !          13797: 
        !          13798: msgctl( msqid, cmd, buf )
        !          13799: 
        !          13800: int msqid;
        !          13801: int cmd;
        !          13802: struct msqid_ds * buf;
        !          13803: 
        !          13804: {
        !          13805:        int parm[4];
        !          13806: 
        !          13807:        if ( msgfno < 0 ) {
        !          13808:                errno = ENODEV;
        !          13809:                return -1;
        !          13810:        }
        !          13811: 
        !          13812:        parm[0] = -1;
        !          13813:        parm[1] = msqid;
        !          13814:        parm[2] = cmd;
        !          13815:        parm[3] = (int) buf;
        !          13816: 
        !          13817:        ioctl( msgfno, MSGCTL, parm );
        !          13818:        return parm[0];
        !          13819: }
        !          13820: 
        !          13821: /*
        !          13822:  * Get Message Queue.
        !          13823:  */
        !          13824: 
        !          13825: msgget( key, msgflg )
        !          13826: 
        !          13827: key_t key;
        !          13828: int msgflg;
        !          13829: 
        !          13830: {
        !          13831:        int parm[4];
        !          13832: 
        !          13833:        if ( msgfno < 0 ) {
        !          13834: 
        !          13835:                msgfno = open(msgdev, 0);
        !          13836: 
        !          13837:                if ( msgfno < 0 ) {
        !          13838:                        perror(msgdev);
        !          13839:                        errno = ENODEV;
        !          13840:                        return -1;
        !          13841:                }
        !          13842:        }
        !          13843: 
        !          13844:        parm[0] = -1;
        !          13845:        parm[1] = key;
        !          13846:        parm[2] = key >> 16;
        !          13847:        parm[3] = msgflg;
        !          13848: 
        !          13849:        ioctl( msgfno, MSGGET, parm );
        !          13850:        return parm[0];
        !          13851: }
        !          13852: 
        !          13853: /*
        !          13854:  * Send Message.
        !          13855:  */
        !          13856:  
        !          13857: msgsnd( msqid, msgp, msgsz, msgflg )
        !          13858: 
        !          13859: int msqid;
        !          13860: struct msgbuf *msgp;
        !          13861: int msgsz;
        !          13862: int msgflg;
        !          13863: 
        !          13864: {
        !          13865:        int parm[5];
        !          13866: 
        !          13867:        if ( msgfno < 0 ) {
        !          13868:                errno = ENODEV;
        !          13869:                return -1;
        !          13870:        }
        !          13871: 
        !          13872:        parm[0] = -1;
        !          13873:        parm[1] = msqid;
        !          13874:        parm[2] = (int) msgp;
        !          13875:        parm[3] = msgsz;
        !          13876:        parm[4] = msgflg;
        !          13877: 
        !          13878:        ioctl( msgfno, MSGSND, parm );
        !          13879:        return parm[0];
        !          13880: }
        !          13881: 
        !          13882: /*
        !          13883:  * Receive Message.
        !          13884:  */
        !          13885:  
        !          13886: msgrcv( msqid, msgp, msgsz, msgtyp, msgflg )
        !          13887: 
        !          13888: int msqid;
        !          13889: struct msgbuf *msgp;
        !          13890: int msgsz;
        !          13891: long msgtyp;
        !          13892: int msgflg;
        !          13893: 
        !          13894: {
        !          13895:        int parm[7];
        !          13896: 
        !          13897:        if ( msgfno < 0 ) {
        !          13898:                errno = ENODEV;
        !          13899:                return -1;
        !          13900:        }
        !          13901: 
        !          13902:        parm[0] = -1;
        !          13903:        parm[1] = msqid;
        !          13904:        parm[2] = (int) msgp;
        !          13905:        parm[3] = msgsz;
        !          13906:        parm[4] = (int) msgtyp;
        !          13907:        parm[5] = (int) (msgtyp >> 16);
        !          13908:        parm[6] = msgflg;
        !          13909: 
        !          13910:        ioctl( msgfno, MSGRCV, parm );
        !          13911:        return parm[0];
        !          13912: }
        !          13913: 0707070064030034641006440000030000030000011777770507310637400004700000045224/newbits/kernel/USRSRC/i8086/drv/nkb.c/*
        !          13914:  * User configurable AT keyboard/display driver.
        !          13915:  * AT COHERENT
        !          13916:  */
        !          13917: #include <sys/coherent.h>
        !          13918: #include <sys/i8086.h>
        !          13919: #include <sys/con.h>
        !          13920: #include <errno.h>
        !          13921: #include <sys/stat.h>
        !          13922: #include <sys/tty.h>
        !          13923: #include <sys/uproc.h>
        !          13924: #include <signal.h>
        !          13925: #include <sys/seg.h>
        !          13926: #include <sys/sched.h>
        !          13927: #include <sys/kb.h>
        !          13928: 
        !          13929: #define        ISMAJ           2               /* Keyboard major device */
        !          13930: #define        ISVEC           1               /* Keyboard interrupt vector */
        !          13931: 
        !          13932: #if    DEBUG
        !          13933: #define        KBDEBUG(x)      printf(x)       /* debugging output */
        !          13934: #define        KBDEBUG2(x,y)   printf(x,y)     /* debugging output */
        !          13935: #define        KBDEBUG3(x,y,z) printf(x,y,z)   /* debugging output */
        !          13936: #else
        !          13937: #define        KBDEBUG(x)                      /* no output */
        !          13938: #define        KBDEBUG2(x,y)                   /* no output */
        !          13939: #define        KBDEBUG3(x,y,z)                 /* no output */
        !          13940: #endif
        !          13941: 
        !          13942: /*
        !          13943:  * values for kbstate
        !          13944:  */
        !          13945: #define        KB_IDLE         0               /* nothing going on right now */
        !          13946: #define        KB_SINGLE       1               /* sent a single byte cmd to the kbd */
        !          13947: #define        KB_DOUBLE_1     2               /* sent 1st byte of 2-byte cmd to kbd */
        !          13948: #define        KB_DOUBLE_2     3               /* sent 2nd byte of 2-byte cmd to kbd */
        !          13949: 
        !          13950: /*
        !          13951:  * patchable params for non-standard keyboards
        !          13952:  */
        !          13953: int    KBDATA = 0x60;                  /* Keyboard data */
        !          13954: int    KBCTRL = 0x61;                  /* Keyboard control */
        !          13955: int    KBSTS_CMD = 0x64;               /* Keyboard status/command */
        !          13956: int    KBFLAG = 0x80;                  /* Keyboard reset flag */
        !          13957: int    KBBOOT = 1;                     /* 0: disallow reboot from keyboard */
        !          13958: int    KBTIMEOUT = 10000;              /* shouldn't need this much */
        !          13959: int    KBCMDBYTE = 0x05;               /* no translation */
        !          13960: 
        !          13961: /*
        !          13962:  * KBSTATUS bits
        !          13963:  */
        !          13964: #define        STS_OBUF_FULL   0x01            /* kbd output buffer full */
        !          13965: #define        STS_IBUF_FULL   0x02            /* kbd input buffer full */
        !          13966: #define        STS_SYSTEM      0x04
        !          13967: #define        STS_CMD_DATA    0x08            /* 1: command or status */
        !          13968: #define        STS_INHIBIT     0x10            /* 0: keyboard inhibited */
        !          13969: #define        STS_AUX_OBUF_FULL       0x20
        !          13970: #define        STS_TIMEOUT     0x40            /* general timeout */
        !          13971: #define        STS_PAR_ERR     0x80            /* parity error */
        !          13972: 
        !          13973: /*
        !          13974:  * The following are magic commands which read from or write to the
        !          13975:  * controller command byte. These get output to the KBSTS_CMD port.
        !          13976:  */
        !          13977: #define        C_READ_CMD      0x20            /* read controller command byte */
        !          13978: #define        C_WRITE_CMD     0x60            /* write controller command byte */
        !          13979: #define        C_TRANSLATE     0x40            /* translate enable bit in cmd byte */
        !          13980: 
        !          13981: /*
        !          13982:  * Globals
        !          13983:  * The keyboard mapping table is too large to fit into kernel data space,
        !          13984:  * so we need to allocate a segment to it.
        !          13985:  * The function keys tend to be small and tend to change substantially
        !          13986:  * more often than the mapping table, so we keep them in the kernel data space.
        !          13987:  */
        !          13988: static unsigned shift;                 /* state of all shift/lock keys */
        !          13989: static SEG     *kbsegp;                /* keyboard table segment */
        !          13990: static unsigned char   **funkeyp = 0;  /* ptr to array of func. keys ptrs */
        !          13991: static FNKEY   *fnkeys = 0;            /* pointer to structure of values */
        !          13992: static unsigned fklength;              /* length of k_fnval field in fnkeys */
        !          13993: static unsigned prev_cmd;              /* previous command sent to KBD */
        !          13994: static unsigned cmd2;                  /* 2nd byte of command to KBD */
        !          13995: static unsigned sh_index;              /* shift/lock state index */
        !          13996: 
        !          13997: /*
        !          13998:  * State variables.
        !          13999:  */
        !          14000: int            islock;                 /* Keyboard locked flag */
        !          14001: int            isbusy;                 /* Raw input conversion busy */
        !          14002: static char    table_loaded;           /* true == keyboard table resident */
        !          14003: static char    fk_loaded;              /* true == function keys resident */
        !          14004: static int     kbstate = KB_IDLE;      /* current keyboard state */
        !          14005: 
        !          14006: /*
        !          14007:  * Functions.
        !          14008:  */
        !          14009: int            isrint();
        !          14010: int            istime();
        !          14011: void           isbatch();
        !          14012: int            mmstart();
        !          14013: int            isopen();
        !          14014: int            isclose();
        !          14015: int            isread();
        !          14016: int            mmwrite();
        !          14017: int            isioctl();
        !          14018: void           mmwatch();
        !          14019: int            isload();
        !          14020: int            isuload();
        !          14021: int            ispoll();
        !          14022: int            nulldev();
        !          14023: int            nonedev();
        !          14024: int            updleds();
        !          14025: 
        !          14026: /*
        !          14027:  * Configuration table.
        !          14028:  */
        !          14029: CON iscon ={
        !          14030:        DFCHR|DFPOL,                    /* Flags */
        !          14031:        ISMAJ,                          /* Major index */
        !          14032:        isopen,                         /* Open */
        !          14033:        isclose,                        /* Close */
        !          14034:        nulldev,                        /* Block */
        !          14035:        isread,                         /* Read */
        !          14036:        mmwrite,                        /* Write */
        !          14037:        isioctl,                        /* Ioctl */
        !          14038:        nulldev,                        /* Powerfail */
        !          14039:        mmwatch,                        /* Timeout */
        !          14040:        isload,                         /* Load */
        !          14041:        isuload,                        /* Unload */
        !          14042:        ispoll                          /* Poll */
        !          14043: };
        !          14044: 
        !          14045: /*
        !          14046:  * Terminal structure.
        !          14047:  */
        !          14048: TTY    istty = {
        !          14049:        {0}, {0}, 0, mmstart, NULL, 0, 0
        !          14050: };
        !          14051: 
        !          14052: /*
        !          14053:  * Load entry point.
        !          14054:  */
        !          14055: isload()
        !          14056: {
        !          14057:        kbstate = KB_IDLE;
        !          14058:        table_loaded = 0;               /* no keyboard table yet */
        !          14059:        fk_loaded = 0;                  /* no Fn keys yet */
        !          14060: 
        !          14061:        /*
        !          14062:         * Enable mmwatch() invocation every second.
        !          14063:         */
        !          14064:        drvl[ISMAJ].d_time = 1;
        !          14065: 
        !          14066:        /*
        !          14067:         * Seize keyboard interrupt.
        !          14068:         */
        !          14069:        setivec(ISVEC, isrint);
        !          14070: 
        !          14071:        /*
        !          14072:         * Initiailize video display.
        !          14073:         */
        !          14074:        mmstart( &istty );
        !          14075: 
        !          14076:        /*
        !          14077:         * Allocate a segment to store the in-core keyboard table.
        !          14078:         * This would be a lot more convenient in kernel data space,
        !          14079:         * but small model COHERENT doesn't have that luxury.
        !          14080:         */
        !          14081:        kbsegp = salloc((fsize_t)MAX_TABLE_SIZE, SFSYST|SFNSWP|SFHIGH);
        !          14082:        if (kbsegp == (SEG *)0)
        !          14083:                printf("kb: unable to allocate keyboard table segment\n");
        !          14084:        fklength = 0;
        !          14085:        KBDEBUG("Exiting kbload()\n");
        !          14086: }
        !          14087: 
        !          14088: /*
        !          14089:  * Unload entry point.
        !          14090:  */
        !          14091: isuload()
        !          14092: {
        !          14093:        if (kbstate != KB_IDLE)
        !          14094:                printf("kb: keyboard busy during unload\n");
        !          14095:        clrivec(ISVEC);
        !          14096:        if (kbsegp != (SEG *)0) {
        !          14097:                table_loaded = 0;
        !          14098:                sfree(kbsegp);
        !          14099:        }
        !          14100: }
        !          14101: 
        !          14102: /*
        !          14103:  * Open routine.
        !          14104:  */
        !          14105: isopen(dev)
        !          14106: dev_t dev;
        !          14107: {
        !          14108:        register int s;
        !          14109: 
        !          14110:        KBDEBUG(" kbopen()");
        !          14111:        if (minor(dev) != 0) {
        !          14112:                u.u_error = ENXIO;
        !          14113:                return;
        !          14114:        }
        !          14115:        if ((istty.t_flags&T_EXCL) != 0 && !super()) {
        !          14116:                u.u_error = ENODEV;
        !          14117:                return;
        !          14118:        }
        !          14119:        ttsetgrp(&istty, dev);
        !          14120: 
        !          14121:        s = sphi();
        !          14122:        if (istty.t_open++ == 0) {
        !          14123:                istty.t_flags = T_CARR; /* indicate "carrier" */
        !          14124:                ttopen(&istty);
        !          14125:        }
        !          14126:        spl(s);
        !          14127: #if 0
        !          14128:        updleds();                      /* update keyboard status LEDS */
        !          14129: #endif
        !          14130: }
        !          14131: 
        !          14132: /*
        !          14133:  * Close a tty.
        !          14134:  */
        !          14135: isclose(dev)
        !          14136: {
        !          14137:        register int s;
        !          14138: 
        !          14139:        s = sphi();
        !          14140:        if (--istty.t_open == 0) {
        !          14141:                ttclose(&istty);
        !          14142:        }
        !          14143:        spl(s);
        !          14144: }
        !          14145: 
        !          14146: /*
        !          14147:  * Read routine.
        !          14148:  */
        !          14149: isread(dev, iop)
        !          14150: dev_t dev;
        !          14151: IO *iop;
        !          14152: {
        !          14153:        ttread(&istty, iop, 0);
        !          14154:        if (istty.t_oq.cq_cc)
        !          14155:                mmtime(&istty);
        !          14156: }
        !          14157: 
        !          14158: /*
        !          14159:  * Ioctl routine.
        !          14160:  * nb: archaic TIOCSHIFT and TIOCCSHIFT no longer needed/supported.
        !          14161:  */
        !          14162: isioctl(dev, com, vec)
        !          14163: dev_t dev;
        !          14164: struct sgttyb *vec;
        !          14165: {
        !          14166:        register int s;
        !          14167: 
        !          14168:        switch (com) {
        !          14169:        case TIOCSETF:
        !          14170:        case TIOCGETF:
        !          14171:                isfunction(com, (char *)vec);
        !          14172:                break;
        !          14173:        case TIOCSETKBT:
        !          14174:                issettable(vec);
        !          14175:                break;
        !          14176:        case TIOCGETKBT:
        !          14177:                isgettable(vec);
        !          14178:                break;
        !          14179:        default:                                /* pass to TTY driver */
        !          14180:                s = sphi();
        !          14181:                ttioctl(&istty, com, vec);
        !          14182:                spl(s);
        !          14183:                break;
        !          14184:        }
        !          14185: }
        !          14186: 
        !          14187: /*
        !          14188:  * Set the in-core keyboard mapping table.
        !          14189:  * The table is sorted by scan code prior to calling ioctl().
        !          14190:  * All unused table entries (holes in the scan code map) have
        !          14191:  * a zero for the k_key field.
        !          14192:  * This makes key lookup at interrupt time fast by using the scan code
        !          14193:  * as an index into the table.
        !          14194:  */
        !          14195: issettable(vec)
        !          14196: char   *vec;
        !          14197: {
        !          14198:        register unsigned i;
        !          14199:        register int s;
        !          14200:        int timeout;
        !          14201:        register faddr_t faddr;         /* address of keyboard table */
        !          14202:        static  KBTBL   this_key;       /* current key from kbd table */
        !          14203:        unsigned int cmd_byte;
        !          14204: 
        !          14205:        KBDEBUG(" TIOCSETKBT");
        !          14206:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
        !          14207:        kb_cmd(K_ALL_TMB_CMD);                  /* default: TMB for all keys */
        !          14208:        faddr = kbsegp->s_faddr;
        !          14209:        for (i = 0; i < MAX_KEYS; ++i) {
        !          14210:                ukcopy(vec, &this_key, sizeof(this_key));
        !          14211:                kfcopy(&this_key, faddr, sizeof(this_key));
        !          14212:                faddr += sizeof(this_key);
        !          14213:                vec += sizeof(this_key);
        !          14214:                if (this_key.k_key != i && this_key.k_key != 0) {
        !          14215:                        printf("kb: incorrect or unsorted table entry %d\n", i);
        !          14216:                        u.u_error = EBADFMT;
        !          14217:                        return;
        !          14218:                }
        !          14219:                if (this_key.k_key != i)
        !          14220:                        continue;               /* no key */
        !          14221:                switch (this_key.k_flags&TMODE) {
        !          14222:                case T:                         /* typematic */
        !          14223:                        kb_cmd2(K_KEY_T_CMD, i);
        !          14224:                        break;
        !          14225:                case M:                         /* make only */
        !          14226:                        kb_cmd2(K_KEY_M_CMD, i);
        !          14227:                        break;
        !          14228:                case MB:                        /* make/break */
        !          14229:                        kb_cmd2(K_KEY_MB_CMD, i);
        !          14230:                        break;
        !          14231:                case TMB:                       /* typematic make/break */
        !          14232:                        break;                  /* this is the default */
        !          14233:                default:
        !          14234:                        printf("kb: bad key mode\n");
        !          14235:                }
        !          14236:        }
        !          14237:        updleds();
        !          14238:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
        !          14239:        kb_cmd(K_ENABLE_CMD);                   /* start scanning */
        !          14240:        /*
        !          14241:         * The following code disables translation from the on-board
        !          14242:         * keyboard/aux controller. Without disabling translation, the
        !          14243:         * received scan codes still look like code set 1 codes even
        !          14244:         * though we put the keyboard controller in scan code set 3.
        !          14245:         * Yes, this is progress....
        !          14246:         */
        !          14247: #if 0
        !          14248:        while (inb(KBSTS_CMD) & STS_IBUF_FULL)
        !          14249:                ;
        !          14250:        outb(KBSTS_CMD, C_READ_CMD);            /* read controller cmd byte */
        !          14251:        while (!(inb(KBSTS_CMD) & STS_OBUF_FULL))
        !          14252:                ;
        !          14253:        cmd_byte = inb(KBDATA);
        !          14254:        KBDEBUG2(" cmd_byte=%x", cmd_byte);
        !          14255: #endif
        !          14256:        timeout = KBTIMEOUT;
        !          14257:        s = sphi();
        !          14258:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
        !          14259:                ;
        !          14260:        outb(KBSTS_CMD, C_WRITE_CMD);           /* write controller cmd byte */
        !          14261:        for (timeout = 50; --timeout > 0; )
        !          14262:                ;
        !          14263:        timeout = KBTIMEOUT;
        !          14264:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
        !          14265:                ;
        !          14266:        outb(KBDATA, KBCMDBYTE);                 /* turn off translation */     
        !          14267:        timeout = KBTIMEOUT;
        !          14268:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
        !          14269:                ;
        !          14270:        spl(s);
        !          14271: #if DEBUG
        !          14272:        kb_cmd2(K_SCANCODE_CMD, 0);             /* query s.c. mode */
        !          14273: #endif
        !          14274:        ++table_loaded;
        !          14275: }
        !          14276: 
        !          14277: /*
        !          14278:  * Get the in-core keyboard mapping table and pass it to the user.
        !          14279:  */
        !          14280: isgettable(vec)
        !          14281: char   *vec;
        !          14282: {
        !          14283:        register unsigned i;
        !          14284:        register faddr_t faddr;         /* address of keyboard table */
        !          14285:        static  KBTBL   this_key;       /* current key from kbd table */
        !          14286: 
        !          14287:        KBDEBUG(" TIOCGETKBT");
        !          14288:        faddr = kbsegp->s_faddr;
        !          14289:        for (i = 0; i < MAX_KEYS; ++i) {
        !          14290:                fkcopy( faddr, &this_key, sizeof(this_key));
        !          14291:                kucopy( &this_key, vec, sizeof(this_key));
        !          14292:                faddr += sizeof(this_key);
        !          14293:                vec += sizeof(this_key);
        !          14294:        }
        !          14295: }
        !          14296: 
        !          14297: /*
        !          14298:  * Set and receive the function keys.
        !          14299:  */
        !          14300: isfunction(c, v)
        !          14301: int c;
        !          14302: FNKEY *v;
        !          14303: {
        !          14304:        register unsigned char *cp;
        !          14305:        register unsigned i;
        !          14306:        unsigned char   numkeys = 0;
        !          14307: 
        !          14308:        if (c == TIOCGETF) {
        !          14309:                KBDEBUG(" TIOCGETF");
        !          14310:                if (!fk_loaded)
        !          14311:                        u.u_error = EINVAL;
        !          14312:                else
        !          14313:                        kucopy(fnkeys, v, fklength);    /* copy ours to user */
        !          14314:        } else { /* TIOCSETF */
        !          14315:                /*
        !          14316:                 * If we had a previous function key arena, free it up.
        !          14317:                 * Since we don't know how large the function key arena will
        !          14318:                 * be, we must size it in the user data space prior to
        !          14319:                 * (re)kalloc()'ing it. This is ugly, but a helluva lot better
        !          14320:                 * than the old driver which used a hard coded limit of 150!
        !          14321:                 */
        !          14322:                KBDEBUG(" TIOCSETF");
        !          14323:                fk_loaded = 0;
        !          14324:                if (fnkeys != (FNKEY *)0)
        !          14325:                        kfree(fnkeys);          /* free old arena */
        !          14326:                if (funkeyp != NULL)
        !          14327:                        kfree(funkeyp);         /* free old ptr array */
        !          14328:                ukcopy(&v->k_nfkeys, &numkeys, sizeof(numkeys));
        !          14329:                fklength = sizeof(FNKEY);
        !          14330:                cp = v->k_fnval;
        !          14331:                for (i = 0; i < numkeys; i++) {
        !          14332:                        do {
        !          14333:                                ++fklength;
        !          14334:                        } while (getubd(cp++) != DELIM);
        !          14335:                }
        !          14336:                fnkeys = (FNKEY *)kalloc(fklength);
        !          14337:                funkeyp = (unsigned char **)kalloc(numkeys * sizeof(char *));
        !          14338:                if (fnkeys == (FNKEY *)0 || funkeyp == NULL) {
        !          14339:                        if (fnkeys != (FNKEY *)0) {
        !          14340:                                kfree(fnkeys);
        !          14341:                                fnkeys = 0;
        !          14342:                        }
        !          14343:                        if (funkeyp != NULL) {
        !          14344:                                kfree(funkeyp);
        !          14345:                                funkeyp = 0;
        !          14346:                        }
        !          14347:                        u.u_error = ENOMEM;
        !          14348:                        return;
        !          14349:                }
        !          14350:                cp = fnkeys->k_fnval;                   /* point to Fn ... */
        !          14351:                v = v->k_fnval;                         /* ... key arena */
        !          14352:                for (i = 0; i < numkeys; i++) {
        !          14353:                        funkeyp[i] = cp;                   /* save pointer */
        !          14354:                        while ((*cp++ = getubd(v++)) != DELIM)  /* copy key */
        !          14355:                                ;
        !          14356:                }
        !          14357:                fnkeys->k_nfkeys = numkeys;
        !          14358:                fk_loaded = 1;
        !          14359:        }
        !          14360: }
        !          14361: 
        !          14362: 
        !          14363: /*
        !          14364:  * Poll routine.
        !          14365:  */
        !          14366: ispoll( dev, ev, msec )
        !          14367: dev_t dev;
        !          14368: int ev;
        !          14369: int msec;
        !          14370: {
        !          14371:        /*
        !          14372:         * Priority polls not supported.
        !          14373:         */
        !          14374:        ev &= ~POLLPRI;
        !          14375: 
        !          14376:        /*
        !          14377:         * Input poll failure.
        !          14378:         */
        !          14379:        if ( (ev & POLLIN) && (istty.t_iq.cq_cc == 0) ) {
        !          14380:                if ( msec != 0 )
        !          14381:                        pollopen( &istty.t_ipolls );
        !          14382:                /*
        !          14383:                 * Second look AFTER enabling monitor, avoiding interrupt race.
        !          14384:                 */
        !          14385:                if ( istty.t_iq.cq_cc == 0 )
        !          14386:                        ev &= ~POLLIN;
        !          14387:        }
        !          14388:        return ev;
        !          14389: }
        !          14390: 
        !          14391: /*
        !          14392:  * Receive interrupt.
        !          14393:  */
        !          14394: isrint()
        !          14395: {
        !          14396:        register unsigned c;
        !          14397:        register unsigned r;
        !          14398:        static  char keyup;
        !          14399: 
        !          14400:        /*
        !          14401:         * Schedule raw input handler if not already active.
        !          14402:         */
        !          14403:        if ( !isbusy ) {
        !          14404:                defer( isbatch, &istty );
        !          14405:                isbusy = 1;
        !          14406:        }
        !          14407: 
        !          14408:        /*
        !          14409:         * Pull character from the data
        !          14410:         * port. Pulse the KBFLAG in the control
        !          14411:         * port to reset the data buffer.
        !          14412:         */
        !          14413:        r = inb(KBDATA) & 0xFF;
        !          14414:        c = inb(KBCTRL);
        !          14415:        outb(KBCTRL, c|KBFLAG);
        !          14416:        outb(KBCTRL, c);
        !          14417: 
        !          14418:        /*
        !          14419:         * check returned value from keyboard to see if it's a command
        !          14420:         * or status back to us. If not, it we assume that it's a key code.
        !          14421:         */
        !          14422:        KBDEBUG2(" intr(%x)", r);
        !          14423:        switch (r) {
        !          14424:        case K_BREAK:
        !          14425:                keyup = 1;                      /* key going up */
        !          14426:                break;
        !          14427:        case K_ECHO_R:
        !          14428:        case K_BAT_OK:
        !          14429:                break;                          /* very nice, but ignored */
        !          14430:        case K_BAT_BAD:
        !          14431:                printf("kb: keyboard BAT failed\n");
        !          14432:                break;
        !          14433:        case K_RESEND:
        !          14434:                KBDEBUG("\nkb: request to resend command\n");
        !          14435:                outb(KBDATA, prev_cmd);
        !          14436:                break;
        !          14437:        case K_OVERRUN_23:
        !          14438:                printf("kb: keyboard buffer overrun\n");
        !          14439:                break;
        !          14440:        case K_ACK:
        !          14441:                /*
        !          14442:                 * we received an ACKnowledgement from the keyboard.
        !          14443:                 * advance the state machine and continue.
        !          14444:                 */
        !          14445:                KBDEBUG(" ACK");
        !          14446:                switch (kbstate) {
        !          14447:                case KB_IDLE:                   /* shouldn't happen */
        !          14448:                        printf("kb: ACK while keyboard idle\n");
        !          14449:                        break;
        !          14450:                case KB_SINGLE:                 /* done with 1-byte command */
        !          14451:                case KB_DOUBLE_2:               /* done w/ 2nd of 2-byte cmd */
        !          14452:                        kbstate = KB_IDLE;
        !          14453:                        wakeup(&kbstate);
        !          14454:                        break;
        !          14455:                case KB_DOUBLE_1:
        !          14456:                        kbstate = KB_DOUBLE_2;
        !          14457:                        outb(KBDATA, cmd2);
        !          14458:                        break;
        !          14459:                default:
        !          14460:                        printf("kb: bad kbstate %d\n", kbstate);
        !          14461:                        break;
        !          14462:                }
        !          14463:                break;
        !          14464:        default:
        !          14465:                process_key(r, keyup);
        !          14466:                keyup = 0;
        !          14467:        }
        !          14468: }
        !          14469: 
        !          14470: /*
        !          14471:  * Process a key given its scan code and direction.
        !          14472:  * 
        !          14473:  * In this table driven version of the keyboard driver, we trade off the
        !          14474:  * code complexity associated with all the black magic that used to be
        !          14475:  * performed on a per-key basis with the increased memory requirements
        !          14476:  * associated with the table driven approach.
        !          14477:  */
        !          14478: process_key( key, up)
        !          14479: unsigned key;
        !          14480: int     up;
        !          14481: {
        !          14482:        register unsigned char *cp;
        !          14483:        KBTBL   key_vals;                       /* table values for this key */
        !          14484:        unsigned val;
        !          14485:        unsigned char flags;
        !          14486: 
        !          14487:        KBDEBUG3(" proc(%x %s)", key, (up ? "up" : "down"));
        !          14488:        if (!table_loaded)
        !          14489:                return;                         /* throw away key */
        !          14490:        fkcopy( kbsegp->s_faddr + (key * sizeof(KBTBL)),
        !          14491:                &key_vals, sizeof(key_vals));
        !          14492:        if (key_vals.k_key != key)              /* empty entry */
        !          14493:                return;
        !          14494:        flags = key_vals.k_flags;
        !          14495: 
        !          14496:        if (flags & S) {                        /* some shift/lock key ? */
        !          14497:                switch (key_vals.k_val[BASE]) {
        !          14498:                case caps:
        !          14499:                case num:
        !          14500:                        if (!up) {
        !          14501:                                shift ^= (1 << key_vals.k_val[BASE]);
        !          14502:                                updleds2();
        !          14503:                        }
        !          14504:                        break;
        !          14505:                case scroll:
        !          14506:                        if (!up) {
        !          14507:                                shift ^= (1 << key_vals.k_val[BASE]);
        !          14508:                                updleds2();
        !          14509:                                if (!(istty.t_sgttyb.sg_flags&RAWIN)) {
        !          14510:                                        if (istty.t_flags & T_STOP) {
        !          14511:                                                isin(istty.t_tchars.t_startc);
        !          14512:                                        } else {
        !          14513:                                                isin(istty.t_tchars.t_stopc);
        !          14514:                                        }
        !          14515:                                }
        !          14516:                        }
        !          14517:                        break;
        !          14518:                default:
        !          14519:                        if (up)
        !          14520:                                shift &= ~(1 << key_vals.k_val[BASE]);
        !          14521:                        else
        !          14522:                                shift |= (1 << key_vals.k_val[BASE]);
        !          14523:                        break;
        !          14524:                }
        !          14525:                /*
        !          14526:                 * Calculate the shift index based upon the state of
        !          14527:                 * the shift and lock keys.
        !          14528:                 */
        !          14529:                sh_index = BASE;                /* default condition */
        !          14530:                if (shift & (1 << altgr))
        !          14531:                        sh_index = ALT_GR;
        !          14532:                else {
        !          14533:                        if (shift & ((1 << lalt)|(1 << ralt)))
        !          14534:                                sh_index |= ALT;
        !          14535:                        if (shift & ((1 << lctrl)|(1 << rctrl)))
        !          14536:                                sh_index |= CTRL;
        !          14537:                        if (shift & ((1 << lshift)|(1 << rshift)))
        !          14538:                                sh_index |= SHIFT;
        !          14539:                }
        !          14540:                return;
        !          14541:        } /* if (flags & S) */
        !          14542: 
        !          14543:        /*
        !          14544:         * If the tty is not open or the key has no value in the current
        !          14545:         * shift state, the key is just tossed away.
        !          14546:         */
        !          14547:        if (up || !istty.t_open || key_vals.k_val[sh_index] == none)
        !          14548:                return;
        !          14549:        if (((flags & C) && (shift & (1 << caps)))
        !          14550:           || ((flags & N) && (shift & (1 << num))))
        !          14551:                val = key_vals.k_val[sh_index^SHIFT];
        !          14552:        else
        !          14553:                val = key_vals.k_val[sh_index];
        !          14554: 
        !          14555:        /*
        !          14556:         * Check for function key or special key implemented as
        !          14557:         * a function key (reboot == f0, tab and back-tab, etc).
        !          14558:         */
        !          14559:        if (flags & F) {
        !          14560:                if (val == 0 && !up && KBBOOT)
        !          14561:                        boot();
        !          14562:                if (!fk_loaded || val >= fnkeys->k_nfkeys)
        !          14563:                        return;
        !          14564:                if ((cp = funkeyp[val]) == NULL) /* has a value? */
        !          14565:                        return;
        !          14566:                while (*cp != DELIM)
        !          14567:                        isin(*cp++);            /* queue up Fn key value */
        !          14568:                return;
        !          14569:        }
        !          14570: 
        !          14571:        /*
        !          14572:         * Normal key processing.
        !          14573:         */
        !          14574:        isin(val);               /* send the char */
        !          14575:        return;
        !          14576: }
        !          14577: 
        !          14578: /**
        !          14579:  *
        !          14580:  * void
        !          14581:  * ismmfunc( c )       -- process keyboard related output escape sequences
        !          14582:  * char c;
        !          14583:  */
        !          14584: void
        !          14585: ismmfunc(c)
        !          14586: register int c;
        !          14587: {
        !          14588:        switch (c) {
        !          14589:        case 't':       /* Enter numlock */
        !          14590:                shift |= (1 << num);
        !          14591:                updleds();                      /* update LED status */
        !          14592:                break;
        !          14593:        case 'u':       /* Leave numlock */
        !          14594:                shift &= ~(1 << num);
        !          14595:                updleds();                      /* update LED status */
        !          14596:                break;
        !          14597:        case '=':                       /* Enter alternate keypad -- ignored */
        !          14598:        case '>':                       /* Exit alternate keypad -- ignored */
        !          14599:                break;
        !          14600:        case 'c':       /* Reset terminal */
        !          14601:                islock = 0;
        !          14602:                break;
        !          14603:        }
        !          14604: }
        !          14605: 
        !          14606: /**
        !          14607:  *
        !          14608:  * void
        !          14609:  * isin( c )   -- append character to raw input silo
        !          14610:  * char c;
        !          14611:  */
        !          14612: static
        !          14613: isin( c )
        !          14614: register int c;
        !          14615: {
        !          14616:        /*
        !          14617:         * Cache received character.
        !          14618:         */
        !          14619:        istty.t_rawin.si_buf[ istty.t_rawin.si_ix ] = c;
        !          14620: 
        !          14621:        if ( ++istty.t_rawin.si_ix >= sizeof(istty.t_rawin.si_buf) )
        !          14622:                istty.t_rawin.si_ix = 0;
        !          14623: }
        !          14624: 
        !          14625: /**
        !          14626:  *
        !          14627:  * void
        !          14628:  * isbatch()   -- raw input conversion routine
        !          14629:  *
        !          14630:  *     Action: Enable the video display.
        !          14631:  *             Canonize the raw input silo.
        !          14632:  *
        !          14633:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
        !          14634:  */
        !          14635: static void
        !          14636: isbatch( tp )
        !          14637: register TTY * tp;
        !          14638: {
        !          14639:        register int c;
        !          14640:        static int lastc;
        !          14641: 
        !          14642:        /*
        !          14643:         * Ensure video display is enabled.
        !          14644:         */
        !          14645:        mm_von();
        !          14646:        isbusy = 0;
        !          14647: 
        !          14648:        /*
        !          14649:         * Process all cached characters.
        !          14650:         */
        !          14651:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          14652:                /*
        !          14653:                 * Get next cached char.
        !          14654:                 */
        !          14655:                c = tp->t_rawin.si_buf[ tp->t_rawin.si_ox ];
        !          14656: 
        !          14657:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          14658:                        tp->t_rawin.si_ox = 0;
        !          14659:                else
        !          14660:                        tp->t_rawin.si_ox++;
        !          14661: 
        !          14662:                if ( (islock == 0) || ISINTR || ISQUIT ) {
        !          14663:                        ttin( tp, c );
        !          14664:                } else if ( (c == 'b') && (lastc == '\033') ) {
        !          14665:                        islock = 0;
        !          14666:                        ttin( tp, lastc );
        !          14667:                        ttin( tp, c );
        !          14668:                } else if ( (c == 'c') && (lastc == '\033') ) {
        !          14669:                        ttin( tp, lastc );
        !          14670:                        ttin( tp, c );
        !          14671:                } else
        !          14672:                        putchar('\007');
        !          14673:                lastc = c;
        !          14674:        }
        !          14675: }
        !          14676: 
        !          14677: /*
        !          14678:  * update the keyboard status LEDS.
        !          14679:  * we chose the shift/lock key positions so this would be easy.
        !          14680:  * this flavor of routine is called while processing a system call on
        !          14681:  * behalf of the user.
        !          14682:  */
        !          14683: updleds()
        !          14684: {
        !          14685:        kb_cmd2(K_LED_CMD, (shift >> 1) & 0x7);
        !          14686: }
        !          14687: 
        !          14688: /*
        !          14689:  * same as above, but callable from interrupt routines and other places
        !          14690:  * which cannot sleep() waiting for the state machine to go idle.
        !          14691:  */
        !          14692: updleds2()
        !          14693: {
        !          14694:        register timeout;
        !          14695:        register int s;
        !          14696: 
        !          14697:        timeout = KBTIMEOUT;
        !          14698:        s = sphi();
        !          14699:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
        !          14700:                ;
        !          14701:        kbstate = KB_DOUBLE_1;
        !          14702:        cmd2 = (shift >> 1) & 0x7;
        !          14703:        prev_cmd = K_LED_CMD;
        !          14704:        outb(KBDATA, K_LED_CMD);
        !          14705:        spl(s);
        !          14706: }
        !          14707: 
        !          14708: /*
        !          14709:  * unlock the scroll in case an interrupt character is received
        !          14710:  */
        !          14711: kbunscroll()
        !          14712: {
        !          14713:        shift &= ~(1 << scroll);
        !          14714:        updleds();
        !          14715: }
        !          14716: 
        !          14717: /*
        !          14718:  * ship a single byte command to the keyboard
        !          14719:  */
        !          14720: kb_cmd(cmd)
        !          14721: unsigned cmd;
        !          14722: {
        !          14723:        register int timeout;
        !          14724:        register int s;
        !          14725: 
        !          14726:        s = sphi();
        !          14727:        KBDEBUG2(" kb_cmd(%x)", cmd);
        !          14728:        while (kbstate != KB_IDLE)
        !          14729:                sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
        !          14730:        kbstate = KB_SINGLE;
        !          14731:        timeout = KBTIMEOUT;
        !          14732:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
        !          14733:                ;
        !          14734:        if (!timeout)
        !          14735:                printf("kb: command timeout\n");
        !          14736:        else {
        !          14737:                outb(KBDATA, cmd);
        !          14738:                while (kbstate != KB_IDLE)
        !          14739:                        sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
        !          14740:        }
        !          14741:        spl(s);
        !          14742: }
        !          14743: 
        !          14744: /*
        !          14745:  * ship a two byte command to the keyboard
        !          14746:  */
        !          14747: kb_cmd2(cmd, arg)
        !          14748: unsigned cmd, arg;
        !          14749: {
        !          14750:        register int timeout;
        !          14751:        register int s;
        !          14752: 
        !          14753:        s = sphi();
        !          14754:        KBDEBUG3(" kb_cmd2(%x, %x)", cmd, arg);
        !          14755:        while (kbstate != KB_IDLE)
        !          14756:                sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
        !          14757:        kbstate = KB_DOUBLE_1;
        !          14758:        cmd2 = arg;
        !          14759:        prev_cmd = cmd;
        !          14760:        timeout = KBTIMEOUT;
        !          14761:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
        !          14762:                ;
        !          14763:        if (!timeout)
        !          14764:                printf("kb: command timeout\n");
        !          14765:        else {
        !          14766:                outb(KBDATA, cmd);
        !          14767:                while (kbstate != KB_IDLE)
        !          14768:                        sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
        !          14769:        }
        !          14770:        spl(s);
        !          14771: }
        !          14772: 
        !          14773: /* End of nkb.c */
        !          14774: 0707070064030150251004440000030000030000011777770507310640000005100000004416/newbits/kernel/USRSRC/i8086/drv/pccon.c/* $Header: /usr/src/sys/i8086/drv/RCS/pccon.c,v 2.1 88/09/03 13:09:51 src Exp $ */
        !          14775: /* (lgl-
        !          14776:  *     The information contained herein is a trade secret of Mark Williams
        !          14777:  *     Company, and  is confidential information.  It is provided  under a
        !          14778:  *     license agreement,  and may be  copied or disclosed  only under the
        !          14779:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          14780:  *     material without the express written authorization of Mark Williams
        !          14781:  *     Company or persuant to the license agreement is unlawful.
        !          14782:  *
        !          14783:  *     COHERENT Version 2.3.37
        !          14784:  *     Copyright (c) 1982, 1983, 1984.
        !          14785:  *     An unpublished work by Mark Williams Company, Chicago.
        !          14786:  *     All rights reserved.
        !          14787:  -lgl) */
        !          14788: /*
        !          14789:  * Configuration table.
        !          14790:  * 8088 Coherent, IBM PC.
        !          14791:  * Minimal system.
        !          14792:  *
        !          14793:  * $Log:       /usr/src/sys/i8086/drv/RCS/pccon.c,v $
        !          14794:  * Revision 2.1        88/09/03  13:09:51      src
        !          14795:  * *** empty log message ***
        !          14796:  * 
        !          14797:  * Revision 1.1        88/03/24  17:05:55      src
        !          14798:  * Initial revision
        !          14799:  * 
        !          14800:  */
        !          14801: #include <sys/coherent.h>
        !          14802: #include <sys/con.h>
        !          14803: #include <mtype.h>
        !          14804: #include <sys/stat.h>
        !          14805: 
        !          14806: extern CON     nlcon[];                /* Null device */
        !          14807: extern CON     ctcon[];                /* Console terminal */
        !          14808: 
        !          14809: /*
        !          14810:  * Device table.
        !          14811:  */
        !          14812: DRV    drvl[NDRV] = {
        !          14813:        {nlcon},        {ctcon},        {NULL },        {NULL },  /*  0 -  3 */
        !          14814:        {NULL },        {NULL },        {NULL },        {NULL },  /*  4 -  7 */
        !          14815:        {NULL },        {NULL },        {NULL },        {NULL },  /*  8 - 11 */
        !          14816:        {NULL },        {NULL },        {NULL },        {NULL },  /* 12 - 15 */
        !          14817:        {NULL },        {NULL },        {NULL },        {NULL },  /* 16 - 19 */
        !          14818:        {NULL },        {NULL },        {NULL },        {NULL },  /* 20 - 23 */
        !          14819:        {NULL },        {NULL },        {NULL },        {NULL },  /* 24 - 27 */
        !          14820:        {NULL },        {NULL },        {NULL },        {NULL }   /* 28 - 31 */
        !          14821: };
        !          14822: 
        !          14823: /*
        !          14824:  * Time.
        !          14825:  */
        !          14826: TIME timer ={
        !          14827:        0,                              /* Initial time */
        !          14828:        0,                              /* Ticks */
        !          14829:        8*60,                           /* Pacific */
        !          14830:        1                               /* Daylight saving time */
        !          14831: };
        !          14832: 
        !          14833: /*
        !          14834:  * Devices and sizes.
        !          14835:  */
        !          14836: dev_t  rootdev = makedev(4, 4);        /* Root device */
        !          14837: dev_t  pipedev = makedev(4, 4);        /* Pipe device */
        !          14838: dev_t  swapdev = makedev(0, 0);        /* Swap device */
        !          14839: daddr_t        swapbot = 0;                    /* Swap base */
        !          14840: daddr_t        swaptop = 0;                    /* Swap end */
        !          14841: int    ronflag = 0;                    /* Not read only root device */
        !          14842: int    drvn    = NDRV;                 /* Maximum number of devices */
        !          14843: int    mactype = M_8086;               /* Machine type */
        !          14844: 
        !          14845: /*
        !          14846:  * Flexible param's
        !          14847:  */
        !          14848: int    NCLIST  = 8;            /* 8 clists per installed tty, never run out */
        !          14849: int    ALLSIZE = 7*1024;       /* 7K has been reasonable */
        !          14850: int    NINODE  = 64;           /* More than enough so far */
        !          14851: int    NBUF    = 16;           /* Stingy */
        !          14852: 0707070064030074511006440000030000030000011777770507310640100004600000012220/newbits/kernel/USRSRC/i8086/drv/qq.c/*
        !          14853:  * qq - sample device driver using absolute memory addressing
        !          14854:  *
        !          14855:  * All this device does is read/write video ram.
        !          14856:  * It assumes that there is a monochrome adapter in use, so that video
        !          14857:  * ram starts at segment B000;  if color, this should be changed to B800.
        !          14858:  *
        !          14859:  * This driver does not do anything useful;  it is intended to serve as
        !          14860:  * an example.
        !          14861:  *
        !          14862:  * Here is how to make the driver and test it (you will need a COHERENT
        !          14863:  * Driver Kit installed on your system):
        !          14864:  * 1.  put this file, "qq.c", in /usr/src/sys/i8086/drv/qq.c
        !          14865:  * 2.  cut out the make file and store it in /usr/src/sys/i8086/drv/Mf.qq
        !          14866:  * 3.  cut out the config file and store it at /usr/sys/confdrv/qq
        !          14867:  * 4.  execute the following commands
        !          14868:  *             cd /usr/src/sys/i8086/drv
        !          14869:  *             make -f Mf.qq
        !          14870:  *             cd /usr/sys
        !          14871:  *             ldconfig qq
        !          14872:  *             drvld ldrv/qq
        !          14873:  * 5.  the driver should now be loaded - try "date > /dev/qq" or
        !          14874:  *     "cat < /dev/qq" (you will have to use Ctrl-C to stop the "cat"
        !          14875:  *     command)
        !          14876:  * 6.  to unload the driver, do "ps -d" to get the PID number for the driver;
        !          14877:  *     then do "kill kill nnn" where nnn is the process number for "<qq>"
        !          14878:  */
        !          14879: /****
        !          14880: Here is the makefile for the "qq" driver (cut it out of this file):
        !          14881: --------------- cut here -----------------
        !          14882: # Make file for a loadable driver
        !          14883: 
        !          14884: AS=exec /bin/as
        !          14885: CC=exec /bin/cc
        !          14886: CPP=exec /lib/cpp
        !          14887: CFLAGS=-I.. -I../sys -I../.. -I../../sys \
        !          14888:        -I/usr/include/sys
        !          14889: AFLAGS=-gx
        !          14890: 
        !          14891: # Include directories
        !          14892: USRINC=/usr/include
        !          14893: SYSINC=/usr/include/sys
        !          14894: KERINC=/usr/src/sys/sys
        !          14895: DRVINC=/usr/src/sys/i8086/sys
        !          14896: USRSYS=/usr/sys
        !          14897: 
        !          14898: DRVOBJ=        objects/qq.o
        !          14899: 
        !          14900: qq: objects/qq.o
        !          14901:        rm -f $(USRSYS)/lib/qq.a
        !          14902:        ar rc $(USRSYS)/lib/qq.a objects/qq.o
        !          14903: 
        !          14904: objects/qq.o:                          \
        !          14905:                $(KERINC)/coherent.h    $(SYSINC)/types.h \
        !          14906:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          14907:                                        $(SYSINC)/fun.h \
        !          14908:                $(SYSINC)/con.h         \
        !          14909:                $(USRINC)/errno.h       \
        !          14910:                $(SYSINC)/sched.h       \
        !          14911:                $(SYSINC)/seg.h         \
        !          14912:                $(SYSINC)/stat.h        \
        !          14913:                $(SYSINC)/types.h       \
        !          14914:                $(SYSINC)/uproc.h       \
        !          14915:                qq.c
        !          14916:        $(CC) $(CFLAGS) -c -o $@ qq.c
        !          14917: --------------- cut here -----------------
        !          14918: 
        !          14919: Here is the configuration file for the "qq" driver.
        !          14920: Cut it out of this file and copy it to "/usr/sys/confdrv/qq".
        !          14921: When "ldconfig" is run, it will create a node for /dev/qq.
        !          14922: --------------- cut here -----------------
        !          14923: :
        !          14924: : 'Dummy driver for write to absolute RAM area'
        !          14925: :
        !          14926: UNDEF="${UNDEF} -u qqcon_ lib/qq.a"
        !          14927: PATCH="${PATCH} drvl_+70=qqcon_"
        !          14928: :
        !          14929: : devices
        !          14930: :
        !          14931: umask 0111
        !          14932: /etc/mknod -f ${DEV-/dev}/qq c 7  0 || exit 1
        !          14933: --------------- cut here -----------------
        !          14934: ****/
        !          14935: #include "coherent.h"
        !          14936: #include "ins8250.h"
        !          14937: #include <sys/stat.h>
        !          14938: #include <sys/uproc.h>
        !          14939: #include <sys/proc.h>
        !          14940: #include <sys/con.h>
        !          14941: #include <errno.h>
        !          14942: #include <sys/types.h>
        !          14943: #include <sys/mmu.h>
        !          14944: 
        !          14945: /*
        !          14946:  * Definitions.
        !          14947:  *
        !          14948:  */
        !          14949: #define        MONOVIDEO       0xB000          /* monochrome text RAM segment */
        !          14950: #define        VIDLENGTH       (2048*2)        /* screen locations (2 bytes each) */
        !          14951: 
        !          14952: /*
        !          14953:  * Export Functions.
        !          14954:  */
        !          14955: int    qqload();
        !          14956: int    qqopen();
        !          14957: int    qqclose();
        !          14958: int    qqread();
        !          14959: int    qqwrite();
        !          14960: int    qqunload();
        !          14961: 
        !          14962: /*
        !          14963:  * Import Functions
        !          14964:  */
        !          14965: int    nulldev();
        !          14966: int    nonedev();
        !          14967: 
        !          14968: /*
        !          14969:  * Configuration table.
        !          14970:  */
        !          14971: CON qqcon ={
        !          14972:        DFCHR,                          /* Flags */
        !          14973:        7,                              /* Major index */
        !          14974:        qqopen,                         /* Open */
        !          14975:        qqclose,                        /* Close */
        !          14976:        nulldev,                        /* Block */
        !          14977:        qqread,                         /* Read */
        !          14978:        qqwrite,                        /* Write */
        !          14979:        nulldev,                        /* Ioctl */
        !          14980:        nulldev,                        /* Powerfail */
        !          14981:        nulldev,                        /* Timeout */
        !          14982:        qqload,                         /* Load */
        !          14983:        qqunload,                       /* Unload */
        !          14984:        nulldev                         /* Poll */
        !          14985: };
        !          14986: 
        !          14987: /*
        !          14988:  * Local variables.
        !          14989:  */
        !          14990: static faddr_t screen_fp;              /* (far *) to access screen */
        !          14991: static paddr_t screen_base;            /* physical address of screen base */
        !          14992: 
        !          14993: /*
        !          14994:  * Load Routine.
        !          14995:  */
        !          14996: static qqload()
        !          14997: {
        !          14998:        /*
        !          14999:         * Allocate a selector to map onto the video RAM.  ptov() will
        !          15000:         * return the first available selector of the 8,192 possible.
        !          15001:         * This is time consuming, so we only want to do this as part
        !          15002:         * of our initialization code and not on every access.
        !          15003:         *
        !          15004:         * Since we are operating in 286 protected mode (ugh), the
        !          15005:         * second argument to ptov() must not exceed 0x10000L.
        !          15006:         */
        !          15007:        screen_base = (paddr_t)((long)(unsigned)MONOVIDEO << 4);
        !          15008:        screen_fp = ptov(screen_base, (fsize_t)VIDLENGTH);
        !          15009: }
        !          15010: 
        !          15011: static qqunload()
        !          15012: {
        !          15013:        /*
        !          15014:         * We have to free up the selector now that we're done using it.
        !          15015:         */
        !          15016:        vrelse(screen_fp);
        !          15017: }
        !          15018: 
        !          15019: /*
        !          15020:  * Open Routine.
        !          15021:  */
        !          15022: qqopen( dev, mode )
        !          15023: dev_t dev;
        !          15024: {
        !          15025: }
        !          15026: 
        !          15027: /*
        !          15028:  * Close Routine.
        !          15029:  */
        !          15030: qqclose( dev )
        !          15031: dev_t dev;
        !          15032: {
        !          15033: }
        !          15034: 
        !          15035: /*
        !          15036:  * Read Routine.
        !          15037:  */
        !          15038: qqread( dev, iop )
        !          15039: dev_t dev;
        !          15040: register IO * iop;
        !          15041: {
        !          15042:        static int offset;
        !          15043:        int c;
        !          15044:        /*
        !          15045:         * Read a character code from video RAM
        !          15046:         * Start reading RAM just after where previous read ended
        !          15047:         *
        !          15048:         * Note that "offset" is the value of the displacement into
        !          15049:         * the screen RAM. Any expression which results in a value
        !          15050:         * which is less than VIDLENGTH is OK here.
        !          15051:         */
        !          15052:        while(iop->io_ioc) {
        !          15053:                c = ffbyte(screen_fp + offset); /* fetch a "far" byte */
        !          15054:                if(ioputc(c, iop) == -1)
        !          15055:                        break;
        !          15056:                offset += 2;
        !          15057:                offset %= VIDLENGTH;
        !          15058:        }
        !          15059: }
        !          15060: 
        !          15061: /*
        !          15062:  * Write Routine.
        !          15063:  */
        !          15064: qqwrite( dev, iop )
        !          15065: dev_t dev;
        !          15066: register IO * iop;
        !          15067: {
        !          15068:        int offset = 0;
        !          15069:        int c;
        !          15070: 
        !          15071:        /*
        !          15072:         * Write a character into the screen RAM
        !          15073:         * Note that "offset" is the value of the displacement into
        !          15074:         * the screen RAM. Any expression which results in a value
        !          15075:         * which is less than VIDLENGTH is OK here.
        !          15076:         */
        !          15077:        while ((c = iogetc(iop)) >= 0 && offset < VIDLENGTH) {
        !          15078:                sfbyte(screen_fp + offset, c);     /* store a "far" byte */
        !          15079:                offset += 2;    /* skip attribute byte */
        !          15080:        }
        !          15081: }
        !          15082: 0707070064030074541006440000030000030000011777770507310640200004600000010215/newbits/kernel/USRSRC/i8086/drv/rm.c/*
        !          15083:  * Block or character device RAM disk driver.
        !          15084:  */
        !          15085: 
        !          15086: #include       <sys/coherent.h>
        !          15087: #include       <sys/buf.h>
        !          15088: #include       <errno.h>
        !          15089: #include       <sys/uproc.h>
        !          15090: #include       <sys/seg.h>
        !          15091: #include       <sys/con.h>
        !          15092: #include       <sys/devices.h>
        !          15093: #include       <sys/inode.h>
        !          15094: #include       <sys/stat.h>
        !          15095: 
        !          15096: /*
        !          15097:  * Minor number encoding: dsssssss
        !          15098:  * d       drive number (0 or 1)
        !          15099:  * sssssss allocation size: 0 to free, 1-127 allocsize (n*ASIZE*BSIZE bytes)
        !          15100:  */
        !          15101: #define        rm_drive(dev)   (minor(dev) >> 7)
        !          15102: #define        rm_asize(dev)   (minor(dev) & 0x7F)
        !          15103: #define        ASIZE           128     /* allocation chunk size in blocks (64KB) */
        !          15104: #define NUM_RM         2       /* number of ram disks */
        !          15105:                                /* - tied to dev encoding (see above) */
        !          15106: 
        !          15107: int    nulldev();
        !          15108: int    nonedev();
        !          15109: int    rmload();
        !          15110: int    rmuload();
        !          15111: int    rmopen();
        !          15112: int    rmclose();
        !          15113: int    rmread();
        !          15114: int    rmwrite();
        !          15115: int    rmblock();
        !          15116: 
        !          15117: CON    rmcon   = {
        !          15118:        DFBLK|DFCHR,
        !          15119:        RM_MAJOR,
        !          15120:        rmopen,                 /* Open */
        !          15121:        rmclose,                /* Close */
        !          15122:        rmblock,                /* Block */
        !          15123:        rmread,                 /* Read */
        !          15124:        rmwrite,                /* Write */
        !          15125:        nonedev,
        !          15126:        nulldev,
        !          15127:        nulldev,
        !          15128:        rmload,                 /* Load */
        !          15129:        rmuload                 /* Unload */
        !          15130: };
        !          15131: 
        !          15132: typedef struct rm {
        !          15133:        fsize_t rm_size;        /* Size in allocation chunks */
        !          15134:        paddr_t rm_paddr;       /* Physical base of ram disc segment */
        !          15135:        SEG     *rm_segp;       /* Segment pointer of ram device */
        !          15136:        BUF     rm_buf;         /* Static buffer for raw requests */
        !          15137:        int     rm_nopen;       /* Open count to avoid blowups */
        !          15138: } RM;
        !          15139: static RM      rm[NUM_RM];
        !          15140: 
        !          15141: /*
        !          15142:  * Load.
        !          15143:  */
        !          15144: static
        !          15145: rmload()
        !          15146: {
        !          15147: }
        !          15148: 
        !          15149: /*
        !          15150:  * Unload.
        !          15151:  * Release the allocated buffers.
        !          15152:  */
        !          15153: static
        !          15154: rmuload()
        !          15155: {
        !          15156:        int i;
        !          15157: 
        !          15158:        for (i = 0; i < NUM_RM; i++){
        !          15159:                if (rm[i].rm_size != 0)
        !          15160:                        sfree(rm[i].rm_segp);
        !          15161:        }
        !          15162: }
        !          15163: 
        !          15164: /*
        !          15165:  * Open.
        !          15166:  * Allocate on the first call.
        !          15167:  * Increment the open count.
        !          15168:  */
        !          15169: static
        !          15170: rmopen(dev, mode) dev_t dev; int mode;
        !          15171: {
        !          15172:        register RM *rmp;
        !          15173:        register fsize_t asize, osize;
        !          15174:        register SEG *segp;
        !          15175: 
        !          15176:        rmp = &rm[rm_drive(dev)];
        !          15177:        asize = rm_asize(dev);
        !          15178:        osize = rmp->rm_size;
        !          15179: 
        !          15180:        /* Fail on read before creation or bogus size. */
        !          15181:        if ((mode == IPR && osize == 0)
        !          15182:         || (asize != 0 && osize != 0 && asize != osize)
        !          15183:         || (asize == 0 && osize == 0)) {
        !          15184:                u.u_error = ENXIO;
        !          15185:                return;
        !          15186:        }
        !          15187: 
        !          15188:        /*
        !          15189:         * Allocate as required.
        !          15190:         * Ignore case asize==0 && osize!=0, handled by rmclose().
        !          15191:         * If asize!=0 && asize==osize, just bump the open count.
        !          15192:         */
        !          15193:        if (asize != 0 && osize == 0) {
        !          15194:                segp = rmp->rm_segp = salloc((fsize_t)ASIZE*BSIZE*asize,
        !          15195:                        SFSYST|SFNSWP|SFNCLR|SFHIGH);
        !          15196:                if (segp == NULL) {
        !          15197:                        u.u_error = ENOMEM;
        !          15198:                        return;
        !          15199:                }
        !          15200:                rmp->rm_size = asize;
        !          15201:                rmp->rm_paddr = segp->s_paddr;
        !          15202:                rmp->rm_nopen = 0;
        !          15203:                pclear(rmp->rm_paddr, 1024L);   /* clear 1st 2 blocks */
        !          15204:        }
        !          15205:        rmp->rm_nopen++;
        !          15206: }
        !          15207: 
        !          15208: /*
        !          15209:  * Close.
        !          15210:  * Decrement the open count.
        !          15211:  * Release the allocated buffer if minor number is 0.
        !          15212:  */
        !          15213: static
        !          15214: rmclose(dev) dev_t dev;
        !          15215: {
        !          15216:        register RM *rmp;
        !          15217:        register fsize_t asize, osize;
        !          15218: 
        !          15219:        rmp = &rm[rm_drive(dev)];
        !          15220:        asize = rm_asize(dev);
        !          15221:        osize = rmp->rm_size;
        !          15222: 
        !          15223:        if (osize == 0
        !          15224:         || (asize != 0 && asize != osize)
        !          15225:         || rmp->rm_nopen == 0) {
        !          15226:                u.u_error = ENXIO;
        !          15227:                return;
        !          15228:        }
        !          15229:        rmp->rm_nopen--;
        !          15230:        if (asize == 0) {
        !          15231:                if (rmp->rm_nopen != 0) {
        !          15232:                        u.u_error = EDBUSY;
        !          15233:                        return;
        !          15234:                }
        !          15235:                sfree(rmp->rm_segp);
        !          15236:                rmp->rm_size = 0;
        !          15237:        }
        !          15238: }
        !          15239: 
        !          15240: static
        !          15241: rmblock(bp) register BUF *bp;
        !          15242: {
        !          15243:        paddr_t base;
        !          15244:        dev_t dev;
        !          15245:        register RM *rmp;
        !          15246:        register fsize_t asize, osize;
        !          15247: 
        !          15248:        dev = bp->b_dev;
        !          15249:        rmp = &rm[rm_drive(dev)];
        !          15250:        asize = rm_asize(dev);
        !          15251:        osize = rmp->rm_size;
        !          15252:        if (osize == 0 || asize != osize)
        !          15253:                bp->b_flag |= BFERR;
        !          15254:        /*
        !          15255:         * Make sure last block requested is within range of device.
        !          15256:         */     
        !          15257:        else if ((bp->b_bno + bp->b_count/BSIZE - 1) >= asize*ASIZE)
        !          15258:                bp->b_flag |= BFERR;
        !          15259:        else {
        !          15260:                base = rmp->rm_paddr + (paddr_t)bp->b_bno * BSIZE;
        !          15261:                if (bp->b_req == BREAD)
        !          15262:                        plrcopy(base, bp->b_paddr, (fsize_t)bp->b_count);
        !          15263:                else
        !          15264:                        plrcopy(bp->b_paddr, base, (fsize_t)bp->b_count);
        !          15265:        }
        !          15266:        bdone(bp);
        !          15267: }
        !          15268: 
        !          15269: /*
        !          15270:  * The read routine calls the common raw I/O processing code,
        !          15271:  * using a static buffer header in the driver.
        !          15272:  */
        !          15273: static
        !          15274: rmread(dev, iop) register dev_t dev; IO *iop;
        !          15275: {
        !          15276:        register BUF *bufp;
        !          15277: 
        !          15278:        bufp = &rm[rm_drive(dev)].rm_buf;
        !          15279:        ioreq(bufp, iop, dev, BREAD, BFIOC|BFRAW);
        !          15280: }
        !          15281: 
        !          15282: /*
        !          15283:  * The write routine is just like the read routine,
        !          15284:  * except that the function code is write instead of read.
        !          15285:  */
        !          15286: static
        !          15287: rmwrite(dev, iop) register dev_t dev; IO *iop;
        !          15288: {
        !          15289:        register BUF *bufp;
        !          15290: 
        !          15291:        bufp = &rm[rm_drive(dev)].rm_buf;
        !          15292:        ioreq(bufp, iop, dev, BWRITE, BFIOC|BFRAW);
        !          15293: }
        !          15294: 
        !          15295: /* end of rm.c */
        !          15296: 0707070064030150211004440000030000030000011777770507310640300004600000015106/newbits/kernel/USRSRC/i8086/drv/rp.c/*
        !          15297:  *     Ram Pipe Device Driver
        !          15298:  */
        !          15299: 
        !          15300: #include <coherent.h>
        !          15301: #include <con.h>
        !          15302: #include <seg.h>
        !          15303: #include <stat.h>
        !          15304: #include <sched.h>
        !          15305: #include <termio.h>
        !          15306: #include <v7sgtty.h>
        !          15307: #include <uproc.h>
        !          15308: #include <errno.h>
        !          15309: 
        !          15310: #define        MAXNRP  30              /* Maximum number of ram pipes (must be < 32) */
        !          15311: #define        NCPQ    2048            /* Size of pipe in bytes */
        !          15312: #define        RPMAJOR 22              /* Major device for ram pipes  */
        !          15313: 
        !          15314: /*
        !          15315:  *     function definitions
        !          15316:  */
        !          15317: int    rpopen();
        !          15318: int    rpread();
        !          15319: int    rpwrite();
        !          15320: int    rpioctl();
        !          15321: int    rppoll();
        !          15322: void   rpuload();
        !          15323: int    nulldev();
        !          15324: int    nonedev();
        !          15325: 
        !          15326: 
        !          15327: /*
        !          15328:  *     configuration table
        !          15329:  */
        !          15330: CON rpcon = {
        !          15331:        DFCHR|DFPOL,                    /* flags        */
        !          15332:        RPMAJOR,                        /* major index  */
        !          15333:        rpopen,                         /* open         */
        !          15334:        nulldev,                        /* close        */
        !          15335:        nonedev,                        /* block        */
        !          15336:        rpread,                         /* read         */
        !          15337:        rpwrite,                        /* write        */
        !          15338:        rpioctl,                        /* ioctl        */
        !          15339:        nulldev,                        /* power fail   */
        !          15340:        nulldev,                        /* timeout      */
        !          15341:        nulldev,                        /* load         */
        !          15342:        rpuload,                        /* unload       */
        !          15343:        rppoll                          /* poll         */
        !          15344: };
        !          15345: 
        !          15346: /*
        !          15347:  *     Ram Pipe Headers
        !          15348:  */
        !          15349: static
        !          15350: struct ring {
        !          15351:        unsigned short  q_size;         /* Number of characters in queue    */
        !          15352:        unsigned short  q_mask;         /* Ring buffer Mask: NCPQ-1         */
        !          15353:        faddr_t         q_ifaddr;       /* Input virtual address            */
        !          15354:        faddr_t         q_ofaddr;       /* Output virtual address           */
        !          15355:        GATE            q_igate;        /* Read lock                        */
        !          15356:        GATE            q_ogate;        /* Write lock                       */
        !          15357:        event_t         q_ipoll;        /* Input polls                      */
        !          15358:        event_t         q_opoll;        /* Output polls                     */
        !          15359: 
        !          15360: } rpq[MAXNRP];
        !          15361: 
        !          15362: static SEG * rpsegp;
        !          15363: unsigned NRP = MAXNRP;
        !          15364: 
        !          15365: /*
        !          15366:  * Initialization Routine
        !          15367:  */
        !          15368: static
        !          15369: rpinit()
        !          15370: {
        !          15371:        register struct ring *rp;
        !          15372:        faddr_t faddr;
        !          15373:        paddr_t paddr;
        !          15374: 
        !          15375:        /*
        !          15376:         * Ensure valid number of ram pipes
        !          15377:         */
        !          15378:        if ( NRP > MAXNRP )
        !          15379:                NRP = MAXNRP;
        !          15380:                
        !          15381:        /*
        !          15382:         * Allocate ram pipe segment, initialize ram pipe queues
        !          15383:         */
        !          15384:         if ( NRP != 0 ) {
        !          15385:                rpsegp = salloc((fsize_t)NRP*NCPQ, SFSYST|SFHIGH|SFNSWP|SFNCLR);
        !          15386: 
        !          15387:                if ( rpsegp == NULL )
        !          15388:                        return -1;
        !          15389: 
        !          15390:                paddr = rpsegp->s_paddr;
        !          15391: 
        !          15392:                for ( rp = &rpq[0]; rp < &rpq[NRP]; rp++, paddr += NCPQ ) {
        !          15393: 
        !          15394:                        faddr = ptov( paddr, (fsize_t)NCPQ );
        !          15395:                        rp->q_size = 0;
        !          15396:                        rp->q_mask = NCPQ - 1;
        !          15397: 
        !          15398:                        rp->q_ifaddr = faddr;
        !          15399:                        rp->q_ofaddr = faddr;
        !          15400:                }
        !          15401:        }
        !          15402:        return 0;
        !          15403: }
        !          15404: 
        !          15405: /*
        !          15406:  * Unload Routine.
        !          15407:  */
        !          15408: static void
        !          15409: rpuload()
        !          15410: {
        !          15411:        register struct ring *rp;
        !          15412: 
        !          15413:        /*
        !          15414:         * Release virtual address mappers.
        !          15415:         */
        !          15416:        for ( rp = &rpq[0]; rp < &rpq[NRP]; rp++ ) {
        !          15417:                if ( rp->q_ifaddr )
        !          15418:                        vrelse( rp->q_ifaddr );
        !          15419:        }
        !          15420: 
        !          15421:        /*
        !          15422:         * Release ring buffer storage.
        !          15423:         */
        !          15424:        if ( rpsegp != NULL ) {
        !          15425:                sfree( rpsegp );
        !          15426:                rpsegp = NULL;
        !          15427:        }
        !          15428: 
        !          15429:        /*
        !          15430:         * Erase private data.
        !          15431:         */
        !          15432:        memset( &rpq[0], 0, sizeof(rpq) );
        !          15433: }
        !          15434: 
        !          15435: /*
        !          15436:  * Open Routine
        !          15437:  */
        !          15438: static
        !          15439: rpopen( dev, mode )
        !          15440: dev_t dev;
        !          15441: {
        !          15442:        int s;
        !          15443: 
        !          15444:        s = sphi();
        !          15445:        if ( rpq[0].q_mask == 0 )
        !          15446:                if ( rpinit() < 0 )
        !          15447:                        u.u_error = ENOSPC;
        !          15448:        spl( s );
        !          15449:        if ( minor(dev) >= NRP )
        !          15450:                u.u_error = ENXIO;
        !          15451: }
        !          15452: 
        !          15453: /*
        !          15454:  * Ioctl Routine
        !          15455:  */
        !          15456: static
        !          15457: rpioctl( dev, com, vec )
        !          15458: dev_t dev;
        !          15459: {
        !          15460:        switch ( com ) {
        !          15461: 
        !          15462:        case TIOCQUERY:
        !          15463:                putuwd( vec, rpq[ minor(dev) ].q_size );
        !          15464:                return;
        !          15465: 
        !          15466:        case TIOCOUTQ:
        !          15467:                putuwd( vec, rpq[ minor(dev) ].q_size );
        !          15468:                return;
        !          15469: 
        !          15470:        case TIOCFLUSH:
        !          15471:        case TCFLSH:
        !          15472:                rpflush( &rpq[minor(dev)] );
        !          15473:                return;
        !          15474: 
        !          15475:        default:
        !          15476:                u.u_error = EINVAL;
        !          15477:                return;
        !          15478:        }
        !          15479: }
        !          15480: 
        !          15481: /*
        !          15482:  * Read Routine
        !          15483:  */
        !          15484: static
        !          15485: rpread( dev, iop )
        !          15486: dev_t dev;
        !          15487: register IO *iop;
        !          15488: {
        !          15489:        register struct ring *rp;
        !          15490:        unsigned n;
        !          15491:        int s;
        !          15492: 
        !          15493:        rp = &rpq[ minor(dev) ];
        !          15494:        s  = sphi();
        !          15495: 
        !          15496:        /*
        !          15497:         * Wait until read is unlocked, and there is data to read
        !          15498:         */
        !          15499:        while ( (rp->q_igate[0] != 0) || ((n = rp->q_size) == 0) ) {
        !          15500: 
        !          15501:                /*
        !          15502:                 * Non-blocking reads.
        !          15503:                 */
        !          15504:                if ( iop->io_flag & IONDLY ) {
        !          15505:                        u.u_error = EAGAIN;
        !          15506:                        return;
        !          15507:                }
        !          15508: 
        !          15509:                ++rp->q_igate[1];
        !          15510:                sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
        !          15511:                --rp->q_igate[1];
        !          15512: 
        !          15513:                if ( SELF->p_ssig && nondsig() ) {      /* signal received */
        !          15514: 
        !          15515:                        spl( s );
        !          15516:                        u.u_error = EINTR;
        !          15517:                        return;
        !          15518:                }
        !          15519:        }
        !          15520:        rp->q_igate[0] = 1;                     /* lock read gate           */
        !          15521:        spl( s );
        !          15522: 
        !          15523:        if ( n > iop->io_ioc )                  /* more data than requested */
        !          15524:                n = iop->io_ioc;
        !          15525: 
        !          15526:        rucopy( rp, iop->io_base, n );          /* copy data to user space  */
        !          15527:        iop->io_base += n;
        !          15528:        iop->io_ioc  -= n;
        !          15529: 
        !          15530:        if ( rp->q_ogate[1] != 0 )              /* someone waiting to write */
        !          15531:                wakeup( rp->q_ogate );
        !          15532:        if ( rp->q_opoll.e_procp )              /* someone polling to write */
        !          15533:                pollwake( &rp->q_opoll );
        !          15534: 
        !          15535:        rp->q_igate[0] = 0;                     /* unlock read gate         */
        !          15536: 
        !          15537:        if ( rp->q_igate[1] != 0 )              /* others waiting to read   */
        !          15538:                wakeup( rp->q_igate );
        !          15539: }
        !          15540: 
        !          15541: /*
        !          15542:  * Write Routine
        !          15543:  */
        !          15544: static
        !          15545: rpwrite( dev, iop )
        !          15546: dev_t dev;
        !          15547: register IO *iop;
        !          15548: {
        !          15549:        register struct ring *rp;
        !          15550:        unsigned n;
        !          15551:        int s;
        !          15552: 
        !          15553:        rp = &rpq[ minor(dev) ];
        !          15554: 
        !          15555:        do {
        !          15556:                s  = sphi();
        !          15557:                /*
        !          15558:                 * Wait until write is unlocked and 512 free slots exist
        !          15559:                 */
        !          15560: 
        !          15561:                while ((rp->q_ogate[0] != 0) || ((n = NCPQ-rp->q_size) < 512)) {
        !          15562: 
        !          15563:                        /*
        !          15564:                         * Non-blocking writes.
        !          15565:                         */
        !          15566:                        if ( iop->io_flag & IONDLY ) {
        !          15567:                                u.u_error = EAGAIN;
        !          15568:                                return;
        !          15569:                        }
        !          15570: 
        !          15571:                        ++rp->q_ogate[1];
        !          15572:                        sleep( rp->q_ogate, CVTTOUT, IVTTOUT, SVTTOUT );
        !          15573:                        --rp->q_ogate[1];
        !          15574: 
        !          15575:                        if (SELF->p_ssig && nondsig()) { /* received signal */
        !          15576: 
        !          15577:                                spl( s );
        !          15578:                                u.u_error = EINTR;
        !          15579:                                return;
        !          15580:                        }
        !          15581:                }
        !          15582:                rp->q_ogate[0] = 1;             /* lock write gate           */
        !          15583:                spl( s );
        !          15584: 
        !          15585:                if ( n > iop->io_ioc )
        !          15586:                        n = iop->io_ioc;
        !          15587: 
        !          15588:                urcopy( iop->io_base, rp, n );  /* copy data from user space */
        !          15589:                iop->io_base += n;
        !          15590:                iop->io_ioc  -= n;
        !          15591: 
        !          15592:                rp->q_ogate[0] = 0;             /* unlock write gate         */
        !          15593: 
        !          15594:                if ( rp->q_igate[1] != 0 )      /* someone waiting to read   */
        !          15595:                        wakeup( rp->q_igate );
        !          15596: 
        !          15597:                if ( rp->q_ipoll.e_procp )      /* someone polling to read */
        !          15598:                        pollwake( &rp->q_ipoll );
        !          15599: 
        !          15600:        } while ( iop->io_ioc != 0 );           /* until all data copied     */
        !          15601: 
        !          15602:        if (rp->q_ogate[1] != 0)                /* someone waiting to write  */
        !          15603:                wakeup( rp->q_ogate );
        !          15604: }
        !          15605: 
        !          15606: /*
        !          15607:  * Poll.
        !          15608:  */
        !          15609: rppoll( dev, ev, msec )
        !          15610: dev_t dev;
        !          15611: int ev;
        !          15612: int msec;
        !          15613: {
        !          15614:        register struct ring *rp = &rpq[ minor(dev) ];
        !          15615: 
        !          15616:        ev &= ~POLLPRI;
        !          15617: 
        !          15618:        /*
        !          15619:         * Input poll.
        !          15620:         */
        !          15621:        if ( ev & POLLIN ) {
        !          15622: 
        !          15623:                /*
        !          15624:                 * Pipe empty.
        !          15625:                 */
        !          15626:                if ( FP_OFF(rp->q_ifaddr) == FP_OFF(rp->q_ofaddr) ) {
        !          15627:                        if ( msec != 0 )
        !          15628:                                pollopen( &rp->q_ipoll );
        !          15629:                        ev &= ~POLLIN;
        !          15630:                }
        !          15631:        }
        !          15632: 
        !          15633:        /*
        !          15634:         * Output poll.
        !          15635:         */
        !          15636:        if ( ev & POLLOUT ) {
        !          15637: 
        !          15638:                /*
        !          15639:                 * Pipe not empty.
        !          15640:                 */
        !          15641:                if ( FP_OFF(rp->q_ifaddr) != FP_OFF(rp->q_ofaddr) ) {
        !          15642:                        if ( msec != 0 )
        !          15643:                                pollopen( &rp->q_opoll );
        !          15644:                        ev &= ~POLLOUT;
        !          15645:                }
        !          15646:        }
        !          15647: 
        !          15648:        return ev;
        !          15649: }
        !          15650: 
        !          15651: /*
        !          15652:  * Flush queue
        !          15653:  */
        !          15654: static
        !          15655: rpflush( rp )
        !          15656: register struct ring *rp;
        !          15657: {
        !          15658:        register int s;
        !          15659: 
        !          15660:        s = sphi();
        !          15661: 
        !          15662:        /*
        !          15663:         * Wait until read is unlocked, or nothing in queue
        !          15664:         */
        !          15665: 
        !          15666:        while ((rp->q_size != 0) && (rp->q_igate[0] != 0) ) {
        !          15667: 
        !          15668:                ++rp->q_igate[1];
        !          15669:                sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
        !          15670:                --rp->q_igate[1];
        !          15671: 
        !          15672:                if (SELF->p_ssig && nondsig()) { /* received signal        */
        !          15673: 
        !          15674:                        spl( s );
        !          15675:                        u.u_error = EINTR;
        !          15676:                        return;
        !          15677:                }
        !          15678:        }
        !          15679: 
        !          15680:        if (rp->q_size != 0) {                  /* flush ram pipe          */
        !          15681: 
        !          15682:                rp->q_ofaddr = rp->q_ifaddr;
        !          15683:                rp->q_size = 0;
        !          15684:        }
        !          15685:        spl( s );
        !          15686: 
        !          15687:        if (rp->q_ogate[1] != 0)                /* someone waiting to write */
        !          15688:                wakeup( rp->q_ogate );
        !          15689: 
        !          15690:        if ( rp->q_opoll.e_procp )              /* someone polling to write */
        !          15691:                pollwake( &rp->q_opoll );
        !          15692: }
        !          15693: 0707070064030150201004440000030000030000011777770507310640500005000000005172/newbits/kernel/USRSRC/i8086/drv/rpas.s////////
        !          15694: /
        !          15695: / Ram Pipe Device Driver Assembler Support
        !          15696: /
        !          15697: /      urcopy( up, np, n )     -- copy user data to pipe
        !          15698: /      rucopy( np, up, n )     -- copy pipe data to user
        !          15699: /
        !          15700: ////////
        !          15701: 
        !          15702:        .globl  urcopy_
        !          15703:        .globl  rucopy_
        !          15704: 
        !          15705: ////////
        !          15706: /
        !          15707: / Offsets of fields within the ram pipe structure
        !          15708: /
        !          15709: ////////
        !          15710: 
        !          15711:        Q_SIZE  = 0
        !          15712:        Q_MASK  = 2
        !          15713:        Q_IX    = 4
        !          15714:        Q_ISEG  = 6
        !          15715:        Q_OX    = 8
        !          15716:        Q_OSEG  = 10
        !          15717:        Q_IGATE = 12
        !          15718:        Q_OGATE = 14
        !          15719: 
        !          15720: ////////
        !          15721: /
        !          15722: / Urcopy ( up, rp, cnt )
        !          15723: / char * up;
        !          15724: / struct ring * rp;
        !          15725: / unsigned cnt;
        !          15726: /
        !          15727: /      Input:  up  = pointer to user data to copy.
        !          15728: /              rp  = pointer to ring structure to copy data to.
        !          15729: /              cnt = number of data bytes to copy.
        !          15730: /
        !          15731: /      Action: Copy CNT bytes from UP to RP->Q_IX.
        !          15732: /
        !          15733: /      Return: Number of bytes transferred.
        !          15734: /
        !          15735: ////////
        !          15736: 
        !          15737: urcopy_:                               / urcopy ( up, rp, cnt )
        !          15738:        push    si                      / register char *up;            /* SI */
        !          15739:        push    di                      / register struct ring *rp;     /* BX */
        !          15740:        push    bp                      / unsigned cnt;
        !          15741:        mov     bp, sp                  / {
        !          15742:        pushf                           /       register char *cp;      /* DI */
        !          15743:        push    ds                      /       register unsigned ret;  /* AX */
        !          15744:        push    es                      /       register unsigned n;    /* CX */
        !          15745:                                        /       register unsigned m;    /* DX */
        !          15746:        mov     si, 8(bp)               /
        !          15747:        mov     bx, 10(bp)              /
        !          15748:        mov     cx, 12(bp)              /       n  = cnt;
        !          15749:        mov     dx, Q_MASK(bx)          /       m  = rp->q_mask;
        !          15750:        les     di, Q_IX(bx)            /       cp = rp->q_ix;
        !          15751:        mov     ds, uds_                /
        !          15752:                                        /
        !          15753:        cld                             /
        !          15754: 0:     movsb                           /       do {    *cp++ = *up++;
        !          15755:        and     di, dx                  /               wrap(cp);
        !          15756:        loop    0b                      /       } while (--n != 0);
        !          15757:                                        /
        !          15758:        pop     es                      /
        !          15759:        pop     ds                      /
        !          15760:        mov     ax, 12(bp)              /       ret = cnt;
        !          15761:        cli                             /       s   = sphi();
        !          15762:        mov     Q_IX(bx), di            /       rp->q_ix = cp;
        !          15763:        add     Q_SIZE(bx), ax          /       rp->q_size += ret;
        !          15764:        popf                            /       spl( s );
        !          15765:        pop     bp                      /
        !          15766:        pop     di                      /       return ret;
        !          15767:        pop     si                      /
        !          15768:        ret                             / }
        !          15769: 
        !          15770: ////////
        !          15771: /
        !          15772: / Rucopy ( rp, up, cnt )
        !          15773: / struct ring * rp;
        !          15774: / char * up;
        !          15775: / unsigned cnt;
        !          15776: /
        !          15777: /      Input:  rp  = pointer to ring structure to copy data from.
        !          15778: /              up  = pointer to user data.
        !          15779: /              cnt = number of data bytes to copy.
        !          15780: /
        !          15781: /      Action: Copy CNT bytes from RP->Q_OX to UP.
        !          15782: /
        !          15783: /      Return: None.
        !          15784: /
        !          15785: ////////
        !          15786: 
        !          15787: rucopy_:                               / rucopy ( rp, up, cnt )
        !          15788:        push    si                      / register struct ring *rp;     /* BX */
        !          15789:        push    di                      / register char * up;           /* DI */
        !          15790:        push    bp                      / unsigned cnt;
        !          15791:        mov     bp, sp                  / {
        !          15792:        pushf                           /       register char *cp;      /* SI */
        !          15793:        push    ds                      /       register unsigned ret;  /* AX */
        !          15794:        push    es                      /       register unsigned n;    /* CX */
        !          15795:                                        /       register unsigned m;    /* DX */
        !          15796:        mov     bx, 8(bp)               /
        !          15797:        mov     di, 10(bp)              /
        !          15798:        mov     cx, 12(bp)              /
        !          15799:        mov     dx, Q_MASK(bx)          /       m = rp->q_mask;
        !          15800:        mov     es, uds_                /
        !          15801:        lds     si, Q_OX(bx)            /       cp = rp->q_ox;
        !          15802:                                        /
        !          15803:        cld                             /
        !          15804: 0:     movsb                           /       do {    *up++ = *cp++;
        !          15805:        and     si, dx                  /               wrap(cp);
        !          15806:        loop    0b                      /       } while (--cnt != 0);
        !          15807:                                        /
        !          15808:        pop     es                      /
        !          15809:        pop     ds                      /
        !          15810:        mov     ax, 12(bp)              /       ret = cnt;
        !          15811:        cli                             /       s   = sphi();
        !          15812:        mov     Q_OX(bx), si            /       rp->q_ox = cp;
        !          15813:        sub     Q_SIZE(bx), ax          /       rp->q_size -= ret;
        !          15814:        popf                            /       spl( s );
        !          15815:        pop     bp                      /
        !          15816:        pop     di                      /       return ret;
        !          15817:        pop     si                      /
        !          15818:        ret                             / }
        !          15819: 0707070064030150221004440000030000030000011777770507310640600004600000050543/newbits/kernel/USRSRC/i8086/drv/rs.c/* (-lgl
        !          15820:  *     COHERENT Driver Kit Version 1.1.0
        !          15821:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          15822:  *     All rights reserved. May not be copied without permission.
        !          15823:  -lgl) */
        !          15824: /*
        !          15825:  * Raw Serial Device Driver.
        !          15826:  *
        !          15827:  *     Provides fast, efficiently buffered serial i/o to COM1 & COM2.
        !          15828:  *     Supports an extreme subset of System V (termio) parameters.
        !          15829:  *             c_iflag: ISTRIP, IXON, IXANY, IGNBRK, INPCK, PARMRK, IGNPAR.
        !          15830:  *             c_oflag: OPOST, ONLCR, ONLRET, TAB3.
        !          15831:  *             c_cflag: *.
        !          15832:  *
        !          15833:  */
        !          15834: 
        !          15835: #include <sys/coherent.h>
        !          15836: #include <sys/ins8250.h>
        !          15837: #include <sys/proc.h>
        !          15838: #include <sys/uproc.h>
        !          15839: #include <sys/con.h>
        !          15840: #include <sys/devices.h>
        !          15841: #include <sys/sched.h>
        !          15842: #include <sys/stat.h>
        !          15843: #include <termio.h>
        !          15844: #include <errno.h>
        !          15845: 
        !          15846: #define        COM1VEC         4               /* interrupt vector for COM1    */
        !          15847: #define        COM2VEC         3               /* interrupt vector for COM2    */
        !          15848: 
        !          15849: #define        COM1PORT        0x3F8           /* i/o port address for COM1    */
        !          15850: #define        COM2PORT        0x2F8           /* i/o port address for COM2    */
        !          15851: 
        !          15852: #ifdef RS1
        !          15853: #      define  CFLAG   RS1CFLAG
        !          15854: #      define  MAJ     AL1_MAJOR       /* major device for /dev/rs1    */
        !          15855: #      define  rscon   rs1con          /* configuration table for "    */
        !          15856: #      define  rstty   rs1tty
        !          15857: #      define  IVEC    COM2VEC         /* interrupt vector for rs1     */
        !          15858: #      define  PORT    COM2PORT        /* i/o port address for rs1     */
        !          15859: #else
        !          15860: #      define  CFLAG   RS0CFLAG
        !          15861: #      define  MAJ     AL0_MAJOR       /* major device for /dev/rs0    */
        !          15862: #      define  rscon   rs0con          /* configuration table for "    */
        !          15863: #      define  rstty   rs0tty
        !          15864: #      define  IVEC    COM1VEC         /* interrupt vector for rs0     */
        !          15865: #      define  PORT    COM1PORT        /* i/o port address for rs0     */
        !          15866: #endif
        !          15867: 
        !          15868: #define        CTRLS   '\023'
        !          15869: #define        CTRLQ   '\021'
        !          15870: 
        !          15871: /*
        !          15872:  * Functions.
        !          15873:  */
        !          15874: 
        !          15875: int    rsload();
        !          15876: int    rsunload();
        !          15877: int    rsopen();
        !          15878: int    rsclose();
        !          15879: int    rsread();
        !          15880: int    rswrite();
        !          15881: int    rsioctl();
        !          15882: int    rspoll();
        !          15883: int    nulldev();
        !          15884: int    nonedev();
        !          15885: 
        !          15886: int    rsintr();
        !          15887: int    rsparam();
        !          15888: 
        !          15889: /*
        !          15890:  * Configuration table.
        !          15891:  */
        !          15892: 
        !          15893: CON rscon ={
        !          15894:        DFCHR|DFPOL,                    /* Flags */
        !          15895:        MAJ,                            /* Major index */
        !          15896:        rsopen,                         /* Open */
        !          15897:        rsclose,                        /* Close */
        !          15898:        nulldev,                        /* Block */
        !          15899:        rsread,                         /* Read */
        !          15900:        rswrite,                        /* Write */
        !          15901:        rsioctl,                        /* Ioctl */
        !          15902:        nulldev,                        /* Powerfail */
        !          15903:        nulldev,                        /* Timeout */
        !          15904:        rsload,                         /* Load */
        !          15905:        rsunload,                       /* Unload */
        !          15906:        rspoll                          /* Poll */
        !          15907: };
        !          15908: 
        !          15909: /*
        !          15910:  * Terminal structure.
        !          15911:  */
        !          15912: 
        !          15913: #define        RAWSZ   (2048-1)
        !          15914: #define        OUTSZ   (2048-1)
        !          15915: 
        !          15916: #define        NRAWC   ((rsrawq.rq_ix - rsrawq.rq_ox) & RAWSZ)
        !          15917: #define        NOUTC   ((rsoutq.rq_ix - rsoutq.rq_ox) & OUTSZ)
        !          15918: 
        !          15919: #define        TTSTOP  00001
        !          15920: #define        TTSBRK  00002
        !          15921: #define        CARRIER 00004
        !          15922: 
        !          15923: typedef
        !          15924: struct rawtty_s {
        !          15925:        unsigned        rt_state;       /* terminal state               */
        !          15926:        int             rt_group;       /* controlling process group    */
        !          15927:        unsigned        rt_ticks;       /* send break 1/10 sec counter  */
        !          15928:        unsigned        rt_iflag;       /* termio input   flags         */
        !          15929:        unsigned        rt_oflag;       /* termio output  flags         */
        !          15930:        unsigned        rt_cflag;       /* termio control flags         */
        !          15931:        unsigned char   rt_col;         /* current output column        */
        !          15932:        unsigned char   rt_refc;        /* # procs accessing the port   */
        !          15933:        unsigned char   rt_irefc;       /* # procs waiting for input    */
        !          15934:        unsigned char   rt_orefc;       /* # procs waitint for output   */
        !          15935:        unsigned char   rt_crefc;       /* # procs waiting for carrier  */
        !          15936:        unsigned char   rt_drefc;       /* # procs waiting for drain    */
        !          15937:        event_t         rt_ipolls;      /* Procs polling on input queue */
        !          15938:        event_t         rt_opolls;      /* Procs polling on output que  */
        !          15939: } RAWTTY;
        !          15940: 
        !          15941: typedef
        !          15942: struct iring_s {
        !          15943:        unsigned short  rq_mask;
        !          15944:        unsigned short  rq_ix;
        !          15945:        unsigned short  rq_ox;
        !          15946:        unsigned char   rq_cc[RAWSZ+1];
        !          15947: } IRING;
        !          15948: 
        !          15949: typedef
        !          15950: struct oring_s {
        !          15951:        unsigned short  rq_mask;
        !          15952:        unsigned short  rq_ix;
        !          15953:        unsigned short  rq_ox;
        !          15954:        unsigned char   rq_cc[OUTSZ+1];
        !          15955: } ORING;
        !          15956: 
        !          15957: /*
        !          15958:  * Local variables.
        !          15959:  */
        !          15960: unsigned CFLAG  = CLOCAL | CREAD | B1200 | CS8 | HUPCL;
        !          15961: RAWTTY rstty;
        !          15962: static ORING   rsoutq;
        !          15963: static IRING   rsrawq;
        !          15964: static TIM     rstim;
        !          15965: 
        !          15966: /*
        !          15967:  * Time constant table.
        !          15968:  * Indexed by ioctl baud rate.
        !          15969:  */
        !          15970: static
        !          15971: int timeconst[] = {
        !          15972:        0,                              /* 0 */
        !          15973:        2304,                           /* 50 */
        !          15974:        1536,                           /* 75 */
        !          15975:        1047,                           /* 110 */
        !          15976:        857,                            /* 134.5 */
        !          15977:        768,                            /* 150 */
        !          15978:        576,                            /* 200 */
        !          15979:        384,                            /* 300 */
        !          15980:        192,                            /* 600 */
        !          15981:        96,                             /* 1200 */
        !          15982:        64,                             /* 1800 */
        !          15983:        48,                             /* 2400 */
        !          15984:        24,                             /* 4800 */
        !          15985:        12,                             /* 9600 */
        !          15986:        6,                              /* 19200/EXTA */
        !          15987:        6                               /* 19200/EXTB */
        !          15988: };
        !          15989: 
        !          15990: /*
        !          15991:  * Rsload() -- Raw Serial Load Routine.
        !          15992:  *
        !          15993:  *     Action: Define terminal parameters.
        !          15994:  *             Initialize terminal hardware.
        !          15995:  *             If serial port exists, seize its interrupt vector.
        !          15996:  *
        !          15997:  *     Return: None.
        !          15998:  */
        !          15999: 
        !          16000: static
        !          16001: rsload()
        !          16002: {
        !          16003:        /*
        !          16004:         * Initialize terminal parameters.
        !          16005:         */
        !          16006:        rsoutq.rq_mask = OUTSZ;
        !          16007:        rsrawq.rq_mask = RAWSZ;
        !          16008: 
        !          16009:        /*
        !          16010:         * Initialize terminal hardware.
        !          16011:         */
        !          16012:        rsparam();
        !          16013: 
        !          16014:        /*
        !          16015:         * If serial port exists, initialize interrupt vector.
        !          16016:         */
        !          16017:        if ( inb(PORT+IER) == 0 ) {
        !          16018:                setivec( IVEC, rsintr);
        !          16019:                rscycle();
        !          16020:        }
        !          16021: }
        !          16022: 
        !          16023: /*
        !          16024:  * Rsunload() -- Raw Serial unload Routine.
        !          16025:  */
        !          16026: 
        !          16027: static
        !          16028: rsunload()
        !          16029: {
        !          16030:        timeout( &rstim, 0, NULL, 0 );  /* cancel timed function */
        !          16031:        clrivec( IVEC );                /* release interrupt vector */
        !          16032:        outb(PORT+IER, 0);              /* disable port interrupts */
        !          16033:        outb(PORT+MCR, MC_OUT2);        /* hangup port */
        !          16034: }
        !          16035: 
        !          16036: /*
        !          16037:  * Rsopen -- Open Routine.
        !          16038:  *
        !          16039:  *     Input:  dev = device to open.
        !          16040:  *             If high bit (0x80) set in minor, modem control is requested.
        !          16041:  *
        !          16042:  *     Action: Validate minor device.
        !          16043:  *             Increment reference count.
        !          16044:  *             If first reference and parameters are not initialized,
        !          16045:  *                     set default parameters and initialize hardware.
        !          16046:  *
        !          16047:  *     Return: None.
        !          16048:  */
        !          16049: 
        !          16050: static
        !          16051: rsopen( dev, mode )
        !          16052: 
        !          16053: dev_t dev;
        !          16054: 
        !          16055: {
        !          16056:        register PROC *pp = SELF;
        !          16057: 
        !          16058:        /*
        !          16059:         * Validate minor device.
        !          16060:         */
        !          16061:        if (minor(dev) & ~0x80) {
        !          16062:                u.u_error = ENODEV;
        !          16063:                return;
        !          16064:        }
        !          16065: 
        !          16066:        /*
        !          16067:         * Validate hardware.
        !          16068:         */
        !          16069:        if (inb(PORT+IER) & ~(IE_RxI|IE_TxI|IE_LSI)) {
        !          16070:                u.u_error = ENXIO;
        !          16071:                return;
        !          16072:        }
        !          16073: 
        !          16074:        /*
        !          16075:         * Ensure controlling terminal and group fields initialized.
        !          16076:         */
        !          16077:        if (pp->p_ttdev == NODEV)
        !          16078:                pp->p_ttdev = dev;
        !          16079:        if (pp->p_group == 0)
        !          16080:                pp->p_group = pp->p_pid;
        !          16081: 
        !          16082:        /*
        !          16083:         * Check for first open.
        !          16084:         */
        !          16085:        if (++rstty.rt_refc == 1) {
        !          16086: 
        !          16087:                if (pp->p_group == pp->p_pid)
        !          16088:                        rstty.rt_group = pp->p_group;
        !          16089: 
        !          16090:                if ((rstty.rt_cflag & CBAUD) == B0) {
        !          16091: 
        !          16092:                        /*
        !          16093:                         * Define terminal parameters.
        !          16094:                         */
        !          16095:                        rstty.rt_state = 0;
        !          16096:                        rstty.rt_col   = 0;
        !          16097:                        rstty.rt_iflag = ISTRIP | IXON;
        !          16098:                        rstty.rt_oflag = OPOST  | ONLCR | TAB3;
        !          16099:                        rstty.rt_cflag = CFLAG;
        !          16100:                        if ( minor(dev) & 0x80 )
        !          16101:                                rstty.rt_cflag &= ~CLOCAL;
        !          16102: 
        !          16103:                        /*
        !          16104:                         * Initialize terminal hardware.
        !          16105:                         */
        !          16106:                        rsparam();
        !          16107:                }
        !          16108: 
        !          16109:                /*
        !          16110:                 * Discard input data.
        !          16111:                 */
        !          16112:                rsrawq.rq_ox = rsrawq.rq_ix;
        !          16113:        }
        !          16114: 
        !          16115:        /*
        !          16116:         * If modem control is requested, check carrier.
        !          16117:         */
        !          16118:        if ( minor(dev) & 0x80 ) {
        !          16119: 
        !          16120:                /*
        !          16121:                 * Delay until carrier is present.
        !          16122:                 */
        !          16123:                while ( (rstty.rt_state & CARRIER) == 0 ) {
        !          16124: 
        !          16125:                        /*
        !          16126:                         * Sleep on carrier.
        !          16127:                         */
        !          16128:                        ++rstty.rt_crefc;
        !          16129:                        sleep( &rstty.rt_crefc,
        !          16130:                                CVTTOUT, IVTTOUT, SVTTOUT);
        !          16131:                        --rstty.rt_crefc;
        !          16132: 
        !          16133:                        /*
        !          16134:                         * Abort if non-ignored signal is received.
        !          16135:                         */
        !          16136:                        if (SELF->p_ssig && nondsig()) {
        !          16137: 
        !          16138:                                if (--rstty.rt_refc == 0) {
        !          16139:                                        rstty.rt_group = 0;
        !          16140:                                        rstty.rt_cflag = 0;
        !          16141:                                        rsparam();
        !          16142:                                }
        !          16143:                                u.u_error = EINTR;
        !          16144:                                return;
        !          16145:                        }
        !          16146:                }
        !          16147:        }
        !          16148: }
        !          16149: 
        !          16150: /*
        !          16151:  * Rsclose -- Close Routine.
        !          16152:  *
        !          16153:  *     Action: Decrement reference count.
        !          16154:  *             If serial port is no longer referenced,
        !          16155:  *             and the hangup on last close bit is set in rt_cflag,
        !          16156:  *             clear terminal parameters, and initialize hardware.
        !          16157:  *
        !          16158:  *     Return: None.
        !          16159:  *
        !          16160:  *     Note:   This routine does not wait for the output queue to empty.
        !          16161:  */
        !          16162: 
        !          16163: static
        !          16164: rsclose( dev )
        !          16165: 
        !          16166: dev_t dev;
        !          16167: 
        !          16168: {
        !          16169:        /*
        !          16170:         * Check for last close and hangup on close.
        !          16171:         */
        !          16172:        if ((rstty.rt_refc == 1) && (rstty.rt_cflag & HUPCL)) {
        !          16173: 
        !          16174:                /*
        !          16175:                 * Wait for output to drain.
        !          16176:                 */
        !          16177:                while ( rsoutq.rq_ox != rsoutq.rq_ix ) {
        !          16178: 
        !          16179:                        ++rstty.rt_drefc;
        !          16180:                        sleep( &rstty.rt_drefc, CVTTOUT, IVTTOUT, SVTTOUT );
        !          16181:                        --rstty.rt_drefc;
        !          16182: 
        !          16183:                        if (rstty.rt_refc != 1) {
        !          16184:                                rstty.rt_refc--;
        !          16185:                                return;
        !          16186:                        }
        !          16187: 
        !          16188:                        if (SELF->p_ssig && nondsig())
        !          16189:                                break;
        !          16190:                }
        !          16191: 
        !          16192:                /*
        !          16193:                 * Initialize terminal hardware.
        !          16194:                 */
        !          16195:                rstty.rt_group = 0;
        !          16196:                rstty.rt_cflag = 0;
        !          16197:                rsparam();
        !          16198: 
        !          16199:                /*
        !          16200:                 * Flush input and output queues.
        !          16201:                 */
        !          16202:                rsrawq.rq_ix =
        !          16203:                rsrawq.rq_ox =
        !          16204:                rsoutq.rq_ox =
        !          16205:                rsoutq.rq_ix = 0;
        !          16206:        }
        !          16207:        --rstty.rt_refc;
        !          16208: }
        !          16209: 
        !          16210: /*
        !          16211:  * Rsread -- Read Routine.
        !          16212:  *
        !          16213:  *     Input:  iop = pointer to structure containing i/o parameters.
        !          16214:  *
        !          16215:  *     Action: Attempt to read data from input buffer until at least
        !          16216:  *             one character has been read, or a signal is received
        !          16217:  *             by the current process.
        !          16218:  *             Update the parameters in the io structure.
        !          16219:  *             If a signal is received, set errno to EINTR.
        !          16220:  *
        !          16221:  *     Return: None.
        !          16222:  */
        !          16223: 
        !          16224: static
        !          16225: rsread( dev, iop )
        !          16226: 
        !          16227: dev_t dev;
        !          16228: register IO *iop;
        !          16229: 
        !          16230: {
        !          16231:        register int sioc;
        !          16232: 
        !          16233:        /*
        !          16234:         * Remember original char count.
        !          16235:         */
        !          16236:        sioc = iop->io_ioc;
        !          16237: 
        !          16238:        do {
        !          16239:                /*
        !          16240:                 * Transfer data until done or input buffer empty.
        !          16241:                 */
        !          16242:                rsin( &rsrawq, iop );
        !          16243: 
        !          16244:                /*
        !          16245:                 * Return if some data was transferred.
        !          16246:                 */
        !          16247:                if (sioc != iop->io_ioc)
        !          16248:                        return;
        !          16249: 
        !          16250:                /*
        !          16251:                 * Non-blocking reads.
        !          16252:                 */
        !          16253:                if ( iop->io_flag & IONDLY ) {
        !          16254:                        u.u_error = EAGAIN;
        !          16255:                        return;
        !          16256:                }
        !          16257: 
        !          16258:                /*
        !          16259:                 * Sleep waiting for a signal or input data.
        !          16260:                 */
        !          16261:                ++rstty.rt_irefc;
        !          16262:                sleep( &rstty.rt_irefc, CVTTOUT, IVTTOUT, SVTTOUT );
        !          16263:                --rstty.rt_irefc;
        !          16264: 
        !          16265:                /*
        !          16266:                 * Abort if a non-ignored signal was received.
        !          16267:                 */
        !          16268:                if (SELF->p_ssig && nondsig()) {
        !          16269:                        u.u_error = EINTR;
        !          16270:                        return;
        !          16271:                }
        !          16272: 
        !          16273:        } while (1);
        !          16274: }
        !          16275: 
        !          16276: /*
        !          16277:  * Rswrite -- Write Routine.
        !          16278:  */
        !          16279: 
        !          16280: static
        !          16281: rswrite( dev, iop )
        !          16282: 
        !          16283: dev_t dev;
        !          16284: register IO *iop;
        !          16285: 
        !          16286: {
        !          16287:        register int n;
        !          16288: 
        !          16289:        /*
        !          16290:         * Non-blocking write.
        !          16291:         */
        !          16292:        if ( iop->io_flag & IONDLY ) {
        !          16293: 
        !          16294:                /*
        !          16295:                 * Calculate free slots.
        !          16296:                 */
        !          16297:                n  = rsoutq.rq_mask - rsoutq.rq_ix + rsoutq.rq_ox;
        !          16298:                n &= rsoutq.rq_mask;
        !          16299: 
        !          16300:                /*
        !          16301:                 * Insufficient space.
        !          16302:                 */
        !          16303:                if ( n <= iop->io_ioc ) {
        !          16304:                        u.u_error = EAGAIN;
        !          16305:                        return;
        !          16306:                }
        !          16307:        }
        !          16308: 
        !          16309:        do {
        !          16310:                /*
        !          16311:                 * Transfer data until done or output queue full.
        !          16312:                 */
        !          16313:                rsout( &rsoutq, iop );
        !          16314: 
        !          16315:                /*
        !          16316:                 * Make sure the transmitter is operating.
        !          16317:                 */
        !          16318:                rsstart();
        !          16319: 
        !          16320:                /*
        !          16321:                 * Return if all data was transferred.
        !          16322:                 */
        !          16323:                if ( iop->io_ioc == 0 )
        !          16324:                        return;
        !          16325: 
        !          16326:                /*
        !          16327:                 * Sleep waiting for a signal or room in the output queue.
        !          16328:                 */
        !          16329:                ++rstty.rt_orefc;
        !          16330:                sleep( &rstty.rt_orefc, CVTTOUT, IVTTOUT, SVTTOUT );
        !          16331:                --rstty.rt_orefc;
        !          16332: 
        !          16333:                /*
        !          16334:                 * Abort if a non-ignored signal was received.
        !          16335:                 */
        !          16336:                if ( SELF->p_ssig && nondsig() ) {
        !          16337:                        u.u_error = EINTR;
        !          16338:                        return;
        !          16339:                }
        !          16340: 
        !          16341:        } while (1);
        !          16342: }
        !          16343: 
        !          16344: /*
        !          16345:  * Rspoll -- Polling Routine.
        !          16346:  */
        !          16347: static int
        !          16348: rspoll( dev, ev, msec )
        !          16349: dev_t dev;
        !          16350: register int ev;
        !          16351: int msec;
        !          16352: {
        !          16353:        /*
        !          16354:         * No priority reports.
        !          16355:         */
        !          16356:        ev &= ~POLLPRI;
        !          16357: 
        !          16358:        /*
        !          16359:         * Input poll with empty input ring.
        !          16360:         */
        !          16361:        if ( (ev & POLLIN) && (rsrawq.rq_ix == rsrawq.rq_ox) ) {
        !          16362: 
        !          16363:                /*
        !          16364:                 * Blocking input poll.
        !          16365:                 */
        !          16366:                if ( msec != 0 )
        !          16367:                        pollopen( &rstty.rt_ipolls );
        !          16368: 
        !          16369:                /*
        !          16370:                 * Second look and clear input report.
        !          16371:                 */
        !          16372:                if ( rsrawq.rq_ix == rsrawq.rq_ox )
        !          16373:                        ev &= ~POLLIN;
        !          16374:        }
        !          16375: 
        !          16376:        /*
        !          16377:         * Output poll with non-empty output ring.
        !          16378:         */
        !          16379:        if ( (ev & POLLOUT) && (rsoutq.rq_ix != rsrawq.rq_ox) ) {
        !          16380: 
        !          16381:                /*
        !          16382:                 * Blocking output poll.
        !          16383:                 */
        !          16384:                if ( msec != 0 )
        !          16385:                        pollopen( &rstty.rt_opolls );
        !          16386: 
        !          16387:                /*
        !          16388:                 * Second look and clear output report.
        !          16389:                 */
        !          16390:                if ( rsoutq.rq_ix != rsoutq.rq_ox )
        !          16391:                        ev &= ~POLLOUT;
        !          16392:        }
        !          16393: 
        !          16394:        return ev;
        !          16395: }
        !          16396: 
        !          16397: /*
        !          16398:  * Cyclic [1 sec] Routine.
        !          16399:  */
        !          16400: static
        !          16401: rscycle()
        !          16402: {
        !          16403:        register PROC *pp;
        !          16404:        register int b;
        !          16405: 
        !          16406:        /*
        !          16407:         * Check for carrier transitions.
        !          16408:         */
        !          16409:        if ( inb( PORT + MSR ) & MS_RLSD ) {
        !          16410: 
        !          16411:                /*
        !          16412:                 * Have carrier.  Wake processes waiting for carrier.
        !          16413:                 */
        !          16414:                rstty.rt_state |= CARRIER;
        !          16415: 
        !          16416:                if ( rstty.rt_crefc )
        !          16417:                        wakeup( &rstty.rt_crefc );
        !          16418:        }
        !          16419:        else if ((rstty.rt_state & CARRIER) && (rstty.rt_cflag&CLOCAL) == 0) {
        !          16420: 
        !          16421:                /*
        !          16422:                 * Lost carrier. Signal attached processes.
        !          16423:                 */
        !          16424:                rstty.rt_state &= ~CARRIER;
        !          16425: 
        !          16426:                if (rstty.rt_refc && (b = rstty.rt_group))
        !          16427:                        for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw)
        !          16428:                                if ( pp->p_group == b )
        !          16429:                                        sendsig( SIGHUP, pp );
        !          16430:        }
        !          16431: 
        !          16432:        /*
        !          16433:         * Wakeup processes waiting to read if input data present.
        !          16434:         */
        !          16435:        if ( rsrawq.rq_ix != rsrawq.rq_ox ) {
        !          16436:                if ( rstty.rt_irefc )
        !          16437:                        wakeup( &rstty.rt_irefc );
        !          16438:                if ( rstty.rt_ipolls.e_procp )
        !          16439:                        pollwake( &rstty.rt_ipolls );
        !          16440:        }
        !          16441: 
        !          16442:        /*
        !          16443:         * Check for break being sent.
        !          16444:         */
        !          16445:        if ( rstty.rt_ticks != 0 ) {
        !          16446: 
        !          16447:                if ( --rstty.rt_ticks == 0 ) {
        !          16448: 
        !          16449:                        b = inb( PORT + LCR );
        !          16450:                        outb( PORT + LCR, b & ~LC_SBRK );
        !          16451:                        rstty.rt_state &= ~TTSBRK;
        !          16452:                }
        !          16453:        }
        !          16454: 
        !          16455:        /*
        !          16456:         * Can check output if not sending break.
        !          16457:         */
        !          16458:        if ( rstty.rt_ticks == 0 ) {
        !          16459: 
        !          16460:                /*
        !          16461:                 * Restart output if necessary.
        !          16462:                 */
        !          16463:                if ( rsoutq.rq_ox != rsoutq.rq_ix )
        !          16464:                        rsstart();
        !          16465: 
        !          16466:                /*
        !          16467:                 * Wakeup processes waiting for drain if output queue empty.
        !          16468:                 */
        !          16469:                if ( rstty.rt_drefc ) {
        !          16470:                        if ( rsoutq.rq_ix == rsoutq.rq_ox )
        !          16471:                                wakeup( &rstty.rt_drefc );
        !          16472:                }
        !          16473: 
        !          16474:                /*
        !          16475:                 * Wakeup processes waiting to write if 512 slots are free.
        !          16476:                 */
        !          16477:                else if ( NOUTC < OUTSZ-512 ) {
        !          16478:                        if ( rstty.rt_orefc )
        !          16479:                                wakeup( &rstty.rt_orefc );
        !          16480:                        if ( rstty.rt_opolls.e_procp )
        !          16481:                                pollwake( &rstty.rt_opolls );
        !          16482:                }
        !          16483:        }
        !          16484: 
        !          16485:        timeout( &rstim, HZ/10, rscycle, 0 );
        !          16486: }
        !          16487: 
        !          16488: /*
        !          16489:  * Rsintr -- Serial Interrupt Handler.
        !          16490:  *
        !          16491:  *     Action: Process all pending interrupt service requests
        !          16492:  *             on the serial port.
        !          16493:  *
        !          16494:  *     Return: None.
        !          16495:  *
        !          16496:  *     Notes:  This routine must loop until all requests are serviced
        !          16497:  *             because of the edge sensitive nature of the programmable
        !          16498:  *             interrupt controller.
        !          16499:  */
        !          16500: 
        !          16501: static
        !          16502: rsintr()
        !          16503: {
        !          16504:        register int b;
        !          16505: 
        !          16506:        /*
        !          16507:         * Service serial port interrupt requests, highest to lowest priority.
        !          16508:         */
        !          16509: rescan:
        !          16510:        b = inb( PORT + IIR );
        !          16511: 
        !          16512:        switch ( b ) {
        !          16513: 
        !          16514:        case LS_INTR:
        !          16515:                /*
        !          16516:                 * Get line status (clear interrupt).
        !          16517:                 */
        !          16518:                b = inb( PORT + LSR );
        !          16519: 
        !          16520:                /*
        !          16521:                 * Check for received break.
        !          16522:                 */
        !          16523:                if (b & LS_BREAK) {
        !          16524: 
        !          16525:                        /*
        !          16526:                         * Read the break char ('\0').
        !          16527:                         */
        !          16528:                        rsrawq.rq_cc[ rsrawq.rq_ix ] = inb( PORT + DREG );
        !          16529: 
        !          16530:                        /*
        !          16531:                         * Clear output stops.
        !          16532:                         */
        !          16533:                        rstty.rt_state &= ~TTSTOP;
        !          16534: 
        !          16535:                        /*
        !          16536:                         * Update input index if not ignoring break.
        !          16537:                         */
        !          16538:                        if ((rstty.rt_iflag & IGNBRK) == 0) {
        !          16539:                                rsrawq.rq_ix ++;
        !          16540:                                rsrawq.rq_ix &= RAWSZ;
        !          16541:                        }
        !          16542:                }
        !          16543: 
        !          16544:                /*
        !          16545:                 * Special handling if frame/parity error and checking enabled.
        !          16546:                 */
        !          16547:                if ((b & (LS_FRAME|LS_PARITY)) && (rstty.rt_iflag & INPCK)) {
        !          16548: 
        !          16549:                        /*
        !          16550:                         * Ignore next input char if IGNPAR set.
        !          16551:                         */
        !          16552:                        if (rstty.rt_iflag & IGNPAR)
        !          16553:                                inb( PORT + DREG );
        !          16554:                        /*
        !          16555:                         * Change next input char into 0377,0,ch if PARMRK set.
        !          16556:                         */
        !          16557:                        else if (rstty.rt_iflag & PARMRK) {
        !          16558: 
        !          16559:                                b = rsrawq.rq_ix;
        !          16560:                                rsrawq.rq_cc[ b++ ] = 0377;
        !          16561:                                b &= RAWSZ;
        !          16562:                                rsrawq.rq_cc[ b++ ] = '\0';
        !          16563:                                b &= RAWSZ;
        !          16564:                                rsrawq.rq_cc[ b++ ] = inb( PORT + DREG );
        !          16565:                                b &= RAWSZ;
        !          16566:                                rsrawq.rq_ix = b;
        !          16567:                        }
        !          16568: 
        !          16569:                        /*
        !          16570:                         * Otherwise change next input char into null.
        !          16571:                         */
        !          16572:                        else {
        !          16573:                                inb( PORT + DREG );
        !          16574:                                rsrawq.rq_cc[ rsrawq.rq_ix++ ] = '\0';
        !          16575:                                rsrawq.rq_ix &= RAWSZ;
        !          16576:                        }
        !          16577:                }
        !          16578:                goto rescan;
        !          16579: 
        !          16580:        case Rx_INTR:
        !          16581:                /*
        !          16582:                 * Read character from receive buffer.
        !          16583:                 */
        !          16584:                b = inb( PORT + DREG );
        !          16585: 
        !          16586:                /*
        !          16587:                 * Discard high bit if ISTRIP set.
        !          16588:                 */
        !          16589:                if ( rstty.rt_iflag & ISTRIP )
        !          16590:                        b &= 0177;
        !          16591: 
        !          16592:                /*
        !          16593:                 * Check for output flow control if IXON set.
        !          16594:                 */
        !          16595:                if ( rstty.rt_iflag & IXON ) {
        !          16596: 
        !          16597:                        /*
        !          16598:                         * Stop output if Ctl-S.
        !          16599:                         */
        !          16600:                        if ( b == CTRLS ) {
        !          16601:                                rstty.rt_state |= TTSTOP;
        !          16602:                                goto rescan;
        !          16603:                        }
        !          16604: 
        !          16605:                        /*
        !          16606:                         * Resume output if Ctl-Q.
        !          16607:                         */
        !          16608:                        if ( b == CTRLQ ) {
        !          16609:                                rstty.rt_state &= ~TTSTOP;
        !          16610:                                goto rescan;
        !          16611:                        }
        !          16612: 
        !          16613:                        /*
        !          16614:                         * Enable output if IXANY set.
        !          16615:                         */
        !          16616:                        if ( rstty.rt_iflag & IXANY )
        !          16617:                                rstty.rt_state &= ~TTSTOP;
        !          16618:                }
        !          16619: 
        !          16620:                /*
        !          16621:                 * Save the character in the input queue.
        !          16622:                 */
        !          16623:                rsrawq.rq_cc[ rsrawq.rq_ix++ ] = b;
        !          16624:                rsrawq.rq_ix &= RAWSZ;
        !          16625: 
        !          16626:                /*
        !          16627:                 * Save again if 0377 and parity marking enabled.
        !          16628:                 */
        !          16629:                if ((b == 0377)
        !          16630:                &&  ((rstty.rt_iflag & (INPCK|PARMRK)) == (INPCK|PARMRK))) {
        !          16631: 
        !          16632:                        rsrawq.rq_cc[ rsrawq.rq_ix++ ] = b;
        !          16633:                        rsrawq.rq_ix &= RAWSZ;
        !          16634:                }
        !          16635: 
        !          16636:                goto rescan;
        !          16637: 
        !          16638:        case Tx_INTR:
        !          16639:                rsstart();
        !          16640:                goto rescan;
        !          16641:        }
        !          16642: }
        !          16643: 
        !          16644: /*
        !          16645:  * Rsstart()
        !          16646:  *
        !          16647:  *     Action: While output data is available, and the transmitter buffer
        !          16648:  *             is empty, transfer one character from the output queue to the
        !          16649:  *             transmit buffer.
        !          16650:  *
        !          16651:  *     Return: None.
        !          16652:  */
        !          16653: 
        !          16654: static
        !          16655: rsstart()
        !          16656: {
        !          16657:        register int b;
        !          16658:        register int s;
        !          16659: 
        !          16660:        /*
        !          16661:         * Can't transmit if output stopped or sending break.
        !          16662:         */
        !          16663:        if ( rstty.rt_state & (TTSTOP|TTSBRK) )
        !          16664:                return;
        !          16665: 
        !          16666:        /*
        !          16667:         * Can't transmit if modem control enabled without CTS present.
        !          16668:         */
        !          16669:        if ( (rstty.rt_cflag & CLOCAL) == 0 )
        !          16670:                if ( (inb(PORT+MSR) & MS_CTS) == 0 )
        !          16671:                        return;
        !          16672: 
        !          16673:        /*
        !          16674:         * Disable interrupts to avoid critical race.
        !          16675:         */
        !          16676:        s = sphi();
        !          16677: 
        !          16678:        /*
        !          16679:         * Can transmit if output data available and transmit buffer empty.
        !          16680:         */
        !          16681:        if ( (rsoutq.rq_ix != rsoutq.rq_ox)
        !          16682:        &&   (inb(PORT+LSR) & LS_TxRDY) ) {
        !          16683: 
        !          16684:                /*
        !          16685:                 * Get next char from output queue.
        !          16686:                 */
        !          16687:                b = rsoutq.rq_cc [ rsoutq.rq_ox ];
        !          16688: 
        !          16689:                if (rstty.rt_oflag & OPOST) {
        !          16690: 
        !          16691:                        /*
        !          16692:                         * Printable characters increment the column.
        !          16693:                         */
        !          16694:                        if (b >= ' ') {
        !          16695:                                rstty.rt_col++;
        !          16696:                        }
        !          16697:                        /*
        !          16698:                         * Carriage return resets the column.
        !          16699:                         */
        !          16700:                        else if (b == '\r') {
        !          16701:                                rstty.rt_col = 0;
        !          16702:                                if (rstty.rt_oflag & OCRNL)
        !          16703:                                        b = '\n';
        !          16704:                        }
        !          16705:                        /*
        !          16706:                         * New-line may also generate a carriage return.
        !          16707:                         */
        !          16708:                        else if (b == '\n') {
        !          16709:                                if (rstty.rt_oflag & ONLCR) {
        !          16710:                                        if (rstty.rt_col) {
        !          16711:                                                rstty.rt_col = 0;
        !          16712:                                                rsoutq.rq_ox--;
        !          16713:                                                b = '\r';
        !          16714:                                        }
        !          16715:                                }
        !          16716:                                else if (rstty.rt_oflag & ONLRET)
        !          16717:                                        rstty.rt_col = 0;
        !          16718:                        }
        !          16719:                        /*
        !          16720:                         * Backspace decrements the column.
        !          16721:                         */
        !          16722:                        else if (b == '\b') {
        !          16723:                                if (rstty.rt_col)
        !          16724:                                        --rstty.rt_col;
        !          16725:                        }
        !          16726:                        /*
        !          16727:                         * Tabs may generate spaces, always move to tab stop.
        !          16728:                         */
        !          16729:                        else if (b == '\t') {
        !          16730:                                if ((rstty.rt_oflag & TABDLY) == TAB3) {
        !          16731:                                        b = ' ';
        !          16732:                                        if (++rstty.rt_col & 7)
        !          16733:                                                rsoutq.rq_ox--;
        !          16734:                                }
        !          16735:                                else {
        !          16736:                                        rstty.rt_col |= 7;
        !          16737:                                        rstty.rt_col++;
        !          16738:                                }
        !          16739:                        }
        !          16740:                }
        !          16741:                rsoutq.rq_ox++;
        !          16742:                rsoutq.rq_ox &= OUTSZ;
        !          16743: 
        !          16744:                /*
        !          16745:                 * Transmit next char.
        !          16746:                 */
        !          16747:                outb( PORT+DREG, b );
        !          16748:        }
        !          16749: 
        !          16750:        spl(s);
        !          16751: }
        !          16752: 
        !          16753: /*
        !          16754:  * Ioctl Routine.
        !          16755:  */
        !          16756: 
        !          16757: static
        !          16758: rsioctl( dev, com, vec )
        !          16759: 
        !          16760: dev_t dev;
        !          16761: int com;
        !          16762: struct termio *vec;
        !          16763: 
        !          16764: {
        !          16765:        register int b;
        !          16766:        struct termio tb;
        !          16767: 
        !          16768:        switch (com) {
        !          16769: 
        !          16770:        case TCSETAW:   /* Set attributes after waiting for output to clear */
        !          16771:        case TCSETAF:   /* ditto, but also flush input queue */
        !          16772:        case TCSBRK:    /* wait for output to clear, send break */
        !          16773: 
        !          16774:                /*
        !          16775:                 * Delay until output queue is empty.
        !          16776:                 */
        !          16777:                while ( rsoutq.rq_ox != rsoutq.rq_ix ) {
        !          16778: 
        !          16779:                        /*
        !          16780:                         * Sleep waiting for empty output queue.
        !          16781:                         */
        !          16782:                        ++rstty.rt_drefc;
        !          16783:                        sleep( &rstty.rt_drefc, CVTTOUT, IVTTOUT, SVTTOUT);
        !          16784:                        --rstty.rt_drefc;
        !          16785: 
        !          16786:                        /*
        !          16787:                         * Abort if a non-ignored signal was received.
        !          16788:                         */
        !          16789:                        if ( SELF->p_ssig && nondsig() ) {
        !          16790:                                u.u_error = EINTR;
        !          16791:                                return;
        !          16792:                        }
        !          16793:                }
        !          16794: 
        !          16795:                if ( com == TCSBRK ) {
        !          16796: 
        !          16797:                        b = inb( PORT + LCR );
        !          16798: 
        !          16799:                        if ( vec == 0 ) {
        !          16800:                                rstty.rt_ticks  = 3;    /* 0.2 to 0.3 sec */
        !          16801:                                rstty.rt_state |= TTSBRK;
        !          16802:                                b |= LC_SBRK;
        !          16803:                        }
        !          16804:                        else {
        !          16805:                                rstty.rt_ticks  = 0;
        !          16806:                                rstty.rt_state &= ~TTSBRK;
        !          16807:                                b &= ~LC_SBRK;
        !          16808:                        }
        !          16809: 
        !          16810:                        outb( PORT + LCR, b );
        !          16811:                        return;
        !          16812:                }
        !          16813:                /* no break */
        !          16814: 
        !          16815:        case TCSETA:
        !          16816:                /*
        !          16817:                 * Get new terminal attributes.
        !          16818:                 */
        !          16819:                ukcopy( vec, &tb, sizeof(tb) );
        !          16820:                if ( u.u_error )
        !          16821:                        return;
        !          16822: 
        !          16823:                /*
        !          16824:                 * Set terminal attributes and hardware.
        !          16825:                 */
        !          16826:                rstty.rt_iflag = tb.c_iflag;
        !          16827:                rstty.rt_oflag = tb.c_oflag;
        !          16828:                if (rstty.rt_cflag != tb.c_cflag) {
        !          16829:                        rstty.rt_cflag = tb.c_cflag;
        !          16830:                        rsparam();
        !          16831:                }
        !          16832: 
        !          16833:                if ((rstty.rt_iflag & IXON) == 0)
        !          16834:                        rstty.rt_state &= ~TTSTOP;
        !          16835: 
        !          16836:                /*
        !          16837:                 * Flush input queue if command was TCSETAF.
        !          16838:                 */
        !          16839:                if ( com == TCSETAF )
        !          16840:                        rsrawq.rq_ox = rsrawq.rq_ix;
        !          16841:                break;
        !          16842: 
        !          16843:        case TCGETA:    /* Get terminal attributes */
        !          16844:                
        !          16845:                memset( &tb, 0, sizeof(tb) );
        !          16846:                tb.c_cflag = rstty.rt_cflag;
        !          16847:                tb.c_iflag = rstty.rt_iflag;
        !          16848:                tb.c_oflag = rstty.rt_oflag;
        !          16849: 
        !          16850:                /*
        !          16851:                 * Transfer terminal attributes to user space.
        !          16852:                 */
        !          16853:                kucopy( &tb, vec, sizeof(tb) );
        !          16854:                break;
        !          16855: 
        !          16856:        case TCFLSH:
        !          16857:                switch ((int) vec) {
        !          16858:                case 0:
        !          16859:                        /* flush input queue */
        !          16860:                        rsrawq.rq_ox = rsrawq.rq_ix;
        !          16861:                        break;
        !          16862:                case 1:
        !          16863:                        /* flush output queue */
        !          16864:                        rsoutq.rq_ox = rsoutq.rq_ix;
        !          16865:                        break;
        !          16866:                case 2:
        !          16867:                        /* flush both input and output queues */
        !          16868:                        rsrawq.rq_ox = rsrawq.rq_ix;
        !          16869:                        rsoutq.rq_ox = rsoutq.rq_ix;
        !          16870:                        break;
        !          16871:                default:
        !          16872:                        u.u_error = EINVAL;
        !          16873:                }
        !          16874:                break;
        !          16875: 
        !          16876:        case TCXONC:
        !          16877:                switch ( (int) vec ) {
        !          16878:                case 0:
        !          16879:                        /* stop output */
        !          16880:                        rstty.rt_state |= TTSTOP;
        !          16881:                        break;
        !          16882:                case 1:
        !          16883:                        /* restart output */
        !          16884:                        rstty.rt_state &= ~TTSTOP;
        !          16885:                        rsstart();
        !          16886:                        break;
        !          16887:                default:
        !          16888:                        u.u_error = EINVAL;
        !          16889:                }
        !          16890:                break;
        !          16891: 
        !          16892:        default:
        !          16893:                u.u_error = EINVAL;
        !          16894:        }
        !          16895: }
        !          16896: 
        !          16897: /*
        !          16898:  * Rsparam -- Setup hardware parameters.
        !          16899:  */
        !          16900: 
        !          16901: static
        !          16902: rsparam()
        !          16903: {
        !          16904:        register int b;
        !          16905:        register int s;
        !          16906: 
        !          16907:        /*
        !          16908:         * Disable interrupts.
        !          16909:         */
        !          16910:        s = sphi();
        !          16911: 
        !          16912:        /*
        !          16913:         * Assert required modem control lines (DTR, RTS).
        !          16914:         */
        !          16915:        if ((rstty.rt_cflag & CBAUD) == B0)
        !          16916:                outb( PORT+MCR, MC_OUT2 );
        !          16917:        else if ((rstty.rt_refc == 0) && (rstty.rt_cflag & HUPCL))
        !          16918:                outb( PORT+MCR, MC_OUT2 );
        !          16919:        else
        !          16920:                outb( PORT+MCR, MC_OUT2+MC_DTR+MC_RTS );
        !          16921: 
        !          16922:        /*
        !          16923:         * Program baud rate.
        !          16924:         */
        !          16925:        if (b = timeconst[ rstty.rt_cflag & CBAUD ]) {
        !          16926:                outb( PORT+LCR, LC_DLAB );
        !          16927:                outb( PORT+DLL, b );
        !          16928:                outb( PORT+DLH, b >> 8 );
        !          16929:        }
        !          16930: 
        !          16931:        /*
        !          16932:         * Program character size, parity, and stop bits.
        !          16933:         */
        !          16934:        switch (rstty.rt_cflag & CSIZE) {
        !          16935:        case CS5:               b = LC_CS5;                     break;
        !          16936:        case CS6:               b = LC_CS6;                     break;
        !          16937:        case CS7:               b = LC_CS7;                     break;
        !          16938:        case CS8:               b = LC_CS8;                     break;
        !          16939:        }
        !          16940: 
        !          16941:        switch (rstty.rt_cflag & (PARENB|PARODD)) {
        !          16942:        case PARENB:            b |= LC_PARENB|LC_PAREVEN;      break;
        !          16943:        case PARENB|PARODD:     b |= LC_PARENB;                 break;
        !          16944:        }
        !          16945: 
        !          16946:        if (rstty.rt_cflag & CSTOPB)
        !          16947:                b |= LC_STOPB;
        !          16948: 
        !          16949:        if (rstty.rt_state & TTSBRK)
        !          16950:                b |= LC_SBRK;
        !          16951: 
        !          16952:        outb( PORT+LCR, b );
        !          16953: 
        !          16954:        /*
        !          16955:         * Enable desired interrupts.
        !          16956:         */
        !          16957:        b = 0;
        !          16958:        if (rstty.rt_cflag & CBAUD) {
        !          16959:                b = IE_TxI | IE_LSI;
        !          16960:                if (rstty.rt_cflag & CREAD)
        !          16961:                        b |= IE_RxI;
        !          16962:        }
        !          16963:        outb( PORT+IER, b );
        !          16964: 
        !          16965:        /*
        !          16966:         * Enable interrupts.
        !          16967:         */
        !          16968:        spl( s );
        !          16969: }
        !          16970: 0707070064030150161004440000030000030000011777770507310641300005000000004214/newbits/kernel/USRSRC/i8086/drv/rsas.s/ (lgl-
        !          16971: /      COHERENT Driver Kit Version 1.1.0
        !          16972: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          16973: /      All rights reserved. May not be copied without permission.
        !          16974: / -lgl)
        !          16975: ////////
        !          16976: /
        !          16977: / Raw Serial Device Driver - Assembler Support
        !          16978: /
        !          16979: ////////
        !          16980: 
        !          16981: ////////
        !          16982: /
        !          16983: / Locally defined global symbols
        !          16984: /
        !          16985: ////////
        !          16986: 
        !          16987:        .globl  rsin_
        !          16988:        .globl  rsout_
        !          16989: 
        !          16990: ////////
        !          16991: /
        !          16992: / Offsets to fields in the IRING and ORING data structures.
        !          16993: /
        !          16994: ////////
        !          16995: 
        !          16996:        Q_MASK  = 0
        !          16997:        Q_IX    = 2
        !          16998:        Q_OX    = 4
        !          16999:        Q_CC    = 6
        !          17000: 
        !          17001: ////////
        !          17002: /
        !          17003: / Offsets to fields in the IO data structure.
        !          17004: /
        !          17005: ////////
        !          17006: 
        !          17007:        IO_IOC  = 2
        !          17008:        IO_BASE = 8
        !          17009: 
        !          17010: ////////
        !          17011: /
        !          17012: / Rsin ( rawqp, iop )  -- transfer data from input ring to user
        !          17013: / IRING *rawqp;
        !          17014: / IO *iop;
        !          17015: /
        !          17016: ////////
        !          17017: 
        !          17018: rsin_:
        !          17019:        push    si                              / Save SI, DI, BP, ES
        !          17020:        push    di
        !          17021:        push    bp
        !          17022:        mov     bp, sp
        !          17023:        push    es
        !          17024: 
        !          17025:        mov     bx, 10(bp)                      / User destination --> ES:DI
        !          17026:        mov     di, IO_BASE(bx)
        !          17027:        mov     es, uds_
        !          17028: 
        !          17029:        cld                                     / Auto Increment
        !          17030:        mov     cx, IO_IOC(bx)                  / Byte count --> CX
        !          17031:        jcxz    1f
        !          17032: 
        !          17033:        mov     bx, 8(bp)                       / rawqp --> BX
        !          17034: 
        !          17035:        mov     si, Q_OX(bx)
        !          17036:        cmp     si, Q_IX(bx)                    / Input data available?
        !          17037:        je      1f
        !          17038: 
        !          17039: 0:     movb    al, Q_CC(bx,si)                 / Yes,  read one character
        !          17040:        inc     si                              /       update index
        !          17041:        and     si, Q_MASK(bx)                  /       (wrap if necessary)
        !          17042:        stosb                                   /       write to user space
        !          17043:        cmp     si, Q_IX(bx)                    /       More input data?
        !          17044:        loopne  0b                              /
        !          17045: 
        !          17046:        mov     Q_OX(bx), si                    / Save revised index
        !          17047:        mov     bx, 10(bp)                      / Update io parameters
        !          17048:        mov     IO_BASE(bx), di
        !          17049:        mov     IO_IOC(bx), cx
        !          17050: 
        !          17051: 1:     pop     es                              / Restore ES, BP, DI, SI.
        !          17052:        pop     bp
        !          17053:        pop     di
        !          17054:        pop     si
        !          17055:        ret
        !          17056: 
        !          17057: ////////
        !          17058: /
        !          17059: / Rsout( outqp, iop )  -- transfer data from user to output ring
        !          17060: / ORING *outqp;
        !          17061: / IO *iop;
        !          17062: /
        !          17063: ////////
        !          17064: 
        !          17065: rsout_:
        !          17066:        push    si                              / Save SI, DI, BP, ES
        !          17067:        push    di
        !          17068:        push    bp
        !          17069:        mov     bp, sp
        !          17070:        push    es
        !          17071: 
        !          17072:        mov     bx, 10(bp)                      / User source --> ES:DI
        !          17073:        mov     di, IO_BASE(bx)
        !          17074:        mov     es, uds_
        !          17075: 
        !          17076:        mov     cx, IO_IOC(bx)                  / Byte count --> CX
        !          17077:        jcxz    2f
        !          17078: 
        !          17079:        mov     bx, 8(bp)                       / outqp --> BX
        !          17080:        mov     si, Q_IX(bx)
        !          17081: 
        !          17082: 0:     movb    al, es:(di)
        !          17083:        inc     di
        !          17084:        movb    Q_CC(bx,si), al
        !          17085:        inc     si
        !          17086:        and     si, Q_MASK(bx)
        !          17087:        cmp     si, Q_OX(bx)
        !          17088:        loopne  0b
        !          17089: 
        !          17090:        jne     1f                              / If can't save last char
        !          17091:        dec     di                              /       Undo changes.
        !          17092:        dec     si
        !          17093:        and     si, Q_MASK(bx)
        !          17094:        inc     cx
        !          17095: 
        !          17096: 1:     mov     Q_IX(bx), si                    / Save revised index
        !          17097:        mov     bx, 10(bp)
        !          17098:        mov     IO_BASE(bx), di                 / Update io parameters
        !          17099:        mov     IO_IOC(bx), cx
        !          17100: 
        !          17101: 2:     pop     es                              / Restore ES, BP, DI, SI.
        !          17102:        pop     bp
        !          17103:        pop     di
        !          17104:        pop     si
        !          17105:        ret
        !          17106: 0707070064030150171006440000030000030000011777770507310641300005000000027231/newbits/kernel/USRSRC/i8086/drv/scsi.c/*
        !          17107:  * This is the generic SCSI part of the
        !          17108:  * Adaptec AHA154x host adapter driver for the AT.
        !          17109:  *
        !          17110:  * $Log:       scsi.c,v $
        !          17111:  * Revision 1.6  91/06/10  13:28:11  hal
        !          17112:  * Refix startup problem with HDGETA.  Text cleanup.
        !          17113:  * 
        !          17114:  * Revision 1.5  91/06/10  12:58:04  hal
        !          17115:  * Partial fix for HDGETA failing if partition table absent.
        !          17116:  * 
        !          17117:  * Revision 1.4  91/06/03  13:50:06  hal
        !          17118:  * Add HDSETA.
        !          17119:  * 
        !          17120:  * Revision 1.3        91/05/08  11:00:30      root
        !          17121:  * Make number of heads - SD_HDS - patchable for Tandy.
        !          17122:  * 
        !          17123:  * Revision 1.2        91/05/01  04:50:11      root
        !          17124:  * Debug code and d_time/sw_active imbalance fixed.
        !          17125:  * 
        !          17126:  * Revision 1.1        91/04/30  11:02:22      root
        !          17127:  * Shipped with COH 3.1.0
        !          17128:  * 
        !          17129:  */
        !          17130: 
        !          17131: #include       <sys/coherent.h>
        !          17132: #include       <sys/fdisk.h>
        !          17133: #include       <sys/hdioctl.h>
        !          17134: #include       <sys/sdioctl.h>
        !          17135: #include       <sys/buf.h>
        !          17136: #include       <sys/con.h>
        !          17137: #include       <sys/stat.h>
        !          17138: #include       <sys/uproc.h>
        !          17139: #include       <errno.h>
        !          17140: #include       <sys/scsiwork.h>
        !          17141: 
        !          17142: extern saddr_t sds;
        !          17143: 
        !          17144: /*
        !          17145:  * Configurable parameters
        !          17146:  *
        !          17147:  * Adaptec ROM translates at 64 heads, except the Tandy version, which
        !          17148:  * uses 16 heads.  Kernel variable SD_HDS is patchable for this reason.
        !          17149:  */
        !          17150: #ifdef TANDY
        !          17151: int SD_HDS = 16;
        !          17152: #else
        !          17153: int SD_HDS = 64;
        !          17154: #endif
        !          17155: int SD_SPT = 32;
        !          17156: 
        !          17157: #define NDRIVE (8 * 4)                 /* 8 SCSI ids and 4 LUNs */
        !          17158: #define        SDMAJOR 13                      /* Major Device Number */
        !          17159: #define        SDDMA   5                       /* Used for first party DMA */
        !          17160: 
        !          17161: /*
        !          17162:  * user configurable paramters
        !          17163:  */
        !          17164: int    SDIRQ   = 11;                   /* Interrupt */
        !          17165: int    SDBASE  = 0x0330;               /* Port base */
        !          17166: 
        !          17167: /*
        !          17168:  *                                     LUN --------++
        !          17169:  * device macros                       Special-+   ||
        !          17170:  * minor device bits are of the form:          76543210
        !          17171:  *                                              |||  ||
        !          17172:  *                                     SCSI ID--+++  ||
        !          17173:  *                                     Partition ----++
        !          17174:  * Partition mapping:
        !          17175:  *
        !          17176:  * Description    Special Bit     Partition #          Device          Type
        !          17177:  * -----------    -----------     -----------          ------          ----
        !          17178:  * partition a         0               00              /dev/sd??a      disk
        !          17179:  * partition b         0               01              /dev/sd??b      disk
        !          17180:  * partition c         0               10              /dev/sd??c      disk
        !          17181:  * partition d         0               11              /dev/sd??d      disk
        !          17182:  * partition table     1               00              /dev/sd??x      disk
        !          17183:  * no rewind tape      1               01              /dev/sd??n      tape
        !          17184:  * UNALLOCATED         1               10                ---           ????
        !          17185:  * rewind tape device  1               11              /dev/sd??       tape
        !          17186:  */
        !          17187: #define        DRIVENO(minor)  (((minor) >> 2) & 0x1F) /* SCSI ID + LUN */
        !          17188: #define        SCSIID(minor)   (((minor) >> 4) & 0x7)  /* SCSI ID */
        !          17189: #define        LUN(minor)      (((minor) >> 2) & 0x3)  /* Logical Unit Number */
        !          17190: #define        PARTITION(minor) ((minor) & 0x3)        /* Partition */
        !          17191: #define        sdmkdev(maj, s, drv)    makedev((maj), ((s)|((drv)<<2)))
        !          17192: 
        !          17193: /*
        !          17194:  * Driver configuration.
        !          17195:  */
        !          17196: void   sdload();
        !          17197: void   sdunload();
        !          17198: void   sdopen();
        !          17199: void   sdclose();
        !          17200: void   sdread();
        !          17201: void   sdwrite();
        !          17202: int    sdioctl();
        !          17203: void   sdblock();
        !          17204: int    sdwatch();
        !          17205: int    nulldev();
        !          17206: int    nonedev();
        !          17207: 
        !          17208: CON    sdcon   = {
        !          17209:        DFBLK|DFCHR,                    /* Flags */
        !          17210:        SDMAJOR,                        /* Major index */
        !          17211:        sdopen,                         /* Open */
        !          17212:        sdclose,                        /* Close */
        !          17213:        sdblock,                        /* Block */
        !          17214:        sdread,                         /* Read */
        !          17215:        sdwrite,                        /* Write */
        !          17216:        sdioctl,                        /* Ioctl */
        !          17217:        nulldev,                        /* Powerfail */
        !          17218:        sdwatch,                        /* Timeout */
        !          17219:        sdload,                         /* Load */
        !          17220:        sdunload                        /* Unload */
        !          17221: };
        !          17222: 
        !          17223: /*
        !          17224:  *     host adapter routines
        !          17225:  */
        !          17226: int    aha_load();             /* initialize host adapter, DMA */
        !          17227: void   aha_unload();           /* shutdown the host adapter */
        !          17228: int    aha_start();            /* see if there's work */
        !          17229: int    aha_command();
        !          17230: 
        !          17231: /*
        !          17232:  * Partition Parameters - copied from disk.
        !          17233:  *
        !          17234:  *     There are NPARTN positions for the user partitions in array PPARM,
        !          17235:  *     plus 1 additional position to span the entire drive.
        !          17236:  *     Array pparmp[] contains a pointer to a kalloc()'ed PPARM
        !          17237:  *     entry if the drive actually exists, is a disk drive and if someone
        !          17238:  *     has attmpted to read a partition table from the drive.
        !          17239:  */
        !          17240: typedef        struct  fdisk_s PPARM[NPARTN + 1];      /* 4 partitions + whole drive */
        !          17241: static PPARM *pparmp[NDRIVE];                  /* one per possible drive */
        !          17242: #define        WHOLE_DRIVE     NPARTN                  /* index for whole drive */
        !          17243: #define        PNULL   ((PPARM *)0)
        !          17244: 
        !          17245: /*
        !          17246:  * Per disk controller data.
        !          17247:  * Only one host adapter; no more, no less.
        !          17248:  */
        !          17249: static
        !          17250: scsi_work_t    sd;
        !          17251: 
        !          17252: static BUF     dbuf;                   /* For raw I/O */
        !          17253: static int     sw_active;
        !          17254: 
        !          17255: /**
        !          17256:  *
        !          17257:  * void
        !          17258:  * sdload()    - load routine.
        !          17259:  *
        !          17260:  *     Action: The controller is reset and the interrupt vector is grabbed.
        !          17261:  *             The drive characteristics are set up at this time.
        !          17262:  */
        !          17263: static void
        !          17264: sdload()
        !          17265: {
        !          17266:        /*
        !          17267:         * Initialize Drive Controller.
        !          17268:         */
        !          17269:        sw_active = 0;
        !          17270:        if (aha_load(SDDMA, SDIRQ, SDBASE, &sd) < 0) {
        !          17271:                u.u_error = ENXIO;
        !          17272:                return;
        !          17273:        }
        !          17274: /*     aha_device_info(); */           /* enable after this gets fixed */
        !          17275: }
        !          17276: 
        !          17277: /**
        !          17278:  *
        !          17279:  * void
        !          17280:  * sdunload()  - unload routine.
        !          17281:  */
        !          17282: static void
        !          17283: sdunload()
        !          17284: {
        !          17285:        register int i;
        !          17286: 
        !          17287:        if (sw_active > 0)
        !          17288:                printf("aha154x: sdunload() athough %d active\n", sw_active);
        !          17289:        aha_unload(SDIRQ);
        !          17290:        for (i = 0; i < NDRIVE; ++i)
        !          17291:                if (pparmp[i] != PNULL)
        !          17292:                        kfree(pparmp[i]);       /* free any partition tables */
        !          17293: }
        !          17294: 
        !          17295: /*
        !          17296:  * int
        !          17297:  * sdgetpartitions(dev)        - load partition table for specified drive
        !          17298:  *
        !          17299:  *                     - return 1 on success and 0 on failure
        !          17300:  */
        !          17301: int sdgetpartitions(dev)
        !          17302: dev_t  dev;
        !          17303: {
        !          17304:        register int    i;
        !          17305:        scsi_cmd_t      sc;
        !          17306:        unsigned char   *buffer;
        !          17307:        struct fdisk_s  *fdp;
        !          17308:        int     d = DRIVENO(minor(dev));
        !          17309: 
        !          17310:        pparmp[d] = kalloc(sizeof *pparmp[0]);
        !          17311:        fdp = (struct fdisk_s *) pparmp[d];     /* point to first entry */
        !          17312:        buffer = kalloc(36+1);
        !          17313:        if (buffer == NULL || pparmp[d] == PNULL) {
        !          17314:                printf("aha154x: out of kernel memory\n");
        !          17315:                u.u_error = EKSPACE;
        !          17316:                return 0;
        !          17317:        }
        !          17318:        kclear(pparmp[d], sizeof *pparmp[0]);
        !          17319:        sc.unit = d;
        !          17320:        sc.block = 0L;
        !          17321:        sc.blklen = 0;
        !          17322: 
        !          17323:        sc.buffer = VTOP2(buffer, sds);
        !          17324:        ++drvl[SDMAJOR].d_time; 
        !          17325: #if    0
        !          17326:        sc.cmd = ScmdINQUIRY;
        !          17327:        sc.buflen = 36;
        !          17328:        aha_command(&sc);
        !          17329:        aha_command(&sc);
        !          17330:        buffer[36] = 0;
        !          17331:        printf("SCSI Disk %s", &buffer[8]);
        !          17332: #endif
        !          17333:        sc.cmd = ScmdREADCAPACITY;
        !          17334:        sc.buflen = 8;
        !          17335: 
        !          17336:        for(i = 0; i < sc.buflen; ++i)
        !          17337:                buffer[i] = 0;
        !          17338:        aha_command(&sc);
        !          17339:        aha_command(&sc);
        !          17340: #if    VERBOSE
        !          17341:        printf("buffer =");
        !          17342:        for(i = 0; i < sc.buflen; ++i)
        !          17343:                printf(" %x", buffer[i]);
        !          17344:        printf("\n");
        !          17345: #endif
        !          17346:        sc.block = (buffer[0]<<8) | buffer[1];
        !          17347:        sc.block <<= 16;
        !          17348:        sc.block |= (buffer[2]<<8) | buffer[3];
        !          17349: 
        !          17350:        sc.blklen = (buffer[6]<<8) | buffer[7];
        !          17351: #if    VERBOSE
        !          17352:        printf("SCSI %D. blocks of size %d\n", sc.block, sc.blklen);
        !          17353: #endif
        !          17354:        kfree(buffer);
        !          17355:        fdp[WHOLE_DRIVE].p_size = sc.block;
        !          17356:        --drvl[SDMAJOR].d_time; 
        !          17357:        return fdisk(sdmkdev(major(dev), SDEV, d), pparmp[d]);
        !          17358: }
        !          17359: 
        !          17360: /**
        !          17361:  *
        !          17362:  * void
        !          17363:  * sdopen(dev, mode)
        !          17364:  * dev_t dev;
        !          17365:  * int mode;
        !          17366:  *
        !          17367:  *     Input:  dev = disk device to be opened.
        !          17368:  *             mode = access mode [IPR,IPW, IPR+IPW].
        !          17369:  *
        !          17370:  *     Action: Validate the minor device.
        !          17371:  *             Update the paritition table if necessary.
        !          17372:  */
        !          17373: static void
        !          17374: sdopen(dev, mode)
        !          17375: register dev_t dev;
        !          17376: {
        !          17377:        register int p;                 /* partition */
        !          17378:        register int d;                 /* drive (SCSI ID + LUN) */
        !          17379:        struct fdisk_s  *fdp;           /* one partition entry */
        !          17380: 
        !          17381:        if (minor(dev) & SDEV) {
        !          17382:                if (PARTITION(minor(dev)) != 0) {       /* tape device ? */
        !          17383:                        u.u_error = ENXIO;              /* not yet! */
        !          17384: devmsg(dev, "No tape yet");
        !          17385:                } else {
        !          17386:                        ++drvl[SDMAJOR].d_time; 
        !          17387:                        ++sw_active;
        !          17388:                }
        !          17389:                return;
        !          17390:        }
        !          17391: 
        !          17392:        d = DRIVENO(minor(dev));
        !          17393:        p = PARTITION(minor(dev));
        !          17394: 
        !          17395:        /*
        !          17396:         * If partition not defined read partition characteristics.
        !          17397:         */
        !          17398:        if (pparmp[d] == PNULL)   /* no entry yet for this drive ? */
        !          17399:                if (!sdgetpartitions(dev)) {
        !          17400:                        u.u_error = ENXIO;
        !          17401:                        return;
        !          17402:                }
        !          17403:        /*
        !          17404:         * Ensure partition lies within drive boundaries and is non-zero size.
        !          17405:         */
        !          17406:        fdp = (struct fdisk_s *) pparmp[d];
        !          17407:        if ((fdp[p].p_base+fdp[p].p_size) > fdp[WHOLE_DRIVE].p_size) {
        !          17408:                u.u_error = EBADFMT;
        !          17409:        } else if (fdp[p].p_size == 0) {
        !          17410:                u.u_error = ENODEV;
        !          17411:        } else {
        !          17412:                ++drvl[SDMAJOR].d_time; 
        !          17413:                ++sw_active;
        !          17414:        }
        !          17415: }
        !          17416: 
        !          17417: void sdclose(dev)
        !          17418: {
        !          17419:        --drvl[SDMAJOR].d_time; 
        !          17420:        --sw_active;    
        !          17421: }
        !          17422: 
        !          17423: /**
        !          17424:  *
        !          17425:  * void
        !          17426:  * sdread(dev, iop)    - write a block to the raw disk
        !          17427:  * dev_t dev;
        !          17428:  * IO * iop;
        !          17429:  *
        !          17430:  *     Input:  dev = disk device to be written to.
        !          17431:  *             iop = pointer to source I/O structure.
        !          17432:  *
        !          17433:  *     Action: Invoke the common raw I/O processing code.
        !          17434:  */
        !          17435: static void
        !          17436: sdread(dev, iop)
        !          17437: dev_t  dev;
        !          17438: IO     *iop;
        !          17439: {
        !          17440:        ioreq(&dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC);
        !          17441: }
        !          17442: 
        !          17443: /**
        !          17444:  *
        !          17445:  * void
        !          17446:  * sdwrite(dev, iop)   - write a block to the raw disk
        !          17447:  * dev_t dev;
        !          17448:  * IO * iop;
        !          17449:  *
        !          17450:  *     Input:  dev = disk device to be written to.
        !          17451:  *             iop = pointer to source I/O structure.
        !          17452:  *
        !          17453:  *     Action: Invoke the common raw I/O processing code.
        !          17454:  */
        !          17455: static void
        !          17456: sdwrite(dev, iop)
        !          17457: dev_t  dev;
        !          17458: IO     *iop;
        !          17459: {
        !          17460:        ioreq(&dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC);
        !          17461: }
        !          17462: 
        !          17463: /**
        !          17464:  *
        !          17465:  * int
        !          17466:  * sdioctl(dev, cmd, arg)
        !          17467:  * dev_t dev;
        !          17468:  * int cmd;
        !          17469:  * char * vec;
        !          17470:  *
        !          17471:  *     Input:  dev = disk device to be operated on.
        !          17472:  *             cmd = input/output request to be performed.
        !          17473:  *             vec = (pointer to) optional argument.
        !          17474:  *
        !          17475:  *     Action: Validate the minor device.
        !          17476:  *             Update the paritition table if necessary.
        !          17477:  */
        !          17478: static int
        !          17479: sdioctl(dev, cmd, vec)
        !          17480: register dev_t dev;
        !          17481: int cmd;
        !          17482: char * vec;
        !          17483: {
        !          17484:        int d;
        !          17485:        hdparm_t hdparm;
        !          17486:        struct fdisk_s  *fdp;
        !          17487:        int do_getpt = 0;       /* 1 if need to call sdgetpartitions() */
        !          17488: 
        !          17489:        d = DRIVENO(minor(dev));
        !          17490: 
        !          17491:        /*
        !          17492:         * Identify input/output request.
        !          17493:         */
        !          17494:        switch (cmd) {
        !          17495: 
        !          17496:        case HDGETA:
        !          17497:                /*
        !          17498:                 * If haven't loaded partition table yet for this drive,
        !          17499:                 * try to do it now.  Note sdgetpartitions() will fail
        !          17500:                 * if there is a new drive (e.g. no signature).  But all
        !          17501:                 * we need is allocation of pparmp[d] and capacity read
        !          17502:                 * properly from the drive.
        !          17503:                 */
        !          17504:                if (pparmp[d] == PNULL) {
        !          17505:                        do_getpt = 1;   /* REALLY just want Read Capacity */
        !          17506:                        sdgetpartitions(dev);
        !          17507:                        if (pparmp[d] == NULL) {
        !          17508:                                u.u_error = ENXIO;
        !          17509:                                return -1;
        !          17510:                        }
        !          17511:                }
        !          17512:                fdp = (struct fdisk_s *) pparmp[d];
        !          17513:                *(short *)&hdparm.landc[0] =
        !          17514:                *(short *)&hdparm.ncyl[0] = fdp[WHOLE_DRIVE].p_size
        !          17515:                                                / (SD_HDS * SD_SPT);
        !          17516:                hdparm.nhead = SD_HDS;
        !          17517:                hdparm.nspt = SD_SPT;
        !          17518:                kucopy(&hdparm, vec, sizeof hdparm);
        !          17519:                /*
        !          17520:                 * I know it's ugly.  But it gets around startup Catch-22.
        !          17521:                 *
        !          17522:                 * The fdisk command needs HDGETA.  HDGETA invokes
        !          17523:                 * sdgetpartitions(), but we want to call it again
        !          17524:                 * after the partition table has been created by the fdisk
        !          17525:                 * command.
        !          17526:                 */
        !          17527:                if (do_getpt) {
        !          17528:                        kfree(pparmp[d]);
        !          17529:                        pparmp[d] = PNULL;      /* force re-read of p. table */
        !          17530:                }
        !          17531:                return 0;
        !          17532:        case HDSETA:
        !          17533:                /*
        !          17534:                 * Set hard disk attributes.
        !          17535:                 */
        !          17536:                fdp = (struct fdisk_s *) pparmp[d];
        !          17537:                ukcopy(vec, &hdparm, sizeof hdparm);
        !          17538:                SD_HDS = hdparm.nhead;
        !          17539:                SD_SPT = hdparm.nspt;
        !          17540:                fdp[WHOLE_DRIVE].p_size =
        !          17541:                        (long)(*(short *)&hdparm.ncyl[0])
        !          17542:                        * (long)SD_HDS * (long)SD_SPT;
        !          17543: 
        !          17544:                return 0;
        !          17545:        case SCSI_HA_CMD:
        !          17546:                return aha_ioctl(cmd, vec);
        !          17547:        case SCSI_CMD:
        !          17548:                return 0;
        !          17549:        case SCSI_CMD_IN:
        !          17550:                return 0;
        !          17551:        case SCSI_CMD_OUT:
        !          17552:                return 0;
        !          17553: 
        !          17554:        default:
        !          17555:                u.u_error = EINVAL;
        !          17556:                return -1;
        !          17557:        }
        !          17558: }
        !          17559: 
        !          17560: /**
        !          17561:  *
        !          17562:  * void
        !          17563:  * sdblock(bp) - queue a block to the disk
        !          17564:  *
        !          17565:  *     Input:  bp = pointer to block to be queued.
        !          17566:  *
        !          17567:  *     Action: Queue a block to the disk.
        !          17568:  *             Make sure that the transfer is within the disk partition.
        !          17569:  */
        !          17570: static void
        !          17571: sdblock(bp)
        !          17572: register BUF   *bp;
        !          17573: {
        !          17574:        register scsi_work_t *sw;
        !          17575:        register int s;
        !          17576:        struct  fdisk_s *fdp;
        !          17577: 
        !          17578:        int p = PARTITION(minor(bp->b_dev));
        !          17579:        int drv = DRIVENO(minor(bp->b_dev));
        !          17580: 
        !          17581:        if (minor(bp->b_dev) & SDEV)
        !          17582:                p = WHOLE_DRIVE;
        !          17583:        bp->b_resid = bp->b_count;
        !          17584:        
        !          17585:        fdp = (struct fdisk_s *) pparmp[drv];
        !          17586: 
        !          17587:        /*
        !          17588:         * Range check disk region.
        !          17589:         */
        !          17590:        if (pparmp[drv] == PNULL) {
        !          17591:                if (p == WHOLE_DRIVE) {
        !          17592:                        if ((bp->b_bno != 0) || (bp->b_count != BSIZE)) {
        !          17593:                                bp->b_flag |= BFERR;
        !          17594:                                bdone(bp);
        !          17595:                                return;
        !          17596:                        }
        !          17597:                } else {
        !          17598:                        printf("aha154x: no partition table\n");
        !          17599:                        bp->b_flag |= BFERR;
        !          17600:                        bdone(bp);
        !          17601:                        return;
        !          17602:                }
        !          17603:        } else if ((bp->b_bno + (bp->b_count/BSIZE)) > fdp[p].p_size) {
        !          17604:                bp->b_flag |= BFERR;
        !          17605:                bdone(bp);
        !          17606:                return;
        !          17607:        }
        !          17608: 
        !          17609:        bp->b_actf = NULL;
        !          17610:        sw = (scsi_work_t *)kalloc(sizeof(*sw));
        !          17611:        if (sw == (scsi_work_t *)0) {
        !          17612:                printf("aha154x: out of kernel memory\n");
        !          17613:                bp->b_flag |= BFERR;
        !          17614:                bdone(bp);
        !          17615:                return;
        !          17616:        }
        !          17617:        sw->sw_bp = bp;
        !          17618:        sw->sw_drv = drv;
        !          17619:        sw->sw_type = 0;
        !          17620:        if (p != WHOLE_DRIVE)
        !          17621:                sw->sw_bno   = fdp[p].p_base + bp->b_bno;
        !          17622:        else
        !          17623:                sw->sw_bno   = bp->b_bno;
        !          17624:        sw->sw_retry = 1;
        !          17625: 
        !          17626: #if    VERBOSE
        !          17627:        printf("sdblock: drv %x bno %x:%x  bp=%x, flag = %o\n",
        !          17628:                drv, (long)sw->sw_bno, bp, bp->b_flag);
        !          17629: #endif
        !          17630: 
        !          17631:        s = sphi();
        !          17632:        if (sd.sw_actf == NULL)
        !          17633:                sd.sw_actf = sw;
        !          17634:        else
        !          17635:                sd.sw_actl->sw_actf = sw;
        !          17636:        sd.sw_actl = sw;
        !          17637:        spl(s);
        !          17638: 
        !          17639:        aha_start();
        !          17640: }
        !          17641: 
        !          17642: sdwatch()
        !          17643: {
        !          17644:        register i;
        !          17645: 
        !          17646:        if (i = aha_start())
        !          17647: #if    VERBOSE
        !          17648:                printf("sdwatch: started %d actions\n", i);
        !          17649: #else
        !          17650:                ;
        !          17651: #endif
        !          17652:        if (i = aha_completed())
        !          17653: #if    VERBOSE
        !          17654:                printf("sdwatch: completed %d actions\n", i);
        !          17655: #else
        !          17656:                ;
        !          17657: #endif
        !          17658: }
        !          17659: 0707070064030150151004440000030000030000011777770507310641600004700000025272/newbits/kernel/USRSRC/i8086/drv/sem.c/* $Header: /usr/src/sys/i8086/drv/RCS/sem.c,v 2.1 88/09/03 13:11:37 src Exp $
        !          17660:  *
        !          17661:  *     The  information  contained herein  is a trade secret  of INETCO
        !          17662:  *     Systems, and is confidential information.   It is provided under
        !          17663:  *     a license agreement,  and may be copied or disclosed  only under
        !          17664:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          17665:  *     this  material  without  the express  written  authorization  of
        !          17666:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          17667:  *
        !          17668:  *     Copyright (c) 1985
        !          17669:  *     An unpublished work by INETCO Systems, Ltd.
        !          17670:  *     All rights reserved.
        !          17671:  */
        !          17672: 
        !          17673: /*
        !          17674:  * System V Compatible Semaphores
        !          17675:  *
        !          17676:  *     This module provides System V compatible semaphore operations.
        !          17677:  *
        !          17678:  *                     Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
        !          17679:  *
        !          17680:  * $Log:       /usr/src/sys/i8086/drv/RCS/sem.c,v $
        !          17681:  * Revision 2.1        88/09/03  13:11:37      src
        !          17682:  * *** empty log message ***
        !          17683:  * 
        !          17684:  * Revision 1.1        88/03/24  17:06:22      src
        !          17685:  * Initial revision
        !          17686:  * 
        !          17687:  * 85/08/06    Allan Cornish
        !          17688:  * Sem.c split into configuration (semcon.c) and implementation (sem.c).
        !          17689:  * Semload() renamed to seminit().
        !          17690:  *
        !          17691:  * 85/07/22    Allan Cornish
        !          17692:  * Semctl, semget, semop now return immediately if u.u_error is set.
        !          17693:  *
        !          17694:  * 85/07/03    Allan Cornish
        !          17695:  * Replaced use of EDOM with EIDRM.
        !          17696:  * Eliminated semlock() and semunlock() functions.
        !          17697:  * Replaced semaccess() by calls to ipcaccess(), increasing shared ipc code.
        !          17698:  */
        !          17699: 
        !          17700: #include <coherent.h>
        !          17701: #include <sched.h>
        !          17702: #include <types.h>
        !          17703: #include <uproc.h>
        !          17704: #include <errno.h>
        !          17705: #include <stat.h>
        !          17706: #include <con.h>
        !          17707: #include <sem.h>
        !          17708: 
        !          17709: #ifndef        EIDRM
        !          17710: #define        EIDRM   EDOM
        !          17711: #endif
        !          17712: 
        !          17713: /*
        !          17714:  *     Semaphore Information
        !          17715:  */
        !          17716: 
        !          17717: #define        NSEMVAL 32767
        !          17718: 
        !          17719: static
        !          17720: struct semid_ds *semids = 0;
        !          17721: 
        !          17722: unsigned NSEMID = 16;
        !          17723: unsigned NSEM   = 16;
        !          17724:                    
        !          17725: /*
        !          17726:  * Semaphore Initialization.
        !          17727:  *
        !          17728:  *     Initialize semaphore ids.
        !          17729:  */
        !          17730: 
        !          17731: seminit()
        !          17732: {
        !          17733:        register struct semid_ds *semidp;
        !          17734: 
        !          17735:        if ( semids = kalloc( NSEMID * sizeof(struct semid_ds) ) ) {
        !          17736: 
        !          17737:                for ( semidp = &semids[NSEMID]; --semidp >= semids; )
        !          17738:                        semidp->sem_perm.mode = 0;
        !          17739:        }
        !          17740:        else {
        !          17741:                printf("could not allocate %u semaphore ids\n", NSEMID);
        !          17742:                NSEMID = 0;
        !          17743:        }
        !          17744: }
        !          17745: 
        !          17746: /*
        !          17747:  * Semctl - Semaphore Control Operations.
        !          17748:  */
        !          17749: 
        !          17750: usemctl( semid, semnum, cmd, arg )
        !          17751: 
        !          17752: unsigned semid;
        !          17753: unsigned semnum;
        !          17754: int cmd;
        !          17755: union semun {
        !          17756:        int val;
        !          17757:        struct semid_ds *buf;
        !          17758:        unsigned short *array;
        !          17759: } arg;
        !          17760: 
        !          17761: {
        !          17762:        register struct semid_ds *semidp;
        !          17763:        register struct sem *semp;
        !          17764:        int nsems, val;
        !          17765: 
        !          17766:        if ( u.u_error )
        !          17767:                return -1;
        !          17768: 
        !          17769:        if ( semid >= NSEMID ) {
        !          17770:                u.u_error = EINVAL;
        !          17771:                return -1;
        !          17772:        }
        !          17773: 
        !          17774:        semidp = &semids[semid];
        !          17775: 
        !          17776:        if ( (semidp->sem_perm.mode & IPC_ALLOC) == 0 ) {
        !          17777:                u.u_error = EINVAL;
        !          17778:                return -1;
        !          17779:        }
        !          17780: 
        !          17781:        if ((ipcaccess( &semidp->sem_perm ) & SEM_R) == 0) { /* can't read */
        !          17782:                u.u_error = EACCES;
        !          17783:                return -1;
        !          17784:        }
        !          17785: 
        !          17786:        if ( semnum >= semidp->sem_nsems ) {
        !          17787:                u.u_error = EFBIG;
        !          17788:                return -1;
        !          17789:        }
        !          17790: 
        !          17791:        semp = &semidp->sem_base[semnum];
        !          17792: 
        !          17793:        switch ( cmd ) {
        !          17794: 
        !          17795:        case GETVAL:            /* Return value of semval */
        !          17796:                return semp->semval;
        !          17797: 
        !          17798:        case SETVAL:                                            /* Set semval */
        !          17799:                if ((ipcaccess( &semidp->sem_perm ) & SEM_A) == 0) {
        !          17800:                        u.u_error = EACCES;     /* can't alter */
        !          17801:                        return -1;
        !          17802:                }
        !          17803: 
        !          17804:                if ( arg.val < 0 ) {                    /* illegal value */
        !          17805:                        u.u_error = ERANGE;
        !          17806:                        return -1;
        !          17807:                }
        !          17808: 
        !          17809:                if ( semp->semval = arg.val ) {
        !          17810: 
        !          17811:                        if ( semp->semncnt )
        !          17812:                                wakeup( &semp->semncnt );
        !          17813:                }
        !          17814:                else {
        !          17815:                        if ( semp->semzcnt )
        !          17816:                                wakeup( &semp->semzcnt );
        !          17817:                }
        !          17818: 
        !          17819:                return 0;
        !          17820: 
        !          17821:        case GETPID:            /* Return value of sempid */
        !          17822:                return semp->sempid;
        !          17823: 
        !          17824:        case GETNCNT:           /* Return value of semncnt */
        !          17825:                return semp->semncnt;
        !          17826: 
        !          17827:        case GETZCNT:           /* Return value of semzcnt */
        !          17828:                return semp->semzcnt;
        !          17829: 
        !          17830:        case GETALL:            /* Return semvals array */
        !          17831:                nsems = semidp->sem_nsems;
        !          17832:                semp  = semidp->sem_base;
        !          17833: 
        !          17834:                while ( --nsems >= 0 ) {
        !          17835: 
        !          17836:                        putuwd( (arg.array)++, (semp++)->semval );
        !          17837: 
        !          17838:                        if ( u.u_error )
        !          17839:                                return -1;
        !          17840:                }
        !          17841:                return 0;
        !          17842: 
        !          17843:        case SETALL:            /* Set semvals array */
        !          17844:                if ( (ipcaccess( &semidp->sem_perm ) & SEM_A) == 0 ) {
        !          17845:                        u.u_error = EACCES;
        !          17846:                        return -1;
        !          17847:                }
        !          17848:                nsems = semidp->sem_nsems;
        !          17849:                semp  = semidp->sem_base;
        !          17850: 
        !          17851:                while ( --nsems >= 0 ) {
        !          17852: 
        !          17853:                        if ( (val = getuwd( arg.array )) < 0 ) {
        !          17854: 
        !          17855:                                if ( u.u_error == 0 )
        !          17856:                                        u.u_error = ERANGE;
        !          17857:                        }
        !          17858:                        else
        !          17859:                                semp->semval = val;
        !          17860:                        arg.array++;
        !          17861:                        semp++;
        !          17862:                }
        !          17863:                if ( u.u_error )
        !          17864:                        return -1;
        !          17865:                return 0;
        !          17866: 
        !          17867:        case IPC_STAT:
        !          17868:                kucopy( semidp, arg.buf, sizeof(struct semid_ds) );
        !          17869:                return 0;
        !          17870: 
        !          17871:        case IPC_SET:
        !          17872:                if ( (u.u_uid != 0) && (u.u_uid != semidp->sem_perm.uid) ) {
        !          17873:                        u.u_error = EPERM;
        !          17874:                        return -1;
        !          17875:                }
        !          17876:                semidp->sem_perm.uid   = getuwd( &((arg.buf)->sem_perm.uid ) );
        !          17877:                semidp->sem_perm.gid   = getuwd( &((arg.buf)->sem_perm.gid ) );
        !          17878:                semidp->sem_perm.mode  =
        !          17879:                        (getuwd(&((arg.buf)->sem_perm.mode))&0777) | IPC_ALLOC;
        !          17880:                return 0;
        !          17881: 
        !          17882:        case IPC_RMID:
        !          17883:                if ( (u.u_uid != 0) && (u.u_uid != semidp->sem_perm.uid) ) {
        !          17884:                        u.u_error = EPERM;
        !          17885:                        return -1;
        !          17886:                }
        !          17887:                semidp->sem_perm.seq++;
        !          17888:                semp = &semidp->sem_base[ semidp->sem_nsems ];
        !          17889: 
        !          17890:                while ( --semp >= semidp->sem_base ) {
        !          17891: 
        !          17892:                        if ( semp->semncnt )
        !          17893:                                wakeup( &semp->semncnt );
        !          17894:                        if ( semp->semzcnt )
        !          17895:                                wakeup( &semp->semzcnt );
        !          17896:                }
        !          17897: 
        !          17898:                kfree( semidp->sem_base );
        !          17899:                semidp->sem_perm.mode = 0;
        !          17900:                return 0;
        !          17901: 
        !          17902:        default:
        !          17903:                u.u_error = EINVAL;
        !          17904:                return -1;
        !          17905:        }
        !          17906: }
        !          17907: 
        !          17908: /*
        !          17909:  * Semget - Get set of semaphores
        !          17910:  */
        !          17911: 
        !          17912: usemget( skey, nsems, semflg )
        !          17913: 
        !          17914: key_t skey;
        !          17915: unsigned nsems;
        !          17916: int semflg;
        !          17917: 
        !          17918: {
        !          17919:        register struct semid_ds *semidp;
        !          17920:        register struct sem *semp;
        !          17921:        struct semid_ds *freeidp = 0;
        !          17922: 
        !          17923:        if ( u.u_error )
        !          17924:                return -1;
        !          17925: 
        !          17926:        if ( nsems >= NSEM ) {
        !          17927:                u.u_error = EINVAL;
        !          17928:                return -1;
        !          17929:        }
        !          17930: 
        !          17931:        for ( semidp = &semids[NSEMID]; --semidp >= semids; ) {
        !          17932: 
        !          17933:                if ( (semidp->sem_perm.mode & IPC_ALLOC) == 0 ) {
        !          17934: 
        !          17935:                        if ((freeidp == 0) ||
        !          17936:                            (freeidp->sem_ctime > semidp->sem_ctime))
        !          17937:                                freeidp = semidp;
        !          17938:                        continue;
        !          17939:                }
        !          17940: 
        !          17941: #ifdef IPC_PRIVATE
        !          17942:                if (skey == IPC_PRIVATE)
        !          17943:                        continue;
        !          17944: #endif
        !          17945: 
        !          17946:                if (skey == semidp->sem_perm.key) {             /* found! */
        !          17947: 
        !          17948:                        if ( (semflg & IPC_CREAT) && (semflg & IPC_EXCL) ) {
        !          17949:                                u.u_error = EEXIST;
        !          17950:                                return -1;
        !          17951:                        }
        !          17952: 
        !          17953:                        if ((semidp->sem_perm.mode & semflg) != (semflg&0777)) {
        !          17954:                                u.u_error = EACCES;
        !          17955:                                return -1;
        !          17956:                        }
        !          17957: 
        !          17958:                        if ( semidp->sem_nsems < nsems ) {
        !          17959:                                u.u_error = EINVAL;
        !          17960:                                return -1;
        !          17961:                        }
        !          17962: 
        !          17963:                        return semidp - semids;
        !          17964:                }
        !          17965:        }
        !          17966: 
        !          17967:        if ( !(semflg & IPC_CREAT) ) {
        !          17968:                u.u_error = ENOENT;
        !          17969:                return -1;
        !          17970:        }
        !          17971: 
        !          17972:        if ( freeidp == 0 ) {
        !          17973:                u.u_error = ENOSPC;
        !          17974:                return -1;
        !          17975:        }
        !          17976: 
        !          17977:        semidp = freeidp;
        !          17978:        semidp->sem_base = kalloc( nsems * sizeof(struct sem) );
        !          17979: 
        !          17980:        if (semidp->sem_base == 0 ) {
        !          17981:                u.u_error = ENOSPC;
        !          17982:                return -1;
        !          17983:        }
        !          17984: 
        !          17985:        semidp->sem_nsems = nsems;
        !          17986:        semidp->sem_otime = 0;
        !          17987:        semidp->sem_ctime = timer.t_time;
        !          17988: 
        !          17989:        for ( semp = &semidp->sem_base[nsems]; --semp >= semidp->sem_base; )
        !          17990:                semp->semval = semp->sempid = semp->semncnt = semp->semzcnt = 0;
        !          17991: 
        !          17992:        semidp->sem_perm.cuid = semidp->sem_perm.uid = u.u_uid;
        !          17993:        semidp->sem_perm.cgid = semidp->sem_perm.gid = u.u_gid;
        !          17994:        semidp->sem_perm.mode = (semflg & 0777) | IPC_ALLOC;
        !          17995:        semidp->sem_perm.key  = skey;
        !          17996: 
        !          17997:        return semidp - semids;
        !          17998: }
        !          17999: 
        !          18000: /*
        !          18001:  * Semop - Semaphore Operations.
        !          18002:  */
        !          18003: 
        !          18004: usemop( semid, sops, nsops )
        !          18005: 
        !          18006: unsigned semid;
        !          18007: struct sembuf *sops;
        !          18008: unsigned nsops;
        !          18009: 
        !          18010: {
        !          18011:        register struct semid_ds *semidp;
        !          18012:        register struct sem *semp;
        !          18013:        struct sembuf *sp;
        !          18014:        unsigned n, semnum, semflg;
        !          18015:        int semop, oval;
        !          18016: 
        !          18017:        if ( u.u_error )
        !          18018:                return -1;
        !          18019: 
        !          18020:        if ( semid >= NSEMID ) {
        !          18021:                u.u_error = EINVAL;
        !          18022:                return -1;
        !          18023:        }
        !          18024: 
        !          18025:        if ( nsops >= NSEM ) {
        !          18026:                u.u_error = E2BIG;
        !          18027:                return -1;
        !          18028:        }
        !          18029: 
        !          18030:        semidp = &semids[semid];
        !          18031: 
        !          18032:        if ( (semidp->sem_perm.mode & IPC_ALLOC) == 0 ) {
        !          18033:                u.u_error = EINVAL;
        !          18034:                return -1;
        !          18035:        }
        !          18036: 
        !          18037:        if ( (ipcaccess( &semidp->sem_perm ) & SEM_A) == 0 ) {
        !          18038:                u.u_error = EACCES;
        !          18039:                return -1;
        !          18040:        }
        !          18041: 
        !          18042:        sp = sops;
        !          18043:        n  = nsops;
        !          18044: 
        !          18045:        while ( n > 0 ) {                               /* do semaphore ops  */
        !          18046: 
        !          18047:                semnum = getuwd( & (sp->sem_num) );
        !          18048:                semop  = getuwd( & (sp->sem_op ) );
        !          18049:                semflg = getuwd( & (sp->sem_flg) );
        !          18050: 
        !          18051:                if ( (u.u_error != 0) || (semnum >= semidp->sem_nsems) ) {
        !          18052: 
        !          18053:                        while ( --sp >= sops ) {        /* undo prev semops  */
        !          18054: 
        !          18055:                                semnum = getuwd( &sp->sem_num );
        !          18056:                                semop  = getuwd( &sp->sem_op  );
        !          18057:                                semp   = &semidp->sem_base[ semnum ];
        !          18058:                                semundo( semp, semop );
        !          18059:                        }
        !          18060: 
        !          18061:                        if ( u.u_error == 0 )
        !          18062:                                u.u_error = EFBIG;
        !          18063:                        return -1;
        !          18064:                }
        !          18065: 
        !          18066:                semp = &semidp->sem_base[semnum];
        !          18067: 
        !          18068:                if ( (oval = semdo( semp, semop )) < 0 ) { /* can't do semop */
        !          18069: 
        !          18070:                        while ( --sp >= sops ) {        /* undo prev semops  */
        !          18071: 
        !          18072:                                unsigned unnum = getuwd( &sp->sem_num );
        !          18073:                                int      unop  = getuwd( &sp->sem_op  );
        !          18074:                                semundo( &semidp->sem_base[ unnum ], unop);
        !          18075:                        }
        !          18076: 
        !          18077:                        if ( u.u_error )
        !          18078:                                return -1;
        !          18079: 
        !          18080:                        if ( semflg & IPC_NOWAIT ) {
        !          18081:                                u.u_error = EAGAIN;
        !          18082:                                return -1;
        !          18083:                        }
        !          18084: 
        !          18085:                        if ( semop < 0 ) {      /* wait for non-zero */
        !          18086: 
        !          18087:                                if (semwait( semidp, &semp->semncnt ) < 0 )
        !          18088:                                        return -1;
        !          18089:                        }
        !          18090:                        else {                  /* wait for zero */
        !          18091: 
        !          18092:                                if ( semwait( semidp, &semp->semzcnt ) < 0 )
        !          18093:                                        return -1;
        !          18094:                        }
        !          18095: 
        !          18096:                        sp = sops;      /* retry set of semaphore operations */
        !          18097:                        n = nsops;
        !          18098:                        continue;
        !          18099:                }
        !          18100: 
        !          18101:                ++sp;
        !          18102:                --n;
        !          18103:        }
        !          18104: 
        !          18105:        for (sp=sops,n=nsops; n > 0; --n,++sp) {/* save pid in each semaphore */
        !          18106: 
        !          18107:                semnum = getuwd( &sp->sem_num );
        !          18108:                semidp->sem_base[ semnum ].sempid = SELF->p_pid;
        !          18109:        }
        !          18110: 
        !          18111:        semidp->sem_otime = timer.t_time;       /* ajust operation time */
        !          18112:        return oval;                            /* return last prev semval */
        !          18113: }
        !          18114: 
        !          18115: /*
        !          18116:  * Do a Semaphore Operation.
        !          18117:  *
        !          18118:  *     Input:  semp  = pointer to semaphore
        !          18119:  *             semop = semaphore operation
        !          18120:  *
        !          18121:  *     Action: If semop < 0 and semval > semop then add semop to semval.
        !          18122:  *             If semop > 0 then add semop to semval.
        !          18123:  *
        !          18124:  *     Return: Previous semval.
        !          18125:  */
        !          18126: 
        !          18127: static
        !          18128: semdo( semp, semop )
        !          18129: 
        !          18130: register struct sem * semp;
        !          18131: register int semop;
        !          18132: 
        !          18133: {
        !          18134:        int ret;
        !          18135: 
        !          18136:        ret = semp->semval;
        !          18137: 
        !          18138:        if ( semop < 0 ) {                      /* want to decrement semval */
        !          18139: 
        !          18140:                semop = -semop;
        !          18141: 
        !          18142:                if ( semp->semval < semop )     /* can't decrement semval */
        !          18143:                        return -1;
        !          18144: 
        !          18145:                semp->semval -= semop;
        !          18146: 
        !          18147:                if ( (semp->semval == 0)  && (semp->semzcnt != 0) )
        !          18148:                        wakeup( &semp->semzcnt );
        !          18149:        }
        !          18150:        else if ( semop > 0 ) {                 /* want to increment semval */
        !          18151: 
        !          18152:                if ( (semp->semval + semop) > NSEMVAL) {
        !          18153:                
        !          18154:                        u.u_error = ERANGE;
        !          18155:                        return -1;
        !          18156:                }
        !          18157: 
        !          18158:                semp->semval += semop;
        !          18159: 
        !          18160:                if ( semp->semncnt )
        !          18161:                        wakeup( &semp->semncnt );
        !          18162:        }
        !          18163:        else /* if ( semop == 0 ) */ {
        !          18164: 
        !          18165:                if ( semp->semval != 0 )
        !          18166:                        return -1;
        !          18167:        }
        !          18168:        return ret;
        !          18169: }
        !          18170: 
        !          18171: /*
        !          18172:  * Undo a Semaphore Operation.
        !          18173:  */
        !          18174: 
        !          18175: static
        !          18176: semundo( semp, semop )
        !          18177: 
        !          18178: register struct sem * semp;
        !          18179: register int semop;
        !          18180: 
        !          18181: {
        !          18182:        if ( semp->semval -= semop ) {
        !          18183: 
        !          18184:                if ( semp->semncnt )
        !          18185:                        wakeup( &semp->semncnt );
        !          18186:        }
        !          18187:        else {
        !          18188:                if ( semp->semzcnt )
        !          18189:                        wakeup( &semp->semzcnt );
        !          18190:        }
        !          18191: }
        !          18192: 
        !          18193: /*
        !          18194:  * Wait on Semaphore Event
        !          18195:  *
        !          18196:  *     Input:  semidp = pointer to semaphore id structure.
        !          18197:  *             ep     = pointer to semncnt or semzcnt event to wait for.
        !          18198:  *
        !          18199:  *     Action: Sleep on a semaphore event.
        !          18200:  *             If semaphore id has been deleted, error return.
        !          18201:  *             If signal has been received, error return.
        !          18202:  *
        !          18203:  *     Output:  0 = Status ok.
        !          18204:  *             -1 = Error occurred, errno is set.
        !          18205:  */
        !          18206: 
        !          18207: static
        !          18208: semwait( semidp, ep )
        !          18209: 
        !          18210: register struct semid_ds * semidp;
        !          18211: register unsigned short *ep;
        !          18212: {
        !          18213:        unsigned seqn;
        !          18214: 
        !          18215:        seqn = semidp->sem_perm.seq;
        !          18216:        ++(*ep);
        !          18217:        sleep( ep, CVTTOUT, IVTTOUT, SVTTOUT );
        !          18218: 
        !          18219:        if (semidp->sem_perm.seq != seqn ) {    /* semaphore id gone */
        !          18220:                u.u_error = EIDRM;
        !          18221:                return -1;
        !          18222:        }
        !          18223: 
        !          18224:        --(*ep);
        !          18225: 
        !          18226:        if ( SELF->p_ssig && nondsig() ) {      /* signal received */
        !          18227:                u.u_error = EINTR;
        !          18228:                return -1;
        !          18229:        }
        !          18230:        return 0;
        !          18231: }
        !          18232: 0707070064030150141004440000030000030000011777770507310642100005200000005210/newbits/kernel/USRSRC/i8086/drv/semcon.c/* $Header: /usr/src/sys/i8086/drv/RCS/semcon.c,v 2.1 88/09/03 13:11:55 src Exp $
        !          18233:  *
        !          18234:  *     The  information  contained herein  is a trade secret  of INETCO
        !          18235:  *     Systems, and is confidential information.   It is provided under
        !          18236:  *     a license agreement,  and may be copied or disclosed  only under
        !          18237:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          18238:  *     this  material  without  the express  written  authorization  of
        !          18239:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          18240:  *
        !          18241:  *     Copyright (c) 1987, 1985, 1984.
        !          18242:  *     An unpublished work by INETCO Systems, Ltd.
        !          18243:  *     All rights reserved.
        !          18244:  */
        !          18245: 
        !          18246: /*
        !          18247:  * System V Compatible Semaphore Device Driver
        !          18248:  *
        !          18249:  *     This device driver provides System V compatible semaphore operations.
        !          18250:  *     Operations are performed through the semaphore device (/dev/sem).
        !          18251:  *     and are implemented as ioctl calls from semctl, semget, semop
        !          18252:  *     utilities.
        !          18253:  *
        !          18254:  *                     Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
        !          18255:  *
        !          18256:  * $Log:       /usr/src/sys/i8086/drv/RCS/semcon.c,v $
        !          18257:  * Revision 2.1        88/09/03  13:11:55      src
        !          18258:  * *** empty log message ***
        !          18259:  * 
        !          18260:  * Revision 1.1        88/03/24  17:06:26      src
        !          18261:  * Initial revision
        !          18262:  * 
        !          18263:  * 87/03/02    Allan Cornish           /usr/src/sys/i8086/drv/semcon.c
        !          18264:  * Semioctl() now supports long key [was short] on SEMGET operations.
        !          18265:  * This allows compatability with System V.
        !          18266:  *
        !          18267:  * 85/08/06    Allan Cornish
        !          18268:  * Sem.c split into configuration (semcon.c) and implementation (sem.c).
        !          18269:  * Semload() renamed to seminit().
        !          18270:  *
        !          18271:  * 85/07/03    Allan Cornish
        !          18272:  * Eliminated semopen() and semclose() functions.
        !          18273:  *
        !          18274:  * 84/09/30    Allan Cornish
        !          18275:  * Initial Revision.
        !          18276:  */
        !          18277: 
        !          18278: #include <coherent.h>
        !          18279: #include <types.h>
        !          18280: #include <uproc.h>
        !          18281: #include <errno.h>
        !          18282: #include <con.h>
        !          18283: #include <sem.h>
        !          18284: 
        !          18285: /*
        !          18286:  * Functions.
        !          18287:  */
        !          18288: 
        !          18289: int seminit();
        !          18290: int semioctl();
        !          18291: int nulldev();
        !          18292: int nonedev();
        !          18293: 
        !          18294: /*
        !          18295:  * Device Configuration.
        !          18296:  */
        !          18297: 
        !          18298: CON semcon = {
        !          18299:        DFCHR,                  /* Flags                        */
        !          18300:        23,                     /* Major Index                  */
        !          18301:        nulldev,                /* Open                         */
        !          18302:        nulldev,                /* Close                        */
        !          18303:        nonedev,                /* Block                        */
        !          18304:        nonedev,                /* Read                         */
        !          18305:        nonedev,                /* Write                        */
        !          18306:        semioctl,               /* Ioctl                        */
        !          18307:        nulldev,                /* Power fail                   */
        !          18308:        nulldev,                /* Timeout                      */
        !          18309:        seminit,                /* Load                         */
        !          18310:        nulldev                 /* Unload                       */
        !          18311: };
        !          18312: 
        !          18313: /*
        !          18314:  * Semaphore Device Ioctl.
        !          18315:  */
        !          18316: 
        !          18317: static
        !          18318: semioctl( dev, com, vec )
        !          18319: 
        !          18320: dev_t dev;
        !          18321: int com;
        !          18322: register int *vec;
        !          18323: 
        !          18324: {
        !          18325:        switch ( com ) {
        !          18326: 
        !          18327:        case SEMCTL:
        !          18328:                putuwd( vec+0,
        !          18329:                        usemctl(getuwd( vec+1 ),
        !          18330:                                getuwd( vec+2 ),
        !          18331:                                getuwd( vec+3 ),
        !          18332:                                getuwd( vec+4 ) ));
        !          18333:                return;
        !          18334: 
        !          18335:        case SEMGET:
        !          18336:                putuwd( vec+0,
        !          18337:                        usemget(getuwd( vec+1 ),
        !          18338:                                getuwd( vec+2 ),
        !          18339:                                getuwd( vec+3 ),
        !          18340:                                getuwd( vec+4 ) ));
        !          18341:                return;
        !          18342: 
        !          18343:        case SEMOP:
        !          18344:                putuwd( vec+0,
        !          18345:                        usemop( getuwd( vec+1 ),
        !          18346:                                getuwd( vec+2 ),
        !          18347:                                getuwd( vec+3 ) ));
        !          18348:                return;
        !          18349: 
        !          18350:        default:
        !          18351:                u.u_error = EINVAL;
        !          18352:                return;
        !          18353:        }
        !          18354: }
        !          18355: 0707070064030150131004440000030000030000011777770507310642200004700000011362/newbits/kernel/USRSRC/i8086/drv/shm.c/* $Header: /usr/src/sys/i8086/drv/RCS/shm.c,v 2.1 88/09/03 13:12:17 src Exp $
        !          18356:  *
        !          18357:  *     The  information  contained herein  is a trade secret  of INETCO
        !          18358:  *     Systems, and is confidential information.   It is provided under
        !          18359:  *     a license agreement,  and may be copied or disclosed  only under
        !          18360:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          18361:  *     this  material  without  the express  written  authorization  of
        !          18362:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          18363:  *
        !          18364:  *     Copyright (c) 1985, 1984
        !          18365:  *     An unpublished work by INETCO Systems, Ltd.
        !          18366:  *     All rights reserved.
        !          18367:  */
        !          18368: 
        !          18369: /*
        !          18370:  * System V Compatible Shared Memory Device Driver
        !          18371:  *
        !          18372:  *     This device driver provides System V compatible shared memory operations.
        !          18373:  *     Operations are performed through the shared memory device (/dev/shm).
        !          18374:  *     and are implemented as ioctl calls from shmctl, shmget, shmat, shmdt
        !          18375:  *     utilities.
        !          18376:  *
        !          18377:  *                     Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
        !          18378:  *
        !          18379:  * $Log:       /usr/src/sys/i8086/drv/RCS/shm.c,v $
        !          18380:  * Revision 2.1        88/09/03  13:12:17      src
        !          18381:  * *** empty log message ***
        !          18382:  * 
        !          18383:  * Revision 1.1        88/03/24  17:06:32      src
        !          18384:  * Initial revision
        !          18385:  * 
        !          18386:  * 85/10/16    Allan Cornish
        !          18387:  * Driver split into shmcon.c, shm.c [driver implementation, System V shm].
        !          18388:  *
        !          18389:  * 85/07/22    Allan Cornish
        !          18390:  * Shmget, shmctl now return immediately if u.u_error is set.
        !          18391:  *
        !          18392:  * 85/07/19    Allan Cornish
        !          18393:  * Separation of io_seek into shmid and off improved through type casting.
        !          18394:  * Errno set to EFAULT if fucopy() or ufcopy() report no bytes transferred.
        !          18395:  * This would occur if an user address fault occurred.
        !          18396:  *
        !          18397:  * 85/07/03    Allan Cornish
        !          18398:  * Replaced use of EDOM with EIDRM.
        !          18399:  * Replaced shmaccess() by calls to ipcaccess(), increasing shared ipc code.
        !          18400:  * Eliminated shmlock() and shmunlock(), as shared memory use is synchronous.
        !          18401:  */
        !          18402: 
        !          18403: #include <coherent.h>
        !          18404: #include <sched.h>
        !          18405: #include <types.h>
        !          18406: #include <uproc.h>
        !          18407: #include <errno.h>
        !          18408: #include <stat.h>
        !          18409: #include <con.h>
        !          18410: #include <seg.h>
        !          18411: #include <shm.h>
        !          18412: 
        !          18413: #ifndef        EIDRM
        !          18414: #define        EIDRM   EDOM
        !          18415: #endif
        !          18416: 
        !          18417: 
        !          18418: extern unsigned NSHMID;
        !          18419: extern struct shmid_ds *shmids;
        !          18420: extern struct seg **shmsegs;
        !          18421: 
        !          18422: /*
        !          18423:  * Shmctl - Shared Memory Control Operations.
        !          18424:  */
        !          18425: 
        !          18426: ushmctl( shmid, cmd, buf )
        !          18427: 
        !          18428: unsigned shmid;
        !          18429: int cmd;
        !          18430: struct shmid_ds *buf;
        !          18431: 
        !          18432: {
        !          18433:        register struct shmid_ds *idp;
        !          18434:        int ret = 0;
        !          18435: 
        !          18436:        if ( u.u_error )
        !          18437:                return -1;
        !          18438: 
        !          18439:        if ( shmid >= NSHMID ) {
        !          18440:                u.u_error = EINVAL;
        !          18441:                return -1;
        !          18442:        }
        !          18443: 
        !          18444:        idp = &shmids[shmid];
        !          18445: 
        !          18446:        if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
        !          18447:                u.u_error = EINVAL;
        !          18448:                return -1;
        !          18449:        }
        !          18450: 
        !          18451:        switch ( cmd ) {
        !          18452: 
        !          18453:        case IPC_STAT:
        !          18454:                if ( ( ipcaccess( &idp->shm_perm ) & SHM_R ) == 0 ) {
        !          18455:                        u.u_error = EACCES;
        !          18456:                        return -1;
        !          18457:                }
        !          18458:                kucopy( idp, buf, sizeof(struct shmid_ds) );
        !          18459:                ret = 0;
        !          18460:                break;
        !          18461: 
        !          18462:        case IPC_SET:
        !          18463:                if ( (u.u_uid != 0) && (u.u_uid != idp->shm_perm.uid) ) {
        !          18464:                        u.u_error = EPERM;
        !          18465:                        ret = -1;
        !          18466:                        break;
        !          18467:                }
        !          18468:                idp->shm_perm.uid   = getuwd( &(buf->shm_perm.uid ) );
        !          18469:                idp->shm_perm.gid   = getuwd( &(buf->shm_perm.gid ) );
        !          18470:                idp->shm_perm.mode &= ~0777;
        !          18471:                idp->shm_perm.mode |= getuwd(&(buf->shm_perm.mode)) & 0777;
        !          18472:                ret = 0;
        !          18473:                break;
        !          18474: 
        !          18475:        case IPC_RMID:
        !          18476:                if ( (u.u_uid != 0) && (u.u_uid != idp->shm_perm.uid) ) {
        !          18477:                        u.u_error = EPERM;
        !          18478:                        ret = -1;
        !          18479:                        break;
        !          18480:                }
        !          18481:                idp->shm_perm.seq++;
        !          18482:                sfree(shmsegs[shmid]);
        !          18483:                idp->shm_perm.mode = 0;
        !          18484:                ret = 0;
        !          18485:                break;
        !          18486: 
        !          18487:        default:
        !          18488:                u.u_error = EINVAL;
        !          18489:                ret = -1;
        !          18490:        }
        !          18491: 
        !          18492:        return ret;
        !          18493: }
        !          18494: 
        !          18495: /*
        !          18496:  * Shmget - Get Shared Memory Segment
        !          18497:  */
        !          18498: 
        !          18499: ushmget( skey, size, shmflg )
        !          18500: 
        !          18501: key_t skey;
        !          18502: unsigned size;
        !          18503: int shmflg;
        !          18504: 
        !          18505: {
        !          18506:        register struct shmid_ds *idp;
        !          18507:        struct shmid_ds *freeidp = 0;
        !          18508: 
        !          18509:        if ( u.u_error )
        !          18510:                return -1;
        !          18511: 
        !          18512:        for ( idp = &shmids[NSHMID]; --idp >= shmids; ) {
        !          18513: 
        !          18514:                if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
        !          18515: 
        !          18516:                        if ((freeidp == 0) ||
        !          18517:                            (freeidp->shm_ctime > idp->shm_ctime))
        !          18518:                                freeidp = idp;
        !          18519:                        continue;
        !          18520:                }
        !          18521: 
        !          18522: #ifdef IPC_PRIVATE
        !          18523:                if (skey == IPC_PRIVATE)
        !          18524:                        continue;
        !          18525: #endif
        !          18526: 
        !          18527:                if (skey == idp->shm_perm.key) {                /* found! */
        !          18528: 
        !          18529:                        if ( (shmflg & IPC_CREAT) && (shmflg & IPC_EXCL) ) {
        !          18530: 
        !          18531:                                u.u_error = EEXIST;
        !          18532:                                return -1;
        !          18533:                        }
        !          18534: 
        !          18535:                        if ((idp->shm_perm.mode & shmflg) != (shmflg&0777)) {
        !          18536: 
        !          18537:                                u.u_error = EACCES;
        !          18538:                                return -1;
        !          18539:                        }
        !          18540: 
        !          18541:                        if ( idp->shm_segsz < size ) {
        !          18542: 
        !          18543:                                u.u_error = EINVAL;
        !          18544:                                return -1;
        !          18545:                        }
        !          18546: 
        !          18547:                        return idp - shmids;
        !          18548:                }
        !          18549:        }
        !          18550: 
        !          18551:        if ( !(shmflg & IPC_CREAT) ) {
        !          18552:                u.u_error = ENOENT;
        !          18553:                return -1;
        !          18554:        }
        !          18555: 
        !          18556:        if ( freeidp == 0 ) {
        !          18557:                u.u_error = ENOSPC;
        !          18558:                return -1;
        !          18559:        }
        !          18560: 
        !          18561:        idp = freeidp;
        !          18562: 
        !          18563:        if ((shmsegs[idp - shmids] = salloc((size_t) size, SFNSWP)) == NULL){
        !          18564:                u.u_error = ENOSPC;
        !          18565:                return -1;
        !          18566:        }
        !          18567: 
        !          18568:        idp->shm_segsz = size;
        !          18569:        idp->shm_atime = 0;
        !          18570:        idp->shm_dtime = 0;
        !          18571:        idp->shm_ctime = timer.t_time;
        !          18572:        idp->shm_cpid  = SELF->p_pid;
        !          18573:        idp->shm_perm.cuid = idp->shm_perm.uid = u.u_uid;
        !          18574:        idp->shm_perm.cgid = idp->shm_perm.gid = u.u_gid;
        !          18575:        idp->shm_perm.mode = (shmflg & 0777) | IPC_ALLOC;
        !          18576:        idp->shm_perm.key  = skey;
        !          18577: 
        !          18578: #ifdef IPC_PRIVATE
        !          18579:        if ( skey == IPC_PRIVATE )
        !          18580:                idp->shm_perm.mode |= SHM_DEST;
        !          18581: #endif
        !          18582: 
        !          18583:        return idp - shmids;
        !          18584: }
        !          18585: 0707070064030150121004440000030000030000011777770507310642300005200000012664/newbits/kernel/USRSRC/i8086/drv/shmcon.c/* $Header: /usr/src/sys/i8086/drv/RCS/shmcon.c,v 2.1 88/09/03 13:12:40 src Exp $
        !          18586:  *
        !          18587:  *     The  information  contained herein  is a trade secret  of INETCO
        !          18588:  *     Systems, and is confidential information.   It is provided under
        !          18589:  *     a license agreement,  and may be copied or disclosed  only under
        !          18590:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          18591:  *     this  material  without  the express  written  authorization  of
        !          18592:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          18593:  *
        !          18594:  *     Copyright (c) 1987, 1985, 1984.
        !          18595:  *     An unpublished work by INETCO Systems, Ltd.
        !          18596:  *     All rights reserved.
        !          18597:  */
        !          18598: 
        !          18599: /*
        !          18600:  * System V Compatible Shared Memory Device Driver
        !          18601:  *
        !          18602:  *     This device driver provides System V compatible shared memory operations.
        !          18603:  *     Operations are performed through the shared memory device (/dev/shm).
        !          18604:  *     and are implemented as ioctl calls from shmctl, shmget, shmat, shmdt
        !          18605:  *     utilities.
        !          18606:  *
        !          18607:  *                     Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
        !          18608:  *
        !          18609:  * $Log:       /usr/src/sys/i8086/drv/RCS/shmcon.c,v $
        !          18610:  * Revision 2.1        88/09/03  13:12:40      src
        !          18611:  * *** empty log message ***
        !          18612:  * 
        !          18613:  * Revision 1.1        88/03/24  17:06:36      src
        !          18614:  * Initial revision
        !          18615:  * 
        !          18616:  * 87/03/02    Allan Cornish           /usr/src/sys/i8086/drv/shmcon.c
        !          18617:  * Shmioctl() now supports long key [was short] on SHMGET operations.
        !          18618:  * This allows compatability with System V.
        !          18619:  *
        !          18620:  * 85/10/16    Allan Cornish
        !          18621:  * Driver split into shmcon.c, shm.c [driver implementation, system V shm].
        !          18622:  *
        !          18623:  * 85/07/22    Allan Cornish
        !          18624:  * Shmget, shmctl now return immediately if u.u_error is set.
        !          18625:  *
        !          18626:  * 85/07/19    Allan Cornish
        !          18627:  * Separation of io_seek into shmid and off improved through type casting.
        !          18628:  * Errno set to EFAULT if fucopy() or ufcopy() report no bytes transferred.
        !          18629:  * This would occur if an user address fault occurred.
        !          18630:  *
        !          18631:  * 85/07/03    Allan Cornish
        !          18632:  * Replaced use of EDOM with EIDRM.
        !          18633:  * Replaced shmaccess() by calls to ipcaccess(), increasing shared ipc code.
        !          18634:  * Eliminated shmlock() and shmunlock(), as shared memory use is synchronous.
        !          18635:  *
        !          18636:  * 84/09/30    Allan Cornish
        !          18637:  * Initial Revision.
        !          18638:  */
        !          18639: 
        !          18640: #include <coherent.h>
        !          18641: #include <sched.h>
        !          18642: #include <types.h>
        !          18643: #include <uproc.h>
        !          18644: #include <errno.h>
        !          18645: #include <stat.h>
        !          18646: #include <con.h>
        !          18647: #include <seg.h>
        !          18648: #include <shm.h>
        !          18649: 
        !          18650: #ifndef        EIDRM
        !          18651: #define        EIDRM   EDOM
        !          18652: #endif
        !          18653: 
        !          18654: /*
        !          18655:  * Functions.
        !          18656:  */
        !          18657: 
        !          18658: int shmload();
        !          18659: int shmread();
        !          18660: int shmwrite();
        !          18661: int shmioctl();
        !          18662: int nulldev();
        !          18663: int nonedev();
        !          18664: 
        !          18665: /*
        !          18666:  * Device Configuration.
        !          18667:  */
        !          18668: 
        !          18669: CON shmcon = {
        !          18670:        DFCHR,                  /* Flags                        */
        !          18671:        24,                     /* Major Index                  */
        !          18672:        nulldev,                /* Open                         */
        !          18673:        nulldev,                /* Close                        */
        !          18674:        nonedev,                /* Block                        */
        !          18675:        shmread,                /* Read                         */
        !          18676:        shmwrite,               /* Write                        */
        !          18677:        shmioctl,               /* Ioctl                        */
        !          18678:        nulldev,                /* Power fail                   */
        !          18679:        nulldev,                /* Timeout                      */
        !          18680:        shmload,                /* Load                         */
        !          18681:        nulldev                 /* Unload                       */
        !          18682: };
        !          18683: 
        !          18684: unsigned NSHMID = 16;
        !          18685: struct shmid_ds *shmids;
        !          18686: struct seg **shmsegs;
        !          18687: 
        !          18688: /*
        !          18689:  * Shared Memory Device Load.
        !          18690:  */
        !          18691: 
        !          18692: static
        !          18693: shmload()
        !          18694: {
        !          18695:        register struct shmid_ds * idp;
        !          18696:        register unsigned wanted;
        !          18697:        
        !          18698:        if ( NSHMID == 0 )
        !          18699:                return 0;
        !          18700: 
        !          18701:        wanted = NSHMID * (sizeof(struct shmid_ds) + sizeof(struct seg *));
        !          18702: 
        !          18703:        if ( (shmids = kalloc( wanted )) == 0 ) {
        !          18704: 
        !          18705:                printf("couldn't kalloc %u shared memory ids\n", NSHMID );
        !          18706:                NSHMID = 0;
        !          18707:                return 0;
        !          18708:        }
        !          18709:        shmsegs = (struct seg *) &shmids[ NSHMID ];
        !          18710: 
        !          18711:        for ( idp = &shmids[NSHMID]; --idp >= shmids; )
        !          18712:                idp->shm_perm.mode = 0;
        !          18713: 
        !          18714:        return 0;
        !          18715: }
        !          18716: 
        !          18717: /*
        !          18718: ** Shared Memory Read.
        !          18719: */
        !          18720: 
        !          18721: static
        !          18722: shmread( dev, iop )
        !          18723: 
        !          18724: dev_t dev;
        !          18725: register IO *iop;
        !          18726: 
        !          18727: {
        !          18728:        register struct shmid_ds *idp;
        !          18729:        int shmid;
        !          18730:        unsigned off;
        !          18731:        faddr_t faddr;
        !          18732: 
        !          18733:        off   = ((unsigned *) &iop->io_seek)[0];
        !          18734:        shmid = ((unsigned *) &iop->io_seek)[1];
        !          18735: 
        !          18736:        if ( shmid >= NSHMID ) {
        !          18737:                u.u_error = EFAULT;
        !          18738:                return -1;
        !          18739:        }
        !          18740: 
        !          18741:        idp = &shmids[shmid];
        !          18742: 
        !          18743:        if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
        !          18744:                u.u_error = EIDRM;
        !          18745:                return -1;
        !          18746:        }
        !          18747: 
        !          18748:        if ( (ipcaccess(&idp->shm_perm) & SHM_R) == 0 ) {
        !          18749:                u.u_error = EACCES;
        !          18750:                return -1;
        !          18751:        }
        !          18752: 
        !          18753:        if ( ((long) off + iop->io_ioc) > idp->shm_segsz ) {
        !          18754:                u.u_error = EFAULT;
        !          18755:                return -1;
        !          18756:        }
        !          18757: 
        !          18758:        FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr);
        !          18759:        FP_OFF(faddr) = off;
        !          18760: 
        !          18761:        if ( ! fucopy( faddr, iop->io_base, iop->io_ioc ) ) {
        !          18762:                u.u_error = EFAULT;
        !          18763:                return -1;
        !          18764:        }
        !          18765: 
        !          18766:        iop->io_ioc = 0;
        !          18767:        return 0;
        !          18768: }
        !          18769: 
        !          18770: /*
        !          18771: ** Shared Memory Write.
        !          18772: */
        !          18773: 
        !          18774: static
        !          18775: shmwrite( dev, iop )
        !          18776: 
        !          18777: dev_t dev;
        !          18778: register IO *iop;
        !          18779: 
        !          18780: {
        !          18781:        register struct shmid_ds *idp;
        !          18782:        int shmid;
        !          18783:        unsigned off;
        !          18784:        faddr_t faddr;
        !          18785: 
        !          18786:        off   = ((unsigned *) &iop->io_seek)[0];
        !          18787:        shmid = ((unsigned *) &iop->io_seek)[1];
        !          18788: 
        !          18789:        if ( shmid >= NSHMID ) {
        !          18790:                u.u_error = EFAULT;
        !          18791:                return -1;
        !          18792:        }
        !          18793: 
        !          18794:        idp = &shmids[shmid];
        !          18795: 
        !          18796:        if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
        !          18797:                u.u_error = EIDRM;
        !          18798:                return -1;
        !          18799:        }
        !          18800: 
        !          18801:        if ( (ipcaccess(&idp->shm_perm) & SHM_W) == 0 ) {
        !          18802:                u.u_error = EFAULT;
        !          18803:                return -1;
        !          18804:        }
        !          18805: 
        !          18806:        if ( ((long) off + iop->io_ioc) > idp->shm_segsz ) {
        !          18807:                u.u_error = EFAULT;
        !          18808:                return -1;
        !          18809:        }
        !          18810: 
        !          18811:        FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr);
        !          18812:        FP_OFF(faddr) = off;
        !          18813: 
        !          18814:        if ( ! ufcopy(iop->io_base, faddr, iop->io_ioc ) ) {
        !          18815:                u.u_error = EFAULT;
        !          18816:                return -1;
        !          18817:        }
        !          18818: 
        !          18819:        iop->io_ioc = 0;
        !          18820:        return 0;
        !          18821: }
        !          18822: 
        !          18823: /*
        !          18824:  * Shared Memory Device Ioctl.
        !          18825:  *
        !          18826:  *     Input:  dev = shared memory device (/dev/shm).
        !          18827:  *             com = command to perform (SHMCTL, SHMGET,SHMAT).
        !          18828:  *             vec = pointer to return value, followed by parameters.
        !          18829:  *
        !          18830:  *     Action: Initiate command.
        !          18831:  *             Save commands return value in *vec.
        !          18832:  */
        !          18833: 
        !          18834: static
        !          18835: shmioctl( dev, com, vec )
        !          18836: 
        !          18837: dev_t dev;
        !          18838: int com;
        !          18839: int *vec;
        !          18840: 
        !          18841: {
        !          18842:        switch ( com ) {
        !          18843: 
        !          18844:        case SHMCTL:
        !          18845:                putuwd( vec+0,
        !          18846:                        ushmctl( getuwd( vec+1 ),
        !          18847:                                 getuwd( vec+2 ),
        !          18848:                                 getuwd( vec+3 ) ));
        !          18849:                break;
        !          18850: 
        !          18851:        case SHMGET:
        !          18852:                putuwd( vec+0,
        !          18853:                        ushmget( getuwd( vec+1 ),
        !          18854:                                 getuwd( vec+2 ),
        !          18855:                                 getuwd( vec+3 ),
        !          18856:                                 getuwd( vec+4 ) ));
        !          18857:                break;
        !          18858: 
        !          18859:        default:
        !          18860:                u.u_error = EINVAL;
        !          18861:                break;
        !          18862:        }
        !          18863: }
        !          18864: 0707070064030150111006440000030000030000011777770507310642400004600000142370/newbits/kernel/USRSRC/i8086/drv/ss.c/*
        !          18865:  * Device driver for Seagate ST01/ST02 scsi host adapters.
        !          18866:  *
        !          18867:  * To do:
        !          18868:  *     nonzero LUN's
        !          18869:  *     start new command during disconnect
        !          18870:  *     rewrite as single state machine, instead of 7 of them
        !          18871:  *     separate SCSI layer from host-dependent stuff
        !          18872:  *
        !          18873:  * $Log:       ss.c,v $
        !          18874:  * Revision 3.3  91/06/21  10:46:27  hal
        !          18875:  * Now talks to TMC-881 + ST4350N.
        !          18876:  * 
        !          18877:  * Revision 3.2  91/06/20  17:10:32  hal
        !          18878:  * First version for TMC-881.
        !          18879:  * 
        !          18880:  * Revision 3.1  91/06/17  07:43:25  hal
        !          18881:  * Add TMC-840 code.
        !          18882:  * 
        !          18883:  * Revision 1.1  91/06/17  07:42:27  hal
        !          18884:  * Add TMC-840 code.
        !          18885:  * 
        !          18886:  * 
        !          18887:  */
        !          18888: 
        !          18889: /*
        !          18890:  * Debug levels.
        !          18891:  * DEBUG = 0   No debug output.
        !          18892:  * DEBUG = 1   Debug output on error only.
        !          18893:  * DEBUG = 2   Debug output on error and at other selected places.
        !          18894:  * DEBUG = 3   Print state machine trace.
        !          18895:  * DEBUG = 4   Print info xfer phases and msg_in values.
        !          18896:  */
        !          18897: #if (DEBUG >= 1)
        !          18898: static int s_id;
        !          18899: #define PR1(str)               printf("%s%d ", str, s_id)
        !          18900: #else
        !          18901: #define PR1(str)
        !          18902: #endif
        !          18903: #if (DEBUG >= 2)
        !          18904: #define PR2(str)               printf(str)
        !          18905: #else
        !          18906: #define PR2(str)
        !          18907: #endif
        !          18908: #if (DEBUG >= 3)
        !          18909: #define PR3(str)               printf("%s%d ", str, s_id)
        !          18910: #else
        !          18911: #define PR3(str)
        !          18912: #endif
        !          18913: #if (DEBUG >= 4)
        !          18914: #define PR4(str)               printf("%s%d ", str, s_id)
        !          18915: #else
        !          18916: #define PR4(str)
        !          18917: #endif
        !          18918: 
        !          18919: /*
        !          18920:  * Includes.
        !          18921:  */
        !          18922: #include       <sys/coherent.h>
        !          18923: #include       <sys/io.h>
        !          18924: #include       <sys/sched.h>
        !          18925: #include       <sys/uproc.h>
        !          18926: #include       <sys/proc.h>
        !          18927: #include       <sys/con.h>
        !          18928: #include       <sys/stat.h>
        !          18929: #include       <sys/devices.h>         /* SCSI_MAJOR */
        !          18930: #include       <errno.h>
        !          18931: #include       <sys/fdisk.h>
        !          18932: #include       <sys/hdioctl.h>
        !          18933: #include       <sys/buf.h>
        !          18934: #include       <sys/scsiwork.h>
        !          18935: 
        !          18936: /*
        !          18937:  * Definitions.
        !          18938:  *     Constants.
        !          18939:  *     Macros with argument lists.
        !          18940:  *     Typedefs.
        !          18941:  *     Enums.
        !          18942:  */
        !          18943: 
        !          18944: #define SS_RAM         0x1800  /* Offset of parameter RAM */
        !          18945: 
        !          18946:                                /* Future Domain */
        !          18947: #define FD_CSR         0x1C00  /* Offset of control/status register */
        !          18948: #define FD_DAT         0x1E00  /* Offset of data port */
        !          18949: 
        !          18950:                                /* Seagate */
        !          18951: #define SS_CSR         0x1A00  /* Offset of control/status register */
        !          18952: #define SS_DAT         0x1C00  /* Offset of data port */
        !          18953: 
        !          18954: #define SS_RAM_LEN     128     /* ST0x has 128 bytes of RAM */
        !          18955: #define SS_DAT_LEN     0x400   /* Byte range mapped to data port */
        !          18956: #define SS_SEL_LEN     0x2000  /* Total size of memory-mapped area */
        !          18957: 
        !          18958: #define WC_ENABLE_SCSI 0x80    /* Write Control (WC) register bits */
        !          18959: #define WC_ENABLE_IRPT 0x40
        !          18960: #define WC_ENABLE_PRTY 0x20
        !          18961: #define WC_ARBITRATE   0x10
        !          18962: #define WC_ATTENTION   0x08
        !          18963: #define WC_BUSY        0x04
        !          18964: #define WC_SELECT      0x02
        !          18965: #define WC_SCSI_RESET          0x01
        !          18966: 
        !          18967: #define RS_ARBIT_COMPL 0x80    /* Read STATUS (RS) register bits */
        !          18968: #define RS_PRTY_ERROR  0x40
        !          18969: #define RS_SELECT      0x20
        !          18970: #define RS_REQUEST     0x10
        !          18971: #define RS_CTRL_DATA   0x08
        !          18972: #define RS_I_O         0x04
        !          18973: #define RS_MESSAGE     0x02
        !          18974: #define RS_BUSY        0x01
        !          18975: 
        !          18976: #define DEV_SCSI_ID(dev)       ((dev >> 4) & 0x0007)
        !          18977: #define DEV_LUN(dev)           ((dev >> 2) & 0x0003)
        !          18978: #define DEV_DRIVE(dev)         ((dev >> 2) & 0x001F)
        !          18979: #define DEV_PARTN(dev)         (dev & 0x0003)
        !          18980: #define DEV_SPECIAL(dev)       (dev & 0x0080)
        !          18981: 
        !          18982: #define HIPRI_RETRIES  5000    /* # of times to retry while hogging CPU */
        !          18983: #define LOPRI_RETRIES  5       /* # of retries with sleep between tries */
        !          18984: #define WHOLE_DRIVE    NPARTN
        !          18985: #define RESET_TICKS    50      /* # of clock ticks for reset settling */
        !          18986: #define LOAD_DELAY     30000   /* Loop counter during ssload() only */
        !          18987: 
        !          18988: #define BUS_FREE       ((ffbyte(ss_csr) & (RS_BUSY | RS_SELECT)) == 0)
        !          18989: #define TGT_RSEL       \
        !          18990:        (  (ffbyte(ss_csr) & (RS_SELECT |  RS_I_O   )) \
        !          18991:        && (ffbyte(ss_dat) & (host_id   | (1<<s_id) )) )
        !          18992: 
        !          18993: #define DELAY_ARB      10      /* delays units are 10 msec (clock ticks) */
        !          18994: #define DELAY_BDR      30
        !          18995: #define DELAY_BSY      20
        !          18996: #define DELAY_RES      50
        !          18997: #define DELAY_RST      40
        !          18998: 
        !          18999: #define MAX_AVL_COUNT  100
        !          19000: #define MAX_BDR_COUNT  3
        !          19001: #define MAX_BSY_COUNT  3
        !          19002: #define MAX_TRY_COUNT  10
        !          19003: #define INL_MAX_REQ_POLL       800000L
        !          19004: #define WKG_MAX_REQ_POLL       20000L
        !          19005: 
        !          19006: typedef unsigned char  uchar;
        !          19007: typedef unsigned int   uint;
        !          19008: typedef unsigned long  ulong;
        !          19009: 
        !          19010: typedef enum {                 /* values for current driver state */
        !          19011:        SST_DEQUEUE =0,
        !          19012:        SST_BUS_DEV_RESET,
        !          19013:        SST_HIPRI_RESET,
        !          19014:        SST_LOPRI_RESET,
        !          19015:        SST_POLL_ARBITN,
        !          19016:        SST_POLL_BEGIN_IO,
        !          19017:        SST_POLL_RESELECT,
        !          19018:        SST_REQ_SENSE,
        !          19019:        SST_RESET_OFF
        !          19020: } SST_TYPE;
        !          19021: 
        !          19022: typedef enum {                 /* values for input to recovery routine */
        !          19023:        RV_A_TIMEOUT,
        !          19024:        RV_P_TIMEOUT,
        !          19025:        RV_R_TIMEOUT,
        !          19026:        RV_BF_TIMEOUT,
        !          19027:        RV_CS_BUSY,
        !          19028:        RV_CS_CHECK
        !          19029: } RV_TYPE;
        !          19030: 
        !          19031: typedef struct ss {
        !          19032:        ulong   capacity;
        !          19033:        ulong   blocklen;
        !          19034:        ulong   bno;
        !          19035:        int     msg_in;
        !          19036:        int     dr_watch;
        !          19037:        uchar   cmdbuf[G1CMDLEN];
        !          19038:        int     cmdlen;
        !          19039:        int     cmd_bytes_out;
        !          19040:        int     cmdstat;
        !          19041:        BUF     *bp;            /* current I/O request node, or NULL */
        !          19042:        struct  fdisk_s parmp[NPARTN+1];
        !          19043:        SST_TYPE state;
        !          19044:        TIM     tim;            /* for target-specific timers */
        !          19045:        uchar   avl_count;
        !          19046:        uchar   bdr_count;
        !          19047:        uchar   bsy_count;
        !          19048:        uchar   try_count;
        !          19049:        uint    busy:1;         /* 1 if command uses local buffer */
        !          19050:        uint    expired:1;      /* 1 if target's timer has expired */
        !          19051:        uint    ptab_read:1;    /* 1 if partition table has been read */
        !          19052:        uint    waiting:1;      /* 1 if target timer is running */
        !          19053: }      ss_type;
        !          19054: 
        !          19055: typedef struct {
        !          19056:        uint    ncyl;
        !          19057:        uchar   nhead;
        !          19058:        uchar   nspt;
        !          19059: }      drv_parm_type;
        !          19060: 
        !          19061: /*
        !          19062:  * Functions.
        !          19063:  *     Import Functions.
        !          19064:  *     Export Functions.
        !          19065:  *     Local Functions.
        !          19066:  */
        !          19067: 
        !          19068: /* functions from bufq.c */
        !          19069: extern int bufq_init();
        !          19070: extern void bufq_rlse();
        !          19071: extern void bufq_wr_tail();
        !          19072: extern BUF * bufq_rd_head();
        !          19073: extern BUF * bufq_rm_head();
        !          19074: 
        !          19075: /* functions from ssas.s */
        !          19076: extern void    ss_get();
        !          19077: extern int     ss_put();
        !          19078: extern int     nulldev();
        !          19079: extern int     nonedev();
        !          19080: extern unsigned char ffbyte();
        !          19081: 
        !          19082: static void    ssopen();               /* CON functions */
        !          19083: static void    ssclose();
        !          19084: static void    ssblock();
        !          19085: static void    ssread();
        !          19086: static void    sswrite();
        !          19087: static int     ssioctl();
        !          19088: static void    sswatch();
        !          19089: static void    ssload();
        !          19090: static void    ssunload();
        !          19091: 
        !          19092: static int     bus_dev_reset();        /* additional support functions */
        !          19093: static int     chk_reconn();
        !          19094: static void    do_connect();
        !          19095: static void    dummy_reconn();
        !          19096: static int     far_info_xfer();
        !          19097: static int     host_ident();
        !          19098: static int     init_call();
        !          19099: static void    init_pointers();
        !          19100: static int     inquiry();
        !          19101: static int     local_info_xfer();
        !          19102: static int     mode_sense();
        !          19103: static void    next_req();
        !          19104: static void    nonpolled();
        !          19105: static int     read_cap();
        !          19106: static void    recover();
        !          19107: static int     req_sense();
        !          19108: static int     rsel_handshake();
        !          19109: static void    ssdelay();
        !          19110: static void    ss_finished();
        !          19111: static void    ss_mach();
        !          19112: static void    set_timeout();
        !          19113: static int     ssinit();
        !          19114: static void    ssintr();
        !          19115: static int     start_arb();
        !          19116: static void    stop_timeout();
        !          19117: static uchar   xpmod();
        !          19118: 
        !          19119: /*
        !          19120:  * Global Data.
        !          19121:  *     Import Variables.
        !          19122:  *     Export Variables.
        !          19123:  *     Local Variables.
        !          19124:  */
        !          19125: CON    sscon   = {
        !          19126:        DFBLK|DFCHR,                    /* Flags */
        !          19127:        SCSI_MAJOR,                     /* Major index */
        !          19128:        ssopen,                         /* Open */
        !          19129:        ssclose,                        /* Close */
        !          19130:        ssblock,                        /* Block */
        !          19131:        ssread,                         /* Read */
        !          19132:        sswrite,                        /* Write */
        !          19133:        ssioctl,                        /* Ioctl */
        !          19134:        nulldev,                        /* Powerfail */
        !          19135:        sswatch,                        /* Timeout */
        !          19136:        ssload,                         /* Load */
        !          19137:        ssunload,                       /* Unload */
        !          19138:        nulldev                         /* Poll */
        !          19139: };
        !          19140: 
        !          19141:        /* Patch these Export Variables to configure the driver. */
        !          19142: /*
        !          19143:  * In the low byte of NSDRIVE, bit n is 1 if SCSI ID n is an installed target.
        !          19144:  * The high byte indicates which type of host adapter:
        !          19145:  *   00 - ST01/ST02
        !          19146:  *   80 - TMC-845/850/860/875/885
        !          19147:  *   40 - TMC-840/841/880/881
        !          19148:  */
        !          19149: uint   NSDRIVE = 0x0000;
        !          19150: uint   SS_INT = 5;             /* ST0[12] use either IRQ3 or IRQ5 */
        !          19151: uint   SS_BASE = 0xCA00;       /* Segment addr of ST0x communication area */
        !          19152: 
        !          19153: /* ncyl, nhead, nspt */
        !          19154: drv_parm_type drv_parm[MAX_SCSI_ID] = {
        !          19155:        { 0, 0, 0},
        !          19156:        { 0, 0, 0},
        !          19157:        { 0, 0, 0},
        !          19158:        { 0, 0, 0},
        !          19159:        { 0, 0, 0},
        !          19160:        { 0, 0, 0},
        !          19161:        { 0, 0, 0}
        !          19162: };
        !          19163: 
        !          19164: static BUF     dbuf;           /* For raw I/O */
        !          19165: static paddr_t ss_base;        /* physical address of ST0x comm area */
        !          19166: static faddr_t ss_fp;          /* (far *) to ST0x comm area */
        !          19167: 
        !          19168: static faddr_t ss_ram;         /* (far *) to parameter RAM */
        !          19169: static faddr_t ss_csr;         /* (far *) to control/status */
        !          19170: static faddr_t ss_dat;         /* (far *) to data port */
        !          19171: 
        !          19172: static TIM     delay_tim;      /* needed for calls to ssdelay() */
        !          19173: static int     do_sst_op;      /* 1 when state machine iteration continues */
        !          19174: static int     ss_expired;     /* 1 after local timeout */
        !          19175: 
        !          19176: static uint    max_req_poll;   /* this changes after initialization */
        !          19177: 
        !          19178: static uchar   host_id;        /* Host is SCSI ID #7 for Seagate, 6 for FD */
        !          19179: static uchar   swap_status_bits;
        !          19180: 
        !          19181: static ss_type *ss_tbl;        /* points to block of "ss" structs */
        !          19182: static ss_type  *ss[MAX_SCSI_ID];
        !          19183: 
        !          19184: /*
        !          19185:  * host_claimed is -1 if host is available, else it's the SCSI id of the
        !          19186:  *     target that claims the host.
        !          19187:  *
        !          19188:  * host is claimed at start of any of the follwoing:
        !          19189:  *     SCSI bus reset
        !          19190:  *     arbitration for block i/o request
        !          19191:  *     reselect
        !          19192:  *
        !          19193:  * host is released at:
        !          19194:  *     end of SCSI bus reset
        !          19195:  *     completion (successful or not) of block i/o request (ss_finished)
        !          19196:  *     disconnect <-- temporarily disabled
        !          19197:  */
        !          19198: static int     host_claimed;
        !          19199: 
        !          19200: /*
        !          19201:  * ssload()    - load routine.
        !          19202:  *
        !          19203:  *     Action: The controller is reset and the interrupt vector is grabbed.
        !          19204:  *             The drive characteristics are set up at this time.
        !          19205:  */
        !          19206: static void ssload()
        !          19207: {
        !          19208:        int erf = 0;  /* 1 if error occurs */
        !          19209:        int i;
        !          19210:        int max_id = -1;
        !          19211:        int num_drives = 0;
        !          19212: 
        !          19213:        /*
        !          19214:         * Allocate a selector to map into ST0x memory-mapped comm area.
        !          19215:         */
        !          19216:        ss_base = (paddr_t)((long)(unsigned)SS_BASE << 4);
        !          19217:        ss_fp = ptov(ss_base, (fsize_t)SS_SEL_LEN);
        !          19218: 
        !          19219:        ss_ram = ss_fp + SS_RAM;
        !          19220: 
        !          19221:        /*
        !          19222:         * Primitive test of ST0x RAM.
        !          19223:         */
        !          19224:        sfword(ss_ram, 0xA55A);
        !          19225:        sfword(ss_ram + 2, 0x3CC3);
        !          19226:        sfword(ss_ram + SS_RAM_LEN - 4, 0xA55A);
        !          19227:        sfword(ss_ram + SS_RAM_LEN - 2, 0x3CC3);
        !          19228:        if (ffword(ss_ram) != 0xA55A            /* fetch a "far" word */
        !          19229:        ||  ffword(ss_ram + 2) != 0x3CC3
        !          19230:        ||  ffword(ss_ram + SS_RAM_LEN - 4) != 0xA55A
        !          19231:        ||  ffword(ss_ram + SS_RAM_LEN - 2) != 0x3CC3) {
        !          19232:                printf("Error - host failed memory test\n");
        !          19233:                erf = 1;
        !          19234:        }
        !          19235: 
        !          19236:        /*
        !          19237:         * Set host-dependent constants.
        !          19238:         */
        !          19239:        switch(NSDRIVE >> 8) {
        !          19240:        case 0x00:      /* ST01/ST02 */
        !          19241:                ss_csr = ss_fp + SS_CSR;
        !          19242:                ss_dat = ss_fp + SS_DAT;
        !          19243:                host_id = 0x80;         /* host is id #7 */
        !          19244:                break;
        !          19245:        case 0x80:      /* TMC-845/850/860/875/885 */
        !          19246:                ss_csr = ss_fp + FD_CSR;
        !          19247:                ss_dat = ss_fp + FD_DAT;
        !          19248:                host_id = 0x40;         /* host is id #6 */
        !          19249:                break;
        !          19250:        case 0x40:      /* TMC-840/841/880/881 */
        !          19251:                ss_csr = ss_fp + SS_CSR;
        !          19252:                ss_dat = ss_fp + SS_DAT;
        !          19253:                host_id = 0x40;         /* host is id #6 */
        !          19254:                swap_status_bits = 1;
        !          19255:                break;
        !          19256:        }
        !          19257:        NSDRIVE &= ~(uint)host_id;
        !          19258: 
        !          19259:        /*
        !          19260:         * Allocate drive structs.
        !          19261:         *
        !          19262:         * Do a single call to kalloc() then put allocated pieces into
        !          19263:         * array ss.
        !          19264:         *
        !          19265:         * First allocate and clear storage.  Then hook up the pointers.
        !          19266:         */
        !          19267:        if (!erf) {
        !          19268:                for (i = 0; i < MAX_SCSI_ID; i++)
        !          19269:                        if ((NSDRIVE >> i) & 1) {
        !          19270:                                max_id = i;
        !          19271:                                num_drives++;
        !          19272:                        }
        !          19273:                if (num_drives == 0) {
        !          19274:                        printf("Error - ss has no valid target id's\n");
        !          19275:                        erf = 1;
        !          19276:                } else if ((ss_tbl = kalloc(num_drives*sizeof(ss_type)))
        !          19277:                == NULL) {
        !          19278:                        printf("Error - ss can't allocate structs\n");
        !          19279:                        erf = 1;
        !          19280:                } else
        !          19281:                        kclear(ss_tbl, num_drives * sizeof(ss_type));
        !          19282:        }
        !          19283:        if (!erf) {
        !          19284:                ss_type *foo = ss_tbl;
        !          19285: 
        !          19286:                for (i = 0; i < MAX_SCSI_ID; i++)
        !          19287:                        if ((NSDRIVE >> i) & 1)
        !          19288:                                ss[i] = foo++;
        !          19289:        }
        !          19290: 
        !          19291:        /*
        !          19292:         * Claim IRQ vector.
        !          19293:         */
        !          19294:        setivec(SS_INT, ssintr);
        !          19295: 
        !          19296:        /*
        !          19297:         * Initialize drives we know about (i.e. in NSDRIVE bitmap).
        !          19298:         */
        !          19299:        host_claimed = -1;
        !          19300:        bufq_init(max_id + 1);
        !          19301:        max_req_poll = INL_MAX_REQ_POLL;
        !          19302:        if (!erf) {
        !          19303:                for (i = 0; i < MAX_SCSI_ID; i++)
        !          19304:                        if ((NSDRIVE >> i) & 1)
        !          19305:                                ssinit(i);
        !          19306:        }
        !          19307:        max_req_poll = WKG_MAX_REQ_POLL;
        !          19308: }
        !          19309: 
        !          19310: /*
        !          19311:  * ssunload()  - unload routine.
        !          19312:  */
        !          19313: static void ssunload()
        !          19314: {
        !          19315:        /*
        !          19316:         * Deallocate driver heap space.
        !          19317:         */
        !          19318:        if (ss_tbl)
        !          19319:                kfree(ss_tbl);
        !          19320:        bufq_rlse();
        !          19321: 
        !          19322:        /*
        !          19323:         * Free the ST0x selector.
        !          19324:         */
        !          19325:        vrelse(ss_fp);
        !          19326: 
        !          19327:        /*
        !          19328:         * Release IRQ vector.
        !          19329:         */
        !          19330:        clrivec(SS_INT);
        !          19331: }
        !          19332: 
        !          19333: /*
        !          19334:  * ssopen()
        !          19335:  *
        !          19336:  *     Input:  dev = disk device to be opened.
        !          19337:  *             mode = access mode [IPR,IPW, IPR+IPW].
        !          19338:  *
        !          19339:  *     Action: Validate the minor device.
        !          19340:  *             Update the paritition table if necessary.
        !          19341:  */
        !          19342: static void ssopen(dev, mode)
        !          19343: register dev_t dev;
        !          19344: {
        !          19345:        int drive, partn;
        !          19346:        struct  fdisk_s *fdp;
        !          19347:        ss_type * ssp;
        !          19348:        int s_id;
        !          19349:        uchar * msg;
        !          19350: 
        !          19351:        /*
        !          19352:         * Set up local variables.
        !          19353:         */
        !          19354:        drive = DEV_SCSI_ID(dev);
        !          19355:        partn = DEV_PARTN(dev);
        !          19356:        s_id = DEV_SCSI_ID(dev);
        !          19357:        ssp = ss[s_id];
        !          19358:        fdp = ssp->parmp;
        !          19359: 
        !          19360: #if (DEBUG >= 3)
        !          19361: devmsg(dev, "ssopen");
        !          19362: #endif
        !          19363: 
        !          19364:        /*
        !          19365:         * LUN must be zero.
        !          19366:         * SCSI id must have corresponding 1 in NSDRIVE bitmapped variable.
        !          19367:         */
        !          19368:        if (DEV_LUN(dev) != 0 || ((1 << drive) & NSDRIVE) == 0) {
        !          19369:                msg = "bad LUN or SCSI id";
        !          19370:                u.u_error = ENXIO;
        !          19371:                goto bad_open;
        !          19372:        }
        !          19373: 
        !          19374:        /*
        !          19375:         * If "special" bit is set, partition field must be zero.
        !          19376:         */
        !          19377:        if (DEV_SPECIAL(dev) && partn != 0) {
        !          19378:                msg = "bad special partition";
        !          19379:                u.u_error = ENXIO;
        !          19380:                goto bad_open;
        !          19381:        }
        !          19382: 
        !          19383:        /*
        !          19384:         * Subscripting gimmick for partition table.
        !          19385:         */
        !          19386:        if (dev & SDEV)
        !          19387:                partn = WHOLE_DRIVE;
        !          19388: 
        !          19389:        /*
        !          19390:         * If not accessing whole drive and the partition table has not
        !          19391:         * been read yet, try to read it now.
        !          19392:         * Do this by calling fdisk() with partition table device on the drive
        !          19393:         * that is being accessed.
        !          19394:         */
        !          19395:        if (partn != WHOLE_DRIVE && !(ssp->ptab_read)) {
        !          19396:                int fdisk_dev;
        !          19397: 
        !          19398:                fdisk_dev = (dev | SDEV) & 0xfff0;
        !          19399: 
        !          19400: #if (DEBUG >=3)
        !          19401:                devmsg(fdisk_dev, "calling fdisk");
        !          19402:                if (fdisk(fdisk_dev, fdp)) {
        !          19403:                        int p;
        !          19404: 
        !          19405:                        fdp[WHOLE_DRIVE].p_size = ssp->capacity;
        !          19406:                        fdp[WHOLE_DRIVE].p_base = 0;
        !          19407:                        printf("fdisk() succeeded\n");
        !          19408:                        for (p=0; p<=WHOLE_DRIVE; p++)
        !          19409:        printf("p=%d base=%ld size=%ld\n", p, fdp[p].p_base, fdp[p].p_size);
        !          19410:                        ssp->ptab_read = 1;
        !          19411:                } else {
        !          19412:                        printf("fdisk() failed\n");
        !          19413:                        u.u_error = ENXIO;
        !          19414:                        goto bad_open;
        !          19415:                }
        !          19416: #else
        !          19417:                if (fdisk(fdisk_dev, fdp)) {
        !          19418:                        fdp[WHOLE_DRIVE].p_size = ssp->capacity;
        !          19419:                        fdp[WHOLE_DRIVE].p_base = 0;
        !          19420:                        ssp->ptab_read = 1;
        !          19421:                } else {
        !          19422:                        msg = "bad partition table";
        !          19423:                        u.u_error = ENXIO;
        !          19424:                        goto bad_open;
        !          19425:                }
        !          19426: #endif
        !          19427: 
        !          19428:        }
        !          19429: 
        !          19430:        /*
        !          19431:         * Ensure partition lies within drive boundaries and is non-zero size.
        !          19432:         */
        !          19433:        if (partn != WHOLE_DRIVE
        !          19434:        && (fdp[partn].p_base+fdp[partn].p_size) > fdp[WHOLE_DRIVE].p_size) {
        !          19435:                msg = "partition exceeds drive capacity";
        !          19436:                u.u_error = EBADFMT;
        !          19437:                goto bad_open;
        !          19438:        }
        !          19439: 
        !          19440:        if (partn != WHOLE_DRIVE && fdp[partn].p_size == 0) {
        !          19441:                msg = "partition not found";
        !          19442:                u.u_error = ENODEV;
        !          19443:                goto bad_open;
        !          19444:        }
        !          19445: 
        !          19446:        /*
        !          19447:         * OK to open the device.
        !          19448:         * Start watchdog timer (if not already started) for the host adapter.
        !          19449:         */
        !          19450:        ++drvl[SCSI_MAJOR].d_time;
        !          19451:        ++ssp->dr_watch;
        !          19452:        goto end_open;
        !          19453: 
        !          19454: bad_open:
        !          19455:        devmsg(dev, msg);
        !          19456: end_open:
        !          19457:        return;
        !          19458: }
        !          19459: 
        !          19460: /*
        !          19461:  * ssclose()
        !          19462:  */
        !          19463: static void ssclose(dev)
        !          19464: dev_t dev;
        !          19465: {
        !          19466:        ss_type * ssp;
        !          19467:        int s_id;
        !          19468: 
        !          19469:        s_id = DEV_SCSI_ID(dev);
        !          19470:        ssp = ss[s_id];
        !          19471: 
        !          19472:        /*
        !          19473:         * Decrement the number of watchdog timer requests open for host
        !          19474:         * adapter and for target.
        !          19475:         */
        !          19476:        --drvl[SCSI_MAJOR].d_time;
        !          19477:        --ssp->dr_watch;
        !          19478: 
        !          19479: #if (DEBUG >= 3)
        !          19480: devmsg(dev, "ssclose");
        !          19481: #endif
        !          19482: 
        !          19483: }
        !          19484: 
        !          19485: /*
        !          19486:  * ssread()    - read a block from the raw disk
        !          19487:  *
        !          19488:  *     Input:  dev = disk device to be written to.
        !          19489:  *             iop = pointer to source I/O structure.
        !          19490:  *
        !          19491:  *     Action: Invoke the common raw I/O processing code.
        !          19492:  */
        !          19493: static void ssread(dev, iop)
        !          19494: dev_t  dev;
        !          19495: IO     *iop;
        !          19496: {
        !          19497:        ioreq( &dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC );
        !          19498: }
        !          19499: 
        !          19500: /*
        !          19501:  * sswrite()   - write a block to the raw disk
        !          19502:  *
        !          19503:  *     Input:  dev = disk device to be written to.
        !          19504:  *             iop = pointer to source I/O structure.
        !          19505:  *
        !          19506:  *     Action: Invoke the common raw I/O processing code.
        !          19507:  */
        !          19508: static void sswrite(dev, iop)
        !          19509: dev_t  dev;
        !          19510: IO     *iop;
        !          19511: {
        !          19512:        ioreq( &dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC );
        !          19513: }
        !          19514: 
        !          19515: /*
        !          19516:  * ssioctl()
        !          19517:  *
        !          19518:  *     Input:  dev = disk device to be operated on.
        !          19519:  *             cmd = input/output request to be performed.
        !          19520:  *             vec = (pointer to) optional argument.
        !          19521:  */
        !          19522: static int ssioctl(dev, cmd, vec)
        !          19523: register dev_t dev;
        !          19524: int cmd;
        !          19525: char * vec;
        !          19526: {
        !          19527:        int ret = 0;
        !          19528:        hdparm_t hdparm;
        !          19529:        struct  fdisk_s *fdp;
        !          19530:        int s_id;
        !          19531:        ss_type * ssp;
        !          19532: 
        !          19533:        s_id = DEV_SCSI_ID(dev);
        !          19534:        ssp = ss[s_id];
        !          19535:        fdp = ssp->parmp;
        !          19536: 
        !          19537:        switch(cmd) {
        !          19538:        case HDGETA:
        !          19539:                /*
        !          19540:                 * Get hard disk attributes.
        !          19541:                 */
        !          19542: PR3("HDGETA");
        !          19543:                fdp = ssp->parmp;
        !          19544:                *(short *)&hdparm.landc[0] =
        !          19545:                *(short *)&hdparm.ncyl[0] = drv_parm[s_id].ncyl;
        !          19546:                hdparm.nhead = drv_parm[s_id].nhead;
        !          19547:                hdparm.nspt = drv_parm[s_id].nspt;
        !          19548: #if (DEBUG >= 3)
        !          19549: printf("ncyl=%d nhead=%d nspt=%d\n",
        !          19550:   hdparm.ncyl[0]+((int)hdparm.ncyl[1]<<8), (int)hdparm.nhead, (int)hdparm.nspt);
        !          19551: #endif
        !          19552:                kucopy(&hdparm, vec, sizeof hdparm);
        !          19553:                ret = 0;
        !          19554:                break;
        !          19555:        case HDSETA:
        !          19556:                /*
        !          19557:                 * Set hard disk attributes.
        !          19558:                 */
        !          19559: PR3("HDSETA");
        !          19560:                fdp = ssp->parmp;
        !          19561:                ukcopy(vec, &hdparm, sizeof hdparm);
        !          19562:                drv_parm[s_id].ncyl = *(short *)&hdparm.ncyl[0];
        !          19563:                drv_parm[s_id].nhead = hdparm.nhead;
        !          19564:                drv_parm[s_id].nspt = hdparm.nspt;
        !          19565: #if (DEBUG >= 3)
        !          19566: printf("ncyl=%d nhead=%d nspt=%d\n",
        !          19567:   hdparm.ncyl[0]+((int)hdparm.ncyl[1]<<8), (int)hdparm.nhead, (int)hdparm.nspt);
        !          19568: #endif
        !          19569:                ret = 0;
        !          19570:                break;
        !          19571:        default:
        !          19572:                u.u_error = EINVAL;
        !          19573:                ret = -1;
        !          19574:        }
        !          19575: 
        !          19576:        return ret;
        !          19577: }
        !          19578: 
        !          19579: /*
        !          19580:  * ssblock()   - queue a block to the disk
        !          19581:  *
        !          19582:  *     Input:  bp = pointer to block to be queued.
        !          19583:  *
        !          19584:  *     Action: Queue a block to the disk.
        !          19585:  *             Make sure that the transfer is within the disk partition.
        !          19586:  */
        !          19587: static void ssblock(bp)
        !          19588: register BUF   *bp;
        !          19589: {
        !          19590:        struct  fdisk_s *fdp;
        !          19591:        int partition, drive, s_id;
        !          19592:        dev_t dev;
        !          19593:        ss_type * ssp;
        !          19594:        uchar * msg = NULL;
        !          19595: 
        !          19596:        /*
        !          19597:         * Set up local variables.
        !          19598:         */
        !          19599:        dev = bp->b_dev;
        !          19600:        partition = DEV_PARTN(dev);
        !          19601:        drive = DEV_DRIVE(dev);
        !          19602:        s_id = DEV_SCSI_ID(dev);
        !          19603:        ssp = ss[s_id];
        !          19604:        if (dev & SDEV)
        !          19605:                partition = WHOLE_DRIVE;
        !          19606:        fdp = ssp->parmp;
        !          19607: 
        !          19608:        bp->b_resid = bp->b_count;
        !          19609: #if (DEBUG >= 2)
        !          19610: if (bp->b_count != BSIZE)
        !          19611:        printf("b_count=%d ", bp->b_count);
        !          19612: #endif
        !          19613: 
        !          19614:        /*
        !          19615:         * Range check disk region.
        !          19616:         */
        !          19617:        if (!(ssp->ptab_read)) {
        !          19618:                if ( partition == WHOLE_DRIVE ) {
        !          19619:                        if ((bp->b_bno != 0) || (bp->b_count != BSIZE)) {
        !          19620:                                msg = "invalid request";
        !          19621:                                bp->b_flag |= BFERR;
        !          19622:                                goto bad_blk;
        !          19623:                        }
        !          19624:                } else {
        !          19625:                        msg = "no partition table";
        !          19626:                        bp->b_flag |= BFERR;
        !          19627:                        goto bad_blk;
        !          19628:                }
        !          19629:        }
        !          19630: 
        !          19631:        /*
        !          19632:         * Check for read at end of partition.
        !          19633:         * (Need to return with b_resid = BSIZE to signal end of volume.)
        !          19634:         */
        !          19635:        else if ((bp->b_req == BREAD) && (bp->b_bno == fdp[partition].p_size)) {
        !          19636:                goto bad_blk;
        !          19637:        }
        !          19638: 
        !          19639:        /*
        !          19640:         * Check for read past end of partition.
        !          19641:         */
        !          19642:        else if ( (bp->b_bno + (bp->b_count/BSIZE))
        !          19643:        > fdp[partition].p_size ) {
        !          19644:                msg = "partition overrun";
        !          19645:                bp->b_flag |= BFERR;
        !          19646:                goto bad_blk;
        !          19647:        }
        !          19648: 
        !          19649:        /*
        !          19650:         * Fail if request is for zero bytes or is not even # of blocks.
        !          19651:         */
        !          19652:        if ((bp->b_count % BSIZE) || bp->b_count == 0) {
        !          19653:                msg = "invalid byte count";
        !          19654:                bp->b_flag |= BFERR;
        !          19655:                goto bad_blk;
        !          19656:        }
        !          19657: 
        !          19658:        /*
        !          19659:         * Operation appears valid.
        !          19660:         * Fill fields in the node and queue the request.
        !          19661:         */
        !          19662:        bufq_wr_tail(s_id, bp);
        !          19663:        ss_mach(s_id);
        !          19664:        goto end_blk;
        !          19665: 
        !          19666:        /*
        !          19667:         * Operation cannot be done.  Release the kernel buffer structure.
        !          19668:         * Value of "bp->b_flag" tells caller if error occurred.
        !          19669:         */
        !          19670: bad_blk:
        !          19671:        if (msg)
        !          19672:                devmsg(dev, msg);
        !          19673:        bdone(bp);
        !          19674: 
        !          19675: end_blk:
        !          19676:        return;
        !          19677: }
        !          19678: 
        !          19679: /*
        !          19680:  * ssintr()    - Interrupt routine.
        !          19681:  *
        !          19682:  * If we have been reselected by a recognized target device
        !          19683:  *     let kernel get out of interrupt mode (defer) and do SCSI
        !          19684:  *     reconnect stuff.
        !          19685:  */
        !          19686: static void ssintr()
        !          19687: {
        !          19688:        int s_id;
        !          19689: 
        !          19690:        s_id = chk_reconn();
        !          19691:        if (s_id != -1) {
        !          19692:                if (ss[s_id]->state == SST_POLL_RESELECT)
        !          19693:                        defer(ss_mach, s_id);
        !          19694:                else
        !          19695:                        defer(dummy_reconn, s_id);
        !          19696: PR3("!");
        !          19697:        }
        !          19698: }
        !          19699: 
        !          19700: /*
        !          19701:  * dummy_reconn()
        !          19702:  *
        !          19703:  * Somehow we are in a state where the driver software does not expect
        !          19704:  * a reconnect but a device is trying one anyway.  Go thru the motions
        !          19705:  * of reconnect because not servicing a hanging reselect seems to leave
        !          19706:  * the target hung - in such a way that it fails to respond to reset
        !          19707:  * messages and to reset on the SCSI bus.
        !          19708:  */
        !          19709: static void dummy_reconn(s_id)
        !          19710: int s_id;
        !          19711: {
        !          19712:        int bus_timeout;
        !          19713:        uchar phase_type;
        !          19714:        int s;
        !          19715:        int msg_in;
        !          19716:        int cmdstat;
        !          19717:        int xfer_good = 1;
        !          19718: PR1("DUM");
        !          19719:        if (ss[s_id]->state == SST_POLL_RESELECT) {
        !          19720:                defer(ss_mach, s_id);
        !          19721:                goto dum_done;
        !          19722:        }
        !          19723:        if (!rsel_handshake())
        !          19724:                goto dum_done;
        !          19725: 
        !          19726:        s = sphi();
        !          19727:        while (req_wait(&bus_timeout) && xfer_good) {
        !          19728:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          19729:                switch (xpmod(phase_type)) {
        !          19730:                case XP_MSG_IN:
        !          19731:                        msg_in = ffbyte(ss_dat);
        !          19732:                        switch(msg_in){
        !          19733:                        case MSG_CMD_CMPLT:
        !          19734:                        case MSG_DISCONNECT:
        !          19735:                                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
        !          19736:                                break;
        !          19737:                        }
        !          19738:                        break;
        !          19739:                case XP_MSG_OUT:
        !          19740:                        sfbyte(ss_dat, MSG_NOP); 
        !          19741:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          19742:                        break;
        !          19743:                case XP_STAT_IN:
        !          19744:                        cmdstat = ffbyte(ss_dat);
        !          19745:                        break;
        !          19746:                case XP_CMD_OUT:
        !          19747:                case XP_DATA_OUT:
        !          19748:                        xfer_good = 0;
        !          19749:                        break;
        !          19750:                case XP_DATA_IN:
        !          19751:                        ffbyte(ss_dat);
        !          19752:                        break;
        !          19753:                default:
        !          19754:                        break;
        !          19755:                } /* endswitch */
        !          19756:        } /* endwhile */
        !          19757:        spl(s);
        !          19758: 
        !          19759: dum_done:
        !          19760:        return;
        !          19761: }
        !          19762: 
        !          19763: /*
        !          19764:  * sswatch()
        !          19765:  *
        !          19766:  * Invoked once per second if any devices going through this driver are open.
        !          19767:  * Poll for any reselect, in case interrupt got lost.
        !          19768:  */
        !          19769: static void sswatch()
        !          19770: {
        !          19771:        int s_id;
        !          19772:        ss_type * ssp;
        !          19773: 
        !          19774:        for (s_id = 0; s_id < MAX_SCSI_ID; s_id++) {
        !          19775:                ssp = ss[s_id];
        !          19776:                if (ssp && ssp->dr_watch)
        !          19777:                        defer(ss_mach, s_id);
        !          19778:        } /* endfor */
        !          19779: }
        !          19780: 
        !          19781: /*
        !          19782:  * bus_wait()
        !          19783:  *
        !          19784:  * Wait for specified bit values to appear in Status Register.
        !          19785:  * This uses a tight loop and does not expect to be interrupted.
        !          19786:  *
        !          19787:  * Argument "flags" is a double-byte value;  the high byte is ANDed with
        !          19788:  * status register contents, and the result is tested for equality with
        !          19789:  * the low byte.
        !          19790:  *
        !          19791:  * Return 1 if values wanted appeared, 0 if timeout occurred.
        !          19792:  */
        !          19793: static int bus_wait(flags)
        !          19794: unsigned short flags;
        !          19795: {
        !          19796:        int found, i;
        !          19797:        unsigned char status;
        !          19798: 
        !          19799:        found = 0;
        !          19800:        for ( i = 0; i < HIPRI_RETRIES; i++) {
        !          19801:                status = ffbyte(ss_csr);
        !          19802:                if ((status & (flags >> 8)) == (flags & 0xff)) {
        !          19803:                        found = 1;
        !          19804:                        break;
        !          19805:                }
        !          19806:        }
        !          19807: 
        !          19808: #if (DEBUG >= 1)
        !          19809:        if (!found)
        !          19810:                printf("TO:f=%x s=%x ", flags, status);
        !          19811: #endif
        !          19812: 
        !          19813:        return found;
        !          19814: }
        !          19815: 
        !          19816: /*
        !          19817:  * ssinit()
        !          19818:  *
        !          19819:  * Attempt to initialize the (unique) drive with a given SCSI id.
        !          19820:  * Assume only one drive per SCSI id, having LUN = 0.
        !          19821:  * 
        !          19822:  * Return 1 if success, 0 if failure.
        !          19823:  */
        !          19824: static int ssinit(s_id)
        !          19825: int s_id;
        !          19826: {
        !          19827:        int retval = 1;
        !          19828:        uchar query_buf[MODESENSELEN];
        !          19829:        ss_type * ssp = ss[s_id];
        !          19830:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          19831: 
        !          19832:        printf("SCSI ID %d  LUN 0\n", s_id);
        !          19833:        if (retval)
        !          19834:                if (init_call(inquiry, s_id, query_buf)) {
        !          19835:                        query_buf[INQUIRYLEN] = 0;
        !          19836: #if (debug >= 2)
        !          19837:                        devmsg(dev, query_buf + 8);
        !          19838: #endif
        !          19839:                        if (query_buf[0] == 0) {
        !          19840:                                retval = 1;
        !          19841:                        } else
        !          19842:                                devmsg(dev, "Not Direct Access Device");
        !          19843:                } else
        !          19844:                        devmsg(dev, "Inquiry Failed");
        !          19845: 
        !          19846:        if (retval)
        !          19847:                if (init_call(read_cap, s_id, query_buf)) {
        !          19848:                        retval = 1;
        !          19849:                        ssp->capacity = query_buf[3] | (query_buf[2] << 8)
        !          19850:                        | (((long)(query_buf[1])) << 16)
        !          19851:                        | (((long)(query_buf[0])) << 24);
        !          19852:                        ssp->blocklen = query_buf[7] | (query_buf[6] << 8)
        !          19853:                        | (((long)(query_buf[5])) << 16)
        !          19854:                        | (((long)(query_buf[4])) << 24);
        !          19855: 
        !          19856:                        printf("Capacity=%ld blocks  Block length=%ld\n",
        !          19857:                                ssp->capacity, ssp->blocklen);
        !          19858:                } else
        !          19859:                        devmsg(dev, "Read Capacity Failed");
        !          19860: 
        !          19861:        if (retval)
        !          19862:                if (init_call(mode_sense, s_id, query_buf)) {
        !          19863:                        /*
        !          19864:                         * Display physical drive parameters.
        !          19865:                         */
        !          19866: #define FMT_PG (4+8+8+12)
        !          19867: #define DDG_PG (4+8+8+12+24)
        !          19868:                        uchar heads;
        !          19869:                        unsigned short spt;
        !          19870:                        ulong cyls;
        !          19871: 
        !          19872:                        spt=((int)query_buf[FMT_PG+10]<<8)
        !          19873:                                + query_buf[FMT_PG+11];
        !          19874:                        cyls=((int)query_buf[DDG_PG+2]<<16)
        !          19875:                                + ((int)query_buf[DDG_PG+3]<<8)
        !          19876:                                + query_buf[DDG_PG+4];
        !          19877:                        heads=query_buf[DDG_PG+5];
        !          19878: 
        !          19879:                        printf("Physical:  cylinders=%ld ", cyls);
        !          19880:                        printf("heads=%d ", heads);
        !          19881:                        printf("spt=%d\n", spt);
        !          19882: 
        !          19883:                        if (drv_parm[s_id].ncyl == 0) {
        !          19884:                                drv_parm[s_id].ncyl = cyls;
        !          19885:                                drv_parm[s_id].nhead = heads;
        !          19886:                                drv_parm[s_id].nspt = spt;
        !          19887:                        } else {
        !          19888:                                printf("Logical:  cylinders=%d ",
        !          19889:                                        drv_parm[s_id].ncyl);
        !          19890:                                printf("heads=%d ", drv_parm[s_id].nhead);
        !          19891:                                printf("spt=%d\n", drv_parm[s_id].nspt);
        !          19892:                        }
        !          19893:                } else
        !          19894:                        devmsg(dev, "Mode Sense Failed");
        !          19895: 
        !          19896:        return retval;
        !          19897: }
        !          19898: 
        !          19899: /*
        !          19900:  * far_info_xfer()
        !          19901:  *
        !          19902:  * Do bus cycle information transfer phases.
        !          19903:  * This includes message in/out, command in/out, and data in/out.
        !          19904:  *
        !          19905:  * If cmdlen is nonzero, cmdbuf is an array of bytes of that length,
        !          19906:  * to be sent to the target.
        !          19907:  *
        !          19908:  * Return 1 if bus timeout did not occur, else 0.
        !          19909:  *
        !          19910:  * pseudocode:
        !          19911:  *
        !          19912:  * while (wait for REQ true or BUSY false on SCSI bus)
        !          19913:  *   if (BUSY false)
        !          19914:  *     break from while loop
        !          19915:  *   else
        !          19916:  *     switch (xfer phase = RS_CTRL_DATA|RS_I_O|RS_MESSAGE)
        !          19917:  *       case XP_MSG_IN/XP_MSG_OUT/...
        !          19918:  *         handle the indicated information transfer phase
        !          19919:  *     endswitch
        !          19920:  *   endif
        !          19921:  * endwhile
        !          19922:  */
        !          19923: static int far_info_xfer(s_id)
        !          19924: int s_id;
        !          19925: {
        !          19926:        int bus_timeout;
        !          19927:        uchar phase_type;
        !          19928:        uchar msg_in;
        !          19929:        int s;
        !          19930:        int bytes_to_send;
        !          19931:        ss_type * ssp = ss[s_id];
        !          19932:        BUF * bp = ssp->bp;
        !          19933:        int xfer_good = 1;
        !          19934:        int xfer_count = bp->b_count - bp->b_resid;
        !          19935:        int irpts_masked;
        !          19936: int block_done=0;
        !          19937: 
        !          19938:        ssp->cmd_bytes_out = 0;
        !          19939:        ssp->msg_in = -1;
        !          19940: 
        !          19941:        irpts_masked = 0;
        !          19942:        while (req_wait(&bus_timeout) && xfer_good) {
        !          19943:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          19944:                if (!irpts_masked) {
        !          19945:                        s = sphi();
        !          19946:                        irpts_masked = 1;
        !          19947:                }
        !          19948:                switch (xpmod(phase_type)) {
        !          19949:                case XP_MSG_IN:
        !          19950:                        msg_in = ffbyte(ss_dat);
        !          19951:                        switch(msg_in){
        !          19952:                        case MSG_CMD_CMPLT:
        !          19953: PR4("Mcc");
        !          19954:                                ssp->msg_in = msg_in;
        !          19955:                                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
        !          19956:                                break;
        !          19957:                        case MSG_DISCONNECT:
        !          19958: PR4("Mdc");
        !          19959:                                ssp->msg_in = msg_in;
        !          19960:                                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
        !          19961:                                break;
        !          19962:                        case MSG_SAVE_DPTR:
        !          19963: PR4("Msd");
        !          19964:                                break;
        !          19965:                        case MSG_RSTOR_DPTR:
        !          19966: PR4("Mrd");
        !          19967:                                break;
        !          19968:                        case MSG_ABORT:
        !          19969: PR4("Mab");
        !          19970:                                break;
        !          19971:                        case MSG_DEV_RESET:
        !          19972: PR4("Mdr");
        !          19973:                                break;
        !          19974:                        case MSG_IDENTIFY:
        !          19975: PR4("Mmi");
        !          19976:                                break;
        !          19977:                        case MSG_IDENT_DC:
        !          19978: PR4("Mmd");
        !          19979:                                break;
        !          19980:                        }
        !          19981:                        break;
        !          19982:                case XP_MSG_OUT:
        !          19983: PR4("MO");
        !          19984:                        /*
        !          19985:                         * This case shouldn't happen.  We weren't
        !          19986:                         * asserting ATTENTION.  Abort the bus cycle.
        !          19987:                         */
        !          19988:                        sfbyte(ss_dat, MSG_NOP); 
        !          19989:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          19990:                        break;
        !          19991:                case XP_STAT_IN:
        !          19992: PR4("SI");
        !          19993:                        ssp->cmdstat = ffbyte(ss_dat);
        !          19994:                        break;
        !          19995:                case XP_CMD_OUT:
        !          19996:                        /*
        !          19997:                         * Ship out command bytes.
        !          19998:                         * Reset SCSI bus if too many command bytes are wanted.
        !          19999:                         */
        !          20000:                        bytes_to_send = ssp->cmdlen - ssp->cmd_bytes_out;
        !          20001:                        if(bytes_to_send > 0) {
        !          20002:                                sfbyte(ss_dat, ssp->cmdbuf[ssp->cmd_bytes_out++]);
        !          20003:                                /*
        !          20004:                                 * If just sent last byte, allow interrupts.
        !          20005:                                 */
        !          20006:                                if (bytes_to_send == 1) {
        !          20007: PR4("CO");
        !          20008:                                        if (bp->b_req == BREAD) {
        !          20009:                                                if (irpts_masked) {
        !          20010:                                                        spl(s);
        !          20011:                                                        irpts_masked = 0;
        !          20012:                                                }
        !          20013:                                        }
        !          20014:                                }
        !          20015:                        } else {        /* This case should not happen. */
        !          20016:                                xfer_good = 0;
        !          20017:                        }
        !          20018:                        break;
        !          20019:                case XP_DATA_IN:
        !          20020:                        /*
        !          20021:                         * If caller's buffer has room, keep incoming
        !          20022:                         * data byte.
        !          20023:                         */
        !          20024:                        if (block_done) {
        !          20025:                                xfer_good = 0;
        !          20026: PR1("Data in overrun");
        !          20027:                        } else if (bp->b_req != BREAD) {
        !          20028:                                xfer_good = 0;
        !          20029:                        } else {
        !          20030: #if 0
        !          20031:                                int getbval;
        !          20032: 
        !          20033:                                block_done=1;
        !          20034: PR4("DI");
        !          20035:                                if(getbval = ss_getb(ss_dat,
        !          20036:                                bp->b_faddr + xfer_count)) {
        !          20037:                                        xfer_good = 0;
        !          20038: #if (DEBUG >= 1)
        !          20039: printf("getb=%d ", getbval);
        !          20040: #endif
        !          20041:                                }
        !          20042: #else
        !          20043:                                block_done=1;
        !          20044:                                ffcopy(ss_dat, bp->b_faddr + xfer_count, BSIZE);
        !          20045: #endif
        !          20046:                        }
        !          20047:                        break;
        !          20048:                case XP_DATA_OUT:
        !          20049:                        /*
        !          20050:                         * Copy output buffer bytes to data register.
        !          20051:                         */
        !          20052:                        if (block_done) {
        !          20053:                                xfer_good = 0;
        !          20054: PR1("Data out overrun");
        !          20055:                        } else if (bp->b_req != BWRITE) {
        !          20056:                                xfer_good = 0;
        !          20057:                        } else {
        !          20058: #if 0
        !          20059:                                int putbval;
        !          20060:                                block_done=1;
        !          20061: PR4("DO");
        !          20062:                                if (putbval = ss_putb(ss_dat,
        !          20063:                                bp->b_faddr + xfer_count)) {
        !          20064:                                        xfer_good = 0;
        !          20065: #if (DEBUG >= 1)
        !          20066: printf("putb=%d ", putbval);
        !          20067: #endif
        !          20068:                                }
        !          20069: #else
        !          20070:                                block_done=1;
        !          20071:                                ffcopy(bp->b_faddr + xfer_count, ss_dat, BSIZE);
        !          20072: #endif
        !          20073:                                if (irpts_masked) {
        !          20074:                                        spl(s);
        !          20075:                                        irpts_masked = 0;
        !          20076:                                }
        !          20077:                        }
        !          20078:                        break;
        !          20079:                default:
        !          20080:                        break;
        !          20081:                } /* endswitch */
        !          20082:        }
        !          20083:        if (irpts_masked)
        !          20084:                spl(s);
        !          20085: 
        !          20086: #if (DEBUG >= 1)
        !          20087:        switch(ssp->cmdstat) {
        !          20088:        case -1:
        !          20089:                if (msg_in != MSG_DISCONNECT)
        !          20090:                        printf("CS-",ssp->cmdstat);
        !          20091:                break;
        !          20092:        case CS_GOOD:
        !          20093:                break;
        !          20094:        case CS_CHECK:
        !          20095:                printf("CSK",ssp->cmdstat);
        !          20096:                break;
        !          20097:        case CS_BUSY:
        !          20098:                printf("CSY",ssp->cmdstat);
        !          20099:                break;
        !          20100:        case CS_RESERVED:
        !          20101:        default:
        !          20102:                printf("CS%x",ssp->cmdstat);
        !          20103:        }
        !          20104: #endif
        !          20105: 
        !          20106:        return (bus_timeout) ? 0 : 1 ;
        !          20107: }
        !          20108: 
        !          20109: /*
        !          20110:  * req_wait()
        !          20111:  *
        !          20112:  * This routine is called at the start of each information transfer
        !          20113:  * phase and after the last such phase.
        !          20114:  *
        !          20115:  * It returns 1 if REQ is asserted on the SCSI bus, meaning another phase
        !          20116:  * may begin, and 0 otherwise.  A REQ signal will not be seen if the function
        !          20117:  * times out or if BUSY drops.  A value of 1 is written to the pointer argument
        !          20118:  * if timeout occurred, else 0 is written.
        !          20119:  */
        !          20120: static int req_wait(to_ptr)
        !          20121: int *to_ptr;
        !          20122: {
        !          20123:        int req_found;
        !          20124:        unsigned char status;
        !          20125:        ulong poll_ct;
        !          20126:        int s;
        !          20127: 
        !          20128:        s = splo();
        !          20129:        *to_ptr = 1;
        !          20130:        req_found = 0;
        !          20131:        for (poll_ct = 0L; poll_ct < max_req_poll; poll_ct++) {
        !          20132:                status = ffbyte(ss_csr);
        !          20133:                if (status & RS_REQUEST) {
        !          20134:                        req_found = 1;
        !          20135:                        *to_ptr = 0;
        !          20136:                        break;
        !          20137:                } else if ((status & RS_BUSY) == 0) {
        !          20138:                        *to_ptr = 0;
        !          20139:                        break;
        !          20140:                }
        !          20141:        }
        !          20142: 
        !          20143: #if (DEBUG >= 1)
        !          20144:        if (*to_ptr) {
        !          20145:                printf("TX: s=%x ", status);
        !          20146:        }
        !          20147: #endif
        !          20148: 
        !          20149:        spl(s);
        !          20150:        return req_found;
        !          20151: }
        !          20152: 
        !          20153: /*
        !          20154:  * req_sense()
        !          20155:  *
        !          20156:  * Request Sense for a device.  The main reason for doing this is to
        !          20157:  * clear a standing Command Status of Device Check.
        !          20158:  *
        !          20159:  * Full results are discarded.  Return 1 if Device returns No Sense or
        !          20160:  * or Unit Attention.  Else return 0.
        !          20161:  *
        !          20162:  */
        !          20163: static int req_sense(s_id)
        !          20164: int s_id;
        !          20165: {
        !          20166:        uchar sense_buf[SENSELEN];
        !          20167:        uchar cmdbuf[G0CMDLEN];
        !          20168:        int ret = 0;
        !          20169: 
        !          20170:        cmdbuf[0] = ScmdREQUESTSENSE;
        !          20171:        cmdbuf[1] = 0;
        !          20172:        cmdbuf[2] = 0;
        !          20173:        cmdbuf[3] = 0;
        !          20174:        cmdbuf[4] = SENSELEN;
        !          20175:        cmdbuf[5] = 0;
        !          20176: 
        !          20177: #if (DEBUG >= 2)
        !          20178: {int i; for (i=0; i<SENSELEN; i++) sense_buf[i]=0;}
        !          20179: #endif
        !          20180: 
        !          20181: PR2("rqs:");
        !          20182:        if (!start_arb()) {
        !          20183: PR2("NO arb");
        !          20184: #if (DEBUG >= 2)
        !          20185: printf("status=%x ", ffbyte(ss_csr));
        !          20186: #endif
        !          20187:                goto rqs_done;
        !          20188:        }
        !          20189: 
        !          20190:        if (!host_ident(s_id, 0)) {
        !          20191: PR2("NO host ident");
        !          20192: #if (DEBUG >= 2)
        !          20193: printf("status=%x ", ffbyte(ss_csr));
        !          20194: #endif
        !          20195:                goto rqs_done;
        !          20196:        }
        !          20197: 
        !          20198:        if(!local_info_xfer(cmdbuf, G0CMDLEN, sense_buf, SENSELEN, NULL, 0)) {
        !          20199: PR2("NO local xfer");
        !          20200:                goto rqs_done;
        !          20201:        } else {
        !          20202:                /*
        !          20203:                 * Return 1 if drive responded with any of these sense keys:
        !          20204:                 *      0x00    No Sense
        !          20205:                 *      0x06    Unit Attention
        !          20206:                 *      0x0B    Aborted Command
        !          20207:                 * In any of the above cases, a retry will likely succeed
        !          20208:                 * without Buse Device Reset or SCSI Bus Reset.
        !          20209:                 */
        !          20210:                switch (sense_buf[2]) {
        !          20211:                case 0x00:
        !          20212:                case 0x06:
        !          20213:                case 0x0B:
        !          20214:                        ret = 1;
        !          20215:                        break;
        !          20216:                } /* endswitch */
        !          20217:        }
        !          20218: 
        !          20219: rqs_done:
        !          20220: #if (DEBUG >= 2)
        !          20221: {
        !          20222:        int i;
        !          20223: 
        !          20224:        for (i=0; i<SENSELEN;i++)
        !          20225:                printf("%x ", sense_buf[i]);
        !          20226:        printf("\n");
        !          20227: }
        !          20228: #endif
        !          20229:        return ret;
        !          20230: }
        !          20231: 
        !          20232: /*
        !          20233:  * inquiry()
        !          20234:  *
        !          20235:  * Inquiry command for a device.
        !          20236:  * Find out if device is direct access, removable, etc.
        !          20237:  *
        !          20238:  * Put result of inquiry into supplied buffer.
        !          20239:  * Return 1 if command succeeds, else 0.
        !          20240:  */
        !          20241: static int inquiry(s_id, buf)
        !          20242: int s_id;
        !          20243: uchar * buf;
        !          20244: {
        !          20245:        int ret = 0;
        !          20246:        uchar cmdbuf[G0CMDLEN];
        !          20247: 
        !          20248:        cmdbuf[0] = ScmdINQUIRY;
        !          20249:        cmdbuf[1] = 0;
        !          20250:        cmdbuf[2] = 0;
        !          20251:        cmdbuf[3] = 0;
        !          20252:        cmdbuf[4] = INQUIRYLEN;
        !          20253:        cmdbuf[5] = 0;
        !          20254: 
        !          20255:        if (start_arb() && host_ident(s_id, 0) &&
        !          20256:        local_info_xfer(cmdbuf, G0CMDLEN, buf, INQUIRYLEN, NULL, 0))
        !          20257:                ret = 1;
        !          20258: 
        !          20259:        return ret;
        !          20260: }
        !          20261: 
        !          20262: /*
        !          20263:  * mode_sense()
        !          20264:  *
        !          20265:  * Mode Sense command for a device.
        !          20266:  * Use this to get disk parameters:
        !          20267:  *     number of cylinders
        !          20268:  *     number of heads
        !          20269:  *     number of sectors per track.
        !          20270:  *
        !          20271:  * Put result of mode sense into supplied buffer.
        !          20272:  * Return 1 if command succeeds, else 0.
        !          20273:  */
        !          20274: static int mode_sense(s_id, buf)
        !          20275: int s_id;
        !          20276: uchar * buf;
        !          20277: {
        !          20278:        int ret = 0;
        !          20279:        uchar cmdbuf[G0CMDLEN];
        !          20280: 
        !          20281:        cmdbuf[0] = ScmdMODESENSE;
        !          20282:        cmdbuf[1] = 0;
        !          20283:        cmdbuf[2] = 0x3F;
        !          20284:        cmdbuf[3] = 0;
        !          20285:        cmdbuf[4] = MODESENSELEN;
        !          20286:        cmdbuf[5] = 0;
        !          20287: 
        !          20288:        if (start_arb() && host_ident(s_id, 0) &&
        !          20289:        local_info_xfer(cmdbuf, G0CMDLEN, buf, MODESENSELEN, NULL, 0))
        !          20290:                ret = 1;
        !          20291: 
        !          20292:        return ret;
        !          20293: }
        !          20294: 
        !          20295: /*
        !          20296:  * read_cap()
        !          20297:  *
        !          20298:  * Read Capacity command for a device.
        !          20299:  *
        !          20300:  * Return 1 if command succeeds, else 0.
        !          20301:  */
        !          20302: static int read_cap(s_id, buf)
        !          20303: int s_id;
        !          20304: uchar * buf;
        !          20305: {
        !          20306:        int ret = 0;
        !          20307:        uchar cmdbuf[G1CMDLEN];
        !          20308: 
        !          20309:        cmdbuf[0] = ScmdREADCAPACITY;
        !          20310:        cmdbuf[1] = 0;
        !          20311:        cmdbuf[2] = 0;
        !          20312:        cmdbuf[3] = 0;
        !          20313:        cmdbuf[4] = 0;
        !          20314:        cmdbuf[5] = 0;
        !          20315:        cmdbuf[6] = 0;
        !          20316:        cmdbuf[7] = 0;
        !          20317:        cmdbuf[8] = 0;
        !          20318:        cmdbuf[9] = 0;
        !          20319: 
        !          20320:        if (start_arb() && host_ident(s_id, 0) &&
        !          20321:        local_info_xfer(cmdbuf, G1CMDLEN, buf, READCAPLEN, NULL, 0))
        !          20322:                ret = 1;
        !          20323: 
        !          20324:        return ret;
        !          20325: }
        !          20326: 
        !          20327: /*
        !          20328:  * bus_dev_reset()
        !          20329:  *
        !          20330:  * Send Bus Device Reset message to the given SCSI id.
        !          20331:  * Return 1 if host adapter was not busy and no obvious timeouts occurred,
        !          20332:  * else 0.
        !          20333:  */
        !          20334: static int bus_dev_reset(s_id)
        !          20335: {
        !          20336:        int bdr_ok = 1;
        !          20337:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          20338: 
        !          20339: PR1("BDR");
        !          20340:        if (bdr_ok) {
        !          20341:                /*
        !          20342:                 * Do ST0x arbitration.
        !          20343:                 *
        !          20344:                 * De-assert SCSI enable bit.
        !          20345:                 * Write my SCSI id to port.
        !          20346:                 * Start arbitration.
        !          20347:                 */
        !          20348:                sfbyte(ss_csr, WC_ENABLE_PRTY);
        !          20349:                sfbyte(ss_dat, host_id);
        !          20350:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ARBITRATE);
        !          20351: 
        !          20352:                /*
        !          20353:                 * SCSI spec says there is "no maximum" to the wait for
        !          20354:                 * arbitration complete.
        !          20355:                 */
        !          20356:                if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
        !          20357:                        bdr_ok = 0;
        !          20358:                }
        !          20359:        }
        !          20360: 
        !          20361:        /*
        !          20362:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          20363:         */
        !          20364:        if (bdr_ok) {
        !          20365:                sfbyte(ss_dat, host_id | (1 << s_id));  /* Write both SCSI id's */
        !          20366:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          20367: 
        !          20368:                if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          20369:                        bdr_ok = 0;
        !          20370:        }
        !          20371: 
        !          20372:        if (bdr_ok) {
        !          20373:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION);
        !          20374: 
        !          20375:                if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          20376:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          20377:                        bdr_ok = 0;
        !          20378:        }
        !          20379: 
        !          20380:        if (bdr_ok) {
        !          20381:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          20382:                sfbyte(ss_dat, MSG_DEV_RESET);
        !          20383:                if (!bus_wait((0xFF << 8) | 0))
        !          20384:                        bdr_ok = 0;
        !          20385:        }
        !          20386: 
        !          20387:        return bdr_ok;
        !          20388: }
        !          20389: 
        !          20390: /*
        !          20391:  * chk_reconn()
        !          20392:  *
        !          20393:  * Check SELECT to see if any SCSI device has tried to reconnect to the host
        !          20394:  * adapter.  Called if there is an interrupt, and by the timer in case
        !          20395:  * we somehow lose an interrupt.
        !          20396:  *
        !          20397:  * Return -1 if no reselect detected, or the SCSI ID of the reselecting
        !          20398:  * target if there is one.
        !          20399:  */
        !          20400: static int chk_reconn()
        !          20401: {
        !          20402:        uchar csr, dat;
        !          20403:        int s_id = -1;
        !          20404: 
        !          20405:        csr = ffbyte(ss_csr);
        !          20406:        if (csr & (RS_SELECT | RS_I_O)) {
        !          20407:                dat = ffbyte(ss_dat);
        !          20408:                if ((dat & host_id) && (dat & NSDRIVE)) {
        !          20409:                        dat &= ~host_id;
        !          20410:                        s_id = 0;
        !          20411:                        while (dat >>=1)
        !          20412:                                s_id++;
        !          20413:                }
        !          20414:        }
        !          20415: 
        !          20416:        return s_id;
        !          20417: }
        !          20418: 
        !          20419: /*
        !          20420:  * ss_mach()
        !          20421:  *
        !          20422:  *     Gives a distinct state machine for each target device.
        !          20423:  */
        !          20424: void   ss_mach(s_id)
        !          20425: int s_id;
        !          20426: {
        !          20427:        ss_type * ssp = ss[s_id];
        !          20428:        BUF * bp;
        !          20429: 
        !          20430:        do_sst_op = 1; /* plan to run this routine again in most cases */
        !          20431:        while (do_sst_op) {
        !          20432:                bp = ssp->bp;  /* nonpolled() below can change ssp->bp */
        !          20433:                switch (ssp->state) {
        !          20434:                /*
        !          20435:                 * Polling states execute whether ssp->waiting or not.
        !          20436:                 */
        !          20437:                case SST_POLL_ARBITN:
        !          20438: PR3("XPAR");
        !          20439:                        if (ffbyte(ss_csr) & RS_ARBIT_COMPL) {
        !          20440:                                ssp->waiting = 0;
        !          20441:                                if (host_ident(s_id, 1))
        !          20442:                                        do_connect(s_id);
        !          20443:                                else
        !          20444:                                        recover(s_id, RV_P_TIMEOUT);
        !          20445:                        } else {
        !          20446:                                if (ssp->expired) {
        !          20447:                                        ssp->expired = 0;
        !          20448:                                        recover(s_id, RV_A_TIMEOUT);
        !          20449:                                } else
        !          20450:                                        do_sst_op = 0;
        !          20451:                        }
        !          20452:                        break;
        !          20453:                case SST_POLL_RESELECT:
        !          20454: PR3("XPRS");
        !          20455:                        if (TGT_RSEL) {
        !          20456:                                ssp->waiting = 0;
        !          20457:                                if (host_claimed == -1)
        !          20458:                                        host_claimed = s_id;
        !          20459:                                else if (host_claimed != s_id) {
        !          20460: #if (DEBUG >= 1)
        !          20461:        printf("%d->%d ", host_claimed, s_id);
        !          20462: #endif
        !          20463:                                }
        !          20464:                                if (rsel_handshake()) {
        !          20465:                                        do_connect(s_id);
        !          20466:                                } else {
        !          20467:                                        recover(s_id, RV_P_TIMEOUT);
        !          20468:                                }
        !          20469:                        } else  { /* Reselect poll is negative */
        !          20470:                                if (ssp->expired) {
        !          20471:                                        ssp->expired = 0;
        !          20472:                                        recover(s_id, RV_R_TIMEOUT);
        !          20473:                                } else
        !          20474:                                        do_sst_op = 0;
        !          20475:                        }
        !          20476:                        break;
        !          20477:                case SST_POLL_BEGIN_IO:
        !          20478: PR3("XPBI");
        !          20479:                        if (bp == NULL)
        !          20480:                                ssp->state = SST_DEQUEUE;
        !          20481:                        else {
        !          20482:                                /*
        !          20483:                                 * At this point a SCSI command is about to
        !          20484:                                 * be initiated.  It may be a retry.
        !          20485:                                 */
        !          20486:                                if (host_claimed == -1 && BUS_FREE && BUS_FREE) {
        !          20487:                                        ssp->waiting = 0;
        !          20488:                                        init_pointers(s_id);
        !          20489:                                        if (start_arb()) {
        !          20490:                                                host_claimed = s_id;
        !          20491:                                                if (host_ident(s_id, 1)) {
        !          20492:                                                        do_connect(s_id);
        !          20493:                                                } else {
        !          20494:                                                        recover(s_id, RV_P_TIMEOUT);
        !          20495:                                                }
        !          20496:                                        } else {
        !          20497:        /*
        !          20498:         * If arbitration does not succeed right away, it is usually
        !          20499:         * because another drive is trying to reselect the host.
        !          20500:         */
        !          20501:                                                set_timeout(s_id, DELAY_ARB);
        !          20502:                                        }
        !          20503:                                } else { /* host busy or bus not free */
        !          20504:                                        int o_id;
        !          20505: 
        !          20506:                                        if ((o_id = chk_reconn()) != -1)
        !          20507:                                                defer(dummy_reconn, s_id);
        !          20508:                                        ++ssp->avl_count;
        !          20509:                                        if (ssp->avl_count >= MAX_AVL_COUNT)
        !          20510:                                                recover(s_id, RV_BF_TIMEOUT);
        !          20511:                                        else
        !          20512:                                                set_timeout(s_id, DELAY_BSY);
        !          20513:                                }
        !          20514:                        }
        !          20515:                        break;
        !          20516:                default:
        !          20517:                        if (ssp->waiting)
        !          20518:                                do_sst_op = 0;
        !          20519:                        else {
        !          20520:                                /*
        !          20521:                                 * Nonpolling states execute only if no
        !          20522:                                 * target timer is running.
        !          20523:                                 */
        !          20524:                                nonpolled(s_id);
        !          20525:                        }
        !          20526:                } /* endswitch */
        !          20527:        } /* endwhile */
        !          20528: }
        !          20529: 
        !          20530: /*
        !          20531:  * nonpolled()
        !          20532:  *
        !          20533:  * Part of ss_mach() - handling of nonpolling states is taken out simply
        !          20534:  * for readability.
        !          20535:  */
        !          20536: static void nonpolled(s_id)
        !          20537: int s_id;
        !          20538: {
        !          20539:        ss_type * ssp = ss[s_id];
        !          20540:        BUF * bp = ssp->bp;
        !          20541:        struct  fdisk_s *fdp;
        !          20542:        int partition;
        !          20543:        dev_t dev;
        !          20544: 
        !          20545:        switch (ssp->state) {
        !          20546:        case SST_BUS_DEV_RESET:
        !          20547: PR3("XBDR");
        !          20548:                if (bus_dev_reset(s_id)) {
        !          20549:                        do_sst_op = 0;
        !          20550:                        set_timeout(s_id, DELAY_BDR);
        !          20551:                        ssp->state = SST_REQ_SENSE;
        !          20552:                } else
        !          20553:                        recover(s_id, RV_P_TIMEOUT);
        !          20554:                break;
        !          20555:        case SST_DEQUEUE:
        !          20556:                if(bufq_rd_head(s_id) != NULL && !ssp->busy) {
        !          20557: PR3("XDQU");
        !          20558:                        ssp->busy = 1;
        !          20559:                        bp = bufq_rm_head(s_id);
        !          20560:                        ssp->bp = bp;
        !          20561:                        dev = bp->b_dev;
        !          20562:                        partition = DEV_PARTN(dev);
        !          20563:                        if (dev & SDEV)
        !          20564:                                partition = WHOLE_DRIVE;
        !          20565:                        fdp = ssp->parmp;
        !          20566:                        if (partition != WHOLE_DRIVE)
        !          20567:                                ssp->bno = fdp[partition].p_base + bp->b_bno;
        !          20568:                        else
        !          20569:                                ssp->bno = bp->b_bno;
        !          20570:                        if (bp->b_req == BREAD)
        !          20571:                                ssp->cmdbuf[0] = ScmdREADEXTENDED;
        !          20572:                        else
        !          20573:                                ssp->cmdbuf[0] = ScmdWRITEXTENDED;
        !          20574:                        ssp->cmdbuf[1] = 0;
        !          20575:                        ssp->cmdbuf[2] = ssp->bno >> 24;
        !          20576:                        ssp->cmdbuf[3] = ssp->bno >> 16;
        !          20577:                        ssp->cmdbuf[4] = ssp->bno >>  8;
        !          20578:                        ssp->cmdbuf[5] = ssp->bno;
        !          20579:                        ssp->cmdbuf[6] = 0;
        !          20580:                        ssp->cmdbuf[7] = 0;
        !          20581:                        ssp->cmdbuf[8] = 1;
        !          20582:                        ssp->cmdbuf[9] = 0;
        !          20583:                        ssp->cmdlen = G1CMDLEN;
        !          20584:                        init_pointers(s_id);
        !          20585:                        ssp->bdr_count = 0;
        !          20586:                        ssp->bsy_count = 0;
        !          20587:                        ssp->try_count = 0;
        !          20588:                        ssp->state = SST_POLL_BEGIN_IO;
        !          20589:                } else /* queue is empty or ssp->busy */
        !          20590:                        do_sst_op = 0;
        !          20591:                break;
        !          20592:        case SST_HIPRI_RESET:
        !          20593:        case SST_LOPRI_RESET:
        !          20594: PR1("XRST");
        !          20595:                /*
        !          20596:                 * SST_LOPRI_RESET is same as SST_HIPRI_RESET for now.
        !          20597:                 * Later, can implement a delay to allow other targets to
        !          20598:                 * finish pending operations.
        !          20599:                 */
        !          20600:                if (host_claimed == s_id || host_claimed == -1) {
        !          20601:                        host_claimed = s_id;
        !          20602:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_SCSI_RESET); /* reset ON */
        !          20603:                        ssp->state = SST_RESET_OFF;
        !          20604:                        set_timeout(s_id, DELAY_RST);
        !          20605: PR1("+");
        !          20606:                } else
        !          20607:                        set_timeout(s_id, DELAY_RST);
        !          20608:                break;
        !          20609:        case SST_REQ_SENSE:
        !          20610: PR1("XRQS");
        !          20611:                /*
        !          20612:                 * Come here at end of SCSI Bus reset (and at other times).
        !          20613:                 * If we have host claimed, release it.
        !          20614:                 */
        !          20615:                if (host_claimed == s_id)
        !          20616:                        host_claimed = -1;
        !          20617:                if (req_sense(s_id))
        !          20618:                        ssp->state = SST_POLL_BEGIN_IO;
        !          20619:                else
        !          20620:                        recover(s_id, RV_P_TIMEOUT);
        !          20621:                break;
        !          20622:        case SST_RESET_OFF:
        !          20623: PR3("XRFF");
        !          20624:                sfbyte(ss_csr, WC_ENABLE_PRTY); /* reset OFF */
        !          20625:                ssp->state = SST_REQ_SENSE;
        !          20626:                set_timeout(s_id, DELAY_RST);
        !          20627:        } /* endswitch */
        !          20628: }
        !          20629: 
        !          20630: /*
        !          20631:  * start_arb()
        !          20632:  *
        !          20633:  * return 1 if host adapter returned Arbitration Complete within allotted
        !          20634:  * number of tries, else 0
        !          20635:  */
        !          20636: static int start_arb()
        !          20637: {
        !          20638:        int ret = 0;
        !          20639:        int poll_ct;
        !          20640: 
        !          20641:        sfbyte(ss_csr, WC_ENABLE_PRTY);
        !          20642:        sfbyte(ss_dat, host_id);
        !          20643:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ARBITRATE);
        !          20644: 
        !          20645:        /*
        !          20646:         * SCSI spec says there is "no maximum" to the wait for arbitration
        !          20647:         * complete.
        !          20648:         */
        !          20649:        for (poll_ct = 0; poll_ct < HIPRI_RETRIES; poll_ct++) {
        !          20650:                if (ffbyte(ss_csr) & RS_ARBIT_COMPL) {
        !          20651:                        ret = 1;
        !          20652:                        break;
        !          20653:                } else if (chk_reconn() != -1) {
        !          20654:                        sfbyte(ss_csr, WC_ENABLE_PRTY);
        !          20655:                        break;
        !          20656:                }
        !          20657:        }
        !          20658: #if (DEBUG >= 1)
        !          20659: if (!ret)
        !          20660:        PR1("oSA");
        !          20661: #endif
        !          20662:        return ret;
        !          20663: }
        !          20664: 
        !          20665: /*
        !          20666:  * host_ident()
        !          20667:  *
        !          20668:  * This routine is the bridge in a SCSI bus cycle between Abitration
        !          20669:  * Complete and the Information Transfer phases.
        !          20670:  *
        !          20671:  * return 1 if everything went ok, 0 in case of timeout
        !          20672:  */
        !          20673: static int host_ident(s_id, disconnect)
        !          20674: int s_id;
        !          20675: int disconnect;
        !          20676: {
        !          20677:        int ret = 0;
        !          20678: 
        !          20679:        /*
        !          20680:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          20681:         */
        !          20682:        sfbyte(ss_dat, host_id | (1 << s_id));  /* Write both SCSI id's */
        !          20683:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          20684: 
        !          20685:        if (bus_wait(RS_BUSY << 8 | RS_BUSY)) {
        !          20686:                /*
        !          20687:                 * Assert ATTN so target expects incoming message byte.
        !          20688:                 */
        !          20689:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION);
        !          20690: 
        !          20691:                if (bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          20692:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE))) {
        !          20693:                        if (disconnect)
        !          20694:                                sfbyte(ss_dat, MSG_IDENT_DC);
        !          20695:                        else
        !          20696:                                sfbyte(ss_dat, MSG_IDENTIFY);
        !          20697:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ENABLE_IRPT);
        !          20698:                        ret = 1;
        !          20699:                } else {
        !          20700: PR1("oHI2");
        !          20701:                }
        !          20702:        } else {
        !          20703: PR1("oHI1");
        !          20704:        }
        !          20705:        return ret;
        !          20706: }
        !          20707: 
        !          20708: /*
        !          20709:  * rsel_handshake()
        !          20710:  *
        !          20711:  * After Reselect is detected, a couple steps are needed before entering
        !          20712:  * Information Transfer phases.  This routine does those steps.
        !          20713:  *
        !          20714:  * return 1 if ok, 0 in case of timeout.
        !          20715:  */
        !          20716: static int rsel_handshake()
        !          20717: {
        !          20718:        int ret = 0;
        !          20719: 
        !          20720:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_BUSY);
        !          20721:        if (bus_wait(RS_SELECT << 8 | 0)) {
        !          20722:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          20723:                ret = 1;
        !          20724:        }
        !          20725:        return ret;
        !          20726: }
        !          20727: 
        !          20728: /*
        !          20729:  * set_timeout()
        !          20730:  *
        !          20731:  * Start a timer so as not to wait forever in case something goes wrong while
        !          20732:  * waiting for an event.  Available delays are:
        !          20733:  *
        !          20734:  *     DELAY_ARB -     wait for arbitration complete
        !          20735:  *     DELAY_BDR -     allow settling time after Bus Device Reset
        !          20736:  *     DELAY_BSY -     wait for not HOST_BUSY and bus free
        !          20737:  *     DELAY_RES -     wait for reselect by target
        !          20738:  *     DELAY_RST -     allow settling times when doing SCSI Bus Reset
        !          20739:  *
        !          20740:  * Second argument is number of clock ticks to wait until timer expiration.
        !          20741:  */
        !          20742: static void set_timeout(s_id, delay)
        !          20743: int s_id, delay;
        !          20744: {
        !          20745:        ss_type * ssp = ss[s_id];
        !          20746: 
        !          20747:        ssp->expired = 0;
        !          20748:        ssp->waiting = 1;
        !          20749:        do_sst_op =  0;
        !          20750:        timeout(&(ssp->tim), delay, stop_timeout, s_id);
        !          20751: }
        !          20752: 
        !          20753: /*
        !          20754:  * stop_timeout()
        !          20755:  *
        !          20756:  * Called on expiration of the timer for a given target.
        !          20757:  * Don't expire a timer if it's no longer active.
        !          20758:  */
        !          20759: static void stop_timeout(s_id)
        !          20760: int s_id;
        !          20761: {
        !          20762:        ss_type * ssp = ss[s_id];
        !          20763: 
        !          20764:        if (ssp->waiting) {
        !          20765:                ssp->expired = 1;
        !          20766:                ssp->waiting = 0;
        !          20767:        }
        !          20768:        ss_mach(s_id);
        !          20769: }
        !          20770: 
        !          20771: /*
        !          20772:  * init_pointers()
        !          20773:  *
        !          20774:  * Initialize command and data pointers when starting (or restarting)
        !          20775:  * a block i/o command.
        !          20776:  */
        !          20777: static void init_pointers(s_id)
        !          20778: int s_id;
        !          20779: {
        !          20780:        ss_type * ssp = ss[s_id];
        !          20781:        BUF * bp = ssp->bp;
        !          20782: 
        !          20783:        ssp->cmdstat = -1;
        !          20784:        ssp->cmd_bytes_out = 0;
        !          20785:        ssp->avl_count = 0;
        !          20786: }
        !          20787: 
        !          20788: /*
        !          20789:  * recover()
        !          20790:  *
        !          20791:  * This routine is called directly or indirectly from ss_mach().  It
        !          20792:  * determines what to do when the interface fails to behave as desired.
        !          20793:  *
        !          20794:  * Arguments are the SCSI id of the target HDC and an error type.
        !          20795:  * Error types are:
        !          20796:  *
        !          20797:  * RV_A_TIMEOUT (arbitration timeout)
        !          20798:  * Host adapter takes too long to respond with arbitration complete.
        !          20799:  * 
        !          20800:  * RV_P_TIMEOUT (protocol timeout)
        !          20801:  * Timeout waiting for desired SCSI bus status while connected to a target.
        !          20802:  * 
        !          20803:  * RV_R_TIMEOUT (reconnect timeout)
        !          20804:  * Timeout after target disconnects, waiting for reconnect.
        !          20805:  * 
        !          20806:  * RV_BF_TIMEOUT (bus free timeout)
        !          20807:  * Waited too long for host not busy and BUS_FREE.
        !          20808:  * 
        !          20809:  * RV_CS_BUSY (target device busy)
        !          20810:  * Command status returned was Busy.
        !          20811:  * 
        !          20812:  * RV_CS_CHECK (target device check)
        !          20813:  * Command status returned was CHECK.
        !          20814:  * 
        !          20815:  * Whenever an error occurs, one of the above inputs, together with the SCSI id
        !          20816:  * of the target, is sent to the recovery process.  The recovery process in turn
        !          20817:  * programs the next state for the machine.
        !          20818:  */
        !          20819: static void recover(s_id, errtype)
        !          20820: int s_id;
        !          20821: RV_TYPE errtype;
        !          20822: {
        !          20823:        ss_type * ssp = ss[s_id];
        !          20824:        BUF * bp = ssp->bp;
        !          20825: 
        !          20826: #if (DEBUG >= 1)
        !          20827: int foo;
        !          20828: if ((foo=chk_reconn()) != -1)
        !          20829:        printf("HONK%d ", foo);
        !          20830: #endif
        !          20831: 
        !          20832:        ++ssp->try_count;
        !          20833:        if (ssp->try_count < MAX_TRY_COUNT) {
        !          20834: 
        !          20835:                switch (errtype) {
        !          20836: 
        !          20837:                case RV_CS_BUSY:
        !          20838:                        ++ssp->bsy_count;
        !          20839:                        if (ssp->bsy_count < MAX_BSY_COUNT) {
        !          20840:                                ssp->state = SST_POLL_BEGIN_IO;
        !          20841:                                set_timeout(s_id, DELAY_BSY);
        !          20842:                        } else
        !          20843:                                ssp->state = SST_BUS_DEV_RESET;
        !          20844:                        break;
        !          20845: 
        !          20846:                case RV_CS_CHECK:
        !          20847:                        ssp->state = SST_REQ_SENSE;
        !          20848:                        break;
        !          20849: 
        !          20850:                case RV_P_TIMEOUT:
        !          20851:                        /* fall thru */
        !          20852:                case RV_R_TIMEOUT:
        !          20853:                        ++ssp->bdr_count;
        !          20854:                        if (ssp->bdr_count < MAX_BDR_COUNT)
        !          20855:                                ssp->state = SST_BUS_DEV_RESET;
        !          20856:                        else
        !          20857:                                ssp->state = SST_LOPRI_RESET;
        !          20858:                        break;
        !          20859: 
        !          20860:                case RV_BF_TIMEOUT:
        !          20861:                        /* fall thru */
        !          20862:                case RV_A_TIMEOUT:
        !          20863:                        ssp->state = SST_HIPRI_RESET;
        !          20864:                }
        !          20865:        } else { /* try_count >= MAX_TRY_COUNT */
        !          20866:                if (bp) {
        !          20867:                        bp->b_flag |= BFERR;
        !          20868:                        printf("(%d,%d): ", major(bp->b_dev), minor(bp->b_dev));
        !          20869:                        printf("%s error bno=%ld\n",
        !          20870:                                (bp->b_req == BREAD) ? "read" : "write",
        !          20871:                                bp->b_bno);
        !          20872:                }
        !          20873:                ss_finished(s_id);
        !          20874:        }
        !          20875: }
        !          20876: 
        !          20877: /*
        !          20878:  * ss_finished
        !          20879:  *
        !          20880:  * Release current i/o buffer to the O/S.
        !          20881:  */
        !          20882: static void ss_finished(s_id)
        !          20883: int s_id;
        !          20884: {
        !          20885:        ss_type * ssp = ss[s_id];
        !          20886:        BUF * bp = ssp->bp;
        !          20887:        int go_again = 1;
        !          20888: 
        !          20889:        if (host_claimed == s_id)
        !          20890:                host_claimed = -1;
        !          20891:        ssp->busy = 0;
        !          20892:        if (bp) {
        !          20893:                if (!(bp->b_flag & BFERR))
        !          20894:                        bp->b_resid -= BSIZE;
        !          20895:                if ((bp->b_flag & BFERR) || bp->b_resid == 0) {
        !          20896:                        ssp->bp = NULL;
        !          20897:                        bdone(bp);
        !          20898:                        go_again = 0;
        !          20899:                }
        !          20900:        }
        !          20901:        if (go_again) {
        !          20902:                ssp->state = SST_POLL_BEGIN_IO;
        !          20903:                ssp->bdr_count = 0;
        !          20904:                ssp->bsy_count = 0;
        !          20905:                ssp->try_count = 0;
        !          20906: 
        !          20907:                ssp->bno++;
        !          20908:                ssp->cmdbuf[2] = ssp->bno >> 24;
        !          20909:                ssp->cmdbuf[3] = ssp->bno >> 16;
        !          20910:                ssp->cmdbuf[4] = ssp->bno >>  8;
        !          20911:                ssp->cmdbuf[5] = ssp->bno;
        !          20912:        } else {
        !          20913:                /*
        !          20914:                 * After processing a kernel i/o request, stop the
        !          20915:                 * state machine for the current id.  Then start
        !          20916:                 * this or some other machine which has a request
        !          20917:                 * pending.
        !          20918:                 */
        !          20919:                do_sst_op =  0;
        !          20920:                ssp->state = SST_DEQUEUE;
        !          20921:                next_req(s_id);
        !          20922:        }
        !          20923: }
        !          20924: 
        !          20925: /*
        !          20926:  * next_req()
        !          20927:  *
        !          20928:  * Given the SCSI id where an i/o request just completed, start handling
        !          20929:  * another i/o request - which may be for the same or other SCSI id.
        !          20930:  * For now, use round-robin scheduling.
        !          20931:  */
        !          20932: static void next_req(s_id)
        !          20933: int s_id;
        !          20934: {
        !          20935:        int next_id = s_id;
        !          20936: 
        !          20937:        while (1) {
        !          20938:                next_id++;
        !          20939:                if (next_id >= MAX_SCSI_ID)
        !          20940:                        next_id = 0;
        !          20941:                if (ss[next_id]
        !          20942:                && (ss[next_id]->state != SST_DEQUEUE || bufq_rd_head(next_id))) {
        !          20943:                        defer(ss_mach, next_id);
        !          20944:                        break;
        !          20945:                }
        !          20946:                if (next_id == s_id)
        !          20947:                        break;
        !          20948:        }
        !          20949: }
        !          20950: 
        !          20951: /*
        !          20952:  * do_connect()
        !          20953:  *
        !          20954:  * This function is called when the host is successfully connected to
        !          20955:  * the target.  It invokes information transfer protocol and then sets
        !          20956:  * up some sort of recovery unless the command completed successfully
        !          20957:  * or there was a normal disconnect.
        !          20958:  */
        !          20959: static void do_connect(s_id)
        !          20960: int s_id;
        !          20961: {
        !          20962:        int result;
        !          20963:        ss_type * ssp = ss[s_id];
        !          20964: 
        !          20965:        result = far_info_xfer(s_id);
        !          20966:        if (!result)
        !          20967:                recover(s_id, RV_P_TIMEOUT);
        !          20968:        else if (ssp->msg_in == MSG_DISCONNECT) {
        !          20969:                ssp->state = SST_POLL_RESELECT;
        !          20970:                set_timeout(s_id, DELAY_RES);
        !          20971: #if 0
        !          20972:                if (host_claimed == s_id)
        !          20973:                        host_claimed = -1;
        !          20974: #endif
        !          20975:        } else if (ssp->msg_in == MSG_CMD_CMPLT && ssp->cmdstat == CS_GOOD)
        !          20976:                ss_finished(s_id);
        !          20977:        else if (ssp->cmdstat == CS_BUSY)
        !          20978:                recover(s_id, RV_CS_BUSY);
        !          20979:        else if (ssp->cmdstat == CS_CHECK)
        !          20980:                recover(s_id, RV_CS_CHECK);
        !          20981:        else  /* something else went wrong */
        !          20982:                recover(s_id, RV_P_TIMEOUT);
        !          20983: }
        !          20984: 
        !          20985: /*
        !          20986:  * local_info_xfer()
        !          20987:  *
        !          20988:  * Do bus cycle information transfer phases.
        !          20989:  * Transfer is for a command which will produce local results in the driver.
        !          20990:  * Other ...info_xfer routine handles kernel block i/o commands.
        !          20991:  *
        !          20992:  * Return 1 if transfer succeeded, else 0.
        !          20993:  *
        !          20994:  */
        !          20995: static int local_info_xfer(cmdbuf, cmdlen, inbuf, inlen, outbuf, outlen)
        !          20996: uchar * cmdbuf, * inbuf, * outbuf;
        !          20997: uint cmdlen, inlen, outlen;
        !          20998: {
        !          20999:        int bus_timeout;
        !          21000:        uchar phase_type;
        !          21001:        int s;
        !          21002:        int cmd_bytes_out = 0;
        !          21003:        int data_bytes_in = 0;
        !          21004:        int data_bytes_out = 0;
        !          21005:        int ret = 0;
        !          21006:        int xfer_good = 1;
        !          21007:        int cmdstat = -1;
        !          21008:        int msg_in = -1;
        !          21009: #if (DEBUG >= 1)
        !          21010: int x, xct=0;
        !          21011: uchar xch[100];
        !          21012: #endif
        !          21013: 
        !          21014:        s = sphi();
        !          21015:        while (req_wait(&bus_timeout) && xfer_good) {
        !          21016:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          21017: #if (DEBUG >= 1)
        !          21018: if (xct < 100)
        !          21019:        xch[xct++]=phase_type;
        !          21020: #endif
        !          21021:                switch (xpmod(phase_type)) {
        !          21022:                case XP_MSG_IN:
        !          21023:                        msg_in = ffbyte(ss_dat);
        !          21024:                        switch(msg_in){
        !          21025:                        case MSG_CMD_CMPLT:
        !          21026:                        case MSG_DISCONNECT:
        !          21027:                                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
        !          21028:                                break;
        !          21029:                        }
        !          21030:                        break;
        !          21031:                case XP_MSG_OUT:
        !          21032:                        /*
        !          21033:                         * This case shouldn't happen.  We weren't
        !          21034:                         * asserting ATTENTION.
        !          21035:                         */
        !          21036:                        sfbyte(ss_dat, MSG_NOP); 
        !          21037:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          21038:                        break;
        !          21039:                case XP_STAT_IN:
        !          21040:                        cmdstat = ffbyte(ss_dat);
        !          21041:                        break;
        !          21042:                case XP_CMD_OUT:
        !          21043:                        /*
        !          21044:                         * Ship out command bytes.
        !          21045:                         */
        !          21046:                        if (cmd_bytes_out < cmdlen) {
        !          21047:                                sfbyte(ss_dat, cmdbuf[cmd_bytes_out++]);
        !          21048: #if 1
        !          21049:                                /*
        !          21050:                                 * If just sent last byte, allow interrupts.
        !          21051:                                 */
        !          21052:                                if (cmd_bytes_out == cmdlen) {
        !          21053:                                        spl(s);
        !          21054:                                        s = sphi();
        !          21055:                                }
        !          21056: #endif
        !          21057:                        } else {        /* This case should not happen. */
        !          21058:                                xfer_good = 0;
        !          21059:                        }
        !          21060:                        break;
        !          21061:                case XP_DATA_IN:
        !          21062:                        /*
        !          21063:                         * If caller's buffer has room, keep incoming
        !          21064:                         * data byte.  Else toss it.
        !          21065:                         */
        !          21066:                        if (data_bytes_in < inlen) {
        !          21067: #if 0
        !          21068:                                do {
        !          21069:                                        inbuf[data_bytes_in++] = ffbyte(ss_dat);
        !          21070:                                } while (data_bytes_in < inlen);
        !          21071: #else
        !          21072:                                inbuf[data_bytes_in++] = ffbyte(ss_dat);
        !          21073: #endif
        !          21074:                        } else
        !          21075:                                xfer_good = 0;
        !          21076:                        break;
        !          21077:                case XP_DATA_OUT:
        !          21078:                        /*
        !          21079:                         * Copy output buffer bytes to data register.
        !          21080:                         */
        !          21081:                        if (data_bytes_out < outlen) {
        !          21082:                                sfbyte(outbuf[data_bytes_out++], ss_dat);
        !          21083:                        } else { /* This case should not happen. */
        !          21084:                                xfer_good = 0;
        !          21085:                        }
        !          21086:                        break;
        !          21087:                default:
        !          21088:                        break;
        !          21089:                } /* endswitch */
        !          21090:        }
        !          21091:        spl(s);
        !          21092: 
        !          21093:        if (bus_timeout) {
        !          21094: PR1("oLX1");
        !          21095:        } else if (!xfer_good) {
        !          21096: PR1("oLX2");
        !          21097:        } else if (cmdstat != CS_GOOD) {
        !          21098: PR1("oLX3");
        !          21099: #if (DEBUG >= 1)
        !          21100: printf("cmdstat=%x ", cmdstat);
        !          21101: #endif
        !          21102:        } else
        !          21103:                ret = 1;
        !          21104: #if (DEBUG >= 1)
        !          21105: if (!ret) {
        !          21106:        printf("csr=%x ", ffbyte(ss_csr));
        !          21107:        printf("xct=%d  ", xct);
        !          21108:        for (x=0; x < xct; x++)
        !          21109:                printf("%x ", xch[x]);
        !          21110: }
        !          21111: #endif
        !          21112: 
        !          21113:        return ret;
        !          21114: }
        !          21115: 
        !          21116: /*
        !          21117:  * scsireset()
        !          21118:  *
        !          21119:  * Reset the SCSI bus.
        !          21120:  * Allow settling time when turning reset on/off.
        !          21121:  * Settling times were determined empirically.
        !          21122:  * Each tick is 10 msec.
        !          21123:  */
        !          21124: static void scsireset()
        !          21125: {
        !          21126:        int s;
        !          21127: 
        !          21128: #if (DEBUG >= 1)
        !          21129: printf("scsireset ");
        !          21130: #endif
        !          21131:        s = splo();
        !          21132:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          21133:        ssdelay(RESET_TICKS);
        !          21134:        sfbyte(ss_csr, WC_ENABLE_PRTY);
        !          21135:        ssdelay(RESET_TICKS);
        !          21136:        spl(s);
        !          21137: }
        !          21138: 
        !          21139: /*
        !          21140:  * ssdelay()
        !          21141:  *
        !          21142:  * Delay for some number of arbitrary ticks.
        !          21143:  *
        !          21144:  * Using sleep() causes a panic if this driver is linked to the kernel,
        !          21145:  * even though this routine is called only via ssload().
        !          21146:  */
        !          21147: static void ssdelay(ticks)
        !          21148: int ticks;
        !          21149: {
        !          21150: #if 0
        !          21151:        timeout(&delay_tim, ticks, wakeup, (int)&delay_tim);
        !          21152:        sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
        !          21153: #else
        !          21154:        int i, j;
        !          21155: 
        !          21156:        for (i = 0; i < ticks; i++)
        !          21157:                for (j = 0; j < LOAD_DELAY; j++);
        !          21158: #endif
        !          21159: }
        !          21160: 
        !          21161: /*
        !          21162:  * init_call()
        !          21163:  *
        !          21164:  * Call SCSI command function during initialization, with error recovery.
        !          21165:  * If the simple command fails, try a Bus Device Reset, then SCSI Bus reset.
        !          21166:  */
        !          21167: static int init_call(fn, s_id, buf)
        !          21168: int (*fn)();
        !          21169: int s_id;
        !          21170: uchar * buf;
        !          21171: {
        !          21172:        int ret = 1;
        !          21173:        int i;
        !          21174:        int o_id;
        !          21175: int s;
        !          21176: s=sphi();
        !          21177:        for (i = 0; i < 2; i++) {
        !          21178:                o_id = chk_reconn();
        !          21179:                if (o_id != -1)
        !          21180:                        dummy_reconn(s_id);
        !          21181:                if ((*fn)(s_id, buf))
        !          21182:                        goto init_call_done;
        !          21183: 
        !          21184:                req_sense(s_id);
        !          21185:                if ((*fn)(s_id, buf))
        !          21186:                        goto init_call_done;
        !          21187: 
        !          21188:                if (bus_dev_reset(s_id)) {
        !          21189:                        ssdelay(RESET_TICKS);
        !          21190:                        req_sense(s_id);
        !          21191:                        if ((*fn)(s_id, buf))
        !          21192:                                goto init_call_done;
        !          21193:                }
        !          21194: 
        !          21195:                scsireset();
        !          21196:                req_sense(s_id);
        !          21197:                if ((*fn)(s_id, buf))
        !          21198:                        goto init_call_done;
        !          21199:        }
        !          21200: 
        !          21201:        ret = 0;
        !          21202: 
        !          21203: init_call_done:
        !          21204: spl(s);
        !          21205:        return ret;
        !          21206: }
        !          21207: 
        !          21208: /*
        !          21209:  * xpmod()
        !          21210:  *
        !          21211:  * Command/Data and Message bits are swapped on-board (outside the chip)
        !          21212:  * on older Future Domain host boards.
        !          21213:  */
        !          21214: static uchar xpmod(oldphase)
        !          21215: uchar oldphase;
        !          21216: {
        !          21217:        uchar ret = oldphase;
        !          21218: 
        !          21219:        if (swap_status_bits) {
        !          21220:                ret &= ~(RS_CTRL_DATA | RS_MESSAGE);
        !          21221:                if (oldphase & RS_MESSAGE)
        !          21222:                        ret |= RS_CTRL_DATA;
        !          21223:                if (oldphase & RS_CTRL_DATA)
        !          21224:                        ret |= RS_MESSAGE;
        !          21225:        }
        !          21226:        return ret;
        !          21227: } 
        !          21228: 0707070064030150071006440000030000030000011777770507310643700005000000010222/newbits/kernel/USRSRC/i8086/drv/ssas.s////////
        !          21229: /
        !          21230: / I/O for Seagate ST01/ST02 SCSI Host Adapters.
        !          21231: /
        !          21232: / $Log:        ssas.s,v $
        !          21233: / Revision 1.7  91/06/01  10:51:00  hal
        !          21234: / Add ffcopy().
        !          21235: / 
        !          21236: / Revision 1.6  91/06/01  10:32:51  hal
        !          21237: / Do handshaking both ways.  Now names are ss_getb()/ss_putb().
        !          21238: / 
        !          21239: / Revision 1.5 91/05/20  17:22:03      root
        !          21240: / Not using ss_put() any more.
        !          21241: / 
        !          21242: / Revision 1.4 91/05/20  16:21:35      root
        !          21243: / Call to ss_putc() now works.
        !          21244: / 
        !          21245: / Revision 1.3 91/05/20  10:23:13      root
        !          21246: / Drop 3rd arg.  Same code for Seagate & Future Domain.
        !          21247: / 
        !          21248: / Revision 1.2 91/05/17  00:24:17      root
        !          21249: / Code ss_put - use REQ handshake.
        !          21250: / 
        !          21251: / Revision 1.1 91/05/16  14:16:21      root
        !          21252: / Initial version - no code yet for ss_put().
        !          21253: / 
        !          21254: /
        !          21255: /      Since these functions are called from the midst of C code in
        !          21256: /      the "ss" driver, they need to preserve the following registers:
        !          21257: /              SI  DI  SP  BP    SS  DS  ES
        !          21258: /      Additionally, surrounding C code is expected to leave the "D"
        !          21259: /      CPU flag clear (string op's increment index registers).
        !          21260: /
        !          21261: ////////
        !          21262: 
        !          21263: ////////
        !          21264: /
        !          21265: /      Export functions.
        !          21266: /
        !          21267: ////////
        !          21268:        .globl  ss_getb_
        !          21269:        .globl  ss_putb_
        !          21270:        .globl  ffcopy_
        !          21271: 
        !          21272: ////////
        !          21273: /
        !          21274: / Constants
        !          21275: /
        !          21276: /      Relative to the RAM base address of the host adapter, offsets
        !          21277: /      for Control/Status Register (CSR) and Data Port (DAT) differ
        !          21278: /      between Seagate and Future Domain as follows:
        !          21279: /                      Seagate         Future Domain
        !          21280: /              SS_CSR  0x1A00          0x1C00
        !          21281: /              SS_DAT  0x1C00          0x1E00
        !          21282: /      The difference between these (CSR_OFF) is 0x200 in either case.
        !          21283: /
        !          21284: ////////
        !          21285: 
        !          21286:        BSIZE   = 0x200         / Disk block size in bytes
        !          21287:        CSR_OFF = 0x200
        !          21288: 
        !          21289:        REQ_LIM = 500
        !          21290:        RS_REQUEST = 0x10
        !          21291: 
        !          21292: ////////
        !          21293: /
        !          21294: / ss_getb(ss_dat_fp, buf_fp)
        !          21295: / faddr_t ss_dat_fp, buf_fp;
        !          21296: /
        !          21297: / Fetch input bytes from host adapter and store at buffer address.
        !          21298: /
        !          21299: / Do REQ handshaking and return the number of bytes remaining to transfer.
        !          21300: / (So return value of 0 means no error.)
        !          21301: /
        !          21302: / Here is the stack after initial "push bp":
        !          21303: /
        !          21304: /      10(bp)  FP_SEL(buf_fp)
        !          21305: /      8(bp)   FP_OFF(buf_fp)
        !          21306: /      6(bp)   FP_SEL(ss_dat_fp)
        !          21307: /      4(bp)   FP_OFF(ss_dat_fp)
        !          21308: /      2(bp)   return IP
        !          21309: /      0(bp)   old bp
        !          21310: /
        !          21311: ////////
        !          21312: 
        !          21313: ss_getb_:
        !          21314:        push    bp
        !          21315:        mov     bp, sp
        !          21316:        push    es
        !          21317:        push    di
        !          21318:        push    ds
        !          21319:        push    si
        !          21320: 
        !          21321:        lds     si, 4(bp)       / ss_dat_fp to DS:SI
        !          21322:        mov     bx, si          / .. and to DS:BX
        !          21323:        sub     bx, $CSR_OFF    / ss_csr to DS:BX
        !          21324:        les     di, 8(bp)       / buf_fp to ES:DI
        !          21325:        mov     cx, $BSIZE      / rep count to CX
        !          21326: 
        !          21327: G01:                           / start outer loop - reading bytes from SCSI
        !          21328:        mov     ax, $REQ_LIM    / max # of times to look for REQ
        !          21329: G02:                           / start inner loop - polling for REQ
        !          21330:        movb    dl, (bx)
        !          21331:        testb   dl, $RS_REQUEST
        !          21332:        jne     G03             / got REQ
        !          21333:        dec     ax
        !          21334:        jnz     G02             / no REQ - look again
        !          21335:        jmp     G04             / no REQ - give up
        !          21336: 
        !          21337: G03:                           / got REQ - ok to read a byte
        !          21338:        movsb
        !          21339:        loop    G01
        !          21340: G04:                           / all done
        !          21341:        mov     ax, cx          / normal exit returns 0
        !          21342: 
        !          21343:        pop     si
        !          21344:        pop     ds
        !          21345:        pop     di
        !          21346:        pop     es
        !          21347:        pop     bp
        !          21348:        ret
        !          21349: 
        !          21350: ////////
        !          21351: /
        !          21352: / int ss_putb(ss_dat_fp, buf_fp)
        !          21353: / faddr_t ss_dat_fp, buf_fp;
        !          21354: /
        !          21355: / Write output bytes to host adapter from buffer address.
        !          21356: /
        !          21357: / Return the number of bytes remaining to be sent (should be 0).
        !          21358: /
        !          21359: / Here is the stack after initial "push bp":
        !          21360: /
        !          21361: /      10(bp)  FP_SEL(buf_fp)
        !          21362: /      8(bp)   FP_OFF(buf_fp)
        !          21363: /      6(bp)   FP_SEL(ss_dat_fp)
        !          21364: /      4(bp)   FP_OFF(ss_dat_fp)
        !          21365: /      2(bp)   return IP
        !          21366: /      0(bp)   old bp
        !          21367: /
        !          21368: ////////
        !          21369: 
        !          21370: ss_putb_:
        !          21371:        push    bp
        !          21372:        mov     bp, sp
        !          21373:        push    es
        !          21374:        push    di
        !          21375:        push    ds
        !          21376:        push    si 
        !          21377:        lds     si, 8(bp)       / buf_fp to DS:SI
        !          21378:        les     di, 4(bp)       / ss_dat_fp  to ES:DI
        !          21379:        mov     bx, di          / .. and to ES:BX
        !          21380:        sub     bx, $CSR_OFF    / ss_csr to ES:BX
        !          21381:        mov     cx, $BSIZE      / count to CX
        !          21382: 
        !          21383: P01:                           / start outer loop - writing bytes to SCSI
        !          21384:        mov     ax, $REQ_LIM    / max # of times to look for REQ
        !          21385: P02:                           / start inner loop - polling for REQ
        !          21386:        movb    dl, es:(bx)
        !          21387:        testb   dl, $RS_REQUEST
        !          21388:        jne     P03             / got REQ
        !          21389:        dec     ax
        !          21390:        jnz     P02             / no REQ - look again
        !          21391:        jmp     P04             / no REQ - give up
        !          21392: 
        !          21393: P03:                           / got REQ - ok to write a byte
        !          21394:        movsb
        !          21395:        loop    P01
        !          21396: P04:                           / all done - now restore registers
        !          21397:        mov     ax, cx
        !          21398:        pop     si
        !          21399:        pop     ds
        !          21400:        pop     di
        !          21401:        pop     es
        !          21402:        pop     bp
        !          21403:        ret
        !          21404: 
        !          21405: ////////
        !          21406: /
        !          21407: / void ffcopy(from_fp, to_fp, count)
        !          21408: / faddr_t from_fp, to_fp;
        !          21409: / int count;
        !          21410: /
        !          21411: / Copy count bytes from from_fp to to_fp.
        !          21412: /
        !          21413: / Here is the stack after initial "push bp":
        !          21414: /
        !          21415: /      12(bp)  count
        !          21416: /      10(bp)  FP_SEL(to_fp)
        !          21417: /      8(bp)   FP_OFF(to_fp)
        !          21418: /      6(bp)   FP_SEL(from_fp)
        !          21419: /      4(bp)   FP_OFF(from_fp)
        !          21420: /      2(bp)   return IP
        !          21421: /      0(bp)   old bp
        !          21422: /
        !          21423: ////////
        !          21424: 
        !          21425: ffcopy_:
        !          21426:        push    bp
        !          21427:        mov     bp, sp
        !          21428:        push    es
        !          21429:        push    di
        !          21430:        push    ds
        !          21431:        push    si
        !          21432: 
        !          21433:        lds     si, 4(bp)       / from_fp  to DS:SI
        !          21434:        les     di, 8(bp)       / to_fp to ES:DI
        !          21435:        mov     cx, 12(bp)      / rep count to CX
        !          21436:        rep
        !          21437:        movsb
        !          21438: 
        !          21439:        pop     si
        !          21440:        pop     ds
        !          21441:        pop     di
        !          21442:        pop     es
        !          21443:        pop     bp
        !          21444:        ret
        !          21445: 0707070064030150101004440000030000030000011777770507310644000004600000055161/newbits/kernel/USRSRC/i8086/drv/st.c/* (-lgl
        !          21446:  *     COHERENT Driver Kit Version 1.1.0
        !          21447:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          21448:  *     All rights reserved. May not be copied without permission.
        !          21449:  -lgl) */
        !          21450: /*
        !          21451:  * This is a driver for the
        !          21452:  * Archive SC-400 Series Tape Controller.
        !          21453:  */
        !          21454: #include       <sys/coherent.h>
        !          21455: #include       <sys/buf.h>
        !          21456: #include       <sys/con.h>
        !          21457: #include       <sys/const.h>
        !          21458: #include       <sys/devices.h>
        !          21459: #include       <sys/inode.h>
        !          21460: #include       <sys/mtioctl.h>
        !          21461: #include       <sys/sched.h>
        !          21462: #include       <sys/seg.h>
        !          21463: #include       <sys/stat.h>
        !          21464: #include       <sys/uproc.h>
        !          21465: #include       <errno.h>
        !          21466: 
        !          21467: /*
        !          21468:  * Fixed parameters.
        !          21469:  */
        !          21470: #define        NCMDS   8                       /* Max # chained commands */
        !          21471: 
        !          21472: /*
        !          21473:  * Configurable parameters
        !          21474:  */
        !          21475: int    STIRQ   = 3;                    /* IRQ Level 3 */
        !          21476: int    STPORT  = 0x200;                /* I/O Port    */
        !          21477: int    STDMA   = 1;                    /* DMA Channel */
        !          21478: 
        !          21479: #define        BIT(n)          (1 << (n))
        !          21480: 
        !          21481: /*
        !          21482:  * Forward referenced functions.
        !          21483:  */
        !          21484: void   stcache();
        !          21485: void   stflush();
        !          21486: void   stinvoke();
        !          21487: void   ststart();
        !          21488: void   stintr();
        !          21489: void   strecov();
        !          21490: void   stnext();
        !          21491: void   stdiag();
        !          21492: void   stspin();
        !          21493: 
        !          21494: /*
        !          21495:  * Driver configuration.
        !          21496:  */
        !          21497: int    stload();
        !          21498: int    stuload();
        !          21499: int    stopen();
        !          21500: int    stclose();
        !          21501: int    stread();
        !          21502: int    stwrite();
        !          21503: int    stioctl();
        !          21504: void   stwatch();
        !          21505: int    nulldev();
        !          21506: int    nonedev();
        !          21507: 
        !          21508: CON    stcon   = {
        !          21509:        DFCHR,                          /* Flags        */
        !          21510:        ST_MAJOR,                               /* Major index  */
        !          21511:        stopen,                         /* Open         */
        !          21512:        stclose,                        /* Close        */
        !          21513:        nonedev,                        /* Block        */
        !          21514:        stread,                         /* Read         */
        !          21515:        stwrite,                        /* Write        */
        !          21516:        stioctl,                        /* Ioctl        */
        !          21517:        nulldev,                        /* Powerfail    */
        !          21518:        stwatch,                        /* Timeout      */
        !          21519:        stload,                         /* Load         */
        !          21520:        stuload                         /* Unload       */
        !          21521: };
        !          21522: 
        !          21523: /*
        !          21524:  * I/O Port Addresses
        !          21525:  */
        !          21526: #define        DATA_REG        (STPORT+0)      /* Data register */
        !          21527: #define        CTRL_REG        (STPORT+1)      /* Control/Status register */
        !          21528: #define        DMAGO_REG       (STPORT+2)      /* DMA Go register */
        !          21529: #define        DMARST_REG      (STPORT+3)      /* DMA reset register */
        !          21530: 
        !          21531: /*
        !          21532:  * Control Register
        !          21533:  */
        !          21534: #define        CR_RSTSAC       BIT(7)          /* 1 -> reset control micro     */
        !          21535: #define        CR_REQ          BIT(6)          /* 1 -> request to LSI chip     */
        !          21536: #define        CR_IEN          BIT(5)          /* 1 -> enables interrupts      */
        !          21537: #define        CR_DNIEN        BIT(4)          /* 1 -> enable DONE interrupts  */
        !          21538: 
        !          21539: /*
        !          21540:  * Status Register
        !          21541:  */
        !          21542: #define        SR_IRQF         BIT(7)          /* 1 -> Interrupt Request Flag  */
        !          21543: #define        SR_NRDY         BIT(6)          /* 0 -> Ready                   */
        !          21544: #define        SR_NEXC         BIT(5)          /* 0 -> Exception               */
        !          21545: #define        SR_DONE         BIT(4)          /* 1 -> DMA Done                */
        !          21546: #define        SR_TO_PC        BIT(3)          /* 1 -> Direction is to PC      */
        !          21547: 
        !          21548: /*
        !          21549:  * Controller Commands.
        !          21550:  */
        !          21551: #define        CC_SELECT       0x01            /* Select Drive 0               */
        !          21552: #define        CC_LOCK         0x11            /* Select Drive 0 and Lock      */
        !          21553: #define        CC_BOT          0x21            /* Rewind to beginning of tape  */
        !          21554: #define        CC_ERASE        0x22            /* Completely erase cartridge   */
        !          21555: #define        CC_TENSION      0x24            /* Wind tape to BOT, EOT, BOT   */
        !          21556: #define        CC_AUTO         0x25            /* Select auto-initialization   */
        !          21557: #define        CC_QIC11        0x26            /* Select QIC-11 media format   */
        !          21558: #define        CC_QIC24        0x27            /* Select QIC-24 media format   */
        !          21559: #define        CC_WRITE        0x40            /* Write to tape                */
        !          21560: #define        CC_WFM          0x60            /* Write file mark              */
        !          21561: #define        CC_READ         0x80            /* Read from tape               */
        !          21562: #define        CC_RFM          0xA0            /* Skip past next file mark     */
        !          21563: #define        CC_SENSE        0xC0            /* Read controller status       */
        !          21564: 
        !          21565: /*
        !          21566:  * Sense Status Bytes 0 and 1.
        !          21567:  */
        !          21568: #define        SS0_FIL         BIT(0)          /* File Mark Detected           */
        !          21569: #define        SS0_BNL         BIT(1)          /* Bad Block Not located        */
        !          21570: #define        SS0_UDA         BIT(2)          /* Unrecoverable data error     */
        !          21571: #define        SS0_EOM         BIT(3)          /* End of media                 */
        !          21572: #define        SS0_WRP         BIT(4)          /* Write Protected Cartridge    */
        !          21573: #define        SS0_USL         BIT(5)          /* Unselected Drive             */
        !          21574: #define        SS0_CNI         BIT(6)          /* Cartridge Not In Place       */
        !          21575: #define        SS0_ERR         (SS0_BNL+SS0_UDA+SS0_USL+SS0_CNI)
        !          21576: 
        !          21577: #define        SS1_POR         BIT(0)          /* Power on Reset Occurred      */
        !          21578: #define        SS1_BOM         BIT(3)          /* Beginning of media           */
        !          21579: #define        SS1_MBD         BIT(4)          /* Marginal Block Detected      */
        !          21580: #define        SS1_NDT         BIT(5)          /* No Data Detected             */
        !          21581: #define        SS1_ILL         BIT(6)          /* Illegal Command              */
        !          21582: #define        SS1_ERR         (SS1_NDT+SS1_ILL)
        !          21583: 
        !          21584: /*
        !          21585:  * Device States.
        !          21586:  */
        !          21587: #define        SDEAD   0               /* controller not found    */
        !          21588: #define        SIDLE   1               /* controller idle         */
        !          21589: #define        SCMD    2               /* initiating command      */
        !          21590: #define        SRUN    3               /* performing command      */
        !          21591: #define        SRDWR   4               /* starting read/write     */
        !          21592: #define        SBLOCK  5               /* performing read/write   */
        !          21593: #define        SBLEND  6               /* concluding block i/o    */
        !          21594: #define        SSENSE  7               /* reading status bytes    */
        !          21595: #define        SSDONE  8               /* concluding status sense */
        !          21596: 
        !          21597: /*
        !          21598:  * Driver State Information.
        !          21599:  */
        !          21600: struct st_s {
        !          21601:        int     st_state;
        !          21602:        int     st_mode;                /* IPR or IPW                   */
        !          21603:        int     st_iocmd;               /* CC_READ or CC_WRITE          */
        !          21604:        int     st_cmd;                 /* last command executed        */
        !          21605:        int     st_cmds[NCMDS];         /* list of chained commands     */
        !          21606:        int     st_ncmds;               /* num of chained commands      */
        !          21607:        int     st_iswr;
        !          21608:        int     st_wasio;
        !          21609:        int     st_iseof;
        !          21610:        int     st_error;
        !          21611:        paddr_t st_paddr;
        !          21612:        fsize_t st_resid;
        !          21613:        fsize_t st_size;
        !          21614:        saddr_t st_sel;
        !          21615:        SEG *   st_seg;
        !          21616:        char    st_status[6];
        !          21617:        int     st_nstat;
        !          21618:        int     st_rdys;                /* number of ready watchdogs    */
        !          21619:        int     st_nlost;               /* number of lost interrupts    */
        !          21620: } st;
        !          21621: 
        !          21622: /**
        !          21623:  *
        !          21624:  * void
        !          21625:  * stload()            -- initialize tape device
        !          21626:  *
        !          21627:  *     Action: Reset tape controller and drive.
        !          21628:  *             Seize tape interrupt vector.
        !          21629:  *
        !          21630:  *     Note:   If the tape controller is present and operational,
        !          21631:  *             a interrupt will occur and set st.st_state to SIDLE.
        !          21632:  */
        !          21633: static
        !          21634: stload()
        !          21635: {
        !          21636:        /*
        !          21637:         * Paranoia - Turn off DMA.
        !          21638:         * Should already be turned off.
        !          21639:         */
        !          21640:        dmaoff( STDMA );
        !          21641: 
        !          21642:        /*
        !          21643:         * Reset tape controller and drive
        !          21644:         */
        !          21645:        outb( CTRL_REG, CR_RSTSAC );
        !          21646: 
        !          21647:        /*
        !          21648:         * Wait at least 25 microseconds
        !          21649:         */
        !          21650:        stspin( 25 );
        !          21651: 
        !          21652:        /*
        !          21653:         * Terminate reset condition
        !          21654:         */
        !          21655:        outb( CTRL_REG, CR_IEN );
        !          21656: 
        !          21657:        /*
        !          21658:         * Seize tape interrupt vector.
        !          21659:         */
        !          21660:        setivec( STIRQ, &stintr );
        !          21661: }
        !          21662: 
        !          21663: /**
        !          21664:  *
        !          21665:  * stuload( dev )              -- Unload tape device.
        !          21666:  * dev_t dev;
        !          21667:  */
        !          21668: stuload( dev )
        !          21669: dev_t dev;
        !          21670: {
        !          21671:        /*
        !          21672:         * Turn off DMA.
        !          21673:         */
        !          21674:        dmaoff( STDMA );
        !          21675: 
        !          21676:        /*
        !          21677:         * Release tape interrupt vector.
        !          21678:         */
        !          21679:        clrivec( STIRQ );
        !          21680: 
        !          21681:        /*
        !          21682:         * Disable tape interrupts.
        !          21683:         */
        !          21684:        outb( CTRL_REG, 0 );
        !          21685: }
        !          21686: 
        !          21687: /**
        !          21688:  *
        !          21689:  * stopen( dev, mode )         -- open tape device
        !          21690:  * dev_t dev;
        !          21691:  * int mode;
        !          21692:  *
        !          21693:  *     Input:  dev  = tape device to be opened.
        !          21694:  *             mode = desired access mode.
        !          21695:  *
        !          21696:  *     Action: Refuse access if tape drive does not exist or is in use.
        !          21697:  *             Refuse simultaneous read and write access.
        !          21698:  *             Refuse access if cartridge is not inserted in tape drive.
        !          21699:  *             Refuse write access to a write protected cartridge.
        !          21700:  *             Allocate tape cache.
        !          21701:  *             Initialize device state.
        !          21702:  *             Lock tape cartridge.
        !          21703:  */
        !          21704: static
        !          21705: stopen( dev, mode )
        !          21706: register dev_t dev;
        !          21707: register int   mode;
        !          21708: {
        !          21709:        int s;
        !          21710: 
        !          21711:        /*
        !          21712:         * Refuse access if no tape drive.
        !          21713:         */
        !          21714:        if ( st.st_state == SDEAD ) {
        !          21715:                u.u_error = ENXIO;
        !          21716:                return;
        !          21717:        }
        !          21718: 
        !          21719:        /*
        !          21720:         * Refuse access if tape drive is already open.
        !          21721:         */
        !          21722:        if ( st.st_mode != 0 ) {
        !          21723:                u.u_error = EDBUSY;
        !          21724:                return;
        !          21725:        }
        !          21726: 
        !          21727:        /*
        !          21728:         * Access must be read-only or write-only.
        !          21729:         */
        !          21730:        if ( (mode != IPR) && (mode != IPW) ) {
        !          21731:                u.u_error = EINVAL;
        !          21732:                return;
        !          21733:        }
        !          21734: 
        !          21735:        /*
        !          21736:         * Wait for tape drive to become idle.
        !          21737:         */
        !          21738:        if ( stwait() < 0 ) {
        !          21739:                u.u_error = EINTR;
        !          21740:                return;
        !          21741:        }
        !          21742: 
        !          21743:        /*
        !          21744:         * Initialize tape interface.
        !          21745:         */
        !          21746:        s = sphi();
        !          21747:        outb( DMARST_REG, 0 );
        !          21748:        outb( CTRL_REG, CR_IEN );
        !          21749:        spl( s );
        !          21750: 
        !          21751:        /*
        !          21752:         * Obtain tape status.
        !          21753:         */
        !          21754:        stinvoke( CC_SENSE );
        !          21755: 
        !          21756:        /*
        !          21757:         * Wait for tape status.
        !          21758:         */
        !          21759:        if ( stwait() < 0 ) {
        !          21760:                u.u_error = EINTR;
        !          21761:                return;
        !          21762:        }
        !          21763: 
        !          21764:        /*
        !          21765:         * Refuse access if no cartridge.
        !          21766:         */
        !          21767:        if ( st.st_status[0] & (SS0_CNI|SS0_USL) ) {
        !          21768:                u.u_error = EDATTN;
        !          21769:                return;
        !          21770:        }
        !          21771: 
        !          21772:        /*
        !          21773:         * Refuse write access to a write protected cartridge.
        !          21774:         */
        !          21775:        if ( (mode == IPW) && (st.st_status[0] & SS0_WRP) ) {
        !          21776:                u.u_error = EROFS;
        !          21777:                return;
        !          21778:        }
        !          21779: 
        !          21780:        /*
        !          21781:         * Calculate desired cache size in Kbytes.
        !          21782:         */
        !          21783:        st.st_size = minor(dev) & ~0x80;
        !          21784:        if ( st.st_size == 0 )
        !          21785:                st.st_size = 256;
        !          21786: 
        !          21787:        /*
        !          21788:         * Allocate cache
        !          21789:         */
        !          21790:        for ( st.st_size *= 1024; st.st_size != 0; st.st_size -= 1024 )
        !          21791:                if ( st.st_seg = salloc( st.st_size, SFSYST|SFNSWP|SFNCLR ) )
        !          21792:                        break;
        !          21793: 
        !          21794:        /*
        !          21795:         * Refuse access if couldn't allocate cache.
        !          21796:         */
        !          21797:        if ( st.st_seg == 0 ) {
        !          21798:                u.u_error = ENOMEM;
        !          21799:                return;
        !          21800:        };
        !          21801: 
        !          21802:        /*
        !          21803:         * Initialize device state.
        !          21804:         */
        !          21805:        st.st_sel   = FP_SEL(st.st_seg->s_faddr);
        !          21806:        st.st_iswr  = (mode == IPW);
        !          21807:        st.st_paddr = st.st_seg->s_paddr;
        !          21808:        st.st_resid = (mode == IPW) ? st.st_size : 0 ;
        !          21809:        st.st_iocmd = (mode == IPW) ? CC_WRITE : CC_READ ;
        !          21810:        st.st_mode  = mode;
        !          21811:        st.st_iseof = 0;
        !          21812:        st.st_wasio = 0;
        !          21813:        st.st_error = 0;
        !          21814:        st.st_rdys  = 0;
        !          21815:        st.st_nlost = 0;
        !          21816: 
        !          21817:        /*
        !          21818:         * Lock cartridge if at beginning of media.
        !          21819:         */
        !          21820:        if ( st.st_status[1] & SS1_BOM )
        !          21821:                stinvoke( CC_LOCK );
        !          21822: }
        !          21823: 
        !          21824: /**
        !          21825:  *
        !          21826:  * stclose( dev, mode )                -- close tape device
        !          21827:  * dev_t dev;
        !          21828:  * int mode;
        !          21829:  *
        !          21830:  *     Input:  dev  = tape device to be closed.
        !          21831:  *             mode = access mode.
        !          21832:  *
        !          21833:  *     Action: If access mode was for writing, flush the tape cache.
        !          21834:  *             If data was written to tape, write a file mark.
        !          21835:  *             If data was read from tape on the non rewinding device,
        !          21836:  *             read until end of file or an error is encountered.
        !          21837:  *             Rewind the tape if the rewinding device is open.
        !          21838:  *             Unlock the tape cartridge.
        !          21839:  *             Clear tape state and release tape cache memory.
        !          21840:  */
        !          21841: static
        !          21842: stclose( dev, mode )
        !          21843: register dev_t dev;
        !          21844: {
        !          21845:        /*
        !          21846:         * Check if tape was opened for writing.
        !          21847:         */
        !          21848:        if ( st.st_iswr ) {
        !          21849: 
        !          21850:                /*
        !          21851:                 * Flush the tape cache.
        !          21852:                 */
        !          21853:                stflush();
        !          21854: 
        !          21855:                /*
        !          21856:                 * Write a file mark if data was written to tape.
        !          21857:                 */
        !          21858:                if ( st.st_wasio )
        !          21859:                        stinvoke( CC_WFM );
        !          21860:        }
        !          21861: 
        !          21862:        /*
        !          21863:         * Check if non-rewinding device was opened for reading.
        !          21864:         */
        !          21865:        else if ( st.st_wasio && (dev & 0x80 ) ) {
        !          21866: 
        !          21867:                /*
        !          21868:                 * Read file mark if not just past one.
        !          21869:                 */
        !          21870:                if ( (st.st_status[0] & SS0_FIL) == 0 )
        !          21871:                        stinvoke( CC_RFM );
        !          21872:        }
        !          21873: 
        !          21874:        /*
        !          21875:         * Rewinding device.
        !          21876:         */
        !          21877:        if ( (dev & 0x80) == 0 ) {
        !          21878: 
        !          21879:                /*
        !          21880:                 * Wait for controller to idle.
        !          21881:                 */
        !          21882:                while ( stwait() < 0 )
        !          21883:                        ;
        !          21884: 
        !          21885:                /*
        !          21886:                 * Initiate rewind.
        !          21887:                 */
        !          21888:                stinvoke( CC_BOT   );
        !          21889: 
        !          21890:                /*
        !          21891:                 * Unlock the drive [turn off the light].
        !          21892:                 */
        !          21893:                stinvoke( CC_SELECT );
        !          21894:        }
        !          21895: 
        !          21896:        /*
        !          21897:         * Clear tape state, releasing tape cache.
        !          21898:         */
        !          21899:        sfree( st.st_seg );
        !          21900:        st.st_seg  = 0;
        !          21901:        st.st_mode = 0;
        !          21902: }
        !          21903: 
        !          21904: /**
        !          21905:  *
        !          21906:  * stread( dev, iop )  -- tape device read
        !          21907:  * dev_t dev;
        !          21908:  * IO * iop;
        !          21909:  *
        !          21910:  *     Input:  dev = tape device to be read from.
        !          21911:  *             iop = pointer to IO structure.
        !          21912:  *
        !          21913:  *     Action: Transfer data from tape cache to user memory,
        !          21914:  *             filling the cache as required by initiating reads from tape.
        !          21915:  */
        !          21916: 
        !          21917: static
        !          21918: stread( dev, iop )
        !          21919: dev_t  dev;
        !          21920: register IO * iop;
        !          21921: {
        !          21922:        register int n;
        !          21923:        register int ioc;
        !          21924: 
        !          21925:        ioc = iop->io_ioc;
        !          21926:        
        !          21927:        while ( iop->io_ioc > 0 ) {
        !          21928: 
        !          21929:                /*
        !          21930:                 * Check for empty cache.
        !          21931:                 */
        !          21932:                while ( st.st_resid == 0 ) {
        !          21933: 
        !          21934:                        /*
        !          21935:                         * Special handling if end of file was encountered.
        !          21936:                         */
        !          21937:                        if ( st.st_iseof ) {
        !          21938: 
        !          21939:                                /*
        !          21940:                                 * Clear EOF if no data was transferred yet.
        !          21941:                                 */
        !          21942:                                if ( ioc == iop->io_ioc )
        !          21943:                                        st.st_iseof = 0;
        !          21944: 
        !          21945:                                return;
        !          21946:                        }
        !          21947: 
        !          21948:                        /*
        !          21949:                         * Abort on I/O error.
        !          21950:                         */
        !          21951:                        if ( u.u_error = st.st_error ) {
        !          21952:                                stdiag();
        !          21953:                                return;
        !          21954:                        }
        !          21955: 
        !          21956:                        /*
        !          21957:                         * Fill the cache from tape.
        !          21958:                         */
        !          21959:                        stcache();
        !          21960:                }
        !          21961: 
        !          21962:                /*
        !          21963:                 * Determine max data transferable in one chunk.
        !          21964:                 */
        !          21965:                n = iop->io_ioc;
        !          21966:                if ( n > st.st_resid )
        !          21967:                        n = st.st_resid;
        !          21968: 
        !          21969:                /*
        !          21970:                 * Transfer some data from cache to user memory.
        !          21971:                 */
        !          21972:                if ( pucopy( st.st_paddr, iop->io_base, n ) != n )
        !          21973:                        return;
        !          21974: 
        !          21975:                /*
        !          21976:                 * Update addresses and counts.
        !          21977:                 */
        !          21978:                iop->io_base += n;
        !          21979:                iop->io_ioc  -= n;
        !          21980:                st.st_resid  -= n;
        !          21981:                st.st_paddr  += n;
        !          21982:        }
        !          21983: }
        !          21984: 
        !          21985: /**
        !          21986:  *
        !          21987:  * stwrite( dev, iop ) -- write to tape device
        !          21988:  * dev_t dev;
        !          21989:  * IO * iop;
        !          21990:  *
        !          21991:  *     Input:  dev = tape device to be written to.
        !          21992:  *             iop = pointer to IO structure.
        !          21993:  *
        !          21994:  *     Action: Transfer data from user memory to tape cache,
        !          21995:  *             flushing the cache as required by initiating writes to tape.
        !          21996:  */
        !          21997: 
        !          21998: static
        !          21999: stwrite( dev, iop )
        !          22000: dev_t  dev;
        !          22001: register IO *iop;
        !          22002: {
        !          22003:        register int n;
        !          22004: 
        !          22005:        while ( iop->io_ioc > 0 ) {
        !          22006: 
        !          22007:                /*
        !          22008:                 * Determine max data transferable in one chunk.
        !          22009:                 */
        !          22010:                n = iop->io_ioc;
        !          22011:                if ( n > st.st_resid )
        !          22012:                        n = st.st_resid;
        !          22013: 
        !          22014:                /*
        !          22015:                 * Transfer some data from user memory to cache.
        !          22016:                 */
        !          22017:                if ( upcopy( iop->io_base, st.st_paddr, n ) != n )
        !          22018:                        break;
        !          22019: 
        !          22020:                /*
        !          22021:                 * Update addresses and counts.
        !          22022:                 */
        !          22023:                iop->io_base += n;
        !          22024:                iop->io_ioc  -= n;
        !          22025:                st.st_paddr  += n;
        !          22026:                st.st_resid  -= n;
        !          22027: 
        !          22028:                /*
        !          22029:                 * Flush the cache to tape if full.
        !          22030:                 */
        !          22031:                if ( st.st_resid == 0 )
        !          22032:                        stflush();
        !          22033: 
        !          22034:                /*
        !          22035:                 * Abort on I/O error.
        !          22036:                 */
        !          22037:                if ( u.u_error = st.st_error ) {
        !          22038:                        stdiag();
        !          22039:                        return;
        !          22040:                }
        !          22041:        }
        !          22042: }
        !          22043: 
        !          22044: /**
        !          22045:  *
        !          22046:  * stioctl( dev, cmd, arg )    -- service tape I/O control requests
        !          22047:  * int dev;
        !          22048:  * int cmd;
        !          22049:  * int arg;
        !          22050:  *
        !          22051:  *     Input:  dev = tape device to be serviced
        !          22052:  *             cmd = ioctl command
        !          22053:  *             arg = argument to ioctl command
        !          22054:  *
        !          22055:  *     Action: Service tape I/O control request.
        !          22056:  */
        !          22057: 
        !          22058: static
        !          22059: stioctl( dev, cmd, arg )
        !          22060: {
        !          22061:        if ( st.st_iswr )
        !          22062:                stflush();
        !          22063: 
        !          22064:        st.st_error = EINVAL;
        !          22065: 
        !          22066:        switch ( cmd ) {
        !          22067: 
        !          22068:        case MTERASE:
        !          22069:                stinvoke( CC_ERASE );
        !          22070:                break;
        !          22071: 
        !          22072:        case MTTENSE:
        !          22073:                stinvoke( CC_TENSION );
        !          22074:                break;
        !          22075: 
        !          22076:        case MTREWIND:
        !          22077:                if ( st.st_iswr && st.st_wasio ) {
        !          22078:                        stinvoke( CC_WFM );
        !          22079:                        st.st_wasio = 0;
        !          22080:                }
        !          22081:                stinvoke( CC_BOT );
        !          22082:                break;
        !          22083: 
        !          22084:        case MTWEOF:
        !          22085:                if ( st.st_iswr ) {
        !          22086:                        stinvoke( CC_WFM );
        !          22087:                        st.st_wasio = 0;
        !          22088:                }
        !          22089:                break;
        !          22090: 
        !          22091:        case MTFSKIP:
        !          22092:                if ( ! st.st_iswr ) {
        !          22093:                        if ( ! st.st_iseof )
        !          22094:                                stinvoke( CC_RFM );
        !          22095:                        st.st_iseof = 0;
        !          22096:                        st.st_resid = 0;
        !          22097:                }
        !          22098:                break;
        !          22099:        }
        !          22100: 
        !          22101:        /*
        !          22102:         * Record tape error code.
        !          22103:         */
        !          22104:        u.u_error = st.st_error;
        !          22105: }
        !          22106: 
        !          22107: /**
        !          22108:  *
        !          22109:  * void
        !          22110:  * stcache()   -- read from tape into cache
        !          22111:  *
        !          22112:  *     Action: Read as much data as possible into the tape cache.
        !          22113:  *             Set st.st_paddr to the cache address.
        !          22114:  *             Set st.st_resid to the number of data bytes in the cache.
        !          22115:  */
        !          22116: static void
        !          22117: stcache()
        !          22118: {
        !          22119:        /*
        !          22120:         * Try to fill cache from tape.
        !          22121:         */
        !          22122:        st.st_paddr = st.st_seg->s_paddr;
        !          22123:        st.st_resid = st.st_size;
        !          22124:        ststart();
        !          22125: 
        !          22126:        /*
        !          22127:         * Update cache information.
        !          22128:         */
        !          22129:        st.st_paddr = st.st_seg->s_paddr;
        !          22130:        st.st_resid = st.st_size - st.st_resid;
        !          22131: 
        !          22132:        /*
        !          22133:         * Clear the cache on I/O error.
        !          22134:         */
        !          22135:        if ( st.st_error )
        !          22136:                st.st_resid = 0;
        !          22137: }
        !          22138: 
        !          22139: /**
        !          22140:  *
        !          22141:  * void
        !          22142:  * stflush()   -- flush cache to tape
        !          22143:  *
        !          22144:  *     Action: Ensure tape cache is block aligned.
        !          22145:  *             Write cache to the tape.
        !          22146:  *             Set st.st_paddr to the cache address.
        !          22147:  *             Set st.st_resid to the number of cache bytes available.
        !          22148:  */
        !          22149: static void
        !          22150: stflush()
        !          22151: {
        !          22152:        static char zc;
        !          22153: 
        !          22154:        /*
        !          22155:         * Check for empty cache.
        !          22156:         */
        !          22157:        if ( st.st_resid == st.st_size )
        !          22158:                return;
        !          22159: 
        !          22160:        /*
        !          22161:         * Block align the cache.
        !          22162:         */
        !          22163:        while ( st.st_resid % BSIZE ) {
        !          22164:                kpcopy( &zc, st.st_paddr, 1 );
        !          22165:                st.st_paddr++;
        !          22166:                st.st_resid--;
        !          22167:        }
        !          22168: 
        !          22169:        /*
        !          22170:         * Flush the cache to tape.
        !          22171:         */
        !          22172:        st.st_paddr = st.st_seg->s_paddr;
        !          22173:        st.st_resid = st.st_size - st.st_resid;
        !          22174:        ststart();
        !          22175: 
        !          22176:        /*
        !          22177:         * Update cache information.
        !          22178:         */
        !          22179:        st.st_paddr = st.st_seg->s_paddr;
        !          22180:        st.st_resid = st.st_size;
        !          22181: }
        !          22182: 
        !          22183: /**
        !          22184:  *
        !          22185:  * void
        !          22186:  * stinvoke()  -- start tape control operation
        !          22187:  *
        !          22188:  *     Action: Initiate tape control operation.
        !          22189:  */
        !          22190: static void
        !          22191: stinvoke( cmd )
        !          22192: int cmd;
        !          22193: {
        !          22194:        register int s;
        !          22195: 
        !          22196:        /*
        !          22197:         * Disable interrupts.
        !          22198:         */
        !          22199:        s = sphi();
        !          22200: 
        !          22201:        /*
        !          22202:         * Wait for controller to become idle.
        !          22203:         */
        !          22204:        while ( st.st_state != SIDLE ) {
        !          22205: 
        !          22206:                /*
        !          22207:                 * Create chained command if possible.
        !          22208:                 */
        !          22209:                if ( st.st_ncmds < NCMDS ) {
        !          22210:                        st.st_cmds[ st.st_ncmds++ ] = cmd;
        !          22211:                        spl( s );
        !          22212:                        return;
        !          22213:                }
        !          22214: 
        !          22215:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          22216:        }
        !          22217: 
        !          22218:        /*
        !          22219:         * Setup for tape operation.
        !          22220:         */
        !          22221:        drvl[ST_MAJOR].d_time = 1;
        !          22222:        st.st_state = SCMD;
        !          22223:        st.st_error = 0;
        !          22224:        st.st_rdys  = 0;
        !          22225:        stspin( 100 );
        !          22226: 
        !          22227:        /*
        !          22228:         * Request tape operation.
        !          22229:         * Do NOT wait for results.
        !          22230:         */
        !          22231:        outb( DATA_REG, st.st_cmd = cmd );
        !          22232:        outb( CTRL_REG, CR_IEN+CR_REQ );
        !          22233: 
        !          22234:        /*
        !          22235:         * Enable interrupts.
        !          22236:         */
        !          22237:        spl( s );
        !          22238: }
        !          22239: 
        !          22240: /**
        !          22241:  *
        !          22242:  * void
        !          22243:  * ststart()   -- start tape read/write operation
        !          22244:  *
        !          22245:  *     Action: Initiate tape read/write operation.
        !          22246:  *             Wait for tape operation to complete.
        !          22247:  */
        !          22248: static void
        !          22249: ststart()
        !          22250: {
        !          22251:        register int s;
        !          22252: 
        !          22253:        /*
        !          22254:         * Disable interrupts.
        !          22255:         */
        !          22256:        s = sphi();
        !          22257: 
        !          22258:        /*
        !          22259:         * Wait for controller to become idle.
        !          22260:         */
        !          22261:        while ( st.st_state != SIDLE )
        !          22262:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          22263: 
        !          22264:        /*
        !          22265:         * Setup for tape read/write.
        !          22266:         */
        !          22267:        drvl[ST_MAJOR].d_time = 1;
        !          22268:        st.st_state = SRDWR;
        !          22269:        st.st_error = 0;
        !          22270:        st.st_rdys  = 0;
        !          22271:        stspin( 100 );
        !          22272: 
        !          22273:        /*
        !          22274:         * Tape read/write was last command executed.
        !          22275:         */
        !          22276:        if ( st.st_cmd == st.st_iocmd ) {
        !          22277:                /*
        !          22278:                 * Resume tape i/o operation.
        !          22279:                 * Simulate RDY interrupt.
        !          22280:                 */
        !          22281:                stintr();
        !          22282:        }
        !          22283:        else {
        !          22284:                /*
        !          22285:                 * Request tape operation.
        !          22286:                 */
        !          22287:                outb( DATA_REG, st.st_cmd = st.st_iocmd );
        !          22288:                outb( CTRL_REG, CR_IEN+CR_REQ );
        !          22289:        }
        !          22290: 
        !          22291:        /*
        !          22292:         * Wait for tape operation to complete.
        !          22293:         */
        !          22294:        while ( st.st_state != SIDLE )
        !          22295:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          22296: 
        !          22297:        /*
        !          22298:         * Enable interrupts.
        !          22299:         */
        !          22300:        spl( s );
        !          22301: }
        !          22302: 
        !          22303: /**
        !          22304:  *
        !          22305:  * void
        !          22306:  * stintr()    -- tape interrupt handler
        !          22307:  *
        !          22308:  *     Action: Service tape interrupts.
        !          22309:  *             Perform transitions to new tape states.
        !          22310:  *             Wake sleeping processes if appropriate.
        !          22311:  */
        !          22312: static void
        !          22313: stintr()
        !          22314: {
        !          22315:        register int csr;
        !          22316:        register int s;
        !          22317: 
        !          22318:        s   = sphi();
        !          22319:        csr = inb( CTRL_REG );
        !          22320: 
        !          22321:        /*
        !          22322:         * Initiate exception recovery.
        !          22323:         */
        !          22324:        if ( (csr & SR_NEXC) == 0 ) {
        !          22325:                strecov();
        !          22326:                spl( s );
        !          22327:                return;
        !          22328:        }
        !          22329: 
        !          22330:        /*
        !          22331:         * Clear ready watchdog count.
        !          22332:         */
        !          22333:        st.st_rdys = 0;
        !          22334: 
        !          22335:        /*
        !          22336:         * Process normal operations.
        !          22337:         */
        !          22338:        switch ( st.st_state ) {
        !          22339: 
        !          22340:        case SCMD:
        !          22341:                /*
        !          22342:                 * Command has been acknowledged.
        !          22343:                 * Wait for command completion.
        !          22344:                 */
        !          22345:                outb( CTRL_REG, CR_IEN );
        !          22346:                st.st_state = (st.st_cmd == CC_SENSE) ? SSENSE : SRUN;
        !          22347:                st.st_nstat = 0;
        !          22348:                break;
        !          22349: 
        !          22350:        case SRUN:
        !          22351:                /*
        !          22352:                 * Command has completed.
        !          22353:                 * Chain a sense status command if no other chained commands.
        !          22354:                 */
        !          22355:                if ( st.st_ncmds == 0 )
        !          22356:                        st.st_cmds[ st.st_ncmds++ ] = CC_SENSE;
        !          22357: 
        !          22358:                /*
        !          22359:                 * Initiate next chained command.
        !          22360:                 */
        !          22361:                stnext();
        !          22362:                break;
        !          22363: 
        !          22364:        case SRDWR:
        !          22365:                /*
        !          22366:                 * Read/Write command had been acknowledged.
        !          22367:                 * Clear tape request, enable done interrupt.
        !          22368:                 */
        !          22369:                outb( CTRL_REG, CR_IEN+CR_DNIEN );
        !          22370: 
        !          22371:                /*
        !          22372:                 * Define direct memory access parameters.
        !          22373:                 */
        !          22374:                dmaon( STDMA, st.st_paddr, BSIZE, st.st_iswr );
        !          22375: 
        !          22376:                /*
        !          22377:                 * If tape read command, wait for interface to switch direction
        !          22378:                 */
        !          22379:                if ( st.st_iocmd == CC_READ )
        !          22380:                        while ( (inb(CTRL_REG) & SR_TO_PC) != SR_TO_PC )
        !          22381:                                ;
        !          22382: 
        !          22383:                /*
        !          22384:                 * Enable DMA transfer on tape interface and at DMA controller chip.
        !          22385:                 */
        !          22386:                st.st_state = SBLOCK;
        !          22387:                outb( DMAGO_REG, 0 );
        !          22388:                dmago( STDMA );
        !          22389:                break;
        !          22390: 
        !          22391:        case SBLOCK:
        !          22392:                /*
        !          22393:                 * Perform Block I/O.
        !          22394:                 * Ignore RDY interrupt, wait for [DMA] DONE interrupt.
        !          22395:                 */
        !          22396:                if ( (csr & SR_DONE) == 0 )
        !          22397:                        break;
        !          22398: 
        !          22399:                /*
        !          22400:                 * Turn off DMA.
        !          22401:                 */
        !          22402:                dmaoff( STDMA );
        !          22403: 
        !          22404:                /*
        !          22405:                 * If more data remains to be transferred, reenable DMA.
        !          22406:                 * NOTE: do -= BEFORE if() to avoid potential compiler bug.
        !          22407:                 */
        !          22408:                st.st_resid -= BSIZE;
        !          22409:                if ( st.st_resid > 0 ) {
        !          22410:                        st.st_paddr += BSIZE;
        !          22411:                        dmaon( STDMA, st.st_paddr, BSIZE, st.st_iswr );
        !          22412:                        outb( DMAGO_REG, 0 );
        !          22413:                        dmago( STDMA );
        !          22414:                        break;
        !          22415:                }
        !          22416: 
        !          22417:                /*
        !          22418:                 * Disable done interrupt.
        !          22419:                 * Wait for I/O completion.
        !          22420:                 */
        !          22421:                outb( CTRL_REG, CR_IEN );
        !          22422:                st.st_state = SBLEND;
        !          22423:                break;
        !          22424: 
        !          22425:        case SBLEND:
        !          22426:                /*
        !          22427:                 * Completion of Block I/O.
        !          22428:                 * Clear the file mark and beginning of media indicators.
        !          22429:                 * Record the fact that data has been transferred.
        !          22430:                 */
        !          22431:                st.st_status[0] &= ~SS0_FIL;
        !          22432:                st.st_status[1] &= ~SS1_BOM;
        !          22433:                st.st_wasio = 1;
        !          22434:                stnext();
        !          22435:                break;
        !          22436: 
        !          22437:        case SSENSE:
        !          22438:                /*
        !          22439:                 * Sense Status Byte.
        !          22440:                 * Wait for availability.
        !          22441:                 */
        !          22442:                do {
        !          22443:                        csr = inb(CTRL_REG) & (SR_NRDY|SR_TO_PC);
        !          22444:                } while ( csr != SR_TO_PC );
        !          22445: 
        !          22446:                /*
        !          22447:                 * Save status byte.
        !          22448:                 */
        !          22449:                st.st_status[st.st_nstat] = inb(DATA_REG);
        !          22450: 
        !          22451:                /*
        !          22452:                 * Acknowledge reception.
        !          22453:                 * CR_REQ must be present for at least 20 microseconds.
        !          22454:                 */
        !          22455:                outb( CTRL_REG, CR_IEN+CR_REQ );
        !          22456:                stspin( 20 );
        !          22457:                outb( CTRL_REG, CR_IEN );
        !          22458: 
        !          22459:                /*
        !          22460:                 * Change state to status completion if all bytes saved.
        !          22461:                 */
        !          22462:                if ( ++(st.st_nstat) == 6 )
        !          22463:                        st.st_state = SSDONE;
        !          22464:                break;
        !          22465: 
        !          22466:        case SSDONE:
        !          22467:                /*
        !          22468:                 * Completion of Sense Status Command.
        !          22469:                 * Check for file mark.
        !          22470:                 */
        !          22471:                if ( st.st_status[0] & SS0_FIL ) {
        !          22472:                        outb( DMARST_REG, 0 );
        !          22473:                        st.st_iseof = 1;
        !          22474:                }
        !          22475: 
        !          22476:                /*
        !          22477:                 * Check for I/O error.
        !          22478:                 */
        !          22479:                else if ( (st.st_status[0] & SS0_ERR) ||
        !          22480:                          (st.st_status[1] & SS1_ERR) ) {
        !          22481:                        st.st_error = EIO;
        !          22482:                }
        !          22483: 
        !          22484:                /*
        !          22485:                 * Check for write protected cartridge.
        !          22486:                 */
        !          22487:                else if ( (st.st_iocmd == CC_WRITE) &&
        !          22488:                          (st.st_status[0] & SS0_WRP) ) {
        !          22489:                        st.st_error = EROFS;
        !          22490:                }
        !          22491: 
        !          22492:                stnext();
        !          22493:                break;
        !          22494:        }
        !          22495: 
        !          22496:        spl( s );
        !          22497: }
        !          22498: 
        !          22499: /**
        !          22500:  *
        !          22501:  * void
        !          22502:  * strecov()   -- initiate recovery from exception conditions
        !          22503:  *
        !          22504:  *     Action: Invoked when the tape controller asserts EXCEPTION.
        !          22505:  *             A sense status command is initiated to clear the exception.
        !          22506:  */
        !          22507: static void
        !          22508: strecov()
        !          22509: {
        !          22510:        /*
        !          22511:         * Ensure tape interface is idle.
        !          22512:         */
        !          22513:        outb( CTRL_REG, CR_IEN );
        !          22514:        stspin( 100 );
        !          22515: 
        !          22516:        /*
        !          22517:         * Turn off DMA on read/write exception.
        !          22518:         */
        !          22519:        if ( st.st_cmd == st.st_iocmd )
        !          22520:                dmaoff( STDMA );
        !          22521: 
        !          22522:        /*
        !          22523:         * Initiate sense status command.
        !          22524:         */
        !          22525:        outb( DATA_REG, st.st_cmd = CC_SENSE );
        !          22526:        outb( CTRL_REG, CR_IEN+CR_REQ );
        !          22527:        drvl[ST_MAJOR].d_time = 1;
        !          22528:        st.st_state = SCMD;
        !          22529:        st.st_error = 0;
        !          22530:        st.st_rdys  = 0;
        !          22531: }
        !          22532: 
        !          22533: /**
        !          22534:  *
        !          22535:  * static void
        !          22536:  * stnext()    -- initiate next chained command.
        !          22537:  */
        !          22538: static void
        !          22539: stnext()
        !          22540: {
        !          22541:        /*
        !          22542:         * Ensure tape interface is idle.
        !          22543:         */
        !          22544:        outb( CTRL_REG, CR_IEN );
        !          22545:        drvl[ST_MAJOR].d_time = 0;
        !          22546:        st.st_state = SIDLE;
        !          22547:        stspin( 100 );
        !          22548: 
        !          22549:        /*
        !          22550:         * Initiate a chained command.
        !          22551:         */
        !          22552:        if ( st.st_ncmds ) {
        !          22553:                outb( DATA_REG, st.st_cmd = st.st_cmds[ --st.st_ncmds ] );
        !          22554:                outb( CTRL_REG, CR_IEN+CR_REQ );
        !          22555:                drvl[ST_MAJOR].d_time = 1;
        !          22556:                st.st_state = SCMD;
        !          22557:                st.st_error = 0;
        !          22558:                st.st_rdys  = 0;
        !          22559:                return;
        !          22560:        }
        !          22561: 
        !          22562:        /*
        !          22563:         * Wake waiting processes.
        !          22564:         */
        !          22565:        wakeup( &st );
        !          22566: }
        !          22567: 
        !          22568: /**
        !          22569:  *
        !          22570:  * void
        !          22571:  * stwatch()   -- periodic [1 sec] watchdog
        !          22572:  *
        !          22573:  *     Action: If an exception condition exists, initate recovery actions.
        !          22574:  *             If ready condition exists for 1-2 seconds, simulate interrupt.
        !          22575:  *
        !          22576:  *     Notes:  If an exception condition occurs after a ready interrupt has
        !          22577:  *             been serviced, but before the ready condition is cleared,
        !          22578:  *             the exception interrupt will not occur, and is simulated here.
        !          22579:  */
        !          22580: static void
        !          22581: stwatch()
        !          22582: {
        !          22583:        register int csr;
        !          22584:        register int s;
        !          22585: 
        !          22586:        /*
        !          22587:         * Disable interrupts, preventing critical race with stintr().
        !          22588:         */
        !          22589:        s   = sphi();
        !          22590:        csr = inb(CTRL_REG);
        !          22591: 
        !          22592:        /*
        !          22593:         * Initiate recovery from exception conditions.
        !          22594:         */
        !          22595:        if ( (csr & SR_NEXC) == 0 )
        !          22596:                strecov();
        !          22597: 
        !          22598:        /*
        !          22599:         * Reset ready watchdog if not ready.
        !          22600:         */
        !          22601:        else if ( csr & SR_NRDY ) 
        !          22602:                st.st_rdys = 0;
        !          22603: 
        !          22604:        /*
        !          22605:         * Simulate lost ready interrupts after 2 seconds.
        !          22606:         */
        !          22607:        else if ( ++st.st_rdys >= 2 )
        !          22608:                stintr();
        !          22609: 
        !          22610:        /*
        !          22611:         * Enable interrupts.
        !          22612:         */
        !          22613:        spl( s );
        !          22614: }
        !          22615: 
        !          22616: /**
        !          22617:  * 
        !          22618:  * void
        !          22619:  * stdiag()    - Report tape status.
        !          22620:  *
        !          22621:  *     Action: Identify and report the highest priority tape error.
        !          22622:  *             There will normally only be one valid error present.
        !          22623:  *             The USL error can invalidate most remaining flags.
        !          22624:  *             The CNI error can invalidate cartridge related flags.
        !          22625:  *
        !          22626:  *     Notes:  Never called from interrupt level, but always from background.
        !          22627:  */
        !          22628: static void
        !          22629: stdiag()
        !          22630: {
        !          22631:        if ( st.st_status[0] & SS0_USL )
        !          22632:                printf( "st: Unselected Drive\n" );
        !          22633: 
        !          22634:        else if ( st.st_status[0] & SS0_CNI )
        !          22635:                printf( "st: Cartridge missing\n" );
        !          22636: 
        !          22637:        else if ( st.st_status[1] & SS1_NDT )
        !          22638:                printf( "st: No data detected\n" );
        !          22639: 
        !          22640:        else if ( st.st_status[0] & SS0_BNL )
        !          22641:                printf( "st: Bad block not located\n" );
        !          22642: 
        !          22643:        else if ( st.st_status[0] & SS0_UDA )
        !          22644:                printf( "st: Unrecoverable data error\n" );
        !          22645: 
        !          22646:        else if ( st.st_status[1] & SS1_ILL )
        !          22647:                printf( "st: Illegal command\n" );
        !          22648: 
        !          22649:        else
        !          22650:                printf( "st: %x\n", (st.st_status[1] << 8) + st.st_status[0] );
        !          22651: }
        !          22652: 
        !          22653: /**
        !          22654:  *
        !          22655:  * int
        !          22656:  * stwait()    -- wait for tape controller to idle.
        !          22657:  *
        !          22658:  *     Return: 0  = tape controller idle.
        !          22659:  *             -1 = signal received.
        !          22660:  */
        !          22661: static int
        !          22662: stwait()
        !          22663: {
        !          22664:        int s;
        !          22665: 
        !          22666:        s = sphi();
        !          22667:        while ( st.st_state != SIDLE ) {
        !          22668: 
        !          22669:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          22670: 
        !          22671:                if ( SELF->p_ssig ) {
        !          22672:                        spl( s );
        !          22673:                        return -1;
        !          22674:                }
        !          22675:        }
        !          22676:        spl( s );
        !          22677: 
        !          22678:        return 0;
        !          22679: }
        !          22680: 
        !          22681: /**
        !          22682:  *
        !          22683:  * void
        !          22684:  * stspin( usec )      -- delay execution
        !          22685:  * int usec;
        !          22686:  *
        !          22687:  *     Input:  usec = number of micro-seconds to delay.
        !          22688:  *
        !          22689:  *     Action: Wait at least 'usec' micro-seconds.
        !          22690:  *
        !          22691:  *     Notes:  Provides minimum delay required at times by tape controller.
        !          22692:  *             Should function properly up to at least 16 Mhz system clock.
        !          22693:  */
        !          22694: 
        !          22695: static void
        !          22696: stspin( usec )
        !          22697: register int usec;
        !          22698: {
        !          22699:        while ( --usec >= 0 )
        !          22700:                ;
        !          22701: }
        !          22702: 0707070064030150061006440000030000030000011777770507310644500005400000000634/newbits/kernel/USRSRC/i8086/drv/template.c/*
        !          22703:  * File:
        !          22704:  *
        !          22705:  * Purpose:
        !          22706:  *
        !          22707:  * $Log:       template.c,v $
        !          22708:  * Revision 1.2  91/06/20  14:55:08  bin
        !          22709:  * update provided by hal
        !          22710:  * 
        !          22711:  */
        !          22712: 
        !          22713: /*
        !          22714:  * Includes.
        !          22715:  */
        !          22716: 
        !          22717: /*
        !          22718:  * Definitions.
        !          22719:  *     Constants.
        !          22720:  *     Macros with argument lists.
        !          22721:  *     Typedefs.
        !          22722:  *     Enums.
        !          22723:  */
        !          22724: 
        !          22725: /*
        !          22726:  * Functions.
        !          22727:  *     Import Functions.
        !          22728:  *     Export Functions.
        !          22729:  *     Local Functions.
        !          22730:  */
        !          22731: 
        !          22732: /*
        !          22733:  * Global Data.
        !          22734:  *     Import Variables.
        !          22735:  *     Export Variables.
        !          22736:  *     Local Variables.
        !          22737:  */
        !          22738: 0707070064030150051004440000030000030000011777770507310644500004600000064442/newbits/kernel/USRSRC/i8086/drv/tn.c/* (-lgl
        !          22739:  *     COHERENT Driver Kit Version 1.1.0
        !          22740:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          22741:  *     All rights reserved. May not be copied without permission.
        !          22742:  -lgl) */
        !          22743: /*
        !          22744:  * Tiac ARCNET PC-234 Device Driver
        !          22745:  *
        !          22746:  * True support for up to 4 network cards through minor devices 0-3.
        !          22747:  * Up to 4 protocols now supported.  Novell access is through normal
        !          22748:  * minor device.  Netbios access is through novell minor device + 16.
        !          22749:  */
        !          22750: 
        !          22751: #include <sys/coherent.h>
        !          22752: #include <sys/con.h>
        !          22753: #include <sys/devices.h>
        !          22754: #include <sys/sched.h>
        !          22755: #include <sys/seg.h>
        !          22756: #include <sys/stat.h>
        !          22757: #include <sys/uproc.h>
        !          22758: #include <sys/tnioctl.h>
        !          22759: #include <errno.h>
        !          22760: 
        !          22761: /*
        !          22762:  * External functions.
        !          22763:  */
        !          22764: extern int  wakeup();
        !          22765: extern void pollwake();
        !          22766: extern void defer();
        !          22767: 
        !          22768: /*
        !          22769:  * Driver functions.
        !          22770:  */
        !          22771: void   tnopen();
        !          22772: void   tnclose();
        !          22773: int    tnread();
        !          22774: int    tnwrite();
        !          22775: int    tnioctl();
        !          22776: void   tncycle();
        !          22777: void   tnload();
        !          22778: void   tnuload();
        !          22779: int    tnpoll();
        !          22780: int    nonedev();
        !          22781: int    nulldev();
        !          22782: void   tn0intr();
        !          22783: void   tn1intr();
        !          22784: void   tn2intr();
        !          22785: void   tn3intr();
        !          22786: void   tnintr();
        !          22787: 
        !          22788: /*
        !          22789:  * Driver Configuration.
        !          22790:  */
        !          22791: CON
        !          22792: tncon = {
        !          22793:        DFCHR|DFPOL,                    /* Flags        */
        !          22794:        TN_MAJOR,                       /* Major Index  */
        !          22795:        tnopen,                         /* Open         */
        !          22796:        tnclose,                        /* Close        */
        !          22797:        nonedev,                        /* Block        */
        !          22798:        tnread,                         /* Read         */
        !          22799:        tnwrite,                        /* Write        */
        !          22800:        tnioctl,                        /* Ioctl        */
        !          22801:        nulldev,                        /* Power fail   */
        !          22802:        tncycle,                        /* Timeout      */
        !          22803:        tnload,                         /* Load         */
        !          22804:        tnuload,                        /* Unload       */
        !          22805:        tnpoll                          /* Poll         */
        !          22806: };
        !          22807: 
        !          22808: /*
        !          22809:  * Interrupt Entry Points.
        !          22810:  */
        !          22811: void (*tnintf[4])() = {
        !          22812:        tn0intr,
        !          22813:        tn1intr,
        !          22814:        tn2intr,
        !          22815:        tn3intr
        !          22816: };
        !          22817: 
        !          22818: #define        BIT(n)          (1 << (n))
        !          22819: 
        !          22820: /*
        !          22821:  * Bitmask, indexed by bit numbers 0..7.
        !          22822:  */
        !          22823: static unsigned char bitm[8] = { BIT(0), BIT(1), BIT(2), BIT(3),
        !          22824:                                 BIT(4), BIT(5), BIT(6), BIT(7) };
        !          22825: 
        !          22826: /*
        !          22827:  * Patchable parameters - Cards 0-3.
        !          22828:  */
        !          22829:                /* Card    0       1       2      3  */
        !          22830: int    TNIRQ [4] = {      2,      7,      4,      0 };
        !          22831: saddr_t        TNSEL [4] = { 0xD000, 0x0000, 0x0000, 0x0000 };
        !          22832: int    TNPORT[4] = {  0x2E0,  0x220,  0x240,  0x000 };
        !          22833: 
        !          22834: /*
        !          22835:  * Patchable parameters - Prefix Byte.
        !          22836:  * Indexed by high nibble of minor device.
        !          22837:  */
        !          22838: int    TNPREFIX[4] = { 0x00,   0xF3,   0x00,   0x00 };
        !          22839: 
        !          22840: /*
        !          22841:  * Patchable variables.
        !          22842:  * TNTIME = Transmit watchdog timer in seconds.
        !          22843:  */
        !          22844: int TNTIME = 5;
        !          22845: 
        !          22846: /*
        !          22847:  * Register addresses.
        !          22848:  */
        !          22849: #define        NIR             (tp->tnport)    /* Network Interrupt Mask Reg (w)  */
        !          22850: #define        NSR             (tp->tnport)    /* Network Status Register    (r)  */
        !          22851: #define        NCR             (tp->tnport+1)  /* Network Command Register   (w)  */
        !          22852: #define        NZR             (tp->tnport+8)  /* Network Zap (reset) Reg    (w)  */
        !          22853: 
        !          22854: /*
        !          22855:  * Network Interrupt Register (NIR).
        !          22856:  */
        !          22857: #define        NI_Tx           BIT(0)          /* Enable Transmitter Avail Intr   */
        !          22858: #define        NI_RECON        BIT(2)          /* Enable Reconfiguration   Intr   */
        !          22859: #define        NI_Rx           BIT(7)          /* Enable Receiver Full     Intr   */
        !          22860: 
        !          22861: /*
        !          22862:  * Network Status Register (NSR).
        !          22863:  */
        !          22864: #define        NS_TxRDY        BIT(0)          /* Transmitter Available           */
        !          22865: #define        NS_TxACK        BIT(1)          /* Transmit Message Acknowledged   */
        !          22866: #define        NS_RECON        BIT(2)          /* Network Reconfiguration         */
        !          22867: #define        NS_TEST         BIT(3)          /* Test                            */
        !          22868: #define        NS_POR          BIT(4)          /* Power on Reset                  */
        !          22869: #define        NS_ETS1         BIT(5)          /* Extended Timeout Status 1       */
        !          22870: #define        NS_ETS2         BIT(6)          /* Extended Timeout Status 2       */
        !          22871: #define        NS_RxRDY        BIT(7)          /* Packet Received - Receiver Off  */
        !          22872: 
        !          22873: /*
        !          22874:  * Network Command Register (NCR).
        !          22875:  */
        !          22876: #define        NC_TxDIS        (((0)<<3) + 1)  /* Disable Transmitter             */
        !          22877: #define        NC_RxDIS        (((0)<<3) + 2)  /* Disable Receiver                */
        !          22878: #define        NC_TxENA(n)     (((n)<<3) + 3)  /* Enable Transmitter on Page n    */
        !          22879: #define        NC_RxENA(n)     (((n)<<3)+0x84) /* Enable Receiver    on Page n    */
        !          22880: #define        NC_DFC          (((1)<<3) + 5)  /* Define Configuration (2k buf)   */
        !          22881: #define        NC_POR          (((1)<<3) + 6)  /* Clear NS_POR flag               */
        !          22882: #define        NC_RECON        (((2)<<3) + 6)  /* Clear NS_RECON flag             */
        !          22883: 
        !          22884: /*
        !          22885:  * Packet Control.
        !          22886:  */
        !          22887: struct tnet_s {
        !          22888: 
        !          22889:        /*
        !          22890:         * Four buffers per card - 2 receive, 2 transmit.
        !          22891:         */
        !          22892:        struct tnbuf_s {                /* tnget*,tnput* use tn_sel:tn_off */
        !          22893:                unsigned        tn_off; /* tn_sel:tn_off  = current byte   */
        !          22894:                saddr_t         tn_sel; /* network buffer selector         */
        !          22895:                struct tnbuf_s *tn_next;/* pointer to next pkt in queue    */
        !          22896:                unsigned        tn_ena; /* Command to enable packet        */
        !          22897:                unsigned        tn_base;/* tn_sel:tn_base = pkt address    */
        !          22898:                unsigned        tn_xnid;/* Transmit node id                */
        !          22899:                unsigned        tn_xlen;/* Transmit length                 */
        !          22900:        } tnbuf [4];
        !          22901: 
        !          22902:        struct tnbuf_s *        RxBusy[4];/* Queues of full receive packets*/
        !          22903:        struct tnbuf_s *        RxIdle; /* Queue of empty receive packets  */
        !          22904: 
        !          22905:        struct tnbuf_s *        TxBusy; /* Queue of full transmit packets  */
        !          22906:        struct tnbuf_s *        TxIdle; /* Queue of empty transmit packets */
        !          22907: 
        !          22908:        event_t                 RxPoll[4];/* Polls for input packets       */
        !          22909:        event_t                 TxPoll; /* Polls for empty output packets  */
        !          22910: 
        !          22911:        char                    RxReq[4];/* 1 = Proc waiting for recv buf  */
        !          22912:        char                    TxReq;  /* 1 = Proc waiting for xmit buf   */
        !          22913:        char                    refc[4];/* # opens, indexed by prefix code */
        !          22914: 
        !          22915:        unsigned                tnmask; /* Interrupt enable mask           */
        !          22916:        unsigned                tnport; /* Base I/O port                   */
        !          22917:        char                    tnaddr[8];/* ARC-NET Node ID, low byte 1st */
        !          22918: 
        !          22919:        unsigned                tntime; /* transmit watchdog timer         */
        !          22920:        unsigned                recon;  /* number of long reconfigurations */
        !          22921:        unsigned                pri;    /* priority event occurred         */
        !          22922:        long                    rbolt;  /* lbolt at last reconfiguration   */
        !          22923:        unsigned char           bad[32];/* bit mask of bad nodes           */
        !          22924:        unsigned char           mod[32];/* bit mask of changed nodes       */
        !          22925:        long                    recons; /* reconfiguration statistic       */
        !          22926:        SEG *                   statseg;/* Segment containing stats        */
        !          22927: 
        !          22928: } tnet [4];
        !          22929: 
        !          22930: /*
        !          22931:  * Load Routine.
        !          22932:  */
        !          22933: void
        !          22934: tnload()
        !          22935: {
        !          22936:        register struct tnet_s  * tp;
        !          22937:        register struct tnbuf_s * np;
        !          22938:        faddr_t faddr;
        !          22939:        paddr_t paddr;
        !          22940:        int i;
        !          22941:        int nid;
        !          22942:        long delay;
        !          22943: 
        !          22944:        for ( tp = &tnet[0], i = 0; i < 4; i++, tp++ ) {
        !          22945: 
        !          22946:                /*
        !          22947:                 * Validate patchable parameters.
        !          22948:                 */
        !          22949:                if ( (TNSEL[i] == 0) || (TNPORT[i] == 0) || (TNIRQ[i] == 0) ) {
        !          22950:                        TNPORT[i] = 0;
        !          22951:                        TNSEL[i]  = 0;
        !          22952:                        TNIRQ[i]  = 0;
        !          22953:                        continue;
        !          22954:                }
        !          22955: 
        !          22956:                tp->tnport = TNPORT[i];
        !          22957: 
        !          22958:                /*
        !          22959:                 * Clear Power-On-Reset Flag.
        !          22960:                 */
        !          22961:                outb( NCR, NC_POR );
        !          22962: 
        !          22963:                /*
        !          22964:                 * Validate card presence.
        !          22965:                 * NOTE: tp->tnport must be programmed before using NIR macro.
        !          22966:                 */
        !          22967:                if ( inb(NSR) & (NS_TEST|NS_POR) ) {
        !          22968:                        tp->tnport = 0;
        !          22969:                        continue;
        !          22970:                }
        !          22971: 
        !          22972:                /*
        !          22973:                 * Convert physical address into virtual address.
        !          22974:                 */
        !          22975:                paddr = TNSEL[i] << 4L;
        !          22976:                faddr = ptov( paddr, (fsize_t) 2048 );
        !          22977: 
        !          22978:                /*
        !          22979:                 * Verify dual-port memory existence.
        !          22980:                 * NOTE: Do not overwrite first two bytes [0xD1,nid].
        !          22981:                 */
        !          22982:                sfword( faddr+8, 0x1234 );
        !          22983:                if ( ffword( faddr+8 ) != 0x1234 ) {
        !          22984:                        vrelse( faddr );
        !          22985:                        tp->tnport = 0;
        !          22986:                        continue;
        !          22987:                }
        !          22988: 
        !          22989:                /*
        !          22990:                 * Allocate statistics segment.
        !          22991:                 */
        !          22992:                tp->statseg = salloc( (fsize_t) (256*NTNST*4), SFSYST|SFHIGH );
        !          22993: 
        !          22994:                /*
        !          22995:                 * Out of memory.
        !          22996:                 */
        !          22997:                if ( ! tp->statseg ) {
        !          22998:                        printf( "tn%d: out of memory\n", i );
        !          22999:                        vrelse( faddr );
        !          23000:                        tp->tnport = 0;
        !          23001:                        continue;
        !          23002:                }
        !          23003: 
        !          23004:                tp->tnbuf[0].tn_sel =
        !          23005:                tp->tnbuf[1].tn_sel =
        !          23006:                tp->tnbuf[2].tn_sel =
        !          23007:                tp->tnbuf[3].tn_sel = FP_SEL(faddr);
        !          23008: 
        !          23009:                tp->tnbuf[0].tn_ena  = NC_TxENA(0);
        !          23010:                tp->tnbuf[1].tn_ena  = NC_TxENA(1);
        !          23011:                tp->tnbuf[2].tn_ena  = NC_RxENA(2);
        !          23012:                tp->tnbuf[3].tn_ena  = NC_RxENA(3);
        !          23013: 
        !          23014:                tp->tnbuf[0].tn_base = 0 * 512;
        !          23015:                tp->tnbuf[1].tn_base = 1 * 512;
        !          23016:                tp->tnbuf[2].tn_base = 2 * 512;
        !          23017:                tp->tnbuf[3].tn_base = 3 * 512;
        !          23018: 
        !          23019:                /*
        !          23020:                 * Initialize transmit idle queue.
        !          23021:                 */
        !          23022:                tp->TxIdle              = &tp->tnbuf[0];
        !          23023:                tp->tnbuf[0].tn_next    = &tp->tnbuf[1];
        !          23024: 
        !          23025:                /*
        !          23026:                 * Initialize receive idle queue.
        !          23027:                 */
        !          23028:                tp->RxIdle              = &tp->tnbuf[2];
        !          23029:                tp->tnbuf[2].tn_next    = &tp->tnbuf[3];
        !          23030: 
        !          23031:                /*
        !          23032:                 * Validate Node Id.
        !          23033:                 */
        !          23034:                np = &tp->tnbuf[0];
        !          23035:                np->tn_off = 0;
        !          23036:                if ( tngetc(np) != 0xD1 ) {
        !          23037: 
        !          23038:                        /*
        !          23039:                         * Initiate Power On Reset.
        !          23040:                         */
        !          23041:                        outb( NZR, 1 );
        !          23042: 
        !          23043:                        /*
        !          23044:                         * Wait minimimum of 180 [suggest 250] milli-seconds.
        !          23045:                         * Should function properly up to at least 16 Mhz clock.
        !          23046:                         */
        !          23047:                        for ( delay = 250000L; --delay != 0; )
        !          23048:                                ;
        !          23049:                }
        !          23050: 
        !          23051:                /*
        !          23052:                 * Validate and Remember Node Id.
        !          23053:                 */
        !          23054:                np->tn_off = 0;
        !          23055:                if ( tngetc(np) == 0xD1 )
        !          23056:                        tp->tnaddr[0] = tngetc( np );
        !          23057: 
        !          23058:                /*
        !          23059:                 * Record starting time of statistics collection.
        !          23060:                 */
        !          23061:                faddr = tp->statseg->s_faddr + TnELAPSED*4;
        !          23062:                for ( nid = 0; nid < 256; nid++, faddr += NTNST*4 )
        !          23063:                        kfcopy( &lbolt, faddr, sizeof(lbolt) );
        !          23064: 
        !          23065:                memset( tp->bad, -1, 32 );      /* Assume LAN is down      */
        !          23066:                memset( tp->mod,  0, 32 );      /* Assume no node changes  */
        !          23067:                tp->tnmask = NI_Rx | NI_RECON;  /* Interrupts to enable    */
        !          23068:                outb( NIR, 0 );                 /* Disable Interrupts      */
        !          23069:                outb( NCR, NC_POR );            /* Clear POR Flag          */
        !          23070:                outb( NCR, NC_DFC );            /* Define 2K buf config    */
        !          23071:                outb( NCR, NC_TxDIS );          /* Disable Transmitter     */
        !          23072:                outb( NCR, tp->RxIdle->tn_ena); /* Enable receiver         */
        !          23073:                setivec( TNIRQ[i], tnintf[i] ); /* Seize Interrupt Vector  */
        !          23074:                outb( NIR, tp->tnmask );        /* Enable Interrupts       */
        !          23075:        }
        !          23076: 
        !          23077:        /*
        !          23078:         * Enable watchdog timer
        !          23079:         */
        !          23080:        drvl[TN_MAJOR].d_time = 1;
        !          23081: }
        !          23082: 
        !          23083: /*
        !          23084:  * Unload Routine.
        !          23085:  */
        !          23086: void
        !          23087: tnuload( dev )
        !          23088: dev_t dev;
        !          23089: {
        !          23090:        register struct tnet_s  * tp;
        !          23091:        register int i;
        !          23092:        faddr_t faddr;
        !          23093: 
        !          23094:        /*
        !          23095:         * Disable watchdog timer.
        !          23096:         */
        !          23097:        drvl[TN_MAJOR].d_time = 0;
        !          23098: 
        !          23099:        /*
        !          23100:         * Scan network adaptors.
        !          23101:         */
        !          23102:        for ( tp = &tnet[0], i = 0; i < 4; i++, tp++ ) {
        !          23103: 
        !          23104:                if ( tp->tnport == 0 )
        !          23105:                        continue;
        !          23106: 
        !          23107:                /*
        !          23108:                 * Disable Interrupts
        !          23109:                 */
        !          23110:                outb( NIR, 0 );
        !          23111: 
        !          23112:                /*
        !          23113:                 * Release interrupt vector.
        !          23114:                 */
        !          23115:                clrivec( TNIRQ[i] );
        !          23116: 
        !          23117:                /*
        !          23118:                 * Release virtual address AFTER disabling interrupts.
        !          23119:                 */
        !          23120:                if ( FP_SEL(faddr) = tp->tnbuf[0].tn_sel )
        !          23121:                        vrelse( faddr );
        !          23122: 
        !          23123:                /*
        !          23124:                 * Release stats segment.
        !          23125:                 */
        !          23126:                if ( tp->statseg != NULL )
        !          23127:                        sfree( tp->statseg );
        !          23128:        }
        !          23129: }
        !          23130: 
        !          23131: /*
        !          23132:  * Open Routine.
        !          23133:  *
        !          23134:  *     Low nibble  of minor device is card identifier 0 to 3.
        !          23135:  *     High nibble of minor device is code identifier 0 to 3.
        !          23136:  */
        !          23137: void
        !          23138: tnopen( dev, mode )
        !          23139: dev_t dev;
        !          23140: {
        !          23141:        register struct tnet_s * tp;
        !          23142:        int card = (dev & 0x0F);
        !          23143:        int code = (dev & 0xF0) >> 4;
        !          23144: 
        !          23145:        /*
        !          23146:         * Validate minor device and card existence.
        !          23147:         */
        !          23148:        if ( (card > 3) || (code > 3) || (tnet[card].tnport == 0)) {
        !          23149:                u.u_error = ENXIO;
        !          23150:                return;
        !          23151:        }
        !          23152: 
        !          23153:        /*
        !          23154:         * Code identifiers 1 to 3 are only valid if a prefix code is known.
        !          23155:         */
        !          23156:        if ( (code > 0) && (TNPREFIX[code] == 0) ) {
        !          23157:                u.u_error = ENXIO;
        !          23158:                return;
        !          23159:        }
        !          23160: 
        !          23161:        /*
        !          23162:         * Access network information.
        !          23163:         */
        !          23164:        tp = &tnet[card];
        !          23165: 
        !          23166:        /*
        !          23167:         * Increment reference count (# opens).
        !          23168:         */
        !          23169:        tp->refc[code]++;
        !          23170: }
        !          23171: 
        !          23172: /*
        !          23173:  * Close Routine.
        !          23174:  */
        !          23175: void
        !          23176: tnclose( dev )
        !          23177: dev_t dev;
        !          23178: {
        !          23179:        register struct tnet_s  * tp =tp = &tnet[ dev & 3];
        !          23180:        register struct tnbuf_s * np;
        !          23181:        int code = (dev & 0x30) >> 4;
        !          23182:        int s;
        !          23183: 
        !          23184:        /*
        !          23185:         * Decrement reference count.
        !          23186:         */
        !          23187:        if ( --tp->refc[code] != 0 )
        !          23188:                return;
        !          23189: 
        !          23190:        /*
        !          23191:         * Last close.
        !          23192:         * Release all queued packets.
        !          23193:         */
        !          23194:        while ( np = tp->RxBusy[code] ) {
        !          23195:                s = sphi( );
        !          23196:                tp->RxBusy[code] = np->tn_next;
        !          23197:                tn_rxena( tp, np );
        !          23198:                spl( s );
        !          23199:        }
        !          23200: }
        !          23201: 
        !          23202: /*
        !          23203:  * Watchdog Timing Routine
        !          23204:  *
        !          23205:  *     If transmit has been enabled for 1-2 seconds:
        !          23206:  *             Abort transmission of packet, forcing interrupt.
        !          23207:  */
        !          23208: void
        !          23209: tncycle( )
        !          23210: {
        !          23211:        register struct tnet_s * tp;
        !          23212:        register int code;
        !          23213:        int s;
        !          23214: 
        !          23215:        /*
        !          23216:         * Scan all network cards.
        !          23217:         */
        !          23218:        for ( tp = &tnet[0]; tp <= &tnet[3]; tp++ ) {
        !          23219: 
        !          23220:                if ( ! tp->tnport )
        !          23221:                        continue;
        !          23222: 
        !          23223:                /*
        !          23224:                 * Disable interrupts.
        !          23225:                 */
        !          23226:                s = sphi();
        !          23227: 
        !          23228:                /*
        !          23229:                 * Enable broadcasts after 5 seconds without reconfiguration.
        !          23230:                 */
        !          23231:                if ( (tp->recon > 0) && ((lbolt - tp->rbolt) > (5*HZ)) ) {
        !          23232:                        /*
        !          23233:                         * LAN was previously down.
        !          23234:                         */
        !          23235:                        if ( tp->bad[0] & 1 ) {
        !          23236:                                faddr_t fp = tp->statseg->s_faddr;
        !          23237:                                aflong( fp+TnSTATMOD*4, 1 );
        !          23238:                                tp->mod[0] |= 1;
        !          23239:                                tp->pri = 1;
        !          23240:                        }
        !          23241:                        tp->bad[0] &= ~1;
        !          23242:                        tp->recon   =  0;
        !          23243:                }
        !          23244: 
        !          23245:                /*
        !          23246:                 * Discard bad packet on transmit watchdog timeout.
        !          23247:                 */
        !          23248:                if ( (tp->tntime > 0) && (--(tp->tntime) == 0) )
        !          23249:                        outb( NCR, NC_TxDIS );
        !          23250: 
        !          23251:                /*
        !          23252:                 * Enable interrupts.
        !          23253:                 */
        !          23254:                spl( s );
        !          23255: 
        !          23256:                /*
        !          23257:                 * LAN/DEVICE UP/DOWN event has occurred.
        !          23258:                 */
        !          23259:                if ( tp->pri == 1 ) {
        !          23260: 
        !          23261:                        tp->pri = 2;
        !          23262: 
        !          23263:                        for ( code = 0; code < 4; code++ )
        !          23264:                                if ( tp->RxPoll[code].e_procp )
        !          23265:                                        pollwake( &tp->RxPoll[code] );
        !          23266:                }
        !          23267:        }
        !          23268: }
        !          23269: 
        !          23270: static
        !          23271: tnioctl( dev, com, arg )
        !          23272: dev_t dev;
        !          23273: int com;
        !          23274: register tnattr_t * arg;
        !          23275: {
        !          23276:        register struct tnet_s * tp = &tnet[dev & 3];
        !          23277:        faddr_t fp;
        !          23278:        int nid;
        !          23279:        long t;
        !          23280:        tnattr_t local;                 /* to avoid fucopy() problems */
        !          23281: 
        !          23282:        switch ( com ) {
        !          23283: 
        !          23284:        case TNGETA:
        !          23285:        case TNGETAF:
        !          23286:                /*
        !          23287:                 * Access node statistics.
        !          23288:                 */
        !          23289:                nid = getubd( &arg->host[5] );
        !          23290:                fp  = tp->statseg->s_faddr + nid * (NTNST*4);
        !          23291: 
        !          23292:                /*
        !          23293:                 * Disable interrupts to avoid race condition with tnintr().
        !          23294:                 */
        !          23295:                sphi();
        !          23296: 
        !          23297:                /*
        !          23298:                 * Copy node status.
        !          23299:                 */
        !          23300:                if ( tp->bad[nid/8] & bitm[nid%8] )
        !          23301:                        putubd( &arg->bad, 1 );
        !          23302:                else
        !          23303:                        putubd( &arg->bad, 0 );
        !          23304: 
        !          23305:                /*
        !          23306:                 * Copy network reconfigurations to user space.
        !          23307:                 * NOTE: This is not a node statistic, but a network stat.
        !          23308:                 */
        !          23309:                kucopy( &tp->recons, &arg->recons, sizeof(tp->recons) );
        !          23310: 
        !          23311:                /*
        !          23312:                 * Copy node statistics to user space.
        !          23313:                 */
        !          23314:                fkcopy( fp, &local.stats[0], sizeof(local.stats) );
        !          23315:                kucopy( &local.stats[0], &arg->stats[0], sizeof(arg->stats) );
        !          23316: 
        !          23317:                /*
        !          23318:                 * Copy true elapsed time of statistics collection.
        !          23319:                 */
        !          23320:                fkcopy( fp+TnELAPSED*4, &t, sizeof(t) );
        !          23321:                t = lbolt - t;
        !          23322:                kucopy( &t, &arg->stats[TnELAPSED], sizeof(arg->stats[0]) );
        !          23323: 
        !          23324:                /*
        !          23325:                 * Clear node statistics.
        !          23326:                 * NOTE: Elapsed time statistic is time of last clear.
        !          23327:                 */
        !          23328:                if ( com == TNGETAF ) {
        !          23329:                        fclear( fp, NTNST * 4 );
        !          23330:                        kfcopy( &lbolt, fp+TnELAPSED*4, sizeof(lbolt) );
        !          23331:                        if ( nid == 0 )
        !          23332:                                tp->recons = 0;
        !          23333:                }
        !          23334: 
        !          23335:                /*
        !          23336:                 * Enable interrupts.
        !          23337:                 */
        !          23338:                splo();
        !          23339: 
        !          23340:                return( 0 );
        !          23341: 
        !          23342:        default:
        !          23343:                u.u_error = EINVAL;
        !          23344:        }
        !          23345: }
        !          23346: 
        !          23347: /*
        !          23348:  * Polling Routine.
        !          23349:  *
        !          23350:  *     Note:   Double-looks are performed to prevent critical race with
        !          23351:  *             interrupt handlers,  without having to disable interrupts.
        !          23352:  */
        !          23353: static
        !          23354: tnpoll( dev, ev, msec )
        !          23355: dev_t dev;
        !          23356: int ev;
        !          23357: int msec;
        !          23358: {
        !          23359:        register struct tnet_s * tp = &tnet[dev & 3];
        !          23360:        int code = (dev & 0x30) >> 4;
        !          23361:        int rev = 0;
        !          23362: 
        !          23363:        /*
        !          23364:         * Fast check for priority, input, and output polls.
        !          23365:         * Priority poll checks for LAN UP/DOWN transition.
        !          23366:         * Input    poll checks for a full receive buffer.
        !          23367:         * Output   poll checks for an empty transmit buffer, or LAN down.
        !          23368:         */
        !          23369:        if ( (ev & POLLPRI) && (tp->pri != 0) )
        !          23370:                rev |= POLLPRI;
        !          23371:        if ( (ev & POLLIN) && (tp->RxBusy[code] != NULL) )
        !          23372:                rev |= POLLIN;
        !          23373:        if ( (ev & POLLOUT) && ((tp->TxIdle != 0) || (tp->bad[0] & 1)) )
        !          23374:                rev |= POLLOUT;
        !          23375: 
        !          23376:        /*
        !          23377:         * Fast check found an event, or this is a non-blocking poll.
        !          23378:         */
        !          23379:        if ( (rev != 0) || (msec == 0) )
        !          23380:                return( rev );
        !          23381: 
        !          23382:        /*
        !          23383:         * Blocking Input poll.
        !          23384:         */
        !          23385:        if ( ev & POLLIN ) {
        !          23386: 
        !          23387:                pollopen( &tp->RxPoll[code] );
        !          23388: 
        !          23389:                /*
        !          23390:                 * Second look to avoid interrupt race.
        !          23391:                 */
        !          23392:                if ( tp->RxBusy[code] )
        !          23393:                        return( POLLIN );
        !          23394:        }
        !          23395: 
        !          23396:        /*
        !          23397:         * Blocking Output poll.
        !          23398:         */
        !          23399:        if ( ev & POLLOUT ) {
        !          23400: 
        !          23401:                pollopen( &tp->TxPoll );
        !          23402: 
        !          23403:                /*
        !          23404:                 * Second look to avoid interrupt race.
        !          23405:                 * NOTE: When the LAN is down broadcasts [nid 0] are disabled.
        !          23406:                 */
        !          23407:                if ( (tp->TxIdle != 0) || (tp->bad[0] & 1) )
        !          23408:                        return( POLLOUT );
        !          23409:        }
        !          23410: 
        !          23411:        return( rev );
        !          23412: }
        !          23413: 
        !          23414: /*
        !          23415:  * Interrupt Entry Point - Card 0.
        !          23416:  */
        !          23417: void
        !          23418: tn0intr()
        !          23419: {
        !          23420:        tnintr( &tnet[0] );
        !          23421: }
        !          23422: 
        !          23423: /*
        !          23424:  * Interrupt Entry Point - Card 1.
        !          23425:  */
        !          23426: void
        !          23427: tn1intr()
        !          23428: {
        !          23429:        tnintr( &tnet[1] );
        !          23430: }
        !          23431: 
        !          23432: /*
        !          23433:  * Interrupt Entry Point - Card 2.
        !          23434:  */
        !          23435: void
        !          23436: tn2intr()
        !          23437: {
        !          23438:        tnintr( &tnet[2] );
        !          23439: }
        !          23440: 
        !          23441: /*
        !          23442:  * Interrupt Entry Point - Card 3.
        !          23443:  */
        !          23444: void
        !          23445: tn3intr()
        !          23446: {
        !          23447:        tnintr( &tnet[3] );
        !          23448: }
        !          23449: 
        !          23450: /*
        !          23451:  * Interrupt Handler.
        !          23452:  *
        !          23453:  *     Process transmit/receive interrupts.
        !          23454:  */
        !          23455: void
        !          23456: tnintr( tp )
        !          23457: register struct tnet_s * tp;
        !          23458: {
        !          23459:        register struct tnbuf_s * np;
        !          23460:        register int csr;
        !          23461:        int nid;
        !          23462:        int n;
        !          23463:        int bit;
        !          23464: 
        !          23465:        /*
        !          23466:         * Read interrupt status.
        !          23467:         * Disable interrupts to ensure edge occurs later.
        !          23468:         */
        !          23469:        csr = inb( NSR );
        !          23470:        tp->tnmask = NI_RECON;
        !          23471:        outb( NIR, 0 );
        !          23472: 
        !          23473:        /*
        !          23474:         * Reconfigurations with a period of 840 msec [600-1100]
        !          23475:         * increment tp->recon.  Other periods clear tp->recon.
        !          23476:         * After 5 reconfigurations at 840 msecs, the network is down.
        !          23477:         * After 1 reconfiguration at another interval, the network is up.
        !          23478:         * Network also comes up in tncycle() 5 seconds after last reconfig.
        !          23479:         */
        !          23480:        if ( csr & NS_RECON ) {
        !          23481: 
        !          23482:                outb( NCR, NC_RECON );
        !          23483:                nid = (unsigned) (lbolt - tp->rbolt) * (1000/HZ);
        !          23484:                tp->rbolt = lbolt;
        !          23485:                tp->recons++;
        !          23486: 
        !          23487:                /*
        !          23488:                 * Not a chained reconfiguration.
        !          23489:                 * Assume the network is up.
        !          23490:                 * NOTE: Expect 840 msecs, but allow interrupt latency slip.
        !          23491:                 */
        !          23492:                if ( (nid < 700) || (nid > 1000) ) {
        !          23493:                        if ( tp->bad[0] & 1 ) {
        !          23494:                                tp->mod[0] |=  1;
        !          23495:                                tp->bad[0] &= ~1;
        !          23496:                                tp->pri = 1;
        !          23497:                        }
        !          23498:                        tp->recon   =  0;
        !          23499:                }
        !          23500: 
        !          23501:                /*
        !          23502:                 * Chained reconfiguration - threshold exceeded.
        !          23503:                 */
        !          23504:                else if ( (++(tp->recon) == 5) && ((tp->bad[0] & 1) == 0) ) {
        !          23505:                        faddr_t fp = tp->statseg->s_faddr;
        !          23506:                        aflong( fp+TnSTATMOD*4, 1 );
        !          23507:                        memset( tp->bad, -1, sizeof(tp->bad) );
        !          23508:                        tp->mod[0] |= 1;
        !          23509:                        tp->pri = 1;
        !          23510:                }
        !          23511:        }
        !          23512: 
        !          23513:        /*
        !          23514:         * Service Power on Resets.
        !          23515:         */
        !          23516:        if ( csr & NS_POR ) {
        !          23517: 
        !          23518:                csr &= ~(NS_RxRDY|NS_TxRDY);    /* Ignore receive/transmit */
        !          23519:                outb( NCR, NC_DFC );            /* Define 2K buf config    */
        !          23520:                outb( NCR, NC_POR );            /* Clear POR flag          */
        !          23521: 
        !          23522:                /*
        !          23523:                 * Enable receiver
        !          23524:                 */
        !          23525:                if ( np = tp->RxIdle )
        !          23526:                        outb( NCR, np->tn_ena );
        !          23527: 
        !          23528:                /*
        !          23529:                 * Enable transmitter
        !          23530:                 */
        !          23531:                if ( np = tp->TxBusy )
        !          23532:                        outb( NCR, np->tn_ena );
        !          23533:        }
        !          23534: 
        !          23535:        /*
        !          23536:         * Service transmit interupts if transmit is pending.
        !          23537:         */
        !          23538:        if ( np = tp->TxBusy ) {
        !          23539: 
        !          23540:                tp->tnmask |= NI_Tx;
        !          23541: 
        !          23542:                /*
        !          23543:                 * Check for transmission completed.
        !          23544:                 */
        !          23545:                if ( csr & NS_TxRDY ) {
        !          23546: 
        !          23547:                        /*
        !          23548:                         * Destination Node Id is in 2nd byte of packet.
        !          23549:                         */
        !          23550:                        np->tn_off = np->tn_base + 1;
        !          23551:                        nid = tngetc( np );
        !          23552: 
        !          23553:                        /*
        !          23554:                         * Get length of short/long packets.
        !          23555:                         */
        !          23556:                        n = 256 - tngetc(np);
        !          23557:                        if ( n == 256 )
        !          23558:                                n = 512 - tngetc(np);
        !          23559: 
        !          23560:                        /*
        !          23561:                         * Transmitted packet was acknowledged.
        !          23562:                         */
        !          23563:                        if ( csr & NS_TxACK ) {
        !          23564:                                /*
        !          23565:                                 * Adjust global and node statistics.
        !          23566:                                 */
        !          23567:                                faddr_t fp = tp->statseg->s_faddr;
        !          23568:                                aflong( fp+TnTxPACKS*4, 1 );
        !          23569:                                aflong( fp+TnTxBYTES*4, n );
        !          23570:                                fp += nid * (NTNST * 4);
        !          23571:                                aflong( fp+TnTxPACKS*4, 1 );
        !          23572:                                aflong( fp+TnTxBYTES*4, n );
        !          23573:                        }
        !          23574: 
        !          23575:                        /*
        !          23576:                         * Transmitted packet was discarded.
        !          23577:                         * NOTE: Do not flag broadcast [nid 0] as bad.
        !          23578:                         */
        !          23579:                        else if ( nid != 0 ) {
        !          23580:                                /*
        !          23581:                                 * Adjust global and node statistics.
        !          23582:                                 */
        !          23583:                                faddr_t fp = tp->statseg->s_faddr;
        !          23584:                                aflong( fp+TnDISCARD*4, 1 );
        !          23585:                                fp += nid * (NTNST * 4);
        !          23586:                                aflong( fp+TnDISCARD*4, 1 );
        !          23587:                                aflong( fp+TnSTATMOD*4, 1 );
        !          23588: 
        !          23589:                                /*
        !          23590:                                 * Flag node as being bad.
        !          23591:                                 */
        !          23592:                                bit = bitm[ nid % 8 ];
        !          23593:                                tp->bad[ nid / 8 ] |= bit;
        !          23594:                                tp->mod[ nid / 8 ] |= bit;
        !          23595:                                tp->pri = 1;
        !          23596:                        }
        !          23597: 
        !          23598:                        /*
        !          23599:                         * Move packet buffer to idle transmit queue.
        !          23600:                         */
        !          23601:                        tp->TxBusy  = np->tn_next;
        !          23602:                        np->tn_next = tp->TxIdle;
        !          23603:                        tp->TxIdle  = np;
        !          23604: 
        !          23605:                        /*
        !          23606:                         * Check for another packet to transmit.
        !          23607:                         */
        !          23608:                        if ( np = tp->TxBusy ) {
        !          23609: 
        !          23610:                                /*
        !          23611:                                 * Enable transmitter, start watchdog timer.
        !          23612:                                 */
        !          23613:                                outb( NCR, np->tn_ena );
        !          23614:                                tp->tntime = TNTIME;
        !          23615:                        }
        !          23616: 
        !          23617:                        /*
        !          23618:                         * Disable Transmit Interrupt, clear watchdog timer.
        !          23619:                         */
        !          23620:                        else {
        !          23621:                                tp->tnmask &= ~NI_Tx;
        !          23622:                                tp->tntime  =  0;
        !          23623:                        }
        !          23624: 
        !          23625:                        /*
        !          23626:                         * Wake processes waiting to transmit.
        !          23627:                         */
        !          23628:                        if ( tp->TxReq ) {
        !          23629:                                tp->TxReq = 0;
        !          23630:                                defer( wakeup, &tp->TxReq );
        !          23631:                        }
        !          23632: 
        !          23633:                        if ( tp->TxPoll.e_procp )
        !          23634:                                defer( pollwake, &tp->TxPoll );
        !          23635:                }
        !          23636:        }
        !          23637: 
        !          23638:        /*
        !          23639:         * Check for receive request.
        !          23640:         */
        !          23641:        if ( np = tp->RxIdle ) {
        !          23642: 
        !          23643:                tp->tnmask |= NI_Rx;
        !          23644: 
        !          23645:                /*
        !          23646:                 * Check for packet received.
        !          23647:                 */
        !          23648:                if ( csr & NS_RxRDY ) {
        !          23649: 
        !          23650:                        /*
        !          23651:                         * Remove first packet from receive ready queue.
        !          23652:                         * Re-enable receiver or disable receive interrupts.
        !          23653:                         */
        !          23654:                        if ( tp->RxIdle = np->tn_next ) {
        !          23655:                                outb( NCR, np->tn_next->tn_ena );
        !          23656:                                np->tn_next = 0;
        !          23657:                        }
        !          23658:                        else
        !          23659:                                tp->tnmask &= ~NI_Rx;
        !          23660: 
        !          23661:                        /*
        !          23662:                         * Source Node Id is in 1st byte of packet.
        !          23663:                         */
        !          23664:                        np->tn_off = np->tn_base;
        !          23665:                        nid = tngetc( np );
        !          23666: 
        !          23667:                        /*
        !          23668:                         * Try to establish our Node Id if not already set.
        !          23669:                         * Destination Node Id (our station)
        !          23670:                         * is in 2nd byte of the received packet.
        !          23671:                         * NOTE: Always read node id byte.
        !          23672:                         *       This ensures offset bytes can be read.
        !          23673:                         */
        !          23674:                        if ( (n = tngetc(np)) && (tp->tnaddr[0] == 0) )
        !          23675:                                tp->tnaddr[0] = n;
        !          23676: 
        !          23677:                        /*
        !          23678:                         * Get offset to first data byte in short/long packet.
        !          23679:                         * Short packet offset is in 3rd byte of packet.
        !          23680:                         * Long  packet offset is in 4th byte of packet.
        !          23681:                         */
        !          23682:                        if ( n = tngetc(np) )
        !          23683:                                np->tn_off = np->tn_base + n;
        !          23684:                        else
        !          23685:                                np->tn_off = np->tn_base + tngetc(np);
        !          23686: 
        !          23687:                        /*
        !          23688:                         * LAN has come up.
        !          23689:                         * Clear bad flag for the broadcast node.
        !          23690:                         */
        !          23691:                        if ( tp->bad[0] & 1 ) {
        !          23692:                                tp->bad[ 0 ] &= ~1;
        !          23693:                                tp->mod[ 0 ] |=  1;
        !          23694:                                tp->pri = 1;
        !          23695:                        }
        !          23696: 
        !          23697:                        /*
        !          23698:                         * Node has come up.
        !          23699:                         * Clear bad flag for the Source Node.
        !          23700:                         */
        !          23701:                        bit = bitm[ nid % 8 ];
        !          23702:                        if ( tp->bad[ nid / 8 ] & bit ) {
        !          23703:                                faddr_t fp = tp->statseg->s_faddr;
        !          23704:                                aflong( fp+TnSTATMOD*4, 1 );
        !          23705:                                fp += nid * (NTNST * 4);
        !          23706:                                aflong( fp+TnSTATMOD*4, 1 );
        !          23707:                                tp->bad[ nid / 8 ] &= ~bit;
        !          23708:                                tp->mod[ nid / 8 ] |=  bit;
        !          23709:                                tp->pri = 1;
        !          23710:                        }
        !          23711: 
        !          23712:                        /*
        !          23713:                         * Get first data byte from packet.
        !          23714:                         */
        !          23715:                        bit = tngetc( np );
        !          23716: 
        !          23717:                        /*
        !          23718:                         * Determine prefix code associated with packet.
        !          23719:                         */
        !          23720:                        for ( n = 3; n > 0; n-- ) {
        !          23721:                                if ( TNPREFIX[n] == bit )
        !          23722:                                        break;
        !          23723:                        }
        !          23724: 
        !          23725:                        /*
        !          23726:                         * Interface is open.
        !          23727:                         */
        !          23728:                        if ( tp->refc[n] ) {
        !          23729: 
        !          23730:                                /*
        !          23731:                                 * Append received packet to received queue.
        !          23732:                                 * NOTE: At most 2 packets in any queue.
        !          23733:                                 */
        !          23734:                                if ( tp->RxBusy[n] )
        !          23735:                                        tp->RxBusy[n]->tn_next = np;
        !          23736:                                else
        !          23737:                                        tp->RxBusy[n] = np;
        !          23738:        
        !          23739:                                /*
        !          23740:                                 * Wake processes waiting to read.
        !          23741:                                 */
        !          23742:                                if ( tp->RxReq[n] ) {
        !          23743:                                        tp->RxReq[n] = 0;
        !          23744:                                        defer( wakeup, &tp->RxReq[n] );
        !          23745:                                }
        !          23746:        
        !          23747:                                if ( tp->RxPoll[n].e_procp )
        !          23748:                                        defer( pollwake, &tp->RxPoll[n] );
        !          23749:                        }
        !          23750: 
        !          23751:                        /*
        !          23752:                         * Interface is closed.
        !          23753:                         * Return packet to end of receive idle queue.
        !          23754:                         */
        !          23755:                        else
        !          23756:                                tn_rxena( tp, np );
        !          23757:                }
        !          23758:        }
        !          23759: 
        !          23760:        /*
        !          23761:         * Restore interrupt mask.
        !          23762:         */
        !          23763:        outb( NIR, tp->tnmask );
        !          23764: }
        !          23765: 
        !          23766: /*
        !          23767:  * Read Routine.
        !          23768:  *
        !          23769:  *     Wait for a packet to be received.
        !          23770:  *     Transform packet header and copy packet body.
        !          23771:  *     Place packet buffer on receive idle queue.
        !          23772:  *     If receiver was inhibited, enable receiver.
        !          23773:  */
        !          23774: 
        !          23775: 
        !          23776: tnread ( dev, iop )
        !          23777: 
        !          23778: dev_t dev;
        !          23779: register IO * iop;
        !          23780: 
        !          23781: {
        !          23782:        register struct tnet_s  * tp = &tnet[ dev & 3 ];
        !          23783:        register struct tnbuf_s * np;
        !          23784:        int code = (dev & 0x30) >> 4;
        !          23785:        unsigned len;
        !          23786:        unsigned cnt;
        !          23787:        unsigned srcid;
        !          23788:        int s;
        !          23789: 
        !          23790:        /*
        !          23791:         * Driver information requested.
        !          23792:         */
        !          23793:        if ( iop->io_ioc <= 2 + sizeof(tp->bad) + sizeof(tp->mod) ) {
        !          23794: 
        !          23795:                /*
        !          23796:                 * Supply null byte, then our node id.
        !          23797:                 */
        !          23798:                ioputc( 0, iop );
        !          23799:                ioputc( tp->tnaddr[0], iop );
        !          23800: 
        !          23801:                /*
        !          23802:                 * Bad and modified node bit masks requested.
        !          23803:                 * Disable interrupts during transfer to prevent
        !          23804:                 * critical race with tnintr().
        !          23805:                 */
        !          23806:                if ( iop->io_ioc == sizeof(tp->bad) + sizeof(tp->mod) ) {
        !          23807:                        sphi();
        !          23808:                        iowrite( iop, tp->bad, sizeof(tp->bad) );
        !          23809:                        iowrite( iop, tp->mod, sizeof(tp->mod) );
        !          23810:                        kclear( tp->mod, sizeof(tp->mod) );
        !          23811:                        tp->pri = 0;
        !          23812:                        splo();
        !          23813:                }
        !          23814: 
        !          23815:                /*
        !          23816:                 * Bad node bit mask requested.
        !          23817:                 */
        !          23818:                else if ( iop->io_ioc == sizeof(tp->bad) )
        !          23819:                        iowrite( iop, tp->bad, sizeof(tp->bad) );
        !          23820: 
        !          23821:                return;
        !          23822:        }
        !          23823: 
        !          23824:        /*
        !          23825:         * Wait for packet reception.
        !          23826:         */
        !          23827:        for ( ; ; ) {
        !          23828: 
        !          23829:                s = sphi( );
        !          23830: 
        !          23831:                /*
        !          23832:                 * Check for received packet.
        !          23833:                 */
        !          23834:                if ( np = tp->RxBusy[code] ) {
        !          23835:                        tp->RxBusy[code] = np->tn_next;
        !          23836:                        np->tn_next = 0;
        !          23837:                        spl( s );
        !          23838:                        break;
        !          23839:                }
        !          23840: 
        !          23841:                /*
        !          23842:                 * Non-blocking reads.
        !          23843:                 */
        !          23844:                if ( iop->io_flag & IONDLY ) {
        !          23845:                        u.u_error = EAGAIN;
        !          23846:                        spl( s );
        !          23847:                        return;
        !          23848:                }
        !          23849: 
        !          23850:                tp->RxReq[code] = 1;
        !          23851: 
        !          23852:                sleep( &tp->RxReq[code], CVTTIN, IVTTIN, SVTTIN );
        !          23853:                spl( s );
        !          23854: 
        !          23855:                /*
        !          23856:                 * Check for pending signal.
        !          23857:                 */
        !          23858:                if ( nondsig() ) {
        !          23859:                        u.u_error = EINTR;
        !          23860:                        return;
        !          23861:                }
        !          23862:        }
        !          23863: 
        !          23864:        /*
        !          23865:         * Copy source and destination node ids
        !          23866:         */
        !          23867:        np->tn_off = np->tn_base;
        !          23868:        ioputc( srcid = tngetc(np), iop );
        !          23869:        ioputc( tngetc(np), iop );
        !          23870: 
        !          23871:        /*
        !          23872:         * Check for short packet.
        !          23873:         */
        !          23874:        if ( cnt = tngetc(np) ) {
        !          23875: 
        !          23876:                np->tn_off = np->tn_base + cnt;
        !          23877:                len = 256 - cnt;
        !          23878:        }
        !          23879: 
        !          23880:        /*
        !          23881:         * Check for long packet.
        !          23882:         */
        !          23883:        else if ( cnt = tngetc(np) ) {
        !          23884: 
        !          23885:                np->tn_off = np->tn_base + cnt;
        !          23886:                len = 512 - cnt;
        !          23887:        }
        !          23888: 
        !          23889:        /*
        !          23890:         * Check for non-empty packet.
        !          23891:         */
        !          23892:        if ( cnt != 0 ) {
        !          23893: 
        !          23894:                /*
        !          23895:                 * Truncate packet if necessary.
        !          23896:                 */
        !          23897:                if ( iop->io_ioc < len )
        !          23898:                        len = iop->io_ioc;
        !          23899: 
        !          23900:                /*
        !          23901:                 * Copy packet body.
        !          23902:                 */
        !          23903:                tucopy( np, iop->io_base, len );
        !          23904:                iop->io_ioc  -= len;
        !          23905:                iop->io_base += len;
        !          23906:        }
        !          23907: 
        !          23908:        /*
        !          23909:         * Adjust received data statistics.
        !          23910:         */
        !          23911:        if ( tp->statseg != NULL ) {
        !          23912:                faddr_t fp = tp->statseg->s_faddr;
        !          23913:                aflong( fp+TnRxPACKS*4, 1 );
        !          23914:                aflong( fp+TnRxBYTES*4, len );
        !          23915:                fp += srcid * (NTNST * 4);
        !          23916:                aflong( fp+TnRxPACKS*4, 1 );
        !          23917:                aflong( fp+TnRxBYTES*4, len );
        !          23918:        }
        !          23919: 
        !          23920:        /*
        !          23921:         * Enable packet reception with buffer.
        !          23922:         */
        !          23923:        tn_rxena( tp, np );
        !          23924: }
        !          23925: 
        !          23926: 
        !          23927: /*
        !          23928:  * Write Routine.
        !          23929:  *
        !          23930:  *     Wait for a empty transmit buffer to become available.
        !          23931:  *     Format the buffer and place on transmit queue.
        !          23932:  *     If transmit queue was empty, start transmitter.
        !          23933:  */
        !          23934: 
        !          23935: tnwrite ( dev, iop )
        !          23936: 
        !          23937: dev_t dev;
        !          23938: register IO * iop;
        !          23939: 
        !          23940: {
        !          23941:        register struct tnet_s  * tp = &tnet[ dev & 3 ];
        !          23942:        register struct tnbuf_s * np;
        !          23943:        unsigned len, cnt;
        !          23944:        int dstid;
        !          23945:        int s;
        !          23946: 
        !          23947:        /*
        !          23948:         * Validate size of write.
        !          23949:         */
        !          23950:        if ( ( iop->io_ioc < 3 ) || ( iop->io_ioc > 510 ) ) {
        !          23951:                u.u_error = EINVAL;
        !          23952:                return;
        !          23953:        }
        !          23954: 
        !          23955:        /*
        !          23956:         * Destination Node Id is 2nd byte of write.
        !          23957:         */
        !          23958:        iogetc( iop );
        !          23959:        dstid = iogetc( iop );
        !          23960: 
        !          23961:        /*
        !          23962:         * Wait for empty transmit buffer.
        !          23963:         */
        !          23964:        for ( ; ; ) {
        !          23965: 
        !          23966:                /*
        !          23967:                 * If Destination Node appears bad, set errno to EDATTN.
        !          23968:                 */
        !          23969:                if ( tp->bad[ dstid / 8 ] & (1 << (dstid % 8)) ) {
        !          23970:                        u.u_error = EDATTN;
        !          23971:                        return;
        !          23972:                }
        !          23973: 
        !          23974:                s = sphi( );
        !          23975: 
        !          23976:                /*
        !          23977:                 * Check for empty transmit buffer.
        !          23978:                 */
        !          23979:                if ( np = tp->TxIdle ) {
        !          23980: 
        !          23981:                        tp->TxIdle  = np->tn_next;
        !          23982:                        np->tn_next = 0;
        !          23983:                        spl( s );
        !          23984:                        break;
        !          23985:                }
        !          23986: 
        !          23987:                /*
        !          23988:                 * Non-blocking writes.
        !          23989:                 */
        !          23990:                if ( iop->io_flag & IONDLY ) {
        !          23991:                        /*
        !          23992:                         * Adjust delayed write stats.
        !          23993:                         */
        !          23994:                        faddr_t fp = tp->statseg->s_faddr;
        !          23995:                        aflong( fp+TnWRTDLYS*4, 1 );
        !          23996:                        fp += dstid * (NTNST * 4);
        !          23997:                        aflong( fp+TnWRTDLYS*4, 1 );
        !          23998: 
        !          23999:                        u.u_error = EAGAIN;
        !          24000:                        spl( s );
        !          24001:                        return;
        !          24002:                }
        !          24003: 
        !          24004:                tp->TxReq = 1;
        !          24005:                sleep( &tp->TxReq, CVTTOUT, IVTTOUT, SVTTOUT );
        !          24006:                spl( s );
        !          24007: 
        !          24008:                /*
        !          24009:                 * Check for pending signal.
        !          24010:                 */
        !          24011:                if ( nondsig() ) {
        !          24012:                        u.u_error = EINTR;
        !          24013:                        return;
        !          24014:                }
        !          24015:        }
        !          24016: 
        !          24017:        /*
        !          24018:         * Copy source and destination node ids
        !          24019:         * NOTE: Hardware inserts source node id automatically.
        !          24020:         */
        !          24021:        np->tn_off = np->tn_base;
        !          24022:        tnputc( np, 0 );
        !          24023:        tnputc( np, dstid );
        !          24024: 
        !          24025:        len = iop->io_ioc;
        !          24026: 
        !          24027:        /*
        !          24028:         * Check for long packet.
        !          24029:         */
        !          24030:        if ( len > 253 ) {
        !          24031:                tnputc( np, 0 );
        !          24032:                tnputc( np, cnt = 512 - len );
        !          24033:                np->tn_off = np->tn_base + cnt;
        !          24034:        }
        !          24035: 
        !          24036:        /*
        !          24037:         * Short packet.
        !          24038:         */
        !          24039:        else {
        !          24040:                tnputc( np, cnt = 256 - len );
        !          24041:                np->tn_off = np->tn_base + cnt;
        !          24042:        }
        !          24043: 
        !          24044:        /*
        !          24045:         * Copy packet body.
        !          24046:         */
        !          24047:        utcopy( iop->io_base, np, len );
        !          24048:        iop->io_base += len;
        !          24049:        iop->io_ioc  -= len;
        !          24050: 
        !          24051:        /*
        !          24052:         * Record length in header structure.
        !          24053:         */
        !          24054:        np->tn_xlen = iop->io_ioc;
        !          24055: 
        !          24056:        sphi();
        !          24057: 
        !          24058:        /*
        !          24059:         * Put packet on transmit ready queue, prime transmitter if necessary.
        !          24060:         */
        !          24061:        if ( ! tp->TxBusy ) {
        !          24062:                tp->TxBusy = np;
        !          24063:                outb( NCR, np->tn_ena );         /* enable transmitter  */
        !          24064:                outb( NIR, tp->tnmask |= NI_Tx); /* enable xmit intr    */
        !          24065:                tp->tntime = TNTIME;             /* restart watchdog    */
        !          24066:        }
        !          24067:        else
        !          24068:                tp->TxBusy->tn_next = np;
        !          24069: 
        !          24070:        spl(s);
        !          24071: }
        !          24072: 
        !          24073: /*
        !          24074:  * Enable packet reception with buffer.
        !          24075:  */
        !          24076: tn_rxena( tp, np )
        !          24077: register struct tnet_s  * tp;
        !          24078: register struct tnbuf_s * np;
        !          24079: {
        !          24080:        int s;
        !          24081: 
        !          24082:        s = sphi( );
        !          24083: 
        !          24084:        /*
        !          24085:         * Put packet on receive ready queue, prime receiver if necessary.
        !          24086:         */
        !          24087:        if ( tp->RxIdle == NULL ) {
        !          24088:                tp->RxIdle = np;
        !          24089:                outb( NCR, np->tn_ena );
        !          24090:                outb( NIR, tp->tnmask |= NI_Rx );
        !          24091:        }
        !          24092:        else
        !          24093:                tp->RxIdle->tn_next = np;
        !          24094: 
        !          24095:        np->tn_next = 0;
        !          24096:        spl( s );
        !          24097: }
        !          24098: 
        !          24099: /*
        !          24100:  * Adjust far long.
        !          24101:  */
        !          24102: static
        !          24103: aflong( fp, i )
        !          24104: faddr_t fp;
        !          24105: int i;
        !          24106: {
        !          24107:        long lw;
        !          24108: 
        !          24109:        fkcopy( fp, &lw, sizeof(lw) );
        !          24110:        lw += i;
        !          24111:        kfcopy( &lw, fp, sizeof(lw) );
        !          24112: }
        !          24113: 0707070064030150031004440000030000030000011777770507310645300005000000007023/newbits/kernel/USRSRC/i8086/drv/tnas.s/ (lgl-
        !          24114: /      COHERENT Driver Kit Version 1.1.0
        !          24115: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          24116: /      All rights reserved. May not be copied without permission.
        !          24117: / -lgl)
        !          24118: ////////
        !          24119: /
        !          24120: / Tiac Network Assembler Support
        !          24121: /
        !          24122: /      tngetc( np )            -- get a character from a tiac network buffer
        !          24123: /      tnputc( np, c)          -- put a character into a tiac network buffer
        !          24124: /      tucopy( np, up, n)      -- copy n bytes from tiac buffer to user space
        !          24125: /      utcopy( up, np, n)      -- copy n bytes from user space to tiac buffer
        !          24126: /
        !          24127: ////////
        !          24128: 
        !          24129:        .globl  tngetc_
        !          24130:        .globl  tnputc_
        !          24131:        .globl  tucopy_
        !          24132:        .globl  utcopy_
        !          24133: 
        !          24134: ////////
        !          24135: /
        !          24136: / Tngetc ( np )
        !          24137: /
        !          24138: /      Input:  np = pointer to seg:offset pair for tiac network buffer
        !          24139: /
        !          24140: /      Action: Read character from network buffer, increment offset.
        !          24141: /
        !          24142: /      Return: Character.
        !          24143: /
        !          24144: ////////
        !          24145: 
        !          24146: tngetc_:                               / tngetc( np )
        !          24147:        push    si                      / char **np;
        !          24148:        push    bp                      / {
        !          24149:        mov     bp, sp                  /       register char c;        /* AX */
        !          24150:        mov     bx, 6(bp)               /       register char *cp;      /* SI */
        !          24151:        push    ds                      /
        !          24152:        lds     si, (bx)                /       cp = *np;
        !          24153:        cld                             /
        !          24154:        lodsb                           /       c = *cp++;
        !          24155:        pop     ds                      /
        !          24156:        mov     (bx), si                /       *np = cp;
        !          24157:        subb    ah, ah                  /
        !          24158:        pop     bp                      /       return( c );
        !          24159:        pop     si                      / }
        !          24160:        ret
        !          24161: 
        !          24162: ////////
        !          24163: /
        !          24164: / Tnputc ( np, c )
        !          24165: / char **np;
        !          24166: / char c;
        !          24167: /
        !          24168: /      Input:  np = pointer to seg:offset pair for tiac network buffer
        !          24169: /              c  = character to transfer
        !          24170: /
        !          24171: /      Action: Transfer character C to network buffer, increment offset.
        !          24172: /
        !          24173: /      Return: Character C.
        !          24174: /
        !          24175: ////////
        !          24176: 
        !          24177: tnputc_:                               / tnputc( np, c )
        !          24178:        push    di                      / char **np;                    /* BX */
        !          24179:        push    bp                      / char c;                       /* AX */
        !          24180:        mov     bp, sp                  / {
        !          24181:        mov     ax, 8(bp)               /       register char *cp;      /* DI */
        !          24182:        mov     bx, 6(bp)               /
        !          24183:        push    es                      /
        !          24184:        les     di, (bx)                /       cp = *np;
        !          24185:        cld                             /
        !          24186:        stosb                           /       *cp++ = c;
        !          24187:        pop     es                      /
        !          24188:        mov     (bx), di                /       *np = cp;
        !          24189:        pop     bp                      /
        !          24190:        pop     di                      /       return c;
        !          24191:        ret                             / }
        !          24192: 
        !          24193: ////////
        !          24194: /
        !          24195: / utcopy( up, np, n )
        !          24196: / char * up;
        !          24197: / char **np;
        !          24198: / unsigned n;
        !          24199: /
        !          24200: /      Input:  up = offset in user data space for source data
        !          24201: /              np = pointer to seg:offset pair for tiac network buffer
        !          24202: /              n  = number of bytes to transfer
        !          24203: /
        !          24204: /      Action: Copy N bytes from user data space to network data space.
        !          24205: /              Add N to network data space offset.
        !          24206: /
        !          24207: /      Return: None.
        !          24208: /
        !          24209: ////////
        !          24210: 
        !          24211: utcopy_:                               / utcopy( up, np, n )
        !          24212:        push    si                      /
        !          24213:        push    di                      / register char *  up;          /* SI */
        !          24214:        push    bp                      / register char ** np;          /* BX */
        !          24215:        mov     bp, sp                  / register unsigned n;          /* CX */
        !          24216:        push    ds                      /
        !          24217:        push    es                      / {
        !          24218:        mov     bx, 10(bp)              /       register char * cp;     /* DI */
        !          24219:                                        /
        !          24220:        les     di, (bx)                /       cp = *np;
        !          24221:                                        /
        !          24222:        mov     si, 8(bp)               /       up;
        !          24223:        mov     ds, uds_                /
        !          24224:                                        /
        !          24225:        mov     cx, 12(bp)              /       n;
        !          24226:                                        /
        !          24227:        cld                             /
        !          24228:        clc                             /
        !          24229:        rcr     cx, $1                  /
        !          24230:        rep                             /       for ( ; n != 0; --n )
        !          24231:        movsw                           /               *cp++ = *up++;
        !          24232:        rcl     cx, $1                  /
        !          24233:        rep                             /
        !          24234:        movsb                           /
        !          24235:                                        /
        !          24236:        pop     es                      /
        !          24237:        pop     ds                      /
        !          24238:        mov     (bx), di                /       *np = cp;
        !          24239:        pop     bp                      / }
        !          24240:        pop     di
        !          24241:        pop     si
        !          24242:        ret
        !          24243: 
        !          24244: ////////
        !          24245: /
        !          24246: / tucopy( np, up, n )
        !          24247: / char **np;
        !          24248: / char * up;
        !          24249: / unsigned n;
        !          24250: /
        !          24251: /      Input:  np = pointer to seg:offset pair for tiac network buffer
        !          24252: /              up = offset in user data space for destination
        !          24253: /              n  = number of bytes to transfer
        !          24254: /
        !          24255: /      Action: Copy N bytes from network data space to user data space.
        !          24256: /              Add N to network data space offset.
        !          24257: /
        !          24258: /      Return: None.
        !          24259: /
        !          24260: ////////
        !          24261: 
        !          24262: tucopy_:                               / tucopy( np, up, n )
        !          24263:        push    si                      /
        !          24264:        push    di                      / register char ** np;          /* BX */
        !          24265:        push    bp                      / register char *  up;          /* DI */
        !          24266:        mov     bp, sp                  / register unsigned n;          /* CX */
        !          24267:        push    ds                      /
        !          24268:        push    es                      / {
        !          24269:        mov     bx, 8(bp)               /       register char * cp;     /* SI */
        !          24270:                                        /
        !          24271:        mov     di, 10(bp)              /       up;
        !          24272:        mov     es, uds_                /
        !          24273:                                        /
        !          24274:        lds     si, (bx)                /       cp = *np;
        !          24275:                                        /
        !          24276:        mov     cx, 12(bp)              /       n;
        !          24277:                                        /
        !          24278:        cld                             /
        !          24279:        clc                             /
        !          24280:        rcr     cx, $1                  /
        !          24281:        rep                             /       for ( ; n != 0; --n )
        !          24282:        movsw                           /               *up++ = *cp++;
        !          24283:        rcl     cx, $1                  /
        !          24284:        rep                             /
        !          24285:        movsb                           /
        !          24286:                                        /
        !          24287:        pop     es                      /
        !          24288:        pop     ds                      /
        !          24289:        mov     (bx), si                /       *np = cp;
        !          24290:        pop     bp                      / }
        !          24291:        pop     di
        !          24292:        pop     si
        !          24293:        ret
        !          24294: 0707070064030104430407770000030000030000011777770507310645400004500000000000/newbits/kernel/USRSRC/i8086/drv/RCS0707070064030110721004440000030000030000011777770507310645400006000000063306/newbits/kernel/USRSRC/i8086/drv/RCS/Makefile,vhead     1.7;
        !          24295: branch   ;
        !          24296: access   ;
        !          24297: symbols  ;
        !          24298: locks    bin:1.7;
        !          24299: comment  @@;
        !          24300: 
        !          24301: 
        !          24302: 1.7
        !          24303: date     91.07.24.07.58.40;  author bin;  state Exp;
        !          24304: branches ;
        !          24305: next     1.6;
        !          24306: 
        !          24307: 1.6
        !          24308: date     91.07.15.14.46.09;  author bin;  state Exp;
        !          24309: branches ;
        !          24310: next     1.5;
        !          24311: 
        !          24312: 1.5
        !          24313: date     91.07.03.13.19.17;  author bin;  state Exp;
        !          24314: branches ;
        !          24315: next     1.4;
        !          24316: 
        !          24317: 1.4
        !          24318: date     91.06.20.14.46.25;  author bin;  state Exp;
        !          24319: branches ;
        !          24320: next     1.3;
        !          24321: 
        !          24322: 1.3
        !          24323: date     91.06.18.08.41.07;  author bin;  state Exp;
        !          24324: branches ;
        !          24325: next     1.2;
        !          24326: 
        !          24327: 1.2
        !          24328: date     91.06.18.08.18.14;  author bin;  state Exp;
        !          24329: branches ;
        !          24330: next     1.1;
        !          24331: 
        !          24332: 1.1
        !          24333: date     90.08.02.13.38.48;  author root;  state Exp;
        !          24334: branches ;
        !          24335: next     ;
        !          24336: 
        !          24337: 
        !          24338: desc
        !          24339: @From alpha driver kit
        !          24340: @
        !          24341: 
        !          24342: 
        !          24343: 1.7
        !          24344: log
        !          24345: @update prov by hal
        !          24346: @
        !          24347: text
        !          24348: @# Makefile for AT specific Coherent drivers
        !          24349: 
        !          24350: # System utility directory
        !          24351: USRSYS=/usr/sys
        !          24352: 
        !          24353: # Source directory
        !          24354: USRSRC=/usr/src/sys
        !          24355: 
        !          24356: # Loadable driver directory
        !          24357: LDRV=$(USRSYS)/ldrv
        !          24358: 
        !          24359: # Include directories
        !          24360: USRINC=/usr/include
        !          24361: SYSINC=/usr/include/sys
        !          24362: 
        !          24363: # Object directory
        !          24364: KOBJ=/usr/kobj
        !          24365: 
        !          24366: ARCHIVES=\
        !          24367:        $(USRSYS)/lib/al.a \
        !          24368:        $(USRSYS)/lib/at.a \
        !          24369:        $(USRSYS)/lib/ati.a \
        !          24370:        $(USRSYS)/lib/fl.a \
        !          24371:        $(USRSYS)/lib/gr.a \
        !          24372:        $(USRSYS)/lib/hs.a \
        !          24373:        $(USRSYS)/lib/kb.a \
        !          24374:        $(USRSYS)/lib/lp.a \
        !          24375:        $(USRSYS)/lib/mm.a \
        !          24376:        $(USRSYS)/lib/ms.a \
        !          24377:        $(USRSYS)/lib/rm.a \
        !          24378:        $(USRSYS)/lib/rs.a \
        !          24379:        $(USRSYS)/lib/st.a \
        !          24380:        $(USRSYS)/lib/tn.a \
        !          24381: 
        !          24382: DRVOBJ=\
        !          24383:        $(KOBJ)/alx.o \
        !          24384:        $(KOBJ)/at.o \
        !          24385:        $(KOBJ)/atas.o \
        !          24386:        $(KOBJ)/ms.o \
        !          24387:        $(KOBJ)/ati.o \
        !          24388:        $(KOBJ)/com1.o $(KOBJ)/com2.o \
        !          24389:        $(KOBJ)/fdisk.o \
        !          24390:        $(KOBJ)/fl.o \
        !          24391:        $(KOBJ)/fontw.o \
        !          24392:        $(KOBJ)/gr.o $(KOBJ)/gras.o \
        !          24393:        $(KOBJ)/hs.o \
        !          24394:        $(KOBJ)/kb.o \
        !          24395:        $(KOBJ)/mm.o \
        !          24396:        $(KOBJ)/lp.o \
        !          24397:        $(KOBJ)/mmas.o \
        !          24398:        $(KOBJ)/rm.o \
        !          24399:        $(KOBJ)/rs0.o $(KOBJ)/rs1.o $(KOBJ)/rsas.o \
        !          24400:        $(KOBJ)/st.o \
        !          24401:        $(KOBJ)/tn.o $(KOBJ)/tnas.o
        !          24402: 
        !          24403: DRIVERS=\
        !          24404:        $(LDRV)/al0 \
        !          24405:        $(LDRV)/al1 \
        !          24406:        $(LDRV)/at \
        !          24407:        $(LDRV)/fl \
        !          24408:        $(LDRV)/gr \
        !          24409:        $(LDRV)/hs \
        !          24410:        $(LDRV)/lp \
        !          24411:        $(LDRV)/mm \
        !          24412:        $(LDRV)/ms \
        !          24413:        $(LDRV)/rm
        !          24414: 
        !          24415: install: $(ARCHIVES) $(DRIVERS)
        !          24416:        @@exec /bin/sync
        !          24417: 
        !          24418: all:   $(DRVOBJ)
        !          24419:        @@exec /bin/sync
        !          24420: 
        !          24421: $(USRSYS)/lib/al.a: $(KOBJ)/com1.o $(KOBJ)/com2.o $(KOBJ)/alx.o
        !          24422:        rm -f $@@
        !          24423:        ar rc $@@ $<
        !          24424: $(USRSYS)/lib/at.a: $(KOBJ)/at.o $(KOBJ)/atas.o $(KOBJ)/fdisk.o
        !          24425:        rm -f $@@
        !          24426:        ar rc $@@ $<
        !          24427: $(USRSYS)/lib/ati.a: $(KOBJ)/mm.o $(KOBJ)/ati.o
        !          24428:        rm -f $@@
        !          24429:        ar rc $@@ $<
        !          24430: $(USRSYS)/lib/fl.a: $(KOBJ)/fl.o
        !          24431:        rm -f $(USRSYS)/lib/fl.a
        !          24432:        ar rc $(USRSYS)/lib/fl.a $(KOBJ)/fl.o
        !          24433: $(USRSYS)/lib/gr.a: $(KOBJ)/mm.o $(KOBJ)/gr.o $(KOBJ)/gras.o \
        !          24434:                                $(KOBJ)/fontw.o
        !          24435:        rm -f $@@
        !          24436:        ar rc $@@ $<
        !          24437: $(USRSYS)/lib/hs.a: $(KOBJ)/hs.o
        !          24438:        rm -f $@@
        !          24439:        ar rc $@@ $<
        !          24440: $(USRSYS)/lib/kb.a: $(KOBJ)/kb.o
        !          24441:        rm -f $@@
        !          24442:        ar rc $@@ $<
        !          24443: $(USRSYS)/lib/lp.a: $(KOBJ)/lp.o
        !          24444:        rm -f $@@
        !          24445:        ar rc $@@ $<
        !          24446: $(USRSYS)/lib/mm.a: $(KOBJ)/mm.o $(KOBJ)/mmas.o
        !          24447:        rm -f $@@
        !          24448:        ar rc $@@ $<
        !          24449: $(USRSYS)/lib/ms.a: $(KOBJ)/ms.o
        !          24450:        rm -f $@@
        !          24451:        ar rc $@@ $<
        !          24452: $(USRSYS)/lib/rm.a: $(KOBJ)/rm.o
        !          24453:        rm -f $@@
        !          24454:        ar rc $@@ $<
        !          24455: $(USRSYS)/lib/rs.a: $(KOBJ)/rs0.o $(KOBJ)/rs1.o $(KOBJ)/rsas.o
        !          24456:        rm -f $@@
        !          24457:        ar rc $@@ $<
        !          24458: $(USRSYS)/lib/st.a: $(KOBJ)/st.o
        !          24459:        rm -f $@@
        !          24460:        ar rc $@@ $<
        !          24461: $(USRSYS)/lib/tn.a: $(KOBJ)/tn.o $(KOBJ)/tnas.o
        !          24462:        rm -f $@@
        !          24463:        ar rc $@@ $<
        !          24464: 
        !          24465: $(KOBJ)/alx.o:                         \
        !          24466:                $(SYSINC)/clist.h       \
        !          24467:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24468:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24469:                                        $(SYSINC)/fun.h \
        !          24470:                $(SYSINC)/con.h         \
        !          24471:                $(USRINC)/errno.h       \
        !          24472:                $(SYSINC)/i8086.h       \
        !          24473:                $(SYSINC)/ins8250.h     \
        !          24474:                $(SYSINC)/sched.h       \
        !          24475:                $(SYSINC)/stat.h        \
        !          24476:                $(SYSINC)/timeout.h     \
        !          24477:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          24478:                $(SYSINC)/uproc.h       \
        !          24479:                alx.c
        !          24480:        $(CC) $(CFLAGS) -c -o $@@ alx.c
        !          24481: 
        !          24482: $(KOBJ)/at.o: at.c                     \
        !          24483:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24484:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24485:                                        $(SYSINC)/fun.h \
        !          24486:                $(SYSINC)/fdisk.h       \
        !          24487:                $(SYSINC)/hdioctl.h     \
        !          24488:                $(SYSINC)/buf.h         \
        !          24489:                $(SYSINC)/con.h         \
        !          24490:                $(SYSINC)/devices.h     \
        !          24491:                $(SYSINC)/stat.h        \
        !          24492:                $(SYSINC)/uproc.h       \
        !          24493:                $(USRINC)/errno.h
        !          24494:        $(CC) $(CFLAGS) -DVERBOSE=1 -c -o $@@ at.c
        !          24495: 
        !          24496: $(KOBJ)/atas.o: atas.s
        !          24497:        $(AS) -go $@@ $<
        !          24498: 
        !          24499: $(KOBJ)/ati.o: ati.m
        !          24500:        $(CC) $(CFLAGS) -DATI_132=1 -c -o $@@ ati.m
        !          24501: 
        !          24502: $(KOBJ)/com1.o:                        \
        !          24503:                $(SYSINC)/al.h          \
        !          24504:                $(SYSINC)/clist.h       \
        !          24505:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24506:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24507:                                        $(SYSINC)/fun.h \
        !          24508:                $(SYSINC)/con.h         \
        !          24509:                $(SYSINC)/devices.h     \
        !          24510:                $(USRINC)/errno.h       \
        !          24511:                $(SYSINC)/i8086.h       \
        !          24512:                $(SYSINC)/ins8250.h     \
        !          24513:                $(SYSINC)/sched.h       \
        !          24514:                $(SYSINC)/stat.h        \
        !          24515:                $(SYSINC)/timeout.h     \
        !          24516:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          24517:                $(SYSINC)/uproc.h       \
        !          24518:                al.c
        !          24519:        $(CC) $(CFLAGS) -DALCOM1=1 -c -o $@@ al.c
        !          24520: 
        !          24521: $(KOBJ)/com2.o:                        \
        !          24522:                $(SYSINC)/al.h          \
        !          24523:                $(SYSINC)/clist.h       \
        !          24524:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24525:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24526:                                        $(SYSINC)/fun.h \
        !          24527:                $(SYSINC)/con.h         \
        !          24528:                $(SYSINC)/devices.h     \
        !          24529:                $(USRINC)/errno.h       \
        !          24530:                $(SYSINC)/i8086.h       \
        !          24531:                $(SYSINC)/ins8250.h     \
        !          24532:                $(SYSINC)/sched.h       \
        !          24533:                $(SYSINC)/stat.h        \
        !          24534:                $(SYSINC)/timeout.h     \
        !          24535:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          24536:                $(SYSINC)/uproc.h       \
        !          24537:                al.c
        !          24538:        $(CC) $(CFLAGS) -DALCOM2=1 -c -o $@@ al.c
        !          24539: 
        !          24540: $(KOBJ)/fdisk.o:                       \
        !          24541:                $(SYSINC)/buf.h         \
        !          24542:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24543:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24544:                                        $(SYSINC)/fun.h \
        !          24545:                $(SYSINC)/con.h         \
        !          24546:                $(USRINC)/errno.h       \
        !          24547:                $(SYSINC)/fdisk.h       \
        !          24548:                $(SYSINC)/inode.h       \
        !          24549:                $(SYSINC)/uproc.h       \
        !          24550:                fdisk.c
        !          24551:        $(CC) $(CFLAGS) -c -o $@@ fdisk.c
        !          24552: 
        !          24553: $(KOBJ)/fl.o:                          \
        !          24554:                $(SYSINC)/buf.h         \
        !          24555:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24556:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24557:                                        $(SYSINC)/fun.h \
        !          24558:                $(SYSINC)/con.h         \
        !          24559:                $(SYSINC)/devices.h     \
        !          24560:                $(SYSINC)/dmac.h        \
        !          24561:                $(USRINC)/errno.h       \
        !          24562:                $(SYSINC)/fdioctl.h     \
        !          24563:                $(SYSINC)/i8086.h       \
        !          24564:                $(SYSINC)/sched.h       \
        !          24565:                $(SYSINC)/stat.h        \
        !          24566:                $(SYSINC)/timeout.h     \
        !          24567:                $(SYSINC)/uproc.h       \
        !          24568:                fl.c
        !          24569:        $(CC) $(CFLAGS) -c -o $@@ fl.c
        !          24570: 
        !          24571: $(KOBJ)/fontw.o: tools/fontgen.c
        !          24572:        $(CC) -o tools/fontgen tools/fontgen.c
        !          24573:        exec tools/fontgen > fontw.s
        !          24574:        exec /bin/rm tools/fontgen
        !          24575:        $(AS) -gxo $(KOBJ)/fontw.o fontw.s
        !          24576:        exec /bin/rm fontw.s
        !          24577: 
        !          24578: $(KOBJ)/gr.o:                          \
        !          24579:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24580:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24581:                                        $(SYSINC)/fun.h \
        !          24582:                $(SYSINC)/con.h         \
        !          24583:                $(SYSINC)/devices.h     \
        !          24584:                $(USRINC)/errno.h       \
        !          24585:                $(SYSINC)/sched.h       \
        !          24586:                $(SYSINC)/timeout.h     \
        !          24587:                $(SYSINC)/types.h       \
        !          24588:                $(SYSINC)/uproc.h       \
        !          24589:                gr.c
        !          24590:        $(CC) $(CFLAGS) -c -o $@@ gr.c
        !          24591: 
        !          24592: $(KOBJ)/gras.o: gras.m
        !          24593:        $(CC) $(CFLAGS) -c -o $@@ gras.m
        !          24594: 
        !          24595: $(KOBJ)/hgas.o: gras.s
        !          24596:        $(CC) $(CFLAGS) -c -o $@@ -DHERCULES gras.m
        !          24597: 
        !          24598: $(KOBJ)/hs.o:                          \
        !          24599:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24600:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24601:                                        $(SYSINC)/fun.h \
        !          24602:                $(SYSINC)/con.h         \
        !          24603:                $(SYSINC)/devices.h     \
        !          24604:                $(USRINC)/errno.h       \
        !          24605:                $(SYSINC)/ins8250.h     \
        !          24606:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          24607:                $(SYSINC)/stat.h        \
        !          24608:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          24609:                $(SYSINC)/uproc.h       \
        !          24610:                hs.c
        !          24611:        $(CC) $(CFLAGS) -c -o $@@ hs.c
        !          24612: 
        !          24613: $(KOBJ)/kb.o:                          \
        !          24614:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24615:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24616:                                        $(SYSINC)/fun.h \
        !          24617:                $(SYSINC)/con.h         \
        !          24618:                $(SYSINC)/devices.h     \
        !          24619:                $(USRINC)/errno.h       \
        !          24620:                $(SYSINC)/i8086.h       \
        !          24621:                $(SYSINC)/sched.h       \
        !          24622:                $(USRINC)/signal.h      \
        !          24623:                $(SYSINC)/stat.h        \
        !          24624:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          24625:                $(SYSINC)/uproc.h       \
        !          24626:                kb.c
        !          24627:        $(CC) $(CFLAGS) -c -o $@@ kb.c
        !          24628: 
        !          24629: $(KOBJ)/lp.o:                          \
        !          24630:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24631:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24632:                                        $(SYSINC)/fun.h \
        !          24633:                $(SYSINC)/con.h         \
        !          24634:                $(SYSINC)/devices.h     \
        !          24635:                $(USRINC)/errno.h       \
        !          24636:                $(SYSINC)/i8086.h       \
        !          24637:                $(SYSINC)/io.h          \
        !          24638:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          24639:                $(SYSINC)/stat.h        \
        !          24640:                $(SYSINC)/timeout.h     \
        !          24641:                $(SYSINC)/uproc.h       \
        !          24642:                lp.c
        !          24643:        $(CC) $(CFLAGS) -c -o $@@ lp.c
        !          24644: 
        !          24645: $(KOBJ)/mm.o:                          \
        !          24646:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24647:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24648:                                        $(SYSINC)/fun.h \
        !          24649:                $(SYSINC)/sched.h       \
        !          24650:                $(USRINC)/errno.h       \
        !          24651:                $(SYSINC)/stat.h        \
        !          24652:                $(SYSINC)/io.h          \
        !          24653:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          24654:                $(SYSINC)/uproc.h       \
        !          24655:                $(SYSINC)/timeout.h     \
        !          24656:                mm.c
        !          24657:        $(CC) $(CFLAGS) -c -o $@@ mm.c
        !          24658: 
        !          24659: $(KOBJ)/mmas.o: mmas.m
        !          24660:        $(CC) $(CFLAGS) -c -o $@@ mmas.m
        !          24661: 
        !          24662: $(KOBJ)/ms.o:                          \
        !          24663:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24664:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24665:                                        $(SYSINC)/fun.h \
        !          24666:                $(SYSINC)/uproc.h       \
        !          24667:                $(SYSINC)/con.h         \
        !          24668:                $(SYSINC)/devices.h     \
        !          24669:                $(SYSINC)/ms.h          \
        !          24670:                $(USRINC)/errno.h       \
        !          24671:                ms.c
        !          24672:        $(CC) $(CFLAGS) -c -o $@@ ms.c
        !          24673: 
        !          24674: $(KOBJ)/rm.o: rm.c                     \
        !          24675:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24676:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24677:                                        $(SYSINC)/fun.h \
        !          24678:                $(SYSINC)/buf.h         \
        !          24679:                $(USRINC)/errno.h       \
        !          24680:                $(SYSINC)/uproc.h       \
        !          24681:                $(SYSINC)/seg.h         \
        !          24682:                $(SYSINC)/con.h         \
        !          24683:                $(SYSINC)/devices.h     \
        !          24684:                $(SYSINC)/inode.h       \
        !          24685:                $(SYSINC)/stat.h
        !          24686:        $(CC) $(CFLAGS) -c -o $@@ rm.c
        !          24687: 
        !          24688: $(KOBJ)/rs0.o:                         \
        !          24689:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24690:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24691:                                        $(SYSINC)/fun.h \
        !          24692:                $(SYSINC)/con.h         \
        !          24693:                $(SYSINC)/devices.h     \
        !          24694:                $(USRINC)/errno.h       \
        !          24695:                $(SYSINC)/ins8250.h     \
        !          24696:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          24697:                $(SYSINC)/sched.h       \
        !          24698:                $(SYSINC)/stat.h        \
        !          24699:                $(USRINC)/termio.h      \
        !          24700:                $(SYSINC)/uproc.h       \
        !          24701:                rs.c
        !          24702:        $(CC) $(CFLAGS) -DRS0 -c -o $@@ rs.c
        !          24703: 
        !          24704: $(KOBJ)/rs1.o:                                 \
        !          24705:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24706:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24707:                                        $(SYSINC)/fun.h \
        !          24708:                $(SYSINC)/con.h         \
        !          24709:                $(SYSINC)/devices.h     \
        !          24710:                $(USRINC)/errno.h       \
        !          24711:                $(SYSINC)/ins8250.h     \
        !          24712:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          24713:                $(SYSINC)/sched.h       \
        !          24714:                $(SYSINC)/stat.h        \
        !          24715:                $(USRINC)/termio.h      \
        !          24716:                $(SYSINC)/uproc.h       \
        !          24717:                rs.c
        !          24718:        $(CC) $(CFLAGS) -DRS1 -c -o $@@ rs.c
        !          24719: 
        !          24720: $(KOBJ)/rsas.o: rsas.s
        !          24721:        $(AS) -gxo $@@ rsas.s
        !          24722: 
        !          24723: $(KOBJ)/st.o:                          \
        !          24724:                $(SYSINC)/buf.h         \
        !          24725:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24726:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24727:                                        $(SYSINC)/fun.h \
        !          24728:                $(SYSINC)/con.h         \
        !          24729:                $(SYSINC)/devices.h     \
        !          24730:                $(SYSINC)/const.h       \
        !          24731:                $(USRINC)/errno.h       \
        !          24732:                $(SYSINC)/inode.h       \
        !          24733:                $(SYSINC)/mtioctl.h     \
        !          24734:                $(SYSINC)/sched.h       \
        !          24735:                $(SYSINC)/seg.h         \
        !          24736:                $(SYSINC)/stat.h        \
        !          24737:                $(SYSINC)/uproc.h       \
        !          24738:                st.c
        !          24739:        $(CC) $(CFLAGS) -c -o $@@ st.c
        !          24740: 
        !          24741: $(KOBJ)/tn.o:                          \
        !          24742:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24743:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24744:                                        $(SYSINC)/fun.h \
        !          24745:                $(SYSINC)/con.h         \
        !          24746:                $(SYSINC)/devices.h     \
        !          24747:                $(USRINC)/errno.h       \
        !          24748:                $(SYSINC)/sched.h       \
        !          24749:                $(SYSINC)/timeout.h     \
        !          24750:                $(SYSINC)/types.h       \
        !          24751:                $(SYSINC)/uproc.h       \
        !          24752:                tn.c
        !          24753:        $(CC) $(CFLAGS) -c -o $@@ tn.c
        !          24754: 
        !          24755: $(KOBJ)/tnas.o: tnas.s
        !          24756:        $(AS) -gxo $@@ tnas.s
        !          24757: 
        !          24758: # How to make loadable drivers.
        !          24759: 
        !          24760: $(LDRV)/al0:   $(USRSYS)/lib/al.a
        !          24761:        ( cd $(USRSYS); ldconfig al0 )
        !          24762: 
        !          24763: $(LDRV)/al1:   $(USRSYS)/lib/al.a
        !          24764:        ( cd $(USRSYS); ldconfig al1 )
        !          24765: 
        !          24766: $(LDRV)/at:    $(USRSYS)/lib/at.a
        !          24767:        ( cd $(USRSYS); ldconfig at )
        !          24768: 
        !          24769: $(LDRV)/fl:    $(USRSYS)/lib/fl.a
        !          24770:        ( cd $(USRSYS); ldconfig fl )
        !          24771: 
        !          24772: $(LDRV)/gr:    $(USRSYS)/lib/gr.a
        !          24773:        ( cd $(USRSYS); ldconfig gr )
        !          24774: 
        !          24775: $(LDRV)/hs:    $(USRSYS)/lib/hs.a
        !          24776:        ( cd $(USRSYS); ldconfig hs )
        !          24777: 
        !          24778: $(LDRV)/lp:    $(USRSYS)/lib/lp.a
        !          24779:        ( cd $(USRSYS); ldconfig lp )
        !          24780: 
        !          24781: $(LDRV)/mm:    $(USRSYS)/lib/mm.a
        !          24782:        ( cd $(USRSYS); ldconfig mm )
        !          24783: 
        !          24784: $(LDRV)/ms:    $(USRSYS)/lib/ms.a
        !          24785:        ( cd $(USRSYS); ldconfig ms )
        !          24786: 
        !          24787: $(LDRV)/rm:    $(USRSYS)/lib/rm.a
        !          24788:        ( cd $(USRSYS); ldconfig rm )
        !          24789: @
        !          24790: 
        !          24791: 
        !          24792: 1.6
        !          24793: log
        !          24794: @update by hal for relocateable objects
        !          24795: @
        !          24796: text
        !          24797: @a1 2
        !          24798: # Environment variable USRSYS must be defined!  It used to be /usr/sys - 
        !          24799: # Environment variable KOBJ must be defined!  Try /tmp/kobj
        !          24800: d3 9
        !          24801: d16 2
        !          24802: a17 7
        !          24803: DEBUG=0
        !          24804: AS=exec /bin/as
        !          24805: CC=exec /bin/cc
        !          24806: CPP=exec /lib/icpp
        !          24807: CFLAGS=
        !          24808: AFLAGS=-gx
        !          24809: NKB=nkb
        !          24810: d19 1
        !          24811: a19 4
        !          24812: # Loadable driver directory
        !          24813: LDRV=$(USRSYS)/ldrv
        !          24814: 
        !          24815: ARCHIVES=$(USRSYS)/lib/aha154x.a \
        !          24816: d26 1
        !          24817: d35 1
        !          24818: a35 1
        !          24819: DRVOBJ=        $(KOBJ)/aha.o \
        !          24820: a38 1
        !          24821:        $(KOBJ)/bufq.o \
        !          24822: a46 2
        !          24823:        $(KOBJ)/nkb.o \
        !          24824:        $(KOBJ)/gkb.o \
        !          24825: a52 3
        !          24826:        $(KOBJ)/scsi.o \
        !          24827:        $(KOBJ)/ss.o \
        !          24828:        $(KOBJ)/ssas.o \
        !          24829: d54 1
        !          24830: a54 1
        !          24831:        $(KOBJ)/tn.o $(KOBJ)/tnas.o \
        !          24832: d56 1
        !          24833: a56 1
        !          24834: DRIVERS=$(LDRV)/aha154x \
        !          24835: d66 1
        !          24836: a66 2
        !          24837:        $(LDRV)/rm \
        !          24838:        $(LDRV)/ss \
        !          24839: d74 1
        !          24840: a74 1
        !          24841: $(USRSYS)/lib/aha154x.a: $(KOBJ)/scsi.o $(KOBJ)/aha.o $(KOBJ)/fdisk.o
        !          24842: a76 3
        !          24843: $(USRSYS)/lib/al.a: $(KOBJ)/com1.o $(KOBJ)/com2.o $(KOBJ)/alx.o
        !          24844:        rm -f $@@
        !          24845:        ar rc $@@ $<
        !          24846: d80 1
        !          24847: a80 1
        !          24848: $(USRSYS)/lib/ati.a: $(KOBJ)/mm.o $(KOBJ)/ati.o $(KOBJ)/$(NKB).o
        !          24849: d87 1
        !          24850: a87 1
        !          24851:                                $(KOBJ)/fontw.o $(KOBJ)/$(NKB).o
        !          24852: d93 3
        !          24853: d99 1
        !          24854: a99 1
        !          24855: $(USRSYS)/lib/mm.a: $(KOBJ)/mm.o $(KOBJ)/mmas.o $(KOBJ)/$(NKB).o
        !          24856: d111 1
        !          24857: a111 1
        !          24858: $(USRSYS)/lib/ss.a: $(KOBJ)/ss.o $(KOBJ)/ssas.o $(KOBJ)/bufq.o $(KOBJ)/fdisk.o
        !          24859: a113 3
        !          24860: $(USRSYS)/lib/st.a: $(KOBJ)/st.o
        !          24861:        rm -f $@@
        !          24862:        ar rc $@@ $<
        !          24863: a117 11
        !          24864: $(KOBJ)/aha.o:                         \
        !          24865:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24866:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24867:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          24868:                $(SYSINC)/buf.h         \
        !          24869:                $(SYSINC)/sched.h               \
        !          24870:                $(SYSINC)/scsiwork.h    \
        !          24871:                $(SYSINC)/aha154x.h     \
        !          24872:                aha.c
        !          24873:        $(CC) $(CFLAGS) -c -o $@@ aha.c
        !          24874: 
        !          24875: d133 1
        !          24876: a133 1
        !          24877:        $(CC) $(CFLAGS) -c -o $(KOBJ)/alx.o alx.c
        !          24878: d135 13
        !          24879: a147 2
        !          24880: $(KOBJ)/at.o: at.c
        !          24881:        $(CC) $(CFLAGS) -DVERBOSE=1 -c -o $@@ $<
        !          24882: d152 2
        !          24883: a153 4
        !          24884: $(KOBJ)/ati.o: ati.s
        !          24885:        $(CPP) -E -DATI_132=1 ati.s > ati.i
        !          24886:        $(AS) -gxo $(KOBJ)/ati.o ati.i
        !          24887:        exec /bin/rm -f ati.i
        !          24888: a154 8
        !          24889: $(KOBJ)/bufq.o:                        \
        !          24890:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24891:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24892:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          24893:                $(SYSINC)/buf.h         \
        !          24894:                bufq.c
        !          24895:        $(CC) $(CFLAGS) -DDEBUG=$(DEBUG) -c -o $@@ bufq.c
        !          24896: 
        !          24897: d162 1
        !          24898: d181 1
        !          24899: d193 1
        !          24900: a193 1
        !          24901: $(KOBJ)/dmareq.o:                      \
        !          24902: a198 1
        !          24903:                $(SYSINC)/dmac.h        \
        !          24904: a199 16
        !          24905:                $(SYSINC)/io.h          \
        !          24906:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          24907:                $(SYSINC)/sched.h       \
        !          24908:                $(SYSINC)/seg.h         \
        !          24909:                $(SYSINC)/stat.h        \
        !          24910:                $(SYSINC)/uproc.h       \
        !          24911:                dmareq.c
        !          24912:        $(CC) $(CFLAGS) -c -o $@@ dmareq.c
        !          24913: 
        !          24914: $(KOBJ)/fdisk.o:                       \
        !          24915:                $(SYSINC)/buf.h         \
        !          24916:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24917:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24918:                                        $(SYSINC)/fun.h \
        !          24919:                $(SYSINC)/con.h         \
        !          24920:                $(USRINC)/errno.h       \
        !          24921: d212 1
        !          24922: d236 1
        !          24923: d245 2
        !          24924: a246 4
        !          24925: $(KOBJ)/gras.o: gras.s
        !          24926:        $(CPP) -E gras.s > gras.i
        !          24927:        $(AS) -gxo $@@ gras.i
        !          24928:        exec /bin/rm -f gras.i
        !          24929: d249 1
        !          24930: a249 3
        !          24931:        $(CPP) -E -DHERCULES gras.s > hgas.i
        !          24932:        $(AS) -gxo $@@ hgas.i
        !          24933:        exec /bin/rm -f hgas.i
        !          24934: a250 3
        !          24935: $(KOBJ)/hd.o: hd.c
        !          24936:        $(CC) $(CFLAGS) -c -o $@@ hd.c
        !          24937: 
        !          24938: d256 1
        !          24939: d271 1
        !          24940: d282 1
        !          24941: a282 1
        !          24942: $(KOBJ)/gkb.o:                         \
        !          24943: d287 1
        !          24944: a289 32
        !          24945:                $(SYSINC)/sched.h       \
        !          24946:                $(USRINC)/signal.h      \
        !          24947:                $(SYSINC)/stat.h        \
        !          24948:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          24949:                $(SYSINC)/uproc.h       \
        !          24950:                gkb.c
        !          24951:        $(CC) $(CFLAGS) -c -o $@@ gkb.c
        !          24952: 
        !          24953: $(KOBJ)/nkb.o:                         \
        !          24954:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24955:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24956:                                        $(SYSINC)/fun.h \
        !          24957:                $(SYSINC)/con.h         \
        !          24958:                $(USRINC)/errno.h       \
        !          24959:                $(SYSINC)/i8086.h       \
        !          24960:                $(SYSINC)/sched.h       \
        !          24961:                $(SYSINC)/seg.h         \
        !          24962:                $(USRINC)/signal.h      \
        !          24963:                $(SYSINC)/stat.h        \
        !          24964:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          24965:                $(SYSINC)/uproc.h       \
        !          24966:                $(SYSINC)/kb.h          \
        !          24967:                nkb.c
        !          24968:        $(CC) $(CFLAGS) -c -o $@@ nkb.c
        !          24969: 
        !          24970: $(KOBJ)/lp.o:                          \
        !          24971:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          24972:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          24973:                                        $(SYSINC)/fun.h \
        !          24974:                $(SYSINC)/con.h         \
        !          24975:                $(USRINC)/errno.h       \
        !          24976:                $(SYSINC)/i8086.h       \
        !          24977: d312 2
        !          24978: a313 4
        !          24979: $(KOBJ)/mmas.o: mmas.s
        !          24980:        -$(CPP) -E mmas.s > mmas.i
        !          24981:        $(AS) -gxo $@@ mmas.i
        !          24982:        exec /bin/rm -f mmas.i
        !          24983: d321 1
        !          24984: d327 12
        !          24985: a338 1
        !          24986: $(KOBJ)/rm.o: rm.c
        !          24987: d346 1
        !          24988: d362 1
        !          24989: d376 2
        !          24990: a377 1
        !          24991: $(KOBJ)/scsi.o:                                \
        !          24992: a379 41
        !          24993:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          24994:                $(SYSINC)/fdisk.h       \
        !          24995:                $(SYSINC)/hdioctl.h     \
        !          24996:                $(SYSINC)/sdioctl.h     \
        !          24997:                $(SYSINC)/buf.h         \
        !          24998:                $(SYSINC)/con.h         \
        !          24999:                $(SYSINC)/stat.h        \
        !          25000:                $(SYSINC)/uproc.h       \
        !          25001:                $(USRINC)/errno.h       \
        !          25002:                $(SYSINC)/scsiwork.h    \
        !          25003:                scsi.c
        !          25004:        $(CC) $(CFLAGS) -c -o $(KOBJ)/scsi.o scsi.c
        !          25005: 
        !          25006: $(KOBJ)/ss.o:                          \
        !          25007:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25008:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          25009:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          25010:                $(SYSINC)/io.h          \
        !          25011:                $(SYSINC)/sched.h       \
        !          25012:                $(SYSINC)/uproc.h       \
        !          25013:                $(SYSINC)/proc.h        \
        !          25014:                $(SYSINC)/con.h         \
        !          25015:                $(SYSINC)/stat.h        \
        !          25016:                $(SYSINC)/devices.h     \
        !          25017:                $(USRINC)/errno.h       \
        !          25018:                $(SYSINC)/ss.h          \
        !          25019:                $(SYSINC)/fdisk.h       \
        !          25020:                $(SYSINC)/hdioctl.h     \
        !          25021:                $(SYSINC)/buf.h         \
        !          25022:                $(SYSINC)/scsiwork.h    \
        !          25023:                ss.c
        !          25024:        $(CC) $(CFLAGS) -DDEBUG=$(DEBUG) -c -o $(KOBJ)/ss.o ss.c
        !          25025: 
        !          25026: $(KOBJ)/ssas.o:                                \
        !          25027:                ssas.s
        !          25028:        $(AS) -go $@@ $<
        !          25029: 
        !          25030: $(KOBJ)/st.o:                          \
        !          25031:                $(SYSINC)/buf.h         \
        !          25032:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25033:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          25034: d382 1
        !          25035: d399 1
        !          25036: a412 3
        !          25037: $(LDRV)/aha154x:       $(USRSYS)/lib/aha154x.a
        !          25038:        ( cd $(USRSYS); ldconfig aha154x )
        !          25039: 
        !          25040: a441 3
        !          25041: 
        !          25042: $(LDRV)/ss:    $(USRSYS)/lib/ss.a
        !          25043:        ( cd $(USRSYS); ldconfig ss )
        !          25044: @
        !          25045: 
        !          25046: 
        !          25047: 1.5
        !          25048: log
        !          25049: @update provided by hal
        !          25050: @
        !          25051: text
        !          25052: @d3 1
        !          25053: d35 26
        !          25054: a60 25
        !          25055: DRVOBJ=        objects/aha.o \
        !          25056:        objects/alx.o \
        !          25057:        objects/at.o \
        !          25058:        objects/atas.o \
        !          25059:        objects/bufq.o \
        !          25060:        objects/ms.o \
        !          25061:        objects/ati.o \
        !          25062:        objects/com1.o objects/com2.o \
        !          25063:        objects/fdisk.o \
        !          25064:        objects/fl.o \
        !          25065:        objects/fontw.o \
        !          25066:        objects/gr.o objects/gras.o \
        !          25067:        objects/hs.o \
        !          25068:        objects/nkb.o \
        !          25069:        objects/kb.o \
        !          25070:        objects/mm.o \
        !          25071:        objects/lp.o \
        !          25072:        objects/mmas.o \
        !          25073:        objects/rm.o \
        !          25074:        objects/rs0.o objects/rs1.o objects/rsas.o \
        !          25075:        objects/scsi.o \
        !          25076:        objects/ss.o \
        !          25077:        objects/ssas.o \
        !          25078:        objects/st.o \
        !          25079:        objects/tn.o objects/tnas.o \
        !          25080: d81 1
        !          25081: a81 1
        !          25082: $(USRSYS)/lib/aha154x.a: objects/scsi.o objects/aha.o objects/fdisk.o
        !          25083: d84 1
        !          25084: a84 1
        !          25085: $(USRSYS)/lib/al.a: objects/com1.o objects/com2.o objects/alx.o
        !          25086: d87 1
        !          25087: a87 1
        !          25088: $(USRSYS)/lib/at.a: objects/at.o objects/atas.o objects/fdisk.o
        !          25089: d90 1
        !          25090: a90 1
        !          25091: $(USRSYS)/lib/ati.a: objects/mm.o objects/ati.o objects/$(NKB).o
        !          25092: d93 1
        !          25093: a93 1
        !          25094: $(USRSYS)/lib/fl.a: objects/fl.o
        !          25095: d95 3
        !          25096: a97 3
        !          25097:        ar rc $(USRSYS)/lib/fl.a objects/fl.o
        !          25098: $(USRSYS)/lib/gr.a: objects/mm.o objects/gr.o objects/gras.o \
        !          25099:                                objects/fontw.o objects/$(NKB).o
        !          25100: d100 1
        !          25101: a100 1
        !          25102: $(USRSYS)/lib/hs.a: objects/hs.o
        !          25103: d103 1
        !          25104: a103 1
        !          25105: $(USRSYS)/lib/lp.a: objects/lp.o
        !          25106: d106 1
        !          25107: a106 1
        !          25108: $(USRSYS)/lib/mm.a: objects/mm.o objects/mmas.o objects/$(NKB).o
        !          25109: d109 1
        !          25110: a109 1
        !          25111: $(USRSYS)/lib/ms.a: objects/ms.o
        !          25112: d112 1
        !          25113: a112 1
        !          25114: $(USRSYS)/lib/rm.a: objects/rm.o
        !          25115: d115 1
        !          25116: a115 1
        !          25117: $(USRSYS)/lib/rs.a: objects/rs0.o objects/rs1.o objects/rsas.o
        !          25118: d118 1
        !          25119: a118 1
        !          25120: $(USRSYS)/lib/ss.a: objects/ss.o objects/ssas.o objects/bufq.o objects/fdisk.o
        !          25121: d121 1
        !          25122: a121 1
        !          25123: $(USRSYS)/lib/st.a: objects/st.o
        !          25124: d124 1
        !          25125: a124 1
        !          25126: $(USRSYS)/lib/tn.a: objects/tn.o objects/tnas.o
        !          25127: d128 1
        !          25128: a128 1
        !          25129: objects/aha.o:                         \
        !          25130: d139 1
        !          25131: a139 1
        !          25132: objects/alx.o:                         \
        !          25133: d154 1
        !          25134: a154 1
        !          25135:        $(CC) $(CFLAGS) -c -o objects/alx.o alx.c
        !          25136: d156 1
        !          25137: a156 1
        !          25138: objects/at.o: at.c
        !          25139: d159 1
        !          25140: a159 1
        !          25141: objects/atas.o: atas.s
        !          25142: d162 1
        !          25143: a162 1
        !          25144: objects/ati.o: ati.s
        !          25145: d164 1
        !          25146: a164 1
        !          25147:        $(AS) -gxo objects/ati.o ati.i
        !          25148: d167 1
        !          25149: a167 1
        !          25150: objects/bufq.o:                        \
        !          25151: d175 1
        !          25152: a175 1
        !          25153: objects/com1.o:                        \
        !          25154: d193 1
        !          25155: a193 1
        !          25156: objects/com2.o:                        \
        !          25157: d211 1
        !          25158: a211 1
        !          25159: objects/dmareq.o:                      \
        !          25160: d228 1
        !          25161: a228 1
        !          25162: objects/fdisk.o:                       \
        !          25163: d241 1
        !          25164: a241 1
        !          25165: objects/fl.o:                          \
        !          25166: d258 1
        !          25167: a258 1
        !          25168: objects/fontw.o: tools/fontgen.c
        !          25169: d262 1
        !          25170: a262 1
        !          25171:        $(AS) -gxo objects/fontw.o fontw.s
        !          25172: d265 1
        !          25173: a265 1
        !          25174: objects/gr.o:                          \
        !          25175: d278 1
        !          25176: a278 1
        !          25177: objects/gras.o: gras.s
        !          25178: d283 1
        !          25179: a283 1
        !          25180: objects/hgas.o: gras.s
        !          25181: d288 1
        !          25182: a288 1
        !          25183: objects/hd.o: hd.c
        !          25184: d291 1
        !          25185: a291 1
        !          25186: objects/hs.o:                          \
        !          25187: d305 1
        !          25188: a305 1
        !          25189: objects/kb.o:                          \
        !          25190: d320 1
        !          25191: a320 1
        !          25192: objects/nkb.o:                         \
        !          25193: d328 15
        !          25194: d352 1
        !          25195: a352 1
        !          25196: objects/lp.o:                          \
        !          25197: d367 1
        !          25198: a367 1
        !          25199: objects/mm.o:                          \
        !          25200: d381 1
        !          25201: a381 1
        !          25202: objects/mmas.o: mmas.s
        !          25203: d386 1
        !          25204: a386 1
        !          25205: objects/ms.o:                          \
        !          25206: d397 1
        !          25207: a397 1
        !          25208: objects/rm.o: rm.c
        !          25209: d400 1
        !          25210: a400 1
        !          25211: objects/rs0.o:                         \
        !          25212: d415 1
        !          25213: a415 1
        !          25214: objects/rs1.o:                                 \
        !          25215: d430 1
        !          25216: a430 1
        !          25217: objects/rsas.o: rsas.s
        !          25218: d433 1
        !          25219: a433 1
        !          25220: objects/scsi.o:                                \
        !          25221: d447 1
        !          25222: a447 1
        !          25223:        $(CC) $(CFLAGS) -c -o objects/scsi.o scsi.c
        !          25224: d449 1
        !          25225: a449 1
        !          25226: objects/ss.o:                          \
        !          25227: d467 1
        !          25228: a467 1
        !          25229:        $(CC) $(CFLAGS) -DDEBUG=$(DEBUG) -c -o objects/ss.o ss.c
        !          25230: d469 1
        !          25231: a469 1
        !          25232: objects/ssas.o:                                \
        !          25233: d473 1
        !          25234: a473 1
        !          25235: objects/st.o:                          \
        !          25236: d490 1
        !          25237: a490 1
        !          25238: objects/tn.o:                          \
        !          25239: d503 1
        !          25240: a503 1
        !          25241: objects/tnas.o: tnas.s
        !          25242: @
        !          25243: 
        !          25244: 
        !          25245: 1.4
        !          25246: log
        !          25247: @update provided by hal
        !          25248: @
        !          25249: text
        !          25250: @d14 1
        !          25251: d47 3
        !          25252: a49 1
        !          25253:        objects/nkb.o objects/mm.o \
        !          25254: d88 1
        !          25255: a88 1
        !          25256: $(USRSYS)/lib/ati.a: objects/mm.o objects/ati.o objects/nkb.o
        !          25257: d95 1
        !          25258: a95 1
        !          25259:                                objects/fontw.o objects/nkb.o
        !          25260: d104 1
        !          25261: a104 1
        !          25262: $(USRSYS)/lib/mm.a: objects/mm.o objects/mmas.o objects/nkb.o
        !          25263: d303 15
        !          25264: d326 1
        !          25265: a328 1
        !          25266:                $(SYSINC)/timeout.h     \
        !          25267: d331 1
        !          25268: @
        !          25269: 
        !          25270: 
        !          25271: 1.3
        !          25272: log
        !          25273: @bob h added new environment variable $USRKER for header file paths
        !          25274: for kernel specific headers.
        !          25275: @
        !          25276: text
        !          25277: @a6 2
        !          25278: KERINC=$(USRKER)/src/sys/sys
        !          25279: DRVINC=$(USRKER)/src/sys/i8086/sys
        !          25280: d12 1
        !          25281: a12 1
        !          25282: CFLAGS=-I$(KERINC) -I$(DRVINC)
        !          25283: a14 2
        !          25284: # USRSYS=$USRSYS
        !          25285: 
        !          25286: d124 1
        !          25287: a124 1
        !          25288:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25289: d126 1
        !          25290: a126 1
        !          25291:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          25292: d129 2
        !          25293: a130 2
        !          25294:                $(DRVINC)/scsiwork.h    \
        !          25295:                $(DRVINC)/aha154x.h     \
        !          25296: d135 2
        !          25297: a136 2
        !          25298:                $(KERINC)/clist.h       \
        !          25299:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25300: d141 2
        !          25301: a142 2
        !          25302:                $(DRVINC)/i8086.h       \
        !          25303:                $(DRVINC)/ins8250.h     \
        !          25304: d146 1
        !          25305: a146 1
        !          25306:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          25307: d163 1
        !          25308: a163 1
        !          25309:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25310: d165 1
        !          25311: a165 1
        !          25312:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          25313: d171 3
        !          25314: a173 3
        !          25315:                $(DRVINC)/al.h          \
        !          25316:                $(KERINC)/clist.h       \
        !          25317:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25318: d178 2
        !          25319: a179 2
        !          25320:                $(DRVINC)/i8086.h       \
        !          25321:                $(DRVINC)/ins8250.h     \
        !          25322: d183 1
        !          25323: a183 1
        !          25324:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          25325: d189 3
        !          25326: a191 3
        !          25327:                $(DRVINC)/al.h          \
        !          25328:                $(KERINC)/clist.h       \
        !          25329:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25330: d196 2
        !          25331: a197 2
        !          25332:                $(DRVINC)/i8086.h       \
        !          25333:                $(DRVINC)/ins8250.h     \
        !          25334: d201 1
        !          25335: a201 1
        !          25336:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          25337: d208 1
        !          25338: a208 1
        !          25339:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25340: d212 1
        !          25341: a212 1
        !          25342:                $(DRVINC)/dmac.h        \
        !          25343: d225 1
        !          25344: a225 1
        !          25345:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25346: d238 1
        !          25347: a238 1
        !          25348:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25349: d242 1
        !          25350: a242 1
        !          25351:                $(DRVINC)/dmac.h        \
        !          25352: d245 1
        !          25353: a245 1
        !          25354:                $(DRVINC)/i8086.h       \
        !          25355: d261 1
        !          25356: a261 1
        !          25357:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25358: d287 1
        !          25359: a287 1
        !          25360:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25361: d292 1
        !          25362: a292 1
        !          25363:                $(DRVINC)/ins8250.h     \
        !          25364: d295 1
        !          25365: a295 1
        !          25366:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          25367: d301 1
        !          25368: a301 1
        !          25369:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25370: d306 1
        !          25371: a306 1
        !          25372:                $(DRVINC)/i8086.h       \
        !          25373: d311 1
        !          25374: a311 1
        !          25375:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          25376: d317 1
        !          25377: a317 1
        !          25378:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25379: d322 1
        !          25380: a322 1
        !          25381:                $(DRVINC)/i8086.h       \
        !          25382: d332 1
        !          25383: a332 1
        !          25384:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25385: d339 1
        !          25386: a339 1
        !          25387:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          25388: d351 1
        !          25389: a351 1
        !          25390:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25391: d365 1
        !          25392: a365 1
        !          25393:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25394: d370 1
        !          25395: a370 1
        !          25396:                $(DRVINC)/ins8250.h     \
        !          25397: d380 1
        !          25398: a380 1
        !          25399:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25400: d385 1
        !          25401: a385 1
        !          25402:                $(DRVINC)/ins8250.h     \
        !          25403: d398 1
        !          25404: a398 1
        !          25405:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25406: d400 1
        !          25407: a400 1
        !          25408:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          25409: d409 1
        !          25410: a409 1
        !          25411:                $(DRVINC)/scsiwork.h    \
        !          25412: d414 1
        !          25413: a414 1
        !          25414:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25415: d416 1
        !          25416: a416 1
        !          25417:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          25418: d425 1
        !          25419: a425 1
        !          25420:                $(DRVINC)/ss.h          \
        !          25421: d429 1
        !          25422: a429 1
        !          25423:                $(DRVINC)/scsiwork.h    \
        !          25424: d439 1
        !          25425: a439 1
        !          25426:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25427: d455 1
        !          25428: a455 1
        !          25429:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25430: @
        !          25431: 
        !          25432: 
        !          25433: 1.2
        !          25434: log
        !          25435: @update provided by hal
        !          25436: @
        !          25437: text
        !          25438: @d7 2
        !          25439: a8 2
        !          25440: KERINC=/usr/src/sys/sys
        !          25441: DRVINC=/usr/src/sys/i8086/sys
        !          25442: @
        !          25443: 
        !          25444: 
        !          25445: 1.1
        !          25446: log
        !          25447: @Initial revision
        !          25448: @
        !          25449: text
        !          25450: @a0 1
        !          25451: #
        !          25452: d2 1
        !          25453: a2 6
        !          25454: #
        !          25455: AS=exec /bin/as
        !          25456: CC=exec /bin/cc
        !          25457: CPP=exec /lib/cpp
        !          25458: CFLAGS=-I.. -I../sys -I../.. -I../../sys -I/usr/include/sys
        !          25459: AFLAGS=-gx
        !          25460: a8 1
        !          25461: USRSYS=/usr/sys
        !          25462: d10 15
        !          25463: a24 1
        !          25464: ARCHIVES=$(USRSYS)/lib/al.a \
        !          25465: a26 1
        !          25466:        $(USRSYS)/lib/gm.a \
        !          25467: a32 1
        !          25468:        $(USRSYS)/lib/rp.a \
        !          25469: d37 5
        !          25470: a41 1
        !          25471: DRVOBJ=        objects/alx.o \
        !          25472: d48 3
        !          25473: a50 3
        !          25474:        objects/gr.o objects/gras.o objects/gmas.o \
        !          25475:        objects/hs.o objects/clocked.o \
        !          25476:        objects/kb.o objects/mm.o \
        !          25477: a53 1
        !          25478:        objects/rp.o objects/rpas.o \
        !          25479: d55 3
        !          25480: d61 14
        !          25481: a74 1
        !          25482: install: $(ARCHIVES)
        !          25483: d80 3
        !          25484: d84 8
        !          25485: a91 5
        !          25486:        rm -f $(USRSYS)/lib/al.a
        !          25487:        ar rc $(USRSYS)/lib/al.a objects/com1.o objects/com2.o objects/alx.o
        !          25488: $(USRSYS)/lib/ati.a: objects/mm.o objects/ati.o objects/kb.o
        !          25489:        rm -f $(USRSYS)/lib/ati.a
        !          25490:        ar rc $(USRSYS)/lib/ati.a objects/mm.o objects/ati.o objects/kb.o
        !          25491: a94 5
        !          25492: $(USRSYS)/lib/gm.a: objects/mm.o objects/gr.o objects/gmas.o \
        !          25493:                                objects/fontw.o objects/kb.o
        !          25494:        rm -f $(USRSYS)/lib/gm.a
        !          25495:        ar rc $(USRSYS)/lib/gm.a objects/mm.o objects/gr.o objects/gmas.o \
        !          25496:                                objects/fontw.o objects/kb.o
        !          25497: d96 6
        !          25498: a101 7
        !          25499:                                objects/fontw.o objects/kb.o
        !          25500:        rm -f $(USRSYS)/lib/gr.a
        !          25501:        ar rc $(USRSYS)/lib/gr.a objects/mm.o objects/gr.o objects/gras.o \
        !          25502:                                objects/fontw.o objects/kb.o
        !          25503: $(USRSYS)/lib/hs.a: objects/hs.o objects/clocked.o
        !          25504:        rm -f $(USRSYS)/lib/hs.a
        !          25505:        ar rc $(USRSYS)/lib/hs.a objects/hs.o objects/clocked.o
        !          25506: d103 5
        !          25507: a107 5
        !          25508:        rm -f $(USRSYS)/lib/lp.a
        !          25509:        ar rc $(USRSYS)/lib/lp.a objects/lp.o
        !          25510: $(USRSYS)/lib/mm.a: objects/mm.o objects/mmas.o objects/kb.o
        !          25511:                rm -f $(USRSYS)/lib/mm.a
        !          25512:        ar rc $(USRSYS)/lib/mm.a objects/mm.o objects/mmas.o objects/kb.o
        !          25513: d109 2
        !          25514: a110 2
        !          25515:        rm -f $(USRSYS)/lib/ms.a
        !          25516:        ar rc $(USRSYS)/lib/ms.a objects/ms.o
        !          25517: d112 2
        !          25518: a113 5
        !          25519:        rm -f $(USRSYS)/lib/rm.a
        !          25520:        ar rc $(USRSYS)/lib/rm.a objects/rm.o
        !          25521: $(USRSYS)/lib/rp.a: objects/rp.o objects/rpas.o
        !          25522:        rm -f $(USRSYS)/lib/rp.a
        !          25523:        ar rc $(USRSYS)/lib/rp.a objects/rp.o objects/rpas.o
        !          25524: d115 5
        !          25525: a119 2
        !          25526:        rm -f $(USRSYS)/lib/rs.a
        !          25527:        ar rc $(USRSYS)/lib/rs.a objects/rs0.o objects/rs1.o objects/rsas.o
        !          25528: d121 2
        !          25529: a122 2
        !          25530:        rm -f $(USRSYS)/lib/st.a
        !          25531:        ar rc $(USRSYS)/lib/st.a objects/st.o
        !          25532: d124 2
        !          25533: a125 2
        !          25534:        rm -f $(USRSYS)/lib/tn.a
        !          25535:        ar rc $(USRSYS)/lib/tn.a objects/tn.o objects/tnas.o
        !          25536: d127 11
        !          25537: d153 1
        !          25538: a153 1
        !          25539:        $(CC) $(CFLAGS) -c -o $@@ alx.c
        !          25540: d155 6
        !          25541: d162 2
        !          25542: a163 2
        !          25543:        exec /lib/cpp -E -DATI_132=1 ati.s > ati.i
        !          25544:        exec /bin/as -gxo $@@ ati.i
        !          25545: d166 7
        !          25546: a172 2
        !          25547: objects/clocked.o: clocked.s
        !          25548:        $(AS) -go $@@ $<
        !          25549: d175 1
        !          25550: d193 1
        !          25551: d257 6
        !          25552: a262 6
        !          25553: objects/fontw.o: fontgen.c
        !          25554:        $(CC) -i fontgen.c
        !          25555:        exec ./fontgen > $*.s
        !          25556:        exec /bin/rm fontgen
        !          25557:        $(AS) -gxo $@@ $*.s
        !          25558:        exec /bin/rm $*.s
        !          25559: a263 5
        !          25560: objects/gmas.o: gras.s
        !          25561:        exec /lib/cpp -E -DTECMAR gras.s > gmas.i
        !          25562:        exec /bin/as -gxo $@@ gmas.i
        !          25563:        exec /bin/rm -f gmas.i
        !          25564: 
        !          25565: d278 2
        !          25566: a279 2
        !          25567:        exec /lib/cpp -E gras.s > gras.i
        !          25568:        exec /bin/as -gxo $@@ gras.i
        !          25569: d283 2
        !          25570: a284 2
        !          25571:        exec /lib/cpp -E -DHERCULES gras.s > hgas.i
        !          25572:        exec /bin/as -gxo $@@ hgas.i
        !          25573: d288 1
        !          25574: a288 1
        !          25575:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          25576: d304 1
        !          25577: a304 1
        !          25578: objects/kb.o:                          \
        !          25579: d317 2
        !          25580: a318 2
        !          25581:                kb.c
        !          25582:        $(CC) $(CFLAGS) -c -o $@@ kb.c
        !          25583: d350 2
        !          25584: a351 2
        !          25585:        -/lib/cpp -E mmas.s > mmas.i
        !          25586:        exec /bin/as -gxo $@@ mmas.i
        !          25587: d366 1
        !          25588: a366 1
        !          25589:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          25590: d368 1
        !          25591: a368 1
        !          25592: objects/rp.o:                          \
        !          25593: a373 18
        !          25594:                $(SYSINC)/seg.h         \
        !          25595:                $(SYSINC)/sched.h       \
        !          25596:                $(SYSINC)/stat.h        \
        !          25597:                $(USRINC)/termio.h      \
        !          25598:                $(SYSINC)/uproc.h       \
        !          25599:                $(USRINC)/v7sgtty.h     \
        !          25600:                rp.c
        !          25601:        $(CC) $(CFLAGS) -c -o $@@ rp.c
        !          25602: 
        !          25603: objects/rpas.o: rpas.s
        !          25604:        $(AS) -gxo $@@ $<
        !          25605: 
        !          25606: objects/rs0.o:                         \
        !          25607:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25608:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          25609:                                        $(SYSINC)/fun.h \
        !          25610:                $(SYSINC)/con.h         \
        !          25611:                $(USRINC)/errno.h       \
        !          25612: d399 1
        !          25613: a399 1
        !          25614:        $(AS) -gxo $@@ $<
        !          25615: d401 40
        !          25616: d472 39
        !          25617: a510 1
        !          25618:        $(AS) -gxo $@@ $<
        !          25619: @
        !          25620: 0707070064030147751004440000030000030000011777770507310646200005500000001704/newbits/kernel/USRSRC/i8086/drv/RCS/Mf.dg,vhead     1.1;
        !          25621: access   ;
        !          25622: symbols  ;
        !          25623: locks    ;
        !          25624: comment  @ * @;
        !          25625: 
        !          25626: 
        !          25627: 1.1
        !          25628: date     91.02.26.10.17.47;  author root;  state Exp;
        !          25629: branches ;
        !          25630: next   ;
        !          25631: 
        !          25632: 
        !          25633: desc
        !          25634: @Makefile for "dg" - Digiboard PC/Xe device driver.
        !          25635: @
        !          25636: 
        !          25637: 
        !          25638: 
        !          25639: 1.1
        !          25640: log
        !          25641: @First RCS version
        !          25642: @
        !          25643: text
        !          25644: @# Make file for a loadable driver
        !          25645: 
        !          25646: AS=exec /bin/as
        !          25647: CC=exec /bin/cc
        !          25648: CPP=exec /lib/cpp
        !          25649: CFLAGS=-I.. -I../sys -I../.. -I../../sys \
        !          25650:        -I/usr/include/sys
        !          25651: AFLAGS=-gx
        !          25652: 
        !          25653: # Include directories
        !          25654: USRINC=/usr/include
        !          25655: SYSINC=/usr/include/sys
        !          25656: KERINC=/usr/src/sys/sys
        !          25657: DRVINC=/usr/src/sys/i8086/sys
        !          25658: USRSYS=/usr/sys
        !          25659: 
        !          25660: DRVOBJ=        objects/dg.o
        !          25661: 
        !          25662: dg: objects/dg.o
        !          25663:        rm -f $(USRSYS)/lib/dg.a
        !          25664:        ar rc $(USRSYS)/lib/dg.a objects/dg.o
        !          25665: 
        !          25666: objects/dg.o:                          \
        !          25667:                $(KERINC)/coherent.h    $(SYSINC)/types.h \
        !          25668:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          25669:                                        $(SYSINC)/fun.h \
        !          25670:                $(SYSINC)/con.h         \
        !          25671:                $(USRINC)/errno.h       \
        !          25672:                $(SYSINC)/sched.h       \
        !          25673:                $(SYSINC)/seg.h         \
        !          25674:                $(SYSINC)/stat.h        \
        !          25675:                $(SYSINC)/types.h       \
        !          25676:                $(SYSINC)/uproc.h       \
        !          25677:                dg.c
        !          25678:        $(CC) $(CFLAGS) -c -o $@@ dg.c
        !          25679: @
        !          25680: 0707070064030104401004440000030000030000011777770507310646300005500000007251/newbits/kernel/USRSRC/i8086/drv/RCS/Mf.ss,vhead     1.8;
        !          25681: branch   ;
        !          25682: access   ;
        !          25683: symbols  ;
        !          25684: locks    ;
        !          25685: comment  @ * @;
        !          25686: 
        !          25687: 
        !          25688: 1.8
        !          25689: date     91.05.21.13.55.54;  author root;  state Exp;
        !          25690: branches ;
        !          25691: next     1.7;
        !          25692: 
        !          25693: 1.7
        !          25694: date     91.05.16.14.15.39;  author root;  state Exp;
        !          25695: branches ;
        !          25696: next     1.6;
        !          25697: 
        !          25698: 1.6
        !          25699: date     91.05.15.21.58.33;  author root;  state Exp;
        !          25700: branches ;
        !          25701: next     1.5;
        !          25702: 
        !          25703: 1.5
        !          25704: date     91.04.16.01.46.27;  author root;  state Exp;
        !          25705: branches ;
        !          25706: next     1.4;
        !          25707: 
        !          25708: 1.4
        !          25709: date     91.04.10.13.56.42;  author root;  state Exp;
        !          25710: branches ;
        !          25711: next     1.3;
        !          25712: 
        !          25713: 1.3
        !          25714: date     91.03.25.19.08.16;  author root;  state Exp;
        !          25715: branches ;
        !          25716: next     1.2;
        !          25717: 
        !          25718: 1.2
        !          25719: date     91.03.21.11.43.44;  author root;  state Exp;
        !          25720: branches ;
        !          25721: next     1.1;
        !          25722: 
        !          25723: 1.1
        !          25724: date     91.03.06.08.05.47;  author root;  state Exp;
        !          25725: branches ;
        !          25726: next     ;
        !          25727: 
        !          25728: 
        !          25729: desc
        !          25730: @Makefile for Seagate SCSI driver
        !          25731: @
        !          25732: 
        !          25733: 
        !          25734: 1.8
        !          25735: log
        !          25736: @Use bufq.c not ssqueue.c.
        !          25737: @
        !          25738: text
        !          25739: @# (lgl-
        !          25740: #      COHERENT Driver Kit Version 1.1.0
        !          25741: #      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          25742: #      All rights reserved. May not be copied without permission.
        !          25743: # -lgl)
        !          25744: #
        !          25745: # Makefile for Seagate ST01/ST02 SCSI driver "ss"
        !          25746: #
        !          25747: AS=exec /bin/as
        !          25748: CC=exec /bin/cc
        !          25749: CPP=exec /lib/icpp
        !          25750: CFLAGS=-I.. -I../sys -I../.. -I../../sys -I/usr/include/sys
        !          25751: DEBUG=1
        !          25752: AFLAGS=-gx
        !          25753: OBJECTS=objects/ss.o objects/fdisk.o objects/bufq.o objects/ssas.o
        !          25754: 
        !          25755: # Include directories
        !          25756: USRINC=/usr/include
        !          25757: SYSINC=/usr/include/sys
        !          25758: KERINC=/usr/src/sys/sys
        !          25759: DRVINC=/usr/src/sys/i8086/sys
        !          25760: USRSYS=/usr/sys
        !          25761: 
        !          25762: ss: $(USRSYS)/lib/ss.a
        !          25763:        :
        !          25764: 
        !          25765: $(USRSYS)/lib/ss.a: $(OBJECTS)
        !          25766:        rm -f $(USRSYS)/lib/ss.a
        !          25767:        ar rc $(USRSYS)/lib/ss.a $(OBJECTS)
        !          25768: 
        !          25769: objects/ss.o:                          \
        !          25770:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25771:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          25772:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          25773:                $(SYSINC)/io.h          \
        !          25774:                $(SYSINC)/sched.h       \
        !          25775:                $(SYSINC)/uproc.h       \
        !          25776:                $(SYSINC)/proc.h        \
        !          25777:                $(SYSINC)/con.h         \
        !          25778:                $(SYSINC)/stat.h        \
        !          25779:                $(SYSINC)/devices.h     \
        !          25780:                $(USRINC)/errno.h       \
        !          25781:                $(DRVINC)/ss.h          \
        !          25782:                $(SYSINC)/fdisk.h       \
        !          25783:                $(SYSINC)/hdioctl.h     \
        !          25784:                $(SYSINC)/buf.h         \
        !          25785:                $(DRVINC)/scsiwork.h    \
        !          25786:                ss.c
        !          25787:        $(CC) $(CFLAGS) -DDEBUG=$(DEBUG) -c -o objects/ss.o ss.c
        !          25788: 
        !          25789: objects/ssas.o:                                \
        !          25790:                ssas.s
        !          25791:        $(AS) -go $@@ ssas.s
        !          25792: 
        !          25793: objects/bufq.o:                        \
        !          25794:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25795:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          25796:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          25797:                $(SYSINC)/buf.h         \
        !          25798:                bufq.c
        !          25799:        $(CC) $(CFLAGS) -DDEBUG=$(DEBUG) -c -o $@@ bufq.c
        !          25800: 
        !          25801: objects/fdisk.o:                       \
        !          25802:                $(SYSINC)/buf.h         \
        !          25803:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          25804:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          25805:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          25806:                $(SYSINC)/con.h \
        !          25807:                $(USRINC)/errno.h       \
        !          25808:                $(SYSINC)/fdisk.h       \
        !          25809:                $(SYSINC)/inode.h       \
        !          25810:                $(SYSINC)/uproc.h       \
        !          25811:                fdisk.c
        !          25812:        $(CC) $(CFLAGS) -c -o $@@ fdisk.c
        !          25813: @
        !          25814: 
        !          25815: 
        !          25816: 1.7
        !          25817: log
        !          25818: @Add ssas.s module.
        !          25819: @
        !          25820: text
        !          25821: @d15 1
        !          25822: a15 1
        !          25823: OBJECTS=objects/ss.o objects/fdisk.o objects/ssqueue.o objects/ssas.o
        !          25824: d55 1
        !          25825: a55 1
        !          25826: objects/ssqueue.o:                     \
        !          25827: d60 2
        !          25828: a61 2
        !          25829:                ssqueue.c
        !          25830:        $(CC) $(CFLAGS) -c -o $@@ ssqueue.c
        !          25831: @
        !          25832: 
        !          25833: 
        !          25834: 1.6
        !          25835: log
        !          25836: @Add ability to define DEBUG level.
        !          25837: @
        !          25838: text
        !          25839: @d15 1
        !          25840: a15 1
        !          25841: OBJECTS=objects/ss.o objects/fdisk.o objects/ssqueue.o
        !          25842: d51 4
        !          25843: @
        !          25844: 
        !          25845: 
        !          25846: 1.5
        !          25847: log
        !          25848: @ssqueue.c - remove dependency on scsiwork.h
        !          25849: @
        !          25850: text
        !          25851: @d13 1
        !          25852: d49 1
        !          25853: a49 1
        !          25854:        $(CC) $(CFLAGS) -DVERBOSE=1 -c -o objects/ss.o ss.c
        !          25855: @
        !          25856: 
        !          25857: 
        !          25858: 1.4
        !          25859: log
        !          25860: @Add ss.h (and other dependencies) to ss.c
        !          25861: @
        !          25862: text
        !          25863: @a54 1
        !          25864:                $(DRVINC)/scsiwork.h    \
        !          25865: @
        !          25866: 
        !          25867: 
        !          25868: 1.3
        !          25869: log
        !          25870: @add ssqueue.c to ss
        !          25871: @
        !          25872: text
        !          25873: @d30 18
        !          25874: a47 1
        !          25875: objects/ss.o: ss.c
        !          25876: d64 1
        !          25877: a64 1
        !          25878:                $(SYSINC)/con.h         \
        !          25879: @
        !          25880: 
        !          25881: 
        !          25882: 1.2
        !          25883: log
        !          25884: @add fdisk.[co] to ss.a
        !          25885: @
        !          25886: text
        !          25887: @a8 2
        !          25888: # $Log$
        !          25889: #
        !          25890: d14 1
        !          25891: d26 1
        !          25892: a26 1
        !          25893: $(USRSYS)/lib/ss.a: objects/ss.o objects/fdisk.o
        !          25894: d28 1
        !          25895: a28 1
        !          25896:        ar rc $(USRSYS)/lib/ss.a objects/ss.o objects/fdisk.o
        !          25897: d33 9
        !          25898: d46 1
        !          25899: a46 1
        !          25900:                                        $(SYSINC)/fun.h \
        !          25901: @
        !          25902: 
        !          25903: 
        !          25904: 1.1
        !          25905: log
        !          25906: @Initial version for test builds
        !          25907: @
        !          25908: text
        !          25909: @d9 2
        !          25910: d27 1
        !          25911: a27 1
        !          25912: $(USRSYS)/lib/ss.a: objects/ss.o
        !          25913: d29 1
        !          25914: a29 1
        !          25915:        ar rc $(USRSYS)/lib/ss.a objects/ss.o
        !          25916: d33 13
        !          25917: @
        !          25918: 0707070064030104451004440000030000030000011777770507310646400005500000043607/newbits/kernel/USRSRC/i8086/drv/RCS/aha.c,vhead     1.6;
        !          25919: branch   ;
        !          25920: access   ;
        !          25921: symbols  ;
        !          25922: locks    bin:1.6;
        !          25923: comment  @ * @;
        !          25924: 
        !          25925: 
        !          25926: 1.6
        !          25927: date     91.06.20.14.46.55;  author bin;  state Exp;
        !          25928: branches ;
        !          25929: next     1.5;
        !          25930: 
        !          25931: 1.5
        !          25932: date     91.06.18.08.09.48;  author bin;  state Exp;
        !          25933: branches ;
        !          25934: next     1.4;
        !          25935: 
        !          25936: 1.4
        !          25937: date     91.06.17.12.26.42;  author bin;  state Exp;
        !          25938: branches ;
        !          25939: next     1.3;
        !          25940: 
        !          25941: 1.3
        !          25942: date     91.06.10.14.44.27;  author bin;  state Exp;
        !          25943: branches ;
        !          25944: next     1.2;
        !          25945: 
        !          25946: 1.2
        !          25947: date     91.05.01.04.54.43;  author root;  state Exp;
        !          25948: branches ;
        !          25949: next     1.1;
        !          25950: 
        !          25951: 1.1
        !          25952: date     91.04.30.11.01.41;  author root;  state Exp;
        !          25953: branches ;
        !          25954: next     ;
        !          25955: 
        !          25956: 
        !          25957: desc
        !          25958: @Adaptec-specific code for "sd" driver.
        !          25959: @
        !          25960: 
        !          25961: 
        !          25962: 1.6
        !          25963: log
        !          25964: @update provided by hal
        !          25965: @
        !          25966: text
        !          25967: @/*
        !          25968:  * This is the host adaptor specific portion of the
        !          25969:  * Adaptec AHA154x driver.
        !          25970:  *
        !          25971:  * $Log:       /usr/src/sys/i8086/drv/RCS/aha.c,v $
        !          25972:  * Revision 1.2        91/05/01  04:54:43      root
        !          25973:  * Debug code and kalloc arg fixes.
        !          25974:  * 
        !          25975:  * Revision 1.1        91/04/30  11:01:41      root
        !          25976:  * Shipped with COH 3.1.0
        !          25977:  * 
        !          25978:  */
        !          25979: #include <sys/coherent.h>
        !          25980: #include <sys/buf.h>
        !          25981: #include <sys/sched.h>
        !          25982: 
        !          25983: #include <sys/scsiwork.h>
        !          25984: #include <sys/aha154x.h>
        !          25985: 
        !          25986: extern saddr_t sds;            /* System Data Selector */
        !          25987: static paddr_t sds_physical;   /* as physical address */
        !          25988: static short   aha_i_o_base;
        !          25989: static char    aha_loaded;     /* did load() find a host adaptor? */
        !          25990: static char    dev_bit_map[8]; /* one byte per SCSI-ID; one bit per LUN */
        !          25991: char   drive_info[MAX_SCSI_ID * MAX_LUN]; /* "per drive" info/flags */
        !          25992: 
        !          25993: void   aha_intr();             /* interrupt service routine */
        !          25994: 
        !          25995: #define        MIN_MAILBOX     1
        !          25996: int    MAX_MAILBOX = { 8 };    /* tunable value */
        !          25997: 
        !          25998: static scsi_work_t     *scsi_work_queue;
        !          25999: static mailentry       *mailbox_in, *mailbox_out;
        !          26000: static char            *aha_err_msg = { "no message" };
        !          26001: 
        !          26002: static long    aha_timeout[] = { 
        !          26003: #define        TIMEOUT_PRESENT 0
        !          26004:        0x30000L,
        !          26005: #define        TIMEOUT_SENDCMD 1
        !          26006:        0x10000L,
        !          26007: #define        TIMEOUT_POLL    2
        !          26008:        0x100L,
        !          26009: };
        !          26010: 
        !          26011: #if    0
        !          26012: static
        !          26013: OUTB( port, value )
        !          26014: short port;
        !          26015: {      printf( "<O(%x,%x)>", port, value );
        !          26016:        outb( port, value );    }
        !          26017: INB( port )
        !          26018: short port;
        !          26019: {      register i = inb(port);
        !          26020:        printf( "<I(%x)=%x>", port, i );
        !          26021:        return i;       }
        !          26022: #else
        !          26023: #define        OUTB( port, value )     outb( port, value )
        !          26024: #define        INB(port)       inb(port)
        !          26025: #endif
        !          26026: 
        !          26027: #if    VERBOSE
        !          26028: #define        SETMSG(msg)     aha_err_msg = msg
        !          26029: 
        !          26030: static
        !          26031: char   *aha_last_msg()
        !          26032: {
        !          26033:        return aha_err_msg;
        !          26034: }
        !          26035: 
        !          26036: #else
        !          26037: 
        !          26038: #define        SETMSG(msg)
        !          26039: static
        !          26040: char   *aha_last_msg()
        !          26041: {
        !          26042:        return "error messages not verbose";
        !          26043: } 
        !          26044: #endif
        !          26045: 
        !          26046: static
        !          26047: int    no_mem()
        !          26048: {
        !          26049:        printf("aha154x: out of kernel memory\n");
        !          26050: }
        !          26051: 
        !          26052: int    aha_set_base( base )
        !          26053: {
        !          26054:        register i;
        !          26055: 
        !          26056:        i = aha_i_o_base;
        !          26057:        aha_i_o_base = base;
        !          26058:        return i;
        !          26059: }
        !          26060: 
        !          26061: int    aha_get_base()
        !          26062: {
        !          26063:        return aha_i_o_base;
        !          26064: }
        !          26065: 
        !          26066: aha_process( ccb )
        !          26067: ccb_t *ccb;
        !          26068: {
        !          26069:        register scsi_work_t *sw = ccb->ccb_sw;
        !          26070:        register BUF *bp;
        !          26071: 
        !          26072: #if    VERBOSE
        !          26073:        printf( "aha_process: ccb %x ", ccb );
        !          26074:        printf("sw=%x bp=%x\n", ccb->ccb_sw, ccb->ccb_sw->sw_bp);
        !          26075:        aha_ccb_print( ccb );
        !          26076: #endif
        !          26077:        if( ccb->ccb_sw == 0 ) {
        !          26078: #if    VERBOSE
        !          26079:                printf( "process: ccb %x with NULL sw\n", ccb );
        !          26080: #endif
        !          26081:                ++ccb->opcode;
        !          26082:                wakeup( ccb );
        !          26083:                return;
        !          26084:        }
        !          26085: 
        !          26086:        bp = sw->sw_bp;
        !          26087: #if    VERBOSE
        !          26088:        printf( "bp = %x\n", bp );
        !          26089: #endif
        !          26090:        if( (ccb->hoststatus != 0) || (ccb->targetstatus != 0) ) {
        !          26091:                if( --sw->sw_retry > 0
        !          26092:                   || (ccb->targetstatus == CHECK_TARGET_STATUS
        !          26093:                   && ccb->cmd_status[12] == SENSE_UNIT_ATTENTION)) {
        !          26094:                        int s = sphi();
        !          26095:                        if( scsi_work_queue->sw_actf == NULL ) {
        !          26096:                                scsi_work_queue->sw_actf = sw;
        !          26097:                        } else {
        !          26098:                                scsi_work_queue->sw_actl->sw_actf = sw;
        !          26099:                        }
        !          26100:                        scsi_work_queue->sw_actl = sw;
        !          26101:                        spl(s);
        !          26102:                        aha_start();
        !          26103:                        return;
        !          26104:                }
        !          26105:                bp->b_flag |= BFERR;
        !          26106:        } else
        !          26107:                bp->b_resid = 0;
        !          26108: #if    VERBOSE
        !          26109:        printf( "bp flag = %o\n", bp->b_flag );
        !          26110: #endif
        !          26111:        bdone( bp );
        !          26112:        kfree( sw );
        !          26113:        kfree( ccb );
        !          26114: }
        !          26115: 
        !          26116: static
        !          26117: int    aha_1out( value )
        !          26118: {
        !          26119:        register i;
        !          26120: 
        !          26121:        while( (i = INB(aha_i_o_base + AHA_STATUS) & AHA_CDOPFULL) != 0 )
        !          26122:                if( (i & AHA_INVDCMD)
        !          26123:                 || (INB(aha_i_o_base+AHA_INTERRUPT) & AHA_CMD_DONE) )
        !          26124:                        return -1;
        !          26125:        OUTB( aha_i_o_base + AHA_WRITE, value );
        !          26126:        return 0;
        !          26127: }
        !          26128: 
        !          26129: static
        !          26130: int    aha_1in()
        !          26131: {
        !          26132:        register i;
        !          26133: 
        !          26134:        while( (i = INB(aha_i_o_base + AHA_STATUS) & AHA_DIPFULL) == 0 )
        !          26135:                if( (i & AHA_INVDCMD)
        !          26136:                 || (INB(aha_i_o_base+AHA_INTERRUPT) & AHA_CMD_DONE) )
        !          26137:                        return -1;
        !          26138:        return INB( aha_i_o_base + AHA_READ ) & 0xFF;
        !          26139: }
        !          26140: 
        !          26141: static
        !          26142: void   aha_cmd_out( value )
        !          26143: {
        !          26144:        register long l;
        !          26145:        register int i;
        !          26146: 
        !          26147:        for( l = aha_timeout[TIMEOUT_SENDCMD]; --l > 0; )
        !          26148:                if( ((i=INB(aha_i_o_base + AHA_STATUS))
        !          26149:                    & AHA_SCSIIDLE ) != 0 ) {
        !          26150:                        aha_1out( value );
        !          26151:                        return;
        !          26152:                }
        !          26153: #if    VERBOSE
        !          26154:                else
        !          26155:                        printf( "aha: cmd_out status = %x\r", i );
        !          26156: #endif
        !          26157:        SETMSG( "timeout sending cmd byte" );
        !          26158:        printf( "aha154x: timeout sending cmd byte\n" );
        !          26159: }
        !          26160: 
        !          26161: static
        !          26162: int    aha_poll()
        !          26163: {
        !          26164:        register i;
        !          26165:        register l = aha_timeout[TIMEOUT_POLL];
        !          26166:        while( (--l > 0 )
        !          26167:          &&  ((i = INB(aha_i_o_base + AHA_INTERRUPT)) & AHA_CMD_DONE) == 0 )
        !          26168:                ;
        !          26169:        if( l == 0 )
        !          26170:                printf( "aha154x: aha_poll timed out\n" );
        !          26171: 
        !          26172:        i = INB(aha_i_o_base + AHA_STATUS);
        !          26173:        OUTB( aha_i_o_base + AHA_CONTROL, AHA_INTRRESET );
        !          26174:        return i;
        !          26175: }
        !          26176: 
        !          26177: static
        !          26178: void   aha_get_data( vec, cnt )
        !          26179: char   *vec;
        !          26180: int    cnt;
        !          26181: {
        !          26182:        while( --cnt >= 0 )
        !          26183:                *vec++ = aha_1in();
        !          26184:        aha_poll();
        !          26185: }
        !          26186: 
        !          26187: static
        !          26188: int    aha_present()
        !          26189: {
        !          26190:        long    l;
        !          26191: 
        !          26192:        if( INB(aha_i_o_base) == 0xFF ) {
        !          26193:                SETMSG( "no adapter found at io base" );
        !          26194:                return -3;
        !          26195:        }
        !          26196:        for( l = aha_timeout[TIMEOUT_PRESENT];
        !          26197:                (--l > 0) && (INB(aha_i_o_base + AHA_STATUS) & AHA_SELFTEST); )
        !          26198:                        ;
        !          26199:        if( l == 0 ) {
        !          26200:                SETMSG( "selftest not completed" );
        !          26201:                return -1;
        !          26202:        }
        !          26203:        if( INB(aha_i_o_base + AHA_STATUS) & AHA_DIAGFAIL ) {
        !          26204:                SETMSG( "diagnostics failed" );
        !          26205:                return -2;
        !          26206:        }
        !          26207:        if( INB(aha_i_o_base + AHA_STATUS) & AHA_INITMAIL ) {
        !          26208:                SETMSG( "mailbox initialization needed" );
        !          26209:                return 1;
        !          26210:        }
        !          26211:        if( INB(aha_i_o_base + AHA_STATUS) & AHA_SCSIIDLE ) {
        !          26212:                SETMSG( "adaptor okay, idle" );
        !          26213:                return 0;
        !          26214:        }
        !          26215:        SETMSG( "unknown status at start" );
        !          26216:        return -4;
        !          26217: }
        !          26218: 
        !          26219: static
        !          26220: void   aha_l_to_p3( value, vec )
        !          26221: paddr_t        value;
        !          26222: unsigned char *vec;
        !          26223: {
        !          26224:        register i;
        !          26225: 
        !          26226:        for( i = 3; --i >= 0; ) {
        !          26227:                vec[i] = value & 0xFF;
        !          26228:                value >>= 8;
        !          26229:        }
        !          26230: }
        !          26231: 
        !          26232: static
        !          26233: char   *aha_p3_to_v( vec )
        !          26234: unsigned char *vec;
        !          26235: {
        !          26236:        paddr_t adr;
        !          26237: 
        !          26238:        adr = vec[0];
        !          26239:        adr <<= 16;
        !          26240:        adr |= (vec[1]<<8) | vec[2];
        !          26241:        adr -= sds_physical;
        !          26242:        return (char *)adr;
        !          26243: }
        !          26244: 
        !          26245: aha_device_info()
        !          26246: {
        !          26247:        register i;
        !          26248:        static char buf[256];
        !          26249: 
        !          26250:        aha_cmd_out( AHA_DO_GET_DEVICES );
        !          26251:        aha_get_data( &buf[0], 8 );
        !          26252:        for( i = 0; i < 8; ++i )
        !          26253:                if( buf[i] != 0 )
        !          26254:                        printf( "[%d] %x ", i, buf[i] );
        !          26255:        printf( "\n" );
        !          26256: }
        !          26257: 
        !          26258: int    aha_unload( ireq )
        !          26259: {
        !          26260: #if    VERBOSE
        !          26261:        printf( "aha_unload: %x\n", ireq );
        !          26262: #endif
        !          26263:        /*
        !          26264:         *      we should really verify that everything
        !          26265:         *      out there gets flushed.
        !          26266:         */
        !          26267:        if (!aha_loaded)
        !          26268:                return;
        !          26269:        if( mailbox_out ) {
        !          26270:                kfree( mailbox_out );
        !          26271:                mailbox_out = 0;
        !          26272:        }
        !          26273:        clrivec( ireq );
        !          26274: }
        !          26275: 
        !          26276: int    aha_load( dma, ireq, base, head )
        !          26277: scsi_work_t *head;
        !          26278: {
        !          26279:        register int    i;
        !          26280:        unsigned char   adr[4];
        !          26281: 
        !          26282: #if    VERBOSE
        !          26283:        printf( "aha_load( %d, %d, 0x%x );\n", dma, ireq, base );
        !          26284: #endif
        !          26285:        aha_set_base(base);
        !          26286:        if( mailbox_out == 0 ) {
        !          26287:                if( (mailbox_out = 
        !          26288:                     kalloc(2 * MAX_MAILBOX * sizeof(mailentry))) == 0 ) {
        !          26289:                        no_mem();
        !          26290:                        return -1;
        !          26291:                } else
        !          26292:                        mailbox_in = &mailbox_out[MAX_MAILBOX];
        !          26293:        }
        !          26294: 
        !          26295:        for( i = 0; i < MAX_MAILBOX; ++i )
        !          26296:                mailbox_out[i].cmd = mailbox_in[i].cmd = 0;
        !          26297: 
        !          26298:        sds_physical = VTOP2( 0, sds );
        !          26299:        aha_l_to_p3( VTOP2( mailbox_out, sds ), &adr[1] );
        !          26300:        adr[0] = MAX_MAILBOX;
        !          26301: 
        !          26302:        /*
        !          26303:         * setup HW
        !          26304:         */
        !          26305:        setivec( ireq, aha_intr );
        !          26306:        outb( 0xD6, 0xC1 );             /* DMA is currently hard coded for */
        !          26307:        outb( 0xD4, 0x01 );             /* DMA channel 5 */
        !          26308: 
        !          26309: 
        !          26310:        OUTB( aha_i_o_base+AHA_CONTROL, AHA_HARDRESET );
        !          26311:        if (aha_present() < 0) {
        !          26312:                printf("aha154x: initialization error or host adaptor not ");
        !          26313:                printf("found at 0x%x\n", aha_i_o_base);
        !          26314:                return -1;
        !          26315:        }
        !          26316:        aha_cmd_out( AHA_DO_MAILBOX_INIT );
        !          26317:        for( i = 0; i < 4; ++i )
        !          26318:                aha_1out( adr[i] );
        !          26319:        scsi_work_queue = head;
        !          26320:        ++aha_loaded;
        !          26321:        return MAX_MAILBOX;
        !          26322: }
        !          26323: 
        !          26324: aha_command( sc )
        !          26325: register scsi_cmd_t *sc;
        !          26326: {
        !          26327:        register i;
        !          26328:        register ccb_t *ccb;
        !          26329: 
        !          26330:        short   count = sc->blklen;
        !          26331:        long    block = sc->block;
        !          26332: 
        !          26333:        ccb = (ccb_t *) kalloc(sizeof (ccb_t));
        !          26334:        if (ccb == (ccb_t *) 0) {
        !          26335:                no_mem();
        !          26336:                return -1;
        !          26337:        }
        !          26338: #if    VERBOSE
        !          26339:        printf( "aha_command( SCSI ID %d, LUN %d, c %x, b %D",
        !          26340:                sc->unit >> 2, sc->unit & 0x3, sc->cmd, sc->block ); 
        !          26341:        printf( " [%d] @@%x:%x )\n",
        !          26342:                sc->buflen, sc->buffer );
        !          26343: #endif
        !          26344:        ccb->ccb_sw = 0;
        !          26345:        ccb->opcode = 0;                        /* SCSI_INITIATOR*/
        !          26346:        ccb->target = (sc->unit & 0x1C) << 3;   /* SCSI ID */
        !          26347:        ccb->target |= sc->unit & 0x3;          /* LUN */
        !          26348:        if( (ccb->cmd_status[0] = sc->cmd) == ScmdWRITEXTENDED ) {
        !          26349:                ccb->target |= AHA_CCB_DATA_OUT;
        !          26350:        } else { /* READEXT, READCAP, INQUIRY */
        !          26351:                ccb->target |= AHA_CCB_DATA_IN;
        !          26352:        }
        !          26353:        ccb->cmd_status[1] = 0;
        !          26354:        ccb->cmd_status[2] = block;
        !          26355:        ccb->cmd_status[3] = block >>16;
        !          26356:        ccb->cmd_status[4] = block >> 8;
        !          26357:        ccb->cmd_status[5] = block;
        !          26358:        ccb->cmd_status[6] = 0;
        !          26359:        ccb->cmd_status[7] = count / 512;
        !          26360:        ccb->cmd_status[8] = count;
        !          26361:        ccb->cmd_status[9] = 0;
        !          26362:        ccb->cmdlen = 10;
        !          26363:        ccb->senselen = MAX_SENSEDATA;
        !          26364: 
        !          26365:        aha_l_to_p3( (long)sc->buflen, ccb->datalen );
        !          26366:        aha_l_to_p3( sc->buffer, ccb->dataptr );
        !          26367:        aha_l_to_p3( VTOP2( ccb, sds ), mailbox_out[0].adr );
        !          26368: #if    VERBOSE
        !          26369:        aha_ccb_print( ccb );
        !          26370: #endif
        !          26371:        mailbox_out[0].cmd = MBO_TO_START;
        !          26372:        aha_1out( AHA_DO_SCSI_START );
        !          26373:        while( ccb->opcode == 0 )
        !          26374:                sleep( ccb, CVBLKIO, IVBLKIO, SVBLKIO );
        !          26375:        
        !          26376: #if    VERBOSE
        !          26377:        printf( "done with status = %d, %d\n",
        !          26378:                ccb->hoststatus, ccb->targetstatus );
        !          26379: #endif
        !          26380:        if( (ccb->targetstatus == CHECK_TARGET_STATUS)
        !          26381:           && (ccb->cmd_status[12] != SENSE_UNIT_ATTENTION) ) {
        !          26382:                printf( "aha: SCSI ID %d LUN %d. SCSI sense =",
        !          26383:                (sc->unit >> 2), sc->unit & 0x3 );
        !          26384:                for( i = 0; i < ccb->senselen; ++i )
        !          26385:                        printf( " %x", ccb->cmd_status[10+i] );
        !          26386:                printf( "\n" );
        !          26387:        }
        !          26388:        i = ccb->hoststatus | ccb->targetstatus;
        !          26389:        kfree( ccb );
        !          26390:        return i;
        !          26391: }
        !          26392: 
        !          26393: ccb_t  *buildccb( sw )
        !          26394: register scsi_work_t *sw;
        !          26395: {
        !          26396:        register ccb_t *ccb;
        !          26397:        ccb = (ccb_t *)kalloc(sizeof(ccb_t));
        !          26398: 
        !          26399: #if    VERBOSE
        !          26400:        printf( "build: drv = %x, bno = %D  ",
        !          26401:                sw->sw_drv, sw->sw_bno );
        !          26402: #endif
        !          26403:        ccb->ccb_sw = sw;
        !          26404:        ccb->opcode = 0;                        /* SCSI INITIATOR */
        !          26405:        ccb->target = (sw->sw_drv & 0x1C) << 3; /* SCSI ID */
        !          26406:        ccb->target |= (sw->sw_drv) & 0x3;      /* LUN */
        !          26407:        if( sw->sw_bp->b_req == BREAD ) {
        !          26408:                ccb->target |= AHA_CCB_DATA_IN;
        !          26409:                ccb->cmd_status[0] = ScmdREADEXTENDED;
        !          26410:        } else {
        !          26411:                ccb->target |= AHA_CCB_DATA_OUT;
        !          26412:                ccb->cmd_status[0] = ScmdWRITEXTENDED;
        !          26413:        }
        !          26414:        ccb->cmd_status[2] = 0;
        !          26415:        ccb->cmd_status[3] = sw->sw_bno >>16;
        !          26416:        ccb->cmd_status[4] = sw->sw_bno >> 8;
        !          26417:        ccb->cmd_status[5] = sw->sw_bno;
        !          26418:        ccb->cmd_status[6] = 0;
        !          26419:        ccb->cmd_status[7] = sw->sw_bp->b_count / (512*256L);
        !          26420:        ccb->cmd_status[8] = sw->sw_bp->b_count / 512;
        !          26421:        ccb->cmd_status[9] = 0;
        !          26422:        ccb->cmdlen = 10;
        !          26423:        ccb->senselen = MAX_SENSEDATA;
        !          26424: 
        !          26425:        aha_l_to_p3( (long)sw->sw_bp->b_count, ccb->datalen );
        !          26426:        aha_l_to_p3( vtop(sw->sw_bp->b_faddr), ccb->dataptr );
        !          26427:        return ccb;
        !          26428: #if    0
        !          26429: /* start of ioctl code */
        !          26430:        if( f == SASI_CMD_IN )
        !          26431:                ccb->target |= AHA_CCB_DATA_IN;
        !          26432:        else if( f == SASI_CMD_OUT )
        !          26433:                ccb->target |= AHA_CCB_DATA_OUT;
        !          26434:        else
        !          26435:                ccb->target |=   AHA_CCB_DATA_IN
        !          26436:                                |AHA_CCB_DATA_OUT;
        !          26437: #endif
        !          26438: }
        !          26439: 
        !          26440: aha_start()
        !          26441: {
        !          26442:        register i, s, n = 0;
        !          26443:        scsi_work_t *sw;
        !          26444:        static char locked;
        !          26445: 
        !          26446:        s = sphi();
        !          26447:        if( locked ) {
        !          26448:                spl(s);
        !          26449:                return;
        !          26450:        }
        !          26451:        ++locked;
        !          26452:        spl(s);
        !          26453: 
        !          26454:        while( (sw = scsi_work_queue->sw_actf) != NULL ) {
        !          26455:                for( i = MIN_MAILBOX; i < MAX_MAILBOX; ++i )
        !          26456:                        if( mailbox_out[i].cmd == MBO_IS_FREE ) {
        !          26457:                                register ccb_t *ccb;
        !          26458:                                int s;
        !          26459: 
        !          26460:                                ++n;
        !          26461:                                ccb = buildccb( sw );
        !          26462: #if    VERBOSE
        !          26463:                                aha_ccb_print( ccb );
        !          26464: #endif
        !          26465:                                aha_l_to_p3( VTOP2( ccb, sds ),
        !          26466:                                                mailbox_out[i].adr );
        !          26467:                                mailbox_out[i].cmd = MBO_TO_START;
        !          26468: #if    VERBOSE
        !          26469:                                printf( "MBO[%d] = %x:%x:%x:%x, ccb = %x ",
        !          26470:                                        i, mailbox_out[i].cmd,
        !          26471:                                        mailbox_out[i].adr[0],
        !          26472:                                        mailbox_out[i].adr[1],
        !          26473:                                        mailbox_out[i].adr[2], ccb );
        !          26474:        printf("sw=%x bp=%x\n", ccb->ccb_sw, ccb->ccb_sw->sw_bp);
        !          26475: #endif
        !          26476:                                aha_1out( AHA_DO_SCSI_START );
        !          26477: 
        !          26478:                                s = sphi();
        !          26479:                                sw = scsi_work_queue->sw_actf = sw->sw_actf;
        !          26480:                                if( sw == NULL )
        !          26481:                                        scsi_work_queue->sw_actl = NULL;
        !          26482:                                spl(s);
        !          26483: 
        !          26484:                                if( sw == NULL )
        !          26485:                                        break;
        !          26486:                        }
        !          26487:                if( i == MAX_MAILBOX )
        !          26488:                        break;
        !          26489:        }
        !          26490:        --locked;
        !          26491:        return n;
        !          26492: }
        !          26493: 
        !          26494: int    aha_completed()
        !          26495: {
        !          26496:        register i, n;
        !          26497: 
        !          26498:        for( n = 0, i = 0; i < MAX_MAILBOX; ++i )
        !          26499:                if( mailbox_in[i].cmd != MBI_IS_FREE ) {
        !          26500: #if    VERBOSE
        !          26501:                        printf( "aha: mail[%d] = %x:%x:%x:%x\n",
        !          26502:                                i, mailbox_in[i].cmd,
        !          26503:                                mailbox_in[i].adr[0],
        !          26504:                                mailbox_in[i].adr[1],
        !          26505:                                mailbox_in[i].adr[2] );
        !          26506: #endif
        !          26507:                        defer( aha_process,
        !          26508:                                aha_p3_to_v( mailbox_in[i].adr ) );
        !          26509:                        mailbox_in[i].cmd = MBI_IS_FREE;
        !          26510:                        ++n;
        !          26511:                }
        !          26512:        return n;
        !          26513: }
        !          26514: 
        !          26515: void   aha_intr()
        !          26516: {
        !          26517:        register i;
        !          26518: 
        !          26519: #if    VERBOSE
        !          26520:        printf( "aha_interrupt routine\n" );
        !          26521: #endif
        !          26522:        if( ((i = INB(aha_i_o_base+AHA_INTERRUPT)) & AHA_ANY_INTER) == 0 )
        !          26523:                printf( "aha: spurious interrupt %x\n", i );
        !          26524: #if    VERBOSE
        !          26525:        printf( "aha_interrupt: %x\n", i );
        !          26526: #endif
        !          26527:        switch( i & AHA_ALL_INTERRUPTS ) {
        !          26528:        case AHA_RESETED:
        !          26529: #if    VERBOSE
        !          26530:                printf( "aha: reseted\n" );
        !          26531: #endif
        !          26532:                break;
        !          26533:        case AHA_CMD_DONE:
        !          26534: #if    VERBOSE
        !          26535:                printf( "aha: adapter command completed\n" );
        !          26536: #endif
        !          26537:                break;
        !          26538:        case AHA_MBO_EMPTY:
        !          26539: #if    VERBOSE
        !          26540:                printf( "aha: MAILBOX emptied\n" );
        !          26541: #endif
        !          26542:                defer( aha_start, (char *)0 );
        !          26543:                break;
        !          26544:        case AHA_MBI_STORED:
        !          26545: #if    VERBOSE
        !          26546:                printf( "aha: MAILBOX in stored\n" );
        !          26547: #endif
        !          26548:                aha_completed();
        !          26549:                break;
        !          26550:        default:
        !          26551:                printf( "aha: multiple interrupts not yet handled\n" );
        !          26552:        }
        !          26553:        outb( aha_i_o_base+AHA_CONTROL, AHA_INTRRESET );
        !          26554: }
        !          26555: 
        !          26556: aha_ioctl()
        !          26557: {
        !          26558:        printf( "aha_ioctl: Not implemented\n" );
        !          26559: }
        !          26560: 
        !          26561: #if    VERBOSE
        !          26562: static unsigned char vec[256];
        !          26563: 
        !          26564: static aha_ports_are() {
        !          26565:        printf( "aha_ports_are: %x %x %x\n",
        !          26566:                INB(aha_i_o_base+0),
        !          26567:                INB(aha_i_o_base+1),
        !          26568:                INB(aha_i_o_base+2) );
        !          26569: }
        !          26570: 
        !          26571: static aha_inquiry_is() {
        !          26572:        printf( "aha_inquiry:" );
        !          26573:        printf( "... aha_present = %d, ", aha_present() );
        !          26574:        printf( "%s\n", aha_last_msg() );
        !          26575:        aha_cmd_out( AHA_DO_INQUIRY );
        !          26576: 
        !          26577:        aha_get_data( &vec[0], 4 );
        !          26578:        printf( " board id '%c'", vec[0] );
        !          26579:        printf( ", options '%c'", vec[1] );
        !          26580:        printf( ", HW '%c'", vec[2] );
        !          26581:        printf( ", FW '%c'\n", vec[3] );
        !          26582: }
        !          26583: 
        !          26584: void   aha_setup_is() {
        !          26585:        register i;
        !          26586: 
        !          26587:        printf( "Setup and Data:\n" );
        !          26588:        aha_cmd_out( AHA_DO_GET_SETUP );
        !          26589:        aha_cmd_out( 16 );
        !          26590:        aha_get_data( &vec[0], 16 );
        !          26591:        printf( "  Data Xfer %s Sync (J1)\n", (vec[0]&1) ? "is" : "not" );
        !          26592:        printf( "  Parity %s Enabled (J1)\n", (vec[0]&2) ? "is" : "not" );
        !          26593:        switch( vec[1] ) {
        !          26594:        case AHA_SPEED_5_0_MB:
        !          26595:                printf( "  5.0 Mb/sec.\n" );    break;
        !          26596:        case AHA_SPEED_6_7_MB:
        !          26597:                printf( "  6.7 Mb/sec.\n" );    break;
        !          26598:        case AHA_SPEED_8_0_MB:
        !          26599:                printf( "  8.0 Mb/sec.\n" );    break;
        !          26600:        case AHA_SPEED_10_MB:
        !          26601:                printf( "  10 Mb/sec.\n" );     break;
        !          26602:        case AHA_SPEED_5_7_MB:
        !          26603:                printf( "  5.7 Mb/sec.\n" );    break;
        !          26604:        default:
        !          26605:                if( vec[1] & 0x80 )
        !          26606:                        printf( "  Pulse Read %d, Write %d, Strobe off %d\n",
        !          26607:                                50*(2+(vec[1]>>4)&0x7), 50*(2+(vec[1]&7)),
        !          26608:                                vec[1] & 0x80 ? 150 : 100 );
        !          26609:        }
        !          26610:        printf( "  Bus Time ON %d, OFF %d\n", vec[2], vec[3] );
        !          26611:        printf( "  %d Mailboxes at %x|%x|%x\n", vec[4],
        !          26612:                vec[5], vec[6], vec[7] );
        !          26613:        for( i = 0; i < 8; ++i )
        !          26614:                if( vec[i+8] )
        !          26615:                        printf( "  Target [%d] = Sync Neg %x\n", i, vec[i+8] );
        !          26616: }
        !          26617: 
        !          26618: static aha_mailboxes_are( n, adr )
        !          26619: mailentry *adr;
        !          26620: {
        !          26621:        register i;
        !          26622: 
        !          26623:        printf( "addresses for mailbox is %x:%x\n", (long)adr );
        !          26624:        for( i = 0; i < n; ++i, ++adr )
        !          26625:                printf( "  mbo[%x] = %x %x|%x|%x\n",
        !          26626:                        i, adr->cmd, adr->adr[0], adr->adr[1], adr->adr[2] );
        !          26627:        for( i = 0; i < n; ++i, ++adr )
        !          26628:                printf( "  mbi[%x] = %x %x|%x|%x\n",
        !          26629:                        i, adr->cmd, adr->adr[0], adr->adr[1], adr->adr[2] );
        !          26630: }
        !          26631: 
        !          26632: void   aha_status()
        !          26633: {
        !          26634:        aha_ports_are();
        !          26635:        aha_inquiry_is();
        !          26636:        aha_devices_are();
        !          26637:        aha_setup_is();
        !          26638:        aha_mailboxes_are( MAX_MAILBOX, mailbox_out );
        !          26639: }
        !          26640: 
        !          26641: aha_ccb_print( ccb )
        !          26642: ccb_t  *ccb;
        !          26643: {
        !          26644:        register i;
        !          26645:        register unsigned char *cp;
        !          26646: 
        !          26647:        printf( "ccb @@%x, sw @@%x, bp @@%x, flag %o\n",
        !          26648:                ccb, ccb->ccb_sw, ccb->ccb_sw->sw_bp,
        !          26649:                ccb->ccb_sw->sw_bp->b_flag );
        !          26650:        printf( "op %d, ", ccb->opcode );
        !          26651:        printf( "target ID=%d, ", (ccb->target>>5) & 0x7 );
        !          26652:        printf( "LUN=%d, ", (ccb->target & 0x7) );
        !          26653:        printf( "dir=%s%s\n",   (ccb->target&AHA_CCB_DATA_IN)?"IN":"",
        !          26654:                                (ccb->target&AHA_CCB_DATA_OUT)?"OUT":"" );
        !          26655:        printf( "data len %x|%x|%x, adr %x|%x|%x\n",
        !          26656:                ccb->datalen[0],ccb->datalen[1],ccb->datalen[2],
        !          26657:                ccb->dataptr[0],ccb->dataptr[1],ccb->dataptr[2] );
        !          26658:        printf( "status host=%x, target=%x\n",
        !          26659:                ccb->hoststatus, ccb->targetstatus );
        !          26660:        printf( "cmddata[%d]:", ccb->cmdlen );
        !          26661:        for( i = 0, cp = ccb->cmd_status; i < ccb->cmdlen; ++i )
        !          26662:                printf( " %x", *cp++ );
        !          26663:        printf( "\nrequest sense[%d]:", ccb->senselen );
        !          26664:        for( i = 0; i < ccb->senselen; ++i )
        !          26665:                printf( " %x", *cp++ );
        !          26666:        if( i = cp[-1] ) {
        !          26667:                printf( "\n   + " );
        !          26668:                while( --i >= 0 )
        !          26669:                        printf( " %x", *cp++ );
        !          26670:        }
        !          26671:        printf( "\n" );
        !          26672: }
        !          26673: 
        !          26674: #endif /* VERBOSE */
        !          26675: 
        !          26676: @
        !          26677: 
        !          26678: 
        !          26679: 1.5
        !          26680: log
        !          26681: @update provided by hal
        !          26682: @
        !          26683: text
        !          26684: @d13 1
        !          26685: a13 1
        !          26686: #include "coherent.h"
        !          26687: d17 2
        !          26688: a18 2
        !          26689: #include "scsiwork.h"
        !          26690: #include "aha154x.h"
        !          26691: @
        !          26692: 
        !          26693: 
        !          26694: 1.4
        !          26695: log
        !          26696: @new version provided y hal for v321
        !          26697: @
        !          26698: text
        !          26699: @@
        !          26700: 
        !          26701: 
        !          26702: 1.3
        !          26703: log
        !          26704: @initial version prov by hal
        !          26705: @
        !          26706: text
        !          26707: @d13 1
        !          26708: a13 1
        !          26709: #include <sys/coherent.h>
        !          26710: @
        !          26711: 
        !          26712: 
        !          26713: 1.2
        !          26714: log
        !          26715: @Debug code and kalloc arg fixes.
        !          26716: @
        !          26717: text
        !          26718: @d6 3
        !          26719: d106 1
        !          26720: d108 1
        !          26721: a108 2
        !          26722: printf("sw=%x bp=%x\n", ccb->ccb_sw, ccb->ccb_sw->sw_bp);
        !          26723: #if    VERBOSE
        !          26724: a130 6
        !          26725: printf("0-swq-f=%x\n", scsi_work_queue->sw_actf);
        !          26726: {BUF *bp=sw->sw_bp;
        !          26727: printf("bno=%lx count=%d ", bp->b_bno, bp->b_count);
        !          26728: printf("faddr=%lx resid=%d ", bp->b_faddr, bp->b_resid);
        !          26729: printf("req=%x bp=%x\n", bp->b_req, bp);
        !          26730: }
        !          26731: a331 1
        !          26732: printf("B");
        !          26733: a332 1
        !          26734: printf("C");
        !          26735: a353 1
        !          26736: printf("1-swq-f=%x\n", scsi_work_queue->sw_actf);
        !          26737: a400 1
        !          26738: printf("D");
        !          26739: d433 1
        !          26740: a433 1
        !          26741: #if    1
        !          26742: d460 1
        !          26743: a460 7
        !          26744: printf("E");
        !          26745: {BUF *bp=sw->sw_bp;
        !          26746: printf("bno=%lx count=%d ", bp->b_bno, bp->b_count);
        !          26747: printf("faddr=%lx resid=%d ", bp->b_faddr, bp->b_resid);
        !          26748: printf("req=%x bp=%x\n", bp->b_req, bp);
        !          26749: }
        !          26750:        aha_l_to_p3( VTOP(sw->sw_bp->b_faddr), ccb->dataptr );
        !          26751: d479 1
        !          26752: a479 1
        !          26753: printf("aha_start ");
        !          26754: a494 1
        !          26755: printf("before buildccb\n");
        !          26756: a495 1
        !          26757: printf("after buildccb\n");
        !          26758: a498 1
        !          26759: printf("F");
        !          26760: d502 1
        !          26761: a502 1
        !          26762: #if    1
        !          26763: d508 1
        !          26764: a508 1
        !          26765: printf("sw=%x bp=%x\n", ccb->ccb_sw, ccb->ccb_sw->sw_bp);
        !          26766: a513 1
        !          26767: printf("2-swq-f=%x\n", scsi_work_queue->sw_actf);
        !          26768: d531 1
        !          26769: a531 1
        !          26770: printf("aha_completed ");
        !          26771: d534 1
        !          26772: a534 1
        !          26773: #if    1
        !          26774: @
        !          26775: 
        !          26776: 
        !          26777: 1.1
        !          26778: log
        !          26779: @Shipped with COH 3.1.0
        !          26780: @
        !          26781: text
        !          26782: @d5 4
        !          26783: a8 1
        !          26784:  * $Log$
        !          26785: a11 2
        !          26786: #include <sys/mmu.h>
        !          26787: #include <sys/types.h>
        !          26788: d103 2
        !          26789: a105 1
        !          26790:        printf( "aha_process: ccb %x\n", ccb );
        !          26791: d126 1
        !          26792: a126 1
        !          26793:                        if( scsi_work_queue->sw_actf == NULL )
        !          26794: d128 7
        !          26795: a134 1
        !          26796:                        else
        !          26797: d136 1
        !          26798: d335 4
        !          26799: a338 2
        !          26800:        sds_physical = vtop( 0, sds );
        !          26801:        aha_l_to_p3( vtop( mailbox_out, sds ), &adr[1] );
        !          26802: d359 1
        !          26803: d373 1
        !          26804: a373 1
        !          26805:        ccb = (ccb_t *) kalloc(sizeof *ccb);
        !          26806: d407 2
        !          26807: a408 1
        !          26808:        aha_l_to_p3( vtop( ccb, sds ), mailbox_out[0].adr );
        !          26809: d438 1
        !          26810: a438 1
        !          26811:        ccb = (ccb_t *)kalloc(10 + sizeof *ccb);
        !          26812: d440 1
        !          26813: a440 1
        !          26814: #if    VERBOSE
        !          26815: d467 7
        !          26816: a473 1
        !          26817:        aha_l_to_p3( vtop(sw->sw_bp->b_faddr), ccb->dataptr );
        !          26818: d492 1
        !          26819: a492 1
        !          26820: 
        !          26821: d508 1
        !          26822: d510 1
        !          26823: d514 2
        !          26824: a515 1
        !          26825:                                aha_l_to_p3( vtop( ccb, sds ),
        !          26826: d518 2
        !          26827: a519 2
        !          26828: #if    VERBOSE
        !          26829:                                printf( "MBO[%d] = %x:%x:%x:%x, ccb = %x\n",
        !          26830: d524 1
        !          26831: d530 1
        !          26832: d548 1
        !          26833: a548 1
        !          26834: 
        !          26835: d551 1
        !          26836: a551 1
        !          26837: #if    VERBOSE
        !          26838: @
        !          26839: 0707070064030106211004440000030000030000011777770507310647000005400000032374/newbits/kernel/USRSRC/i8086/drv/RCS/al.c,vhead     1.8;
        !          26840: branch   ;
        !          26841: access   ;
        !          26842: symbols  ;
        !          26843: locks    bin:1.8;
        !          26844: comment  @ * @;
        !          26845: 
        !          26846: 
        !          26847: 1.8
        !          26848: date     91.08.01.13.47.28;  author bin;  state Exp;
        !          26849: branches ;
        !          26850: next     1.7;
        !          26851: 
        !          26852: 1.7
        !          26853: date     91.06.20.14.47.12;  author bin;  state Exp;
        !          26854: branches ;
        !          26855: next     1.6;
        !          26856: 
        !          26857: 1.6
        !          26858: date     91.06.18.08.10.26;  author bin;  state Exp;
        !          26859: branches ;
        !          26860: next     1.5;
        !          26861: 
        !          26862: 1.5
        !          26863: date     91.06.17.12.27.58;  author bin;  state Exp;
        !          26864: branches ;
        !          26865: next     1.4;
        !          26866: 
        !          26867: 1.4
        !          26868: date     91.06.10.14.44.45;  author bin;  state Exp;
        !          26869: branches ;
        !          26870: next     1.3;
        !          26871: 
        !          26872: 1.3
        !          26873: date     91.02.22.16.05.43;  author root;  state Exp;
        !          26874: branches ;
        !          26875: next     1.2;
        !          26876: 
        !          26877: 1.2
        !          26878: date     91.02.21.11.21.28;  author hal;  state Exp;
        !          26879: branches ;
        !          26880: next     1.1;
        !          26881: 
        !          26882: 1.1
        !          26883: date     91.02.21.11.07.36;  author hal;  state Exp;
        !          26884: branches ;
        !          26885: next     ;
        !          26886: 
        !          26887: 
        !          26888: desc
        !          26889: @@
        !          26890: 
        !          26891: 
        !          26892: 1.8
        !          26893: log
        !          26894: @updated by hal to include rts/cts handshaking.
        !          26895: @
        !          26896: text
        !          26897: @/* (-lgl
        !          26898:  *     COHERENT Driver Kit Version 1.1.0
        !          26899:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          26900:  *     All rights reserved. May not be copied without permission.
        !          26901:  *
        !          26902:  * $Log:       al.c,v $
        !          26903:  * Revision 1.4  91/07/31  16:06:33  hal
        !          26904:  * Change include usage.  Use AL[01]_MAJOR.
        !          26905:  * 
        !          26906:  * Revision 1.2        91/02/21  11:21:28      hal
        !          26907:  * Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          26908:  * 
        !          26909:  * Revision 1.1        91/02/21  11:07:36      hal
        !          26910:  * Used in COH Release 3.0.0 - no COM3/COM4
        !          26911:  * 
        !          26912:  -lgl) */
        !          26913: /*
        !          26914:  * Driver for an IBM PC asyncronous
        !          26915:  * line, using interrupts. The interface
        !          26916:  * uses a Natty/WD 8250 chip.
        !          26917:  */
        !          26918: #include <sys/coherent.h>
        !          26919: #include <sys/i8086.h>
        !          26920: #include <sys/con.h>
        !          26921: #include <errno.h>
        !          26922: #include <sys/stat.h>
        !          26923: #include <sys/tty.h>
        !          26924: #include <sys/uproc.h>
        !          26925: #include <sys/clist.h>
        !          26926: #include <sys/ins8250.h>
        !          26927: #include <sys/sched.h>
        !          26928: #include <sys/al.h>
        !          26929: #include <sys/devices.h>
        !          26930: 
        !          26931: #define        minor_st(dev)   (dev & 0x3f)
        !          26932: #define        DEV_TTY         (alttab[minor_st(dev)])
        !          26933: #define ALPORT         (((COM_DDP *)(DEV_TTY.t_ddp))->port)
        !          26934: 
        !          26935: /*
        !          26936:  * This driver can be compiled to drive any possible
        !          26937:  * async port by appropriate definitions of:
        !          26938:  *     ALPORT[ab]      the io port address(es)
        !          26939:  *     ALNUM[ab]       com index number (0..3 for com[1..4])
        !          26940:  *     ALINT   the interrupt level
        !          26941:  *     ALNAME  the xxcon name
        !          26942:  *     ALMAJ   the major device number
        !          26943:  *      ALCNT  number of ports sharing the interrupt
        !          26944:  *
        !          26945:  *     NOTE:   if ALCNT is changed, alttab and alintr will need hacking
        !          26946:  * Common code for the different ports is handled by alx.c
        !          26947:  */
        !          26948: 
        !          26949: #ifdef ALCOM1                  /* COM1_3 definitions */
        !          26950: #define ALPORTa        0x3F8           /* Base of com1 port */
        !          26951: #define ALPORTb        0x3E8           /* Base of com3 port */
        !          26952: #define ALNUMa 0               /* com1 has com number of 0 */
        !          26953: #define ALNUMb 2               /* com3 has com number of 2 */
        !          26954: #define ALINT  4               /* Interrupt level of com1_3 ports */
        !          26955: #define        ALNAME  a0con           /* CON name of com1_3 ports */
        !          26956: #define ALMAJ  AL0_MAJOR       /* Major number of com1_3 port */
        !          26957: #define ALCNT  A0CNT           /* Number of ports for this IRQ */
        !          26958: #define ALSPEEDa C1BAUD                /* Name of patchable variable for com1 speed */
        !          26959: #define ALSPEEDb C3BAUD                /* Name of patchable variable for com3 speed */
        !          26960: #endif
        !          26961: 
        !          26962: #ifdef ALCOM2                  /* COM2_4 definitions */
        !          26963: #define ALPORTa        0x2F8           /* Base of com2 port */
        !          26964: #define ALPORTb        0x2E8           /* Base of com4 port */
        !          26965: #define ALNUMa 1               /* com2 has com number of 1 */
        !          26966: #define ALNUMb 3               /* com4 has com number of 3 */
        !          26967: #define ALINT  3               /* Interrupt level of com2_4 ports */
        !          26968: #define ALNAME a1con           /* CON name of com2_4 ports */
        !          26969: #define ALMAJ  AL1_MAJOR       /* Major number of com2_4 ports */
        !          26970: #define ALCNT  A1CNT           /* Number of ports for this IRQ */
        !          26971: #define ALSPEEDa C2BAUD                /* Name of patchable variable for com2 speed */
        !          26972: #define ALSPEEDb C4BAUD                /* Name of patchable variable for com4 speed */
        !          26973: #endif
        !          26974: 
        !          26975: /*
        !          26976:  * Functions.
        !          26977:  */
        !          26978: int    alxopen();
        !          26979: int    alxclose();
        !          26980: int    alxioctl();
        !          26981: int    alxtimer();
        !          26982: int    alxparam();
        !          26983: int    alxcycle();
        !          26984: int    alxstart();
        !          26985: int    alxbreak();
        !          26986: 
        !          26987: int    alintr();
        !          26988: int    alopen();
        !          26989: int    alclose();
        !          26990: int    alread();
        !          26991: int    alwrite();
        !          26992: int    alioctl();
        !          26993: int    alload();
        !          26994: int    alunload();
        !          26995: int    alpoll();
        !          26996: int    nulldev();
        !          26997: int    nonedev();
        !          26998: 
        !          26999: /*
        !          27000:  * Configuration table.
        !          27001:  */
        !          27002: CON ALNAME ={
        !          27003:        DFCHR|DFPOL,                    /* Flags */
        !          27004:        ALMAJ,                          /* Major index */
        !          27005:        alopen,                         /* Open */
        !          27006:        alclose,                        /* Close */
        !          27007:        nulldev,                        /* Block */
        !          27008:        alread,                         /* Read */
        !          27009:        alwrite,                        /* Write */
        !          27010:        alioctl,                        /* Ioctl */
        !          27011:        nulldev,                        /* Powerfail */
        !          27012:        alxtimer,                       /* Timeout */
        !          27013:        alload,                         /* Load */
        !          27014:        alunload,                       /* Unload */
        !          27015:        alpoll                          /* Poll */
        !          27016: };
        !          27017: 
        !          27018: /*
        !          27019:  * Terminal structures.
        !          27020:  */
        !          27021: static COM_DDP * ddp;
        !          27022: static TTY     * alttab;
        !          27023: static TTY     * irqtty;  /* point to alttab entry which is IRQ-enabled */
        !          27024: 
        !          27025: /*
        !          27026:  * to change default speeds - patch kernel variables C1BAUD..C4BAUD
        !          27027:  *   new value should be one of B0..B9600 in /usr/include/sgtty.h
        !          27028:  */
        !          27029: int ALSPEEDa = B9600;
        !          27030: int ALSPEEDb = B9600;
        !          27031: 
        !          27032: /*
        !          27033:  * to enable com[34], patch here
        !          27034:  *     A0CNT should be 2 if you want com3, 1 otherwise
        !          27035:  *     A1CNT should be 2 if you want com4, 1 otherwise
        !          27036:  */
        !          27037: int ALCNT = 2;
        !          27038: 
        !          27039: static
        !          27040: alload()
        !          27041: {
        !          27042:        register int s;
        !          27043:        static int init;
        !          27044:        extern int albaud[];
        !          27045:        int port, i;
        !          27046: 
        !          27047:        if (init == 0
        !          27048:          && (alttab = (TTY *)kalloc(ALCNT * sizeof(TTY)))
        !          27049:          && (ddp = (COM_DDP *)kalloc(ALCNT * sizeof(COM_DDP)))) {
        !          27050:                kclear(alttab, ALCNT*sizeof(TTY));
        !          27051:                kclear(ddp, ALCNT*sizeof(COM_DDP));
        !          27052:                s = sphi();
        !          27053:                ++init;
        !          27054: 
        !          27055:                alttab[0].t_dispeed = alttab[0].t_dospeed = ALSPEEDa;
        !          27056:                alttab[0].t_ddp = (char *)&ddp[0];
        !          27057:                tp_table[ALNUMa] = alttab; /* set TTY pointers for polling */
        !          27058:                ddp[0].port = ALPORTa;
        !          27059:                ddp[0].com_num = ALNUMa;
        !          27060: 
        !          27061:                if (ALCNT > 1) {
        !          27062:                        alttab[1].t_dispeed = alttab[1].t_dospeed = ALSPEEDb;
        !          27063:                        alttab[1].t_ddp = (char *)&ddp[1];
        !          27064:                        tp_table[ALNUMb] = alttab+1;
        !          27065:                        ddp[1].port = ALPORTb;
        !          27066:                        ddp[1].com_num = ALNUMb;
        !          27067:                }
        !          27068: 
        !          27069:                for (i = 0;  i < ALCNT; i++) {
        !          27070:                        int speed = alttab[i].t_dospeed;
        !          27071: 
        !          27072:                        /* port = base I/O address */
        !          27073:                        port = ((COM_DDP *)(alttab[i].t_ddp))->port;
        !          27074:                        outb(port+IER, 0);      /* disable port interrupts */
        !          27075:                        if (inb(port+IER) == 0) {
        !          27076:                                outb(port+MCR, 0);  /* hangup port */
        !          27077:                                outb(port+LCR, LC_DLAB);
        !          27078:                                outb(port+DLL, albaud[speed]);
        !          27079:                                outb(port+DLH, albaud[speed] >> 8);
        !          27080:                                outb(port+LCR, LC_CS8);
        !          27081:                        }
        !          27082:                        alttab[i].t_start = alxstart;
        !          27083:                        alttab[i].t_param = alxparam;
        !          27084:                        alttab[i].t_cs_sel= cs_sel();
        !          27085:                }
        !          27086: 
        !          27087:                setivec(ALINT, alintr);     /* set interrupt vector */
        !          27088:                spl(s);
        !          27089:        }
        !          27090: }
        !          27091: 
        !          27092: static
        !          27093: alunload()
        !          27094: {
        !          27095:        int port, i;
        !          27096: 
        !          27097:        for (i = 0;  i < ALCNT; i++) {
        !          27098:                port = ((COM_DDP *)(alttab[i].t_ddp))->port;
        !          27099:                outb(port+IER, 0);      /* disable port interrupts */
        !          27100:                outb(port+MCR, 0);      /* hangup port */
        !          27101:                timeout(alttab[i].t_rawtim, 0, NULL, 0);/* cancel timer */
        !          27102:        }
        !          27103:        clrivec(ALINT);                 /* release interrupt vector */
        !          27104:        kfree(alttab);
        !          27105:        kfree(ddp);
        !          27106: }
        !          27107: 
        !          27108: static
        !          27109: alopen(dev, mode)
        !          27110: dev_t  dev;
        !          27111: int    mode;
        !          27112: {
        !          27113:        if (minor_st(dev) < ALCNT) {
        !          27114:                alload();
        !          27115:                alxcycle(&DEV_TTY);
        !          27116:                alxopen(dev, mode, &DEV_TTY, &irqtty);
        !          27117:        } else
        !          27118:                u.u_error = ENXIO;
        !          27119: }
        !          27120: 
        !          27121: static
        !          27122: alclose(dev, mode)
        !          27123: dev_t  dev;
        !          27124: int    mode;
        !          27125: {
        !          27126:        register int s;
        !          27127: 
        !          27128:        if (--DEV_TTY.t_open == 0) {    /* Last open */
        !          27129:                s = sphi();
        !          27130:                alxclose(dev, mode, &DEV_TTY);
        !          27131:                spl(s);
        !          27132:        }
        !          27133: }
        !          27134: 
        !          27135: static
        !          27136: alread(dev, iop)
        !          27137: dev_t  dev;
        !          27138: IO     *iop;
        !          27139: {
        !          27140:        ttread(&DEV_TTY, iop);
        !          27141: }
        !          27142: 
        !          27143: static
        !          27144: alwrite(dev, iop)
        !          27145: dev_t  dev;
        !          27146: register IO    *iop;
        !          27147: {
        !          27148:        register int c;
        !          27149: 
        !          27150:        /*
        !          27151:         * Treat user writes through tty driver.
        !          27152:         */
        !          27153:        if (iop->io_seg != IOSYS) {
        !          27154:                ttwrite(&DEV_TTY, iop);
        !          27155:                return;
        !          27156:        }
        !          27157: 
        !          27158:        /*
        !          27159:         * Treat kernel writes by blocking on transmit buffer.
        !          27160:         */
        !          27161:        while ((c = iogetc(iop)) >= 0) {
        !          27162:                /*
        !          27163:                 * Wait until transmit buffer is empty.
        !          27164:                 * Check twice to prevent critical race with interrupt handler.
        !          27165:                 */
        !          27166:                for (;;) {
        !          27167:                        if (inb(ALPORT+LSR) & LS_TxRDY)
        !          27168:                                if (inb(ALPORT+LSR) & LS_TxRDY)
        !          27169:                                        break;
        !          27170:                }
        !          27171: 
        !          27172:                /*
        !          27173:                 * Output the next character.
        !          27174:                 */
        !          27175:                outb(ALPORT+DREG, c);
        !          27176:        }
        !          27177: }
        !          27178: 
        !          27179: static
        !          27180: alioctl(dev, com, vec)
        !          27181: dev_t  dev;
        !          27182: struct sgttyb *vec;
        !          27183: {
        !          27184:        alxioctl(dev, com, vec, &DEV_TTY);
        !          27185: }
        !          27186: 
        !          27187: static
        !          27188: alpoll(dev, ev, msec)
        !          27189: dev_t dev;
        !          27190: int ev;
        !          27191: int msec;
        !          27192: {
        !          27193:        return ttpoll(&DEV_TTY, ev, msec);
        !          27194: }
        !          27195: 
        !          27196: static
        !          27197: alintr()
        !          27198: {
        !          27199:        alxintr(irqtty);
        !          27200: }
        !          27201: @
        !          27202: 
        !          27203: 
        !          27204: 1.7
        !          27205: log
        !          27206: @update provided by hal
        !          27207: @
        !          27208: text
        !          27209: @d6 4
        !          27210: a9 1
        !          27211:  * $Log:       /usr/src/sys/i8086/drv/RCS/al.c,v $
        !          27212: d33 1
        !          27213: d60 1
        !          27214: a60 1
        !          27215: #define ALMAJ  5               /* Major number of com1_3 port */
        !          27216: d73 1
        !          27217: a73 1
        !          27218: #define ALMAJ  6               /* Major number of com2_4 ports */
        !          27219: d151 1
        !          27220: a151 1
        !          27221:        if ( init == 0
        !          27222: d173 1
        !          27223: a173 1
        !          27224:                for ( i = 0;  i < ALCNT; i++ ) {
        !          27225: d179 1
        !          27226: a179 1
        !          27227:                        if ( inb(port+IER) == 0 ) {
        !          27228: d182 3
        !          27229: a184 3
        !          27230:                                outb(port+DLL, albaud[speed] );
        !          27231:                                outb(port+DLH, albaud[speed] >> 8 );
        !          27232:                                outb(port+LCR, LC_CS8 );
        !          27233: d192 1
        !          27234: a192 1
        !          27235:                spl( s );
        !          27236: d201 1
        !          27237: a201 1
        !          27238:        for ( i = 0;  i < ALCNT; i++ ) {
        !          27239: d207 1
        !          27240: a207 1
        !          27241:        clrivec( ALINT );                       /* release interrupt vector */
        !          27242: d219 2
        !          27243: a220 2
        !          27244:                alxcycle( &DEV_TTY );
        !          27245:                alxopen( dev, mode, &DEV_TTY, &irqtty);
        !          27246: d234 1
        !          27247: a234 1
        !          27248:                alxclose( dev, mode, &DEV_TTY );
        !          27249: d244 1
        !          27250: a244 1
        !          27251:        ttread(&DEV_TTY, iop, 0);
        !          27252: d257 2
        !          27253: a258 2
        !          27254:        if ( iop->io_seg != IOSYS ) {
        !          27255:                ttwrite( &DEV_TTY, iop, 0 );
        !          27256: d265 1
        !          27257: a265 1
        !          27258:        while ( (c = iogetc(iop)) >= 0 ) {
        !          27259: d271 2
        !          27260: a272 2
        !          27261:                        if ( inb(ALPORT+LSR) & LS_TxRDY )
        !          27262:                                if ( inb(ALPORT+LSR) & LS_TxRDY )
        !          27263: d279 1
        !          27264: a279 1
        !          27265:                outb( ALPORT+DREG, c );
        !          27266: d292 1
        !          27267: a292 1
        !          27268: alpoll( dev, ev, msec )
        !          27269: d297 1
        !          27270: a297 1
        !          27271:        return ttpoll( &DEV_TTY, ev, msec );
        !          27272: @
        !          27273: 
        !          27274: 
        !          27275: 1.6
        !          27276: log
        !          27277: @update provided by hal
        !          27278: @
        !          27279: text
        !          27280: @d19 2
        !          27281: a20 2
        !          27282: #include <coherent.h>
        !          27283: #include <i8086.h>
        !          27284: d26 2
        !          27285: a27 2
        !          27286: #include <clist.h>
        !          27287: #include <ins8250.h>
        !          27288: d29 1
        !          27289: a29 1
        !          27290: #include <al.h>
        !          27291: @
        !          27292: 
        !          27293: 
        !          27294: 1.5
        !          27295: log
        !          27296: @new version provided y hal for v321
        !          27297: @
        !          27298: text
        !          27299: @@
        !          27300: 
        !          27301: 
        !          27302: 1.4
        !          27303: log
        !          27304: @initial version prov by hal
        !          27305: @
        !          27306: text
        !          27307: @d21 1
        !          27308: a21 1
        !          27309: #include <con.h>
        !          27310: d23 3
        !          27311: a25 3
        !          27312: #include <stat.h>
        !          27313: #include <tty.h>
        !          27314: #include <uproc.h>
        !          27315: d28 1
        !          27316: a28 1
        !          27317: #include <sched.h>
        !          27318: @
        !          27319: 
        !          27320: 
        !          27321: 1.3
        !          27322: log
        !          27323: @alxintr():  add irq_mode argument;  use alx.c 1.5
        !          27324: @
        !          27325: text
        !          27326: @d299 1
        !          27327: a299 1
        !          27328:        alxintr(irqtty, 1);
        !          27329: @
        !          27330: 
        !          27331: 
        !          27332: 1.2
        !          27333: log
        !          27334: @Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          27335: @
        !          27336: text
        !          27337: @d7 3
        !          27338: d299 1
        !          27339: a299 1
        !          27340:        alxintr(irqtty);
        !          27341: @
        !          27342: 
        !          27343: 
        !          27344: 1.1
        !          27345: log
        !          27346: @Used in COH Release 3.0.0 - no COM3/COM4
        !          27347: @
        !          27348: text
        !          27349: @d1 4
        !          27350: a4 8
        !          27351: /* $Header: /usr/src/sys/i8086/drv/RCS/al.c,v 2.2 89/03/31 16:16:50 src Exp $ */
        !          27352: /* (lgl-
        !          27353:  *     The information contained herein is a trade secret of Mark Williams
        !          27354:  *     Company, and  is confidential information.  It is provided  under a
        !          27355:  *     license agreement,  and may be  copied or disclosed  only under the
        !          27356:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          27357:  *     material without the express written authorization of Mark Williams
        !          27358:  *     Company or persuant to the license agreement is unlawful.
        !          27359: d6 4
        !          27360: a9 4
        !          27361:  *     COHERENT Version 2.3.37
        !          27362:  *     Copyright (c) 1982, 1983, 1984.
        !          27363:  *     An unpublished work by Mark Williams Company, Chicago.
        !          27364:  *     All rights reserved.
        !          27365: a14 37
        !          27366:  *
        !          27367:  * $Log$
        !          27368:  * Revision 2.2        89/03/31  16:16:50      src
        !          27369:  * Bug:        Did not cancel timed functions during an unload.  This could result
        !          27370:  *     in a system panic.
        !          27371:  * Fix:        Now cancels timed functions during an unload. (ABC)
        !          27372:  * 
        !          27373:  * Revision 2.1        88/09/03  06:02:24      src
        !          27374:  * *** empty log message ***
        !          27375:  * 
        !          27376:  * Revision 1.1        88/03/24  17:04:07      src
        !          27377:  * Initial revision
        !          27378:  * 
        !          27379:  * 88/01/23    Allan Cornish           /usr/src/sys/i8086/drv/al.c
        !          27380:  * Unload function added to support loadable device drivers.
        !          27381:  *
        !          27382:  * 86/12/12    Allan Cornish           /usr/src/sys/i8086/drv/al.c
        !          27383:  * Added 3rd argument to alpoll() to support non-blocking poll.
        !          27384:  *
        !          27385:  * 86/11/24    Allan Cornish           /usr/src/sys/i8086/drv/al.c
        !          27386:  * The new tty struct raw input and output buffers are now used.
        !          27387:  * Moved alstart() to alx.c/alxstart().
        !          27388:  * Replaced altime() by alxcycle().
        !          27389:  *
        !          27390:  * 86/11/19    Allan Cornish           /usr/src/sys/i8086/drv/al.c
        !          27391:  * Added support for non-blocking read/write, and System V.3 compatible polls.
        !          27392:  * alintr() now uses defer() rather than timeout() to delay call to altime().
        !          27393:  * Increased raw input buffer size from 48 to 64 bytes.
        !          27394:  *
        !          27395:  * 86/07/27    Allan Cornish           /usr/src/sys/i8086/drv/al.c
        !          27396:  * Made alload() disable interrupts, and verify hardware existence.
        !          27397:  * Revised to use ins8250.h header file rather than wd8250.h.
        !          27398:  *
        !          27399:  * 85/06/27    Allan Cornish           /usr/src/sys/i8086/drv/al.c
        !          27400:  * Made alintr() recognize received XOFF characters immediately,
        !          27401:  * rather than deferring recognization through timeout() to altime().
        !          27402:  * This is necessary to avoid input buffer overflow in some printers.
        !          27403: d26 1
        !          27404: d28 4
        !          27405: d35 2
        !          27406: a36 1
        !          27407:  *     ALPORT  the io port address
        !          27408: d40 3
        !          27409: d46 11
        !          27410: a56 5
        !          27411: #ifdef ALCOM1          /* COM1 definitions */
        !          27412: #define ALPORT 0x3F8           /* Base of com1 port */
        !          27413: #define ALINT  4               /* Interrupt level of com1 port */
        !          27414: #define        ALNAME  a0con           /* CON name of com1 port */
        !          27415: #define ALMAJ  5               /* Major number of com1 port */
        !          27416: d59 11
        !          27417: a69 5
        !          27418: #ifdef ALCOM2          /* COM2 definitions */
        !          27419: #define ALPORT 0x2F8           /* Base of com2 port */
        !          27420: #define ALINT  3               /* Interrupt level of com2 port */
        !          27421: #define ALNAME a1con           /* CON name of com2 port */
        !          27422: #define ALMAJ  6               /* Major number of com2 port */
        !          27423: a71 7
        !          27424: #ifdef ALCOM3          /* COM3 definitions */
        !          27425: #define ALPORT 0x2F0           /* Base of com3 port */
        !          27426: #define ALINT  2               /* Interrupt level of com3 port */
        !          27427: #define ALNAME a2con           /* CON name of com3 port */
        !          27428: #define ALMAJ  3               /* Major number of com3 port */
        !          27429: #endif
        !          27430: 
        !          27431: d116 1
        !          27432: a116 1
        !          27433:  * Terminal structure.
        !          27434: d118 3
        !          27435: a120 1
        !          27436: static TTY     altty = { {0}, {0}, ALPORT, alxstart, alxparam, B9600, B9600 };
        !          27437: d122 14
        !          27438: d142 1
        !          27439: d144 6
        !          27440: a149 3
        !          27441:        s = sphi();
        !          27442:        if ( init == 0 ) {
        !          27443:                outb(ALPORT+IER, 0);        /* disable port interrupts */
        !          27444: d151 13
        !          27445: a163 7
        !          27446:                if ( inb(ALPORT+IER) == 0 ) {
        !          27447:                        outb(ALPORT+MCR, MC_OUT2);  /* hangup port */
        !          27448:                        outb(ALPORT+LCR, LC_DLAB);
        !          27449:                        outb(ALPORT+DLL, albaud[B9600] );
        !          27450:                        outb(ALPORT+DLH, albaud[B9600] >> 8 );
        !          27451:                        outb(ALPORT+LCR, LC_CS8 );
        !          27452:                        setivec(ALINT, alintr);     /* set interrupt vector */
        !          27453: d165 21
        !          27454: a186 1
        !          27455:        spl( s );
        !          27456: d192 8
        !          27457: d201 2
        !          27458: a202 3
        !          27459:        outb(ALPORT+IER, 0);                    /* disable port interrupts */
        !          27460:        outb(ALPORT+MCR, MC_OUT2);              /* hangup port */
        !          27461:        timeout( &altty.t_rawtim, 0, NULL, 0 ); /* cancel cyclic timer */
        !          27462: d210 6
        !          27463: a215 3
        !          27464:        alload();
        !          27465:        alxcycle( &altty );
        !          27466:        alxopen( dev, mode, &altty );
        !          27467: d225 1
        !          27468: a225 1
        !          27469:        if (--altty.t_open == 0) {      /* Last open */
        !          27470: d227 1
        !          27471: a227 1
        !          27472:                alxclose( dev, mode, &altty );
        !          27473: d237 1
        !          27474: a237 1
        !          27475:        ttread(&altty, iop, 0);
        !          27476: d251 1
        !          27477: a251 1
        !          27478:                ttwrite( &altty, iop, 0 );
        !          27479: a258 1
        !          27480: 
        !          27481: d281 1
        !          27482: a281 1
        !          27483:        alxioctl(dev, com, vec, &altty);
        !          27484: d290 1
        !          27485: a290 1
        !          27486:        return ttpoll( &altty, ev, msec );
        !          27487: d296 1
        !          27488: a296 1
        !          27489:        alxintr( &altty );
        !          27490: @
        !          27491: 0707070064030105321004440000030000030000011777770507310647300005500000105463/newbits/kernel/USRSRC/i8086/drv/RCS/alx.c,vhead     1.12;
        !          27492: branch   ;
        !          27493: access   ;
        !          27494: symbols  ;
        !          27495: locks    bin:1.12;
        !          27496: comment  @ * @;
        !          27497: 
        !          27498: 
        !          27499: 1.12
        !          27500: date     91.08.06.10.32.23;  author bin;  state Exp;
        !          27501: branches ;
        !          27502: next     1.11;
        !          27503: 
        !          27504: 1.11
        !          27505: date     91.08.01.13.48.25;  author bin;  state Exp;
        !          27506: branches ;
        !          27507: next     1.10;
        !          27508: 
        !          27509: 1.10
        !          27510: date     91.08.01.10.04.16;  author hal;  state Exp;
        !          27511: branches ;
        !          27512: next     1.9;
        !          27513: 
        !          27514: 1.9
        !          27515: date     91.06.20.14.47.20;  author bin;  state Exp;
        !          27516: branches ;
        !          27517: next     1.8;
        !          27518: 
        !          27519: 1.8
        !          27520: date     91.06.18.08.10.35;  author bin;  state Exp;
        !          27521: branches ;
        !          27522: next     1.7;
        !          27523: 
        !          27524: 1.7
        !          27525: date     91.06.17.12.28.08;  author bin;  state Exp;
        !          27526: branches ;
        !          27527: next     1.6;
        !          27528: 
        !          27529: 1.6
        !          27530: date     91.04.03.18.55.07;  author root;  state Exp;
        !          27531: branches ;
        !          27532: next     1.5;
        !          27533: 
        !          27534: 1.5
        !          27535: date     91.04.02.17.53.37;  author root;  state Exp;
        !          27536: branches ;
        !          27537: next     1.4;
        !          27538: 
        !          27539: 1.4
        !          27540: date     91.02.22.09.21.17;  author root;  state Exp;
        !          27541: branches ;
        !          27542: next     1.3;
        !          27543: 
        !          27544: 1.3
        !          27545: date     91.02.21.14.58.16;  author root;  state Exp;
        !          27546: branches ;
        !          27547: next     1.2;
        !          27548: 
        !          27549: 1.2
        !          27550: date     91.02.21.11.21.40;  author hal;  state Exp;
        !          27551: branches 1.2.1.1 1.2.2.1;
        !          27552: next     1.1;
        !          27553: 
        !          27554: 1.1
        !          27555: date     91.02.21.11.08.31;  author hal;  state Exp;
        !          27556: branches ;
        !          27557: next     ;
        !          27558: 
        !          27559: 1.2.1.1
        !          27560: date     91.02.21.12.37.34;  author root;  state Exp;
        !          27561: branches ;
        !          27562: next     ;
        !          27563: 
        !          27564: 1.2.2.1
        !          27565: date     91.02.21.13.58.46;  author root;  state Exp;
        !          27566: branches ;
        !          27567: next     ;
        !          27568: 
        !          27569: 
        !          27570: desc
        !          27571: @@
        !          27572: 
        !          27573: 
        !          27574: 1.12
        !          27575: log
        !          27576: @2nd rts/cts version form hal
        !          27577: @
        !          27578: text
        !          27579: @/* (-lgl
        !          27580:  *     COHERENT Driver Kit Version 1.1.0
        !          27581:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          27582:  *     All rights reserved. May not be copied without permission.
        !          27583:  *
        !          27584:  * $Log:       alx.c,v $
        !          27585:  * Revision 1.7  91/08/02  07:59:27  hal
        !          27586:  * Raw input silo uses last slot for byte count.
        !          27587:  * Modem control now gives RTS/CTS flow control:
        !          27588:  *     CTS is checked 10x/sec (probably not often enough).
        !          27589:  *     On Rx_INT, check T_ISTOP and rawin silo levels; drop RTS if need to.
        !          27590:  * 
        !          27591:  * Revision 1.6        91/04/03  18:55:07      root
        !          27592:  * alxclose():  do closing state machine BEFORE dropping control lines.
        !          27593:  * alxioctl():  save and restore interrupt enable register.
        !          27594:  * alxopen():   wait for pending last close (fixes SLOW port bug).
        !          27595:  * This version needs al.h 1.3 or later.
        !          27596:  *
        !          27597:  * Revision 1.5        91/04/02  17:53:37      root
        !          27598:  * save MSR delta status; add MS_INTR handling; use al.h 1.2
        !          27599:  *
        !          27600:  * Revision 1.4        91/02/22  09:21:17      root
        !          27601:  * alxintr():  replace repeated use of ALPORT macro by local variable
        !          27602:  *
        !          27603:  * Revision 1.3        91/02/21  14:58:16      root
        !          27604:  * Fix unconditional "hupcl" bug in 3.1.0 version.
        !          27605:  *
        !          27606:  * Revision 1.2        91/02/21  11:21:40      hal
        !          27607:  * Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          27608:  *
        !          27609:  * Revision 1.1        91/02/21  11:08:31      hal
        !          27610:  * Used in COH Release 3.0.0 - no COM3/COM4
        !          27611:  *
        !          27612:  -lgl) */
        !          27613: /*
        !          27614:  * Shared parts of IBM async port drivers.
        !          27615:  */
        !          27616: #include <sys/coherent.h>
        !          27617: #include <sys/i8086.h>
        !          27618: #include <sys/al.h>
        !          27619: #include <sys/con.h>
        !          27620: #include <errno.h>
        !          27621: #include <sys/stat.h>
        !          27622: #include <sys/tty.h>
        !          27623: #include <sys/uproc.h>
        !          27624: #include <sys/timeout.h>
        !          27625: #include <sys/clist.h>
        !          27626: #include <sys/ins8250.h>
        !          27627: #include <sys/sched.h>
        !          27628: 
        !          27629: #define ALPORT (((COM_DDP *)(tp->t_ddp))->port)
        !          27630: #define AL_TIM (((COM_DDP *)(tp->t_ddp))->tim)
        !          27631: #define AL_NUM (((COM_DDP *)(tp->t_ddp))->com_num)
        !          27632: #define AL_MSR_DELTAS  (((COM_DDP *)(tp->t_ddp))->msr_deltas)
        !          27633: #define AL_H_CLOSE     (((COM_DDP *)(tp->t_ddp))->h_close)
        !          27634: 
        !          27635: #define DTRTMOUT  3    /* DTR timeout interval in seconds for close */
        !          27636: #define        IENABLE (IE_RxI+IE_TxI+IE_LSI+IE_MSI)
        !          27637: 
        !          27638: /*
        !          27639:  * For rawin silo (see ktty.h), use last element of si_buf to count the number
        !          27640:  * of characters in the silo.
        !          27641:  */
        !          27642: #define SILO_CHAR_COUNT        si_buf[SI_BUFSIZ-1]
        !          27643: #define SILO_HIGH_MARK (SI_BUFSIZ-SI_BUFSIZ/4)
        !          27644: #define MAX_SILO_INDEX (SI_BUFSIZ-2)
        !          27645: #define MAX_SILO_CHARS (SI_BUFSIZ-1)
        !          27646: 
        !          27647: int    al_sg_set = 0;
        !          27648: int    al_sg_clr = 0;
        !          27649: static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          27650: 
        !          27651: /*
        !          27652:  * functions herein
        !          27653:  */
        !          27654: int    alxopen();
        !          27655: int    alxclose();
        !          27656: int    alxtimer();
        !          27657: int    alxioctl();
        !          27658: int    alxparam();
        !          27659: int    alxcycle();
        !          27660: int    alxstart();
        !          27661: int    alxbreak();
        !          27662: int    alxintr();
        !          27663: static int alxclk();
        !          27664: static set_poll_rate();
        !          27665: 
        !          27666: /*
        !          27667:  * Baud rate table and polling rate table.
        !          27668:  * Indexed by ioctl bit rates.
        !          27669:  */
        !          27670: int albaud[] ={
        !          27671:        0,                              /* 0 */
        !          27672:        2304,                           /* 50 */
        !          27673:        1536,                           /* 75 */
        !          27674:        1047,                           /* 110 */
        !          27675:        857,                            /* 134.5 */
        !          27676:        768,                            /* 150 */
        !          27677:        576,                            /* 200 */
        !          27678:        384,                            /* 300 */
        !          27679:        192,                            /* 600 */
        !          27680:        96,                             /* 1200 */
        !          27681:        64,                             /* 1800 */
        !          27682:        58,                             /* 2000 */
        !          27683:        48,                             /* 2400 */
        !          27684:        32,                             /* 3600 */
        !          27685:        24,                             /* 4800 */
        !          27686:        16,                             /* 7200 */
        !          27687:        12,                             /* 9600 */
        !          27688:        6,                              /* 19200 */
        !          27689:        0,                              /* EXTA */
        !          27690:        0                               /* EXTB */
        !          27691: };
        !          27692: 
        !          27693: /*
        !          27694:  *     alp_rate[] is tied to albaud[] - it gives the minimum polling
        !          27695:  *     rate for the corresponding port speed; it must be a multiple
        !          27696:  *     of 100 (system clock Hz) and >= baud/6
        !          27697:  */
        !          27698: int alp_rate[] ={                      /* baud/6 or zero */
        !          27699:        0,                              /* 0 */
        !          27700:        1*HZ,                           /* 50 */
        !          27701:        1*HZ,                           /* 75 */
        !          27702:        1*HZ,                           /* 110 */
        !          27703:        1*HZ,                           /* 134.5 */
        !          27704:        1*HZ,                           /* 150 */
        !          27705:        1*HZ,                           /* 200 */
        !          27706:        1*HZ,                           /* 300 */
        !          27707:        1*HZ,                           /* 600 */
        !          27708:        2*HZ,                           /* 1200 */
        !          27709:        3*HZ,                           /* 1800 */
        !          27710:        4*HZ,                           /* 2000 */
        !          27711:        4*HZ,                           /* 2400 */
        !          27712:        6*HZ,                           /* 3600 */
        !          27713:        8*HZ,                           /* 4800 */
        !          27714:        12*HZ,                          /* 7200 */
        !          27715:        16*HZ,                          /* 9600 */
        !          27716:        0,                              /* 19200 */
        !          27717:        0,                              /* EXTA */
        !          27718:        0                               /* EXTB */
        !          27719: };
        !          27720: 
        !          27721: /*
        !          27722:  *     the following is for debug only
        !          27723:  */
        !          27724: #if 0
        !          27725: #define CDUMP(text)    cdump(text);
        !          27726: 
        !          27727: cdump(message)
        !          27728: char *message;
        !          27729: {
        !          27730:        int i, b;
        !          27731: 
        !          27732:        for (i = 0; i < NUM_AL_PORTS; i++) {
        !          27733:                b = ((COM_DDP *)(tp_table[i]->t_ddp))->port;
        !          27734:                printf("%x:%x:%x:%x ", i+1, b, inb(b+MCR), inb(b+IER));
        !          27735:        }
        !          27736:        printf("poll=%d ", poll_rate);
        !          27737:        printf("%s\n", message);
        !          27738: }
        !          27739: #else
        !          27740: #define CDUMP(text)
        !          27741: #endif
        !          27742: 
        !          27743: /*
        !          27744:  * alxopen()
        !          27745:  */
        !          27746: alxopen(dev, mode, tp, irqtty)
        !          27747: dev_t  dev;
        !          27748: int    mode;
        !          27749: register TTY   *tp, **irqtty;
        !          27750: {
        !          27751:        register int    s;
        !          27752:        register int    b;
        !          27753:        register int    minor_h;  /* minor device number including high bit */
        !          27754:        unsigned char   msr;
        !          27755: 
        !          27756:        minor_h = minor(dev);     /* complete minor number */
        !          27757: 
        !          27758:        b = ALPORT;
        !          27759: 
        !          27760:        if (inb(b+IER) & ~IENABLE) { /* chip not found */
        !          27761:                u.u_error = ENXIO;
        !          27762:                return;
        !          27763:        }
        !          27764: 
        !          27765:        if ((tp->t_flags & T_EXCL) && !super()) {
        !          27766:                u.u_error = ENODEV;
        !          27767:                return;
        !          27768:        }
        !          27769: 
        !          27770:        if (drvl[major(dev)].d_time != 0) {     /* Modem settling */
        !          27771:                u.u_error = EDBUSY;
        !          27772:                return;
        !          27773:        }
        !          27774: 
        !          27775:        /*
        !          27776:         * Can't open a polled port if another driver is using polling.
        !          27777:         */
        !          27778:        if (dev & CPOLL && poll_owner & ~ POLL_AL) {
        !          27779:                u.u_error = EDBUSY;
        !          27780:                return;
        !          27781:        }
        !          27782: 
        !          27783:        /*
        !          27784:         * exclusion conditions:
        !          27785:         *      can't have same port polled and IRQ at once
        !          27786:         *      can't have both com[13] or both com[24] IRQ at once
        !          27787:         */
        !          27788:        if (dev & CPOLL) {
        !          27789:                if (com_usage[AL_NUM] == COM_IRQ) {
        !          27790:                        u.u_error = EDBUSY;
        !          27791:                        return;
        !          27792:                }
        !          27793:        } else {
        !          27794:                if (com_usage[AL_NUM] == COM_POLLED
        !          27795:                   || com_usage[AL_NUM ^ 2] == COM_IRQ) {
        !          27796:                        u.u_error = EDBUSY;
        !          27797:                        return;
        !          27798:                }
        !          27799:        }
        !          27800: 
        !          27801:        if (tp->t_open == 0) {        /* not already open */
        !          27802:                /*
        !          27803:                 * Wait for pending last close (if any) to finish.
        !          27804:                 */
        !          27805:                while (AL_H_CLOSE) {
        !          27806:                        sleep((char *)(&AL_H_CLOSE), CVTTOUT, IVTTOUT,
        !          27807:                                SVTTOUT);
        !          27808:                }
        !          27809:                s = sphi();
        !          27810:                /*
        !          27811:                 * Raise basic modem control lines even if modem
        !          27812:                 * control hasn't been specified.
        !          27813:                 * MC_OUT2 turns on NON-open-collector IRQ line from the UART.
        !          27814:                 * since we can't have two UART's on same IRQ with MC_OUT2 on
        !          27815:                 */
        !          27816:                if (dev & CPOLL) {
        !          27817:                        outb(b+MCR, MC_RTS|MC_DTR);
        !          27818:                } else {
        !          27819:                        *irqtty = tp_table[AL_NUM];
        !          27820:                        outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          27821:                }
        !          27822: 
        !          27823:                outb(b+IER, IENABLE);        /* enable interrupts */
        !          27824: 
        !          27825:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          27826:                        tp->t_flags |= T_MODC | T_HOPEN | T_STOP;
        !          27827:                        while (1) {     /* wait for carrier */
        !          27828:                                msr = inb(b+MSR);
        !          27829:                                AL_MSR_DELTAS |= msr;
        !          27830:                                if (msr & MS_RLSD)
        !          27831:                                        break;
        !          27832:                                sleep((char *)(&tp->t_open), CVTTOUT, IVTTOUT,
        !          27833:                                        SVTTOUT);       /* wait for carrier */
        !          27834:                                if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          27835:                                        outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          27836:                                        /*
        !          27837:                                         * make sure port is hungup
        !          27838:                                         * disable all ints except for TxI
        !          27839:                                         */
        !          27840:                                        outb(b+IER, IE_TxI);
        !          27841:                                        u.u_error = EINTR;
        !          27842:                                        spl(s);
        !          27843:                                        return;
        !          27844:                                }
        !          27845:                        }
        !          27846:                        tp->t_flags &= ~T_HOPEN; /* no longer hanging in open */
        !          27847:                        if (msr & MS_CTS)
        !          27848:                                tp->t_flags &= ~T_STOP;
        !          27849:                } else {
        !          27850:                        tp->t_flags &= ~T_MODC;         /* no modem control */
        !          27851:                }
        !          27852:                tp->t_flags |= T_CARR;                  /* carrier on */
        !          27853:                ttopen(tp);                             /* stty inits */
        !          27854: 
        !          27855:                /*
        !          27856:                 * Allow custom modification of defaults.
        !          27857:                 */
        !          27858:                tp->t_sgttyb.sg_flags |=  al_sg_set;
        !          27859:                tp->t_sgttyb.sg_flags &= ~al_sg_clr;
        !          27860:                alxparam(tp);
        !          27861:                spl(s);
        !          27862:        } else {                                /* already open */
        !          27863:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          27864:                    if ((tp->t_flags & T_MODC)==0) { /* already not modem control? */
        !          27865:                        u.u_error = ENODEV;     /* yes, don't allow open */
        !          27866:                        return;
        !          27867:                    }
        !          27868:                } else {                         /* don't want modem control */
        !          27869:                        if (tp->t_flags & T_MODC) { /* already modem control? */
        !          27870:                                u.u_error = ENODEV; /* yes, don't allow open */
        !          27871:                                return;
        !          27872:                        }
        !          27873:                }
        !          27874:        }
        !          27875:        tp->t_open++;
        !          27876:        ttsetgrp(tp, dev);
        !          27877: 
        !          27878:        /*
        !          27879:         * now that we've successfully opened, designate port as
        !          27880:         * polled or interrupt driven to avoid future conflicts
        !          27881:         */
        !          27882:        if (dev & CPOLL) {
        !          27883:                com_usage[AL_NUM] = COM_POLLED;
        !          27884:                set_poll_rate();
        !          27885:        } else {                                /* irq-driven port */
        !          27886:                com_usage[AL_NUM] = COM_IRQ;
        !          27887:        }
        !          27888: 
        !          27889:        CDUMP((dev&CPOLL)?"open polled":"open irq")
        !          27890: }
        !          27891: 
        !          27892: /*
        !          27893:  * alxclose()
        !          27894:  *
        !          27895:  *     Called at high priority on last close for the device.
        !          27896:  */
        !          27897: alxclose(dev, mode, tp)
        !          27898: dev_t  dev;
        !          27899: int    mode;
        !          27900: TTY    *tp;
        !          27901: {
        !          27902:        register unsigned holdflags;
        !          27903:        register int b;
        !          27904:        int state, maj;
        !          27905:        int s;
        !          27906: 
        !          27907:        /*
        !          27908:         * Called at high priority by alclose after al_buff is drained
        !          27909:         */
        !          27910:        holdflags = tp->t_flags;        /* save flags */
        !          27911:        AL_H_CLOSE = 1;                 /* disallow reopen til done closing */
        !          27912:        ttclose(tp);                    /* clear flags */
        !          27913:        b = ALPORT;
        !          27914:        /*
        !          27915:         * ttclose() only emptied the output queue tp->t_oq;
        !          27916:         * now wait for the silo tp->rawout to empty
        !          27917:         * and allow a delay for the UART on-chip xmit buffer to empty
        !          27918:         * state 2: waiting for silo to empty
        !          27919:         * state 1: stalling so UART can empty xmit buffer
        !          27920:         * state 0: done!  ok to shut off IRQ for this chip by clearing MC_OUT2
        !          27921:         */
        !          27922:        state = 2;
        !          27923:        while (state) {
        !          27924:                timeout(&AL_TIM, 10, wakeup, (int)&AL_TIM);
        !          27925:                sleep((char *)&AL_TIM, CVTTOUT, IVTTOUT, SVTTOUT);
        !          27926:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          27927:                        state--;
        !          27928:        }
        !          27929: 
        !          27930:        /*
        !          27931:         * If not hanging in open
        !          27932:         */
        !          27933:        if ((holdflags & T_HOPEN) == 0) {
        !          27934:                /*
        !          27935:                 * Disable all ints except TxI
        !          27936:                 */
        !          27937:                outb(b+IER, IE_TxI);
        !          27938:        } else {
        !          27939:                /*
        !          27940:                 * Flags for first open
        !          27941:                 */
        !          27942:                tp->t_flags = T_MODC | T_HOPEN;
        !          27943:        }
        !          27944: 
        !          27945:        /*
        !          27946:         * If hupcls
        !          27947:         */
        !          27948:        if (holdflags & T_HPCL) {
        !          27949:                /*
        !          27950:                 * Hangup port
        !          27951:                 */
        !          27952:                s = sphi();
        !          27953:                outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          27954:                spl(s);
        !          27955: 
        !          27956:                /*
        !          27957:                 * Hold dtr low for timeout
        !          27958:                 */
        !          27959:                maj = major(dev);
        !          27960:                drvl[maj].d_time = 1;
        !          27961:                sleep((char *)&drvl[maj].d_time, CVTTOUT, IVTTOUT, SVTTOUT);
        !          27962:                drvl[maj].d_time = 0;
        !          27963:        }
        !          27964:        s = sphi();
        !          27965:        outb(b+MCR, inb(b+MCR)&(~MC_OUT2));
        !          27966:        spl(s);
        !          27967:        com_usage[AL_NUM] = COM_UNUSED;
        !          27968:        set_poll_rate();
        !          27969:        AL_H_CLOSE = 0;         /* allow reopen - done closing */
        !          27970:        wakeup((char *)&AL_H_CLOSE);
        !          27971:        CDUMP("closed")
        !          27972: }
        !          27973: 
        !          27974: /*
        !          27975:  * Common c_timer routine for async ports.
        !          27976:  */
        !          27977: alxtimer(dev)
        !          27978: dev_t dev;
        !          27979: {
        !          27980:        if (++drvl[major(dev)].d_time > DTRTMOUT)
        !          27981:                wakeup((char *)&drvl[major(dev)].d_time);
        !          27982: }
        !          27983: 
        !          27984: 
        !          27985: /*
        !          27986:  * Common c_ioctl routine for async ports.
        !          27987:  */
        !          27988: alxioctl(dev, com, vec, tp)
        !          27989: dev_t  dev;
        !          27990: struct sgttyb *vec;
        !          27991: register TTY   *tp;
        !          27992: {
        !          27993:        register int    s, b;
        !          27994:        int stat1, stat2;
        !          27995:        unsigned char   msr;
        !          27996:        unsigned char ier_save;
        !          27997: 
        !          27998:        s = sphi();
        !          27999:        b = ALPORT;
        !          28000:        ier_save=inb(b+IER);
        !          28001:        stat1 = inb(b+MCR);             /* get current MCR register status */
        !          28002:        stat2 = inb(b+LCR);             /* get current LCR register status */
        !          28003: 
        !          28004:        switch(com) {
        !          28005:        case TIOCSBRK:                  /* set BREAK */
        !          28006:                outb(b+LCR, stat2|LC_SBRK);
        !          28007:                break;
        !          28008:        case TIOCCBRK:                  /* clear BREAK */
        !          28009:                outb(b+LCR, stat2 & ~LC_SBRK);
        !          28010:                break;
        !          28011:        case TIOCSDTR:                  /* set DTR */
        !          28012:                outb(b+MCR, stat1|MC_DTR);
        !          28013:                break;
        !          28014:        case TIOCCDTR:                  /* clear DTR */
        !          28015:                outb(b+MCR, stat1 & ~MC_DTR);
        !          28016:                break;
        !          28017:        case TIOCSRTS:                  /* set RTS */
        !          28018:                outb(b+MCR, stat1|MC_RTS);
        !          28019:                break;
        !          28020:        case TIOCCRTS:                  /* clear RTS */
        !          28021:                outb(b+MCR, stat1 & ~MC_RTS);
        !          28022:                break;
        !          28023:        case TIOCRSPEED:                /* set "raw" I/O speed divisor */
        !          28024:                outb(b+LCR, stat2|LC_DLAB);  /* set speed latch bit */
        !          28025:                outb(b+DLL, (unsigned) vec);
        !          28026:                outb(b+DLH, (unsigned) vec >> 8);
        !          28027:                outb(b+LCR, stat2);       /* reset latch bit */
        !          28028:                break;
        !          28029:        case TIOCWORDL:         /* set word length and stop bits */
        !          28030:                outb(b+LCR, ((stat2&~0x7) | ((unsigned) vec & 0x7)));
        !          28031:                break;
        !          28032:        case TIOCRMSR:          /* get CTS/DSR/RI/RLSD (MSR) */
        !          28033:                msr = inb(b+MSR);
        !          28034:                AL_MSR_DELTAS |= msr;
        !          28035:                stat1 = msr >> 4;
        !          28036:                kucopy(&stat1, (unsigned *) vec, sizeof(unsigned));
        !          28037:                break;
        !          28038:        default:
        !          28039:                ttioctl(tp, com, vec);
        !          28040:        }
        !          28041:        outb(b+IER, ier_save);
        !          28042:        spl(s);
        !          28043: }
        !          28044: 
        !          28045: alxparam(tp)
        !          28046: TTY    *tp;
        !          28047: {
        !          28048:        register int    b;
        !          28049:        register int    baud;
        !          28050:        int s;
        !          28051: 
        !          28052:        b = ALPORT;
        !          28053: 
        !          28054:        /*
        !          28055:         * error if input speed not the same as output speed
        !          28056:         */
        !          28057:        if (tp->t_sgttyb.sg_ispeed!=tp->t_sgttyb.sg_ospeed) {
        !          28058:                u.u_error = ENODEV;
        !          28059:                return;
        !          28060:        }
        !          28061: 
        !          28062:        if ((baud = albaud[tp->t_sgttyb.sg_ispeed]) == 0) {
        !          28063:                if (tp->t_flags & T_MODC) {  /* modem control? */
        !          28064:                        tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          28065:                        s = sphi();
        !          28066:                        outb(b+MCR, inb(b+MCR) & MC_OUT2); /* hangup */
        !          28067:                        spl(s);
        !          28068:                }
        !          28069:        }
        !          28070: 
        !          28071:        if (baud) {
        !          28072:                unsigned char ier_save;
        !          28073: 
        !          28074:                s=sphi();
        !          28075:                ier_save=inb(b+IER);    /* some chips need this */
        !          28076:                outb(b+LCR, LC_DLAB);
        !          28077:                outb(b+DLL, baud);
        !          28078:                outb(b+DLH, baud >> 8);
        !          28079:                switch (tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW)) {
        !          28080:                case EVENP:
        !          28081:                        outb(b+LCR, LC_CS7 + LC_PARENB + LC_PAREVEN);
        !          28082:                        break;
        !          28083: 
        !          28084:                case ODDP:
        !          28085:                        outb(b+LCR, LC_CS7 + LC_PARENB);
        !          28086:                        break;
        !          28087: 
        !          28088:                default:
        !          28089:                        outb(b+LCR, LC_CS8);
        !          28090:                        break;
        !          28091:                }
        !          28092:                outb(b+IER, ier_save);
        !          28093:                spl(s);
        !          28094:        }
        !          28095:        set_poll_rate();
        !          28096: }
        !          28097: 
        !          28098: /*
        !          28099:  * Middle level processor.
        !          28100:  *
        !          28101:  *     Invoked 10 times per second.
        !          28102:  *     Checks modem status for loss of carrier.
        !          28103:  *     Tranfers rawin buffer [from intr level] to canonical input queue.
        !          28104:  *     Transfers output queue to rawout buffer [for intr level].
        !          28105:  */
        !          28106: alxcycle(tp)
        !          28107: register TTY * tp;
        !          28108: {
        !          28109:        register int b;
        !          28110:        register int n;
        !          28111:        unsigned char msr, mcr;
        !          28112:        int s;
        !          28113: 
        !          28114:        /*
        !          28115:         * Check modem status every ten clock ticks.
        !          28116:         *
        !          28117:         * Modem status interrupts were not enabled due to 8250 hardware bug.
        !          28118:         * Enabling modem status and receive interrupts may cause lockup
        !          28119:         * on older parts.
        !          28120:         *
        !          28121:         * Also check if input silo is nearly full in case we need RTS
        !          28122:         * flow control.
        !          28123:         */
        !          28124:        if (tp->t_flags & T_MODC) {
        !          28125: 
        !          28126:                /*
        !          28127:                 * Get status
        !          28128:                 */
        !          28129:                msr = inb(ALPORT+MSR);
        !          28130:                AL_MSR_DELTAS |= msr;
        !          28131: 
        !          28132:                /*
        !          28133:                 * Carrier changed.
        !          28134:                 */
        !          28135:                if (AL_MSR_DELTAS & MS_DRLSD) {
        !          28136:                        AL_MSR_DELTAS &= ~MS_DRLSD;
        !          28137:                        /*
        !          28138:                         * wakeup open
        !          28139:                         */
        !          28140:                        if (tp->t_open == 0) {
        !          28141:                                wakeup((char *)(&tp->t_open));
        !          28142:                        }
        !          28143: 
        !          28144:                        /*
        !          28145:                         * carrier off?
        !          28146:                         */
        !          28147:                        else if ((msr & MS_RLSD) == 0) {
        !          28148:                                /*
        !          28149:                                 * clear carrier flag; send hangup signal
        !          28150:                                 */
        !          28151:                                s = sphi();
        !          28152:                                tp->t_rawin.si_ox = tp->t_rawin.si_ix;
        !          28153:                                tp->t_rawin.SILO_CHAR_COUNT = 0;
        !          28154:                                spl(s);
        !          28155:                                tthup(tp);
        !          28156:                        }
        !          28157:                }
        !          28158: 
        !          28159:                /*
        !          28160:                 * CTS changed.
        !          28161:                 */
        !          28162:                if (AL_MSR_DELTAS & MS_DCTS) {
        !          28163:                        AL_MSR_DELTAS &= ~MS_DCTS;
        !          28164:                        if (msr & MS_CTS)
        !          28165:                                tp->t_flags &= ~T_STOP;
        !          28166:                        else
        !          28167:                                tp->t_flags |= T_STOP;
        !          28168:                }
        !          28169: 
        !          28170:                /*
        !          28171:                 * If input silo not nearly full, assert RTS.
        !          28172:                 */
        !          28173:                if (tp->t_rawin.SILO_CHAR_COUNT <= SILO_HIGH_MARK) {
        !          28174:                        mcr = inb(ALPORT+MCR);
        !          28175:                        if ((mcr & MC_RTS) == 0) {
        !          28176: printf("%x RTS ON\n", ALPORT);
        !          28177:                                outb(ALPORT+MCR, mcr | MC_RTS);
        !          28178:                        }
        !          28179:                }
        !          28180:        }
        !          28181: 
        !          28182:        /*
        !          28183:         * Empty raw input buffer.
        !          28184:         * If modem control enabled and tt input queue is at high limit
        !          28185:         * (e.g., tp->t_iq.cq_cc >= IHILIM), don't copy from rawin silo
        !          28186:         * to tt input queue.
        !          28187:         */
        !          28188:        if (!(tp->t_flags & T_MODC) || !(tp->t_flags & T_ISTOP))
        !          28189:                while (tp->t_rawin.SILO_CHAR_COUNT > 0) {
        !          28190:                        ttin(tp, tp->t_rawin.si_buf[tp->t_rawin.si_ox]);
        !          28191:                        if (tp->t_rawin.si_ox < MAX_SILO_INDEX)
        !          28192:                                tp->t_rawin.si_ox++;
        !          28193:                        else
        !          28194:                                tp->t_rawin.si_ox = 0;
        !          28195:                        tp->t_rawin.SILO_CHAR_COUNT--;
        !          28196:                }
        !          28197: 
        !          28198:        /*
        !          28199:         * Calculate free output slot count.
        !          28200:         */
        !          28201:        n  = sizeof(tp->t_rawout.si_buf) - 1;
        !          28202:        n += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          28203:        n %= sizeof(tp->t_rawout.si_buf);
        !          28204: 
        !          28205:        /*
        !          28206:         * Fill raw output buffer.
        !          28207:         */
        !          28208:        while ((--n >= 0) && ((b = ttout(tp)) >= 0)) {
        !          28209:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = b;
        !          28210:                if (tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1)
        !          28211:                        tp->t_rawout.si_ix = 0;
        !          28212:                else
        !          28213:                        tp->t_rawout.si_ix++;
        !          28214:        }
        !          28215: 
        !          28216:        /*
        !          28217:         * (Re)start output, wake sleeping processes, etc.
        !          28218:         */
        !          28219:        ttstart(tp);
        !          28220: 
        !          28221:        /*
        !          28222:         * Schedule next cycle.
        !          28223:         */
        !          28224:        timeout(&tp->t_rawtim, HZ/10, alxcycle, tp);
        !          28225: }
        !          28226: 
        !          28227: /*
        !          28228:  * Serial Transmit Start Routine.
        !          28229:  */
        !          28230: alxstart(tp)
        !          28231: register TTY * tp;
        !          28232: {
        !          28233:        register int b;
        !          28234:        register int s;
        !          28235:        extern alxbreak();
        !          28236: 
        !          28237:        /*
        !          28238:         * Read line status register AFTER disabling interrupts.
        !          28239:         */
        !          28240:        s = sphi();
        !          28241:        b = inb(ALPORT+LSR);
        !          28242: 
        !          28243:        /*
        !          28244:         * Process break indication.
        !          28245:         * NOTE: Break indication cleared when line status register was read.
        !          28246:         */
        !          28247:        if (b & LS_BREAK)
        !          28248:                defer(alxbreak, tp);
        !          28249: 
        !          28250:        /*
        !          28251:         * Transmitter is empty, output data is pending.
        !          28252:         */
        !          28253:        if ((b & LS_TxRDY) && (tp->t_rawout.si_ix != tp->t_rawout.si_ox)) {
        !          28254:                outb(   ALPORT+DREG,
        !          28255:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ]);
        !          28256:                if (++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf))
        !          28257:                        tp->t_rawout.si_ox = 0;
        !          28258:        }
        !          28259:        spl(s);
        !          28260: }
        !          28261: 
        !          28262: /*
        !          28263:  * Serial Received Break Handler.
        !          28264:  */
        !          28265: alxbreak(tp)
        !          28266: TTY * tp;
        !          28267: {
        !          28268:        ttsignal(tp, SIGINT);
        !          28269: }
        !          28270: 
        !          28271: /*
        !          28272:  * Serial Interrupt Handler.
        !          28273:  */
        !          28274: alxintr(tp)
        !          28275: register TTY * tp;
        !          28276: {
        !          28277:        register int    b;
        !          28278:        int port = ALPORT;
        !          28279:        unsigned char mcr;
        !          28280: 
        !          28281: rescan:
        !          28282:        switch (inb(port+IIR)) {
        !          28283: 
        !          28284:        case LS_INTR:
        !          28285:                if (inb(port+LSR) & LS_BREAK)
        !          28286:                        defer(alxbreak, tp);
        !          28287:                goto rescan;
        !          28288: 
        !          28289:        case Rx_INTR:
        !          28290:                b = inb(port+DREG);
        !          28291:                if (tp->t_open == 0)
        !          28292:                        goto rescan;
        !          28293:                /*
        !          28294:                 * Must recognize XOFF quickly to avoid transmit overrun.
        !          28295:                 * Recognize XON here as well to avoid race conditions.
        !          28296:                 */
        !          28297:                if ((tp->t_sgttyb.sg_flags & RAWIN) == 0) {
        !          28298:                        /*
        !          28299:                         * XOFF.
        !          28300:                         */
        !          28301:                        if (tp->t_tchars.t_stopc == (b & 0177)) {
        !          28302:                                tp->t_flags |= T_STOP;
        !          28303:                                goto rescan;
        !          28304:                        }
        !          28305: 
        !          28306:                        /*
        !          28307:                         * XON.
        !          28308:                         */
        !          28309:                        if (tp->t_tchars.t_startc == (b & 0177)) {
        !          28310:                                tp->t_flags &= ~T_STOP;
        !          28311:                                goto rescan;
        !          28312:                        }
        !          28313:                }
        !          28314: 
        !          28315:                /*
        !          28316:                 * Save char in raw input buffer.
        !          28317:                 */
        !          28318:                if (tp->t_rawin.SILO_CHAR_COUNT < MAX_SILO_CHARS) {
        !          28319:                        tp->t_rawin.si_buf[tp->t_rawin.si_ix] = b;
        !          28320:                        if (tp->t_rawin.si_ix < MAX_SILO_INDEX)
        !          28321:                                tp->t_rawin.si_ix++;
        !          28322:                        else
        !          28323:                                tp->t_rawin.si_ix = 0;
        !          28324:                        tp->t_rawin.SILO_CHAR_COUNT++;
        !          28325:                }
        !          28326:                if (tp->t_flags & T_MODC)
        !          28327:                        if ((tp->t_flags & T_ISTOP)
        !          28328:                        || (tp->t_rawin.SILO_CHAR_COUNT > SILO_HIGH_MARK)) {
        !          28329:                                mcr = inb(port+MCR);
        !          28330:                                if (mcr & MC_RTS) {
        !          28331:                                        outb(port+MCR, mcr & ~MC_RTS);
        !          28332: printf("%x RTS OFF\n", port);
        !          28333:                                }
        !          28334:                        }
        !          28335:                goto rescan;
        !          28336: 
        !          28337:        case Tx_INTR:
        !          28338:                /*
        !          28339:                 * Do nothing if no raw output data or output is stopped.
        !          28340:                 */
        !          28341:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox) {
        !          28342:                        goto rescan;
        !          28343:                }
        !          28344:                if (tp->t_flags & T_STOP)
        !          28345:                        goto rescan;
        !          28346: 
        !          28347:                /*
        !          28348:                 * Transmit next char in raw output buffer.
        !          28349:                 */
        !          28350:                outb(port+DREG,
        !          28351:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ]);
        !          28352: 
        !          28353:                /*
        !          28354:                 * Adjust raw output buffer output index.
        !          28355:                 */
        !          28356:                if (++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf))
        !          28357:                        tp->t_rawout.si_ox = 0;
        !          28358: 
        !          28359:                /*
        !          28360:                 * Try to fill buffer if now empty.
        !          28361:                 */
        !          28362:                if (tp->t_rawout.si_ox == tp->t_rawout.si_ix) {
        !          28363:                        defer(alxcycle, tp);
        !          28364:                }
        !          28365:                goto rescan;
        !          28366: 
        !          28367:        case MS_INTR:
        !          28368:                AL_MSR_DELTAS |= inb(port+MSR);
        !          28369:                defer(alxcycle, tp);
        !          28370:                goto rescan;
        !          28371:        }
        !          28372: }
        !          28373: 
        !          28374: /*
        !          28375:  * alxclk will be called every time T0 interrupts - if it returns 0,
        !          28376:  * the usual system timer interrupt stuff is done
        !          28377:  */
        !          28378: static int alxclk()
        !          28379: {
        !          28380:        static int count;
        !          28381:        int i;
        !          28382: 
        !          28383:        for (i = 0; i < NUM_AL_PORTS;  i++)
        !          28384:                if (com_usage[i] == COM_POLLED)
        !          28385:                        alxintr(tp_table[i]);
        !          28386:        count++;
        !          28387:        if (count >= poll_divisor)
        !          28388:                count = 0;
        !          28389:        return count;
        !          28390: }
        !          28391: 
        !          28392: /*
        !          28393:  * set_poll_rate is called when a port is opened or closed or changes speed
        !          28394:  * it sets the polling rate only as fast as needed, and shuts off polling
        !          28395:  * whenever possible
        !          28396:  */
        !          28397: static set_poll_rate()
        !          28398: {
        !          28399:        int port_num, max_rate, port_rate;
        !          28400: 
        !          28401:        /*
        !          28402:         * If another driver has the polling clock, do nothing.
        !          28403:         */
        !          28404:        if (poll_owner & ~ POLL_AL)
        !          28405:                return;
        !          28406: 
        !          28407:        /*
        !          28408:         * find highest valid polling rate in units of HZ/10
        !          28409:         */
        !          28410:        max_rate = 0;
        !          28411:        for (port_num = 0; port_num < NUM_AL_PORTS; port_num++) {
        !          28412:                if (com_usage[port_num] == COM_POLLED) {
        !          28413:                        port_rate = alp_rate[(tp_table[port_num])->t_sgttyb.sg_ispeed];
        !          28414:                        if (max_rate < port_rate)
        !          28415:                                max_rate = port_rate;
        !          28416:                }
        !          28417:        }
        !          28418:        /*
        !          28419:         * if max_rate is not current rate, adjust the system clock
        !          28420:         */
        !          28421:        if (max_rate != poll_rate) {
        !          28422:                poll_rate = max_rate;
        !          28423:                poll_divisor = poll_rate/HZ;  /* used in alxclk() */
        !          28424:                altclk_out();           /* stop previous polling */
        !          28425:                poll_owner &= ~ POLL_AL;
        !          28426:                if (max_rate) { /* resume polling at new rate if needed */
        !          28427:                        poll_owner |= POLL_AL;
        !          28428:                        altclk_in(poll_rate, alxclk);
        !          28429:                }
        !          28430:                CDUMP("new rate")
        !          28431:        }
        !          28432: }
        !          28433: @
        !          28434: 
        !          28435: 
        !          28436: 1.11
        !          28437: log
        !          28438: @updated by hal to include rts/cts handshaking
        !          28439: @
        !          28440: text
        !          28441: @d6 7
        !          28442: a12 1
        !          28443:  * $Log:       /usr/src/sys/i8086/drv/RCS/alx.c,v $
        !          28444: d58 1
        !          28445: a58 1
        !          28446: #define        IENABLE (IE_RxI+IE_TxI+IE_LSI)
        !          28447: d65 1
        !          28448: a65 1
        !          28449: #define SILO_HIGH_MARK (SI_BUFSIZ-26)
        !          28450: d327 1
        !          28451: d374 1
        !          28452: d376 1
        !          28453: d386 1
        !          28454: d388 1
        !          28455: d487 1
        !          28456: d489 1
        !          28457: d533 1
        !          28458: a533 1
        !          28459:        unsigned char   msr;
        !          28460: a537 2
        !          28461:         * Modem status interrupts are not enabled due to 8250 hardware bug.
        !          28462:         * Enabling modem status and receive interrupts may cause lockup.
        !          28463: d539 4
        !          28464: a550 1
        !          28465:                s = sphi();
        !          28466: a552 1
        !          28467:                spl(s);
        !          28468: d596 5
        !          28469: a600 1
        !          28470:                        outb(ALPORT+MCR, inb(ALPORT+MCR) | MC_RTS);
        !          28471: d610 1
        !          28472: a610 1
        !          28473:        if (!(tp->t_flags & T_MODC) || !(tp->t_flags & T_ISTOP)) 
        !          28474: d701 1
        !          28475: d748 9
        !          28476: a756 4
        !          28477:                if ((tp->t_flags & T_MODC)
        !          28478:                && (tp->t_rawin.SILO_CHAR_COUNT > SILO_HIGH_MARK)) {
        !          28479:                        outb(port+MCR, inb(port+MCR) & ~MC_RTS);
        !          28480:                }
        !          28481: d772 1
        !          28482: a772 1
        !          28483:                outb(   port+DREG,
        !          28484: d791 1
        !          28485: @
        !          28486: 
        !          28487: 
        !          28488: 1.10
        !          28489: log
        !          28490: @Fix '&' for '&=' in alxcycle().
        !          28491: @
        !          28492: text
        !          28493: @d12 1
        !          28494: a12 1
        !          28495:  * 
        !          28496: d15 1
        !          28497: a15 1
        !          28498:  * 
        !          28499: d18 1
        !          28500: a18 1
        !          28501:  * 
        !          28502: d21 1
        !          28503: a21 1
        !          28504:  * 
        !          28505: d24 1
        !          28506: a24 1
        !          28507:  * 
        !          28508: d54 9
        !          28509: d79 1
        !          28510: a79 1
        !          28511: static int     alxclk();
        !          28512: d176 1
        !          28513: a176 1
        !          28514:        if ( inb(b+IER) & ~IENABLE ) { /* chip not found */
        !          28515: d202 1
        !          28516: a202 1
        !          28517:         *      can't have both com[13] or both com[24] IRQ at once 
        !          28518: d238 1
        !          28519: a238 1
        !          28520:        
        !          28521: d240 1
        !          28522: a240 1
        !          28523:        
        !          28524: d242 1
        !          28525: a242 1
        !          28526:                        tp->t_flags |= T_MODC | T_HOPEN; /* yes, set flags */
        !          28527: d263 2
        !          28528: d266 1
        !          28529: a266 1
        !          28530:                        tp->t_flags &= ~T_MODC;         /* no modem control */ 
        !          28531: d281 1
        !          28532: a281 1
        !          28533:                        u.u_error = ENODEV;     /* yes, don't allow open */     
        !          28534: d310 2
        !          28535: d348 1
        !          28536: a348 1
        !          28537:        if ( (holdflags & T_HOPEN) == 0 ) {
        !          28538: d391 1
        !          28539: a391 1
        !          28540:        if ( ++drvl[major(dev)].d_time > DTRTMOUT )
        !          28541: d416 1
        !          28542: a416 1
        !          28543:        case TIOCSBRK:                  /* set BREAK */         
        !          28544: d424 1
        !          28545: a424 1
        !          28546:                break;  
        !          28547: d426 1
        !          28548: a426 1
        !          28549:                outb(b+MCR, stat1 & ~MC_DTR);   
        !          28550: d429 1
        !          28551: a429 1
        !          28552:                outb(b+MCR, stat1|MC_RTS);      
        !          28553: d432 2
        !          28554: a433 2
        !          28555:                outb(b+MCR, stat1 & ~MC_RTS);   
        !          28556:                break;  
        !          28557: d448 1
        !          28558: a448 1
        !          28559:                break;  
        !          28560: d469 1
        !          28561: a469 1
        !          28562:                u.u_error = ENODEV;       
        !          28563: d490 1
        !          28564: a490 1
        !          28565:                        outb(b+LCR, LC_CS7 + LC_PARENB + LC_PAREVEN );
        !          28566: d494 1
        !          28567: a494 1
        !          28568:                        outb(b+LCR, LC_CS7 + LC_PARENB );
        !          28569: d498 1
        !          28570: a498 1
        !          28571:                        outb(b+LCR, LC_CS8 );
        !          28572: d515 1
        !          28573: a515 1
        !          28574: alxcycle( tp )
        !          28575: d524 1
        !          28576: a524 1
        !          28577:         * Check modem status every clock tick.
        !          28578: d527 3
        !          28579: d531 1
        !          28580: a531 1
        !          28581:        if ( tp->t_flags & T_MODC ) {
        !          28582: d544 1
        !          28583: a544 1
        !          28584:                if ( AL_MSR_DELTAS & MS_DRLSD ) {
        !          28585: d549 1
        !          28586: a549 1
        !          28587:                        if ( tp->t_open == 0 ) {
        !          28588: d556 1
        !          28589: a556 1
        !          28590:                        else if ( (msr & MS_RLSD) == 0 ) {
        !          28591: d560 1
        !          28592: d562 3
        !          28593: a564 1
        !          28594:                                tthup( tp );
        !          28595: d567 18
        !          28596: d589 3
        !          28597: d593 9
        !          28598: a601 7
        !          28599:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          28600:                ttin( tp, tp->t_rawin.si_buf[ tp->t_rawin.si_ox ] );
        !          28601:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          28602:                        tp->t_rawin.si_ox = 0;
        !          28603:                else
        !          28604:                        tp->t_rawin.si_ox++;
        !          28605:        }
        !          28606: d613 1
        !          28607: a613 1
        !          28608:        while ( (--n >= 0) && ((b = ttout(tp)) >= 0) ) {
        !          28609: d615 1
        !          28610: a615 1
        !          28611:                if ( tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1 )
        !          28612: d624 1
        !          28613: a624 1
        !          28614:        ttstart( tp );
        !          28615: d629 1
        !          28616: a629 1
        !          28617:        timeout( &tp->t_rawtim, HZ/10, alxcycle, tp );
        !          28618: d635 1
        !          28619: a635 1
        !          28620: alxstart( tp )
        !          28621: d652 2
        !          28622: a653 2
        !          28623:        if ( b & LS_BREAK )
        !          28624:                defer( alxbreak, tp );
        !          28625: d658 1
        !          28626: a658 1
        !          28627:        if ( (b & LS_TxRDY) && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          28628: d660 2
        !          28629: a661 2
        !          28630:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          28631:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          28632: d664 1
        !          28633: a664 1
        !          28634:        spl( s );
        !          28635: d670 2
        !          28636: a671 2
        !          28637: alxbreak( tp )
        !          28638: register TTY * tp;
        !          28639: d673 1
        !          28640: a673 1
        !          28641:        ttsignal( tp, SIGINT );
        !          28642: d679 1
        !          28643: a679 1
        !          28644: alxintr( tp )
        !          28645: d686 1
        !          28646: a686 1
        !          28647:        switch ( inb(port+IIR) ) {
        !          28648: d689 2
        !          28649: a690 2
        !          28650:                if ( inb(port+LSR) & LS_BREAK )
        !          28651:                        defer( alxbreak, tp );
        !          28652: d695 1
        !          28653: a695 1
        !          28654:                if ( tp->t_open == 0 )
        !          28655: d701 1
        !          28656: a701 1
        !          28657:                if ( (tp->t_sgttyb.sg_flags & RAWIN) == 0 ) {
        !          28658: d705 1
        !          28659: a705 1
        !          28660:                        if ( tp->t_tchars.t_stopc == (b & 0177) ) {
        !          28661: d713 1
        !          28662: a713 1
        !          28663:                        if ( tp->t_tchars.t_startc == (b & 0177) ) {
        !          28664: d722 12
        !          28665: a733 3
        !          28666:                tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          28667:                if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          28668:                        tp->t_rawin.si_ix = 0;
        !          28669: d740 1
        !          28670: a740 1
        !          28671:                if ( tp->t_rawout.si_ix == tp->t_rawout.si_ox ) {
        !          28672: d743 1
        !          28673: a743 1
        !          28674:                if ( tp->t_flags & T_STOP )
        !          28675: d750 1
        !          28676: a750 1
        !          28677:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          28678: d755 1
        !          28679: a755 1
        !          28680:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          28681: d761 2
        !          28682: a762 2
        !          28683:                if ( tp->t_rawout.si_ox == tp->t_rawout.si_ix ) {
        !          28684:                        defer( alxcycle, tp );
        !          28685: d765 1
        !          28686: a765 1
        !          28687:                
        !          28688: @
        !          28689: 
        !          28690: 
        !          28691: 1.9
        !          28692: log
        !          28693: @update provided by hal
        !          28694: @
        !          28695: text
        !          28696: @d529 1
        !          28697: a529 1
        !          28698:                        AL_MSR_DELTAS & ~MS_DRLSD;
        !          28699: @
        !          28700: 
        !          28701: 
        !          28702: 1.8
        !          28703: log
        !          28704: @update provided by hal
        !          28705: @
        !          28706: text
        !          28707: @d32 3
        !          28708: a34 3
        !          28709: #include <coherent.h>
        !          28710: #include <i8086.h>
        !          28711: #include <al.h>
        !          28712: d41 2
        !          28713: a42 2
        !          28714: #include <clist.h>
        !          28715: #include <ins8250.h>
        !          28716: @
        !          28717: 
        !          28718: 
        !          28719: 1.7
        !          28720: log
        !          28721: @new version provided y hal for v321
        !          28722: @
        !          28723: text
        !          28724: @@
        !          28725: 
        !          28726: 
        !          28727: 1.6
        !          28728: log
        !          28729: @alxclose():  do closing state machine BEFORE dropping control lines.
        !          28730: alxioctl():  save and restore interrupt enable register.
        !          28731: alxopen():   wait for pending last close (fixes SLOW port bug).
        !          28732: This version needs al.h 1.3 or later.
        !          28733: @
        !          28734: text
        !          28735: @d7 6
        !          28736: d35 1
        !          28737: a35 1
        !          28738: #include <con.h>
        !          28739: d37 3
        !          28740: a39 3
        !          28741: #include <stat.h>
        !          28742: #include <tty.h>
        !          28743: #include <uproc.h>
        !          28744: d43 1
        !          28745: a43 1
        !          28746: #include <sched.h>
        !          28747: @
        !          28748: 
        !          28749: 
        !          28750: 1.5
        !          28751: log
        !          28752: @save MSR delta status; add MS_INTR handling; use al.h 1.2
        !          28753: @
        !          28754: text
        !          28755: @d7 3
        !          28756: d43 1
        !          28757: d144 3
        !          28758: d203 7
        !          28759: d217 1
        !          28760: a217 1
        !          28761:                if (dev & CPOLL)
        !          28762: d219 1
        !          28763: a219 1
        !          28764:                else {
        !          28765: d291 3
        !          28766: d306 3
        !          28767: a308 2
        !          28768:        holdflags = tp->t_flags;       /* save flags */
        !          28769:        ttclose(tp);                   /* clear flags */
        !          28770: d310 15
        !          28771: d349 1
        !          28772: a357 15
        !          28773:        /*
        !          28774:         * ttclose() only emptied the output queue tp->t_oq;
        !          28775:         * now wait for the silo tp->rawout to empty
        !          28776:         * and allow a delay for the UART on-chip xmit buffer to empty
        !          28777:         * state 2: waiting for silo to empty
        !          28778:         * state 1: stalling so UART can empty xmit buffer
        !          28779:         * state 0: done!  ok to shut off IRQ for this chip by clearing MC_OUT2
        !          28780:         */
        !          28781:        state = 2;
        !          28782:        while (state) {
        !          28783:                timeout(&AL_TIM, 10, wakeup, (int)&AL_TIM);
        !          28784:                sleep((char *)&AL_TIM, CVTTOUT, IVTTOUT, SVTTOUT);
        !          28785:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          28786:                        state--;
        !          28787:        }
        !          28788: d361 2
        !          28789: d388 1
        !          28790: d392 1
        !          28791: d433 1
        !          28792: d462 1
        !          28793: a462 1
        !          28794:                char ier_save=inb(b+IER);       /* some chips need this */
        !          28795: d465 1
        !          28796: @
        !          28797: 
        !          28798:                        else if ( (b & MS_RLSD) == 0 ) {
        !          28799: d683 4
        !          28800: @
        !          28801:        outb(   ALPORT+DREG,
        !          28802: @
        !          28803: 
        !          28804: 
        !          28805: 1.2
        !          28806: log
        !          28807: @Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          28808: @
        !          28809: text
        !          28810: @d7 3
        !          28811: d327 1
        !          28812: a327 1
        !          28813:        outb(b+MCR, 0);
        !          28814: @
        !          28815: 
        !          28816: 
        !          28817: 1.2.2.1
        !          28818: log
        !          28819: @Multiple changes for Larry Rachman
        !          28820: @
        !          28821: text
        !          28822: @d1 2
        !          28823: a2 1
        !          28824: /* (-lgl *     COHERENT Driver Kit Version 1.1.0
        !          28825: a4 4
        !          28826:  -lgl) */
        !          28827:  
        !          28828: /*
        !          28829:  * This branch (1.2.2) has these additions to the COH 3.1.0 release:
        !          28830: a5 8
        !          28831:  * Extended diagnostics (more calls to CDUMP).
        !          28832:  * Save & restore IER during calls to alxioctl().
        !          28833:  * Add case to alxintr() to clear MS_INTR.
        !          28834:  * Add msr_deltas field to COM_DDP struct.
        !          28835:  * Save MSR delta bits whenever MSR is read.
        !          28836:  * Do software edge trigger during alxintr().
        !          28837:  * Replace repeated uses of ALPORT macro in alxintr() by local variable.
        !          28838:  *
        !          28839: a6 3
        !          28840:  * Revision 1.2        91/02/21  11:21:40      hal
        !          28841:  * Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          28842:  * 
        !          28843: d9 2
        !          28844: a10 2
        !          28845:  */
        !          28846:  
        !          28847: a29 1
        !          28848: #define AL_MSR_DELTAS  (((COM_DDP *)(tp->t_ddp))->msr_deltas)
        !          28849: d36 1
        !          28850: a36 1
        !          28851: static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          28852: d111 1
        !          28853: a111 1
        !          28854: #if 1
        !          28855: a137 1
        !          28856:        char msr;
        !          28857: d203 1
        !          28858: a203 5
        !          28859:                        while (1) {     /* wait for carrier */
        !          28860:                                msr = inb(b+MSR);
        !          28861:                                AL_MSR_DELTAS |= msr;
        !          28862:                                if (msr & MS_RLSD)
        !          28863:                                        break;
        !          28864: a350 2
        !          28865:        char ier_save;
        !          28866:        char msr;
        !          28867: a351 1
        !          28868: CDUMP("start ioctl")
        !          28869: a353 1
        !          28870:        ier_save=inb(b+IER);            /* some chips need this */
        !          28871: d386 1
        !          28872: a386 3
        !          28873:                msr = inb(b+MSR);
        !          28874:                AL_MSR_DELTAS |= msr;
        !          28875:                stat1 = msr >> 4;
        !          28876: a391 1
        !          28877:        outb(b+IER, ier_save);
        !          28878: a392 1
        !          28879: CDUMP("end ioctl")
        !          28880: d401 1
        !          28881: a401 2
        !          28882:        
        !          28883: CDUMP("start set params")
        !          28884: a442 1
        !          28885: CDUMP("end set params")
        !          28886: a457 2
        !          28887:        int s;
        !          28888:        char msr;
        !          28889: d469 1
        !          28890: a469 4
        !          28891:                s = sphi();
        !          28892:                msr = inb(ALPORT+MSR);
        !          28893:                AL_MSR_DELTAS |= msr;
        !          28894:                spl(s);
        !          28895: d474 1
        !          28896: a474 2
        !          28897:                if ( AL_MSR_DELTAS & MS_DRLSD ) {
        !          28898:                        AL_MSR_DELTAS & ~MS_DRLSD;
        !          28899: d485 1
        !          28900: a485 1
        !          28901:                        else if ( (msr & MS_RLSD) == 0 ) {
        !          28902: a585 1
        !          28903:        int port = ALPORT;
        !          28904: d588 1
        !          28905: a588 1
        !          28906:        switch ( inb(port+IIR) ) {
        !          28907: d591 1
        !          28908: a591 1
        !          28909:                if ( inb(port+LSR) & LS_BREAK )
        !          28910: d596 1
        !          28911: a596 1
        !          28912:                b = inb(port+DREG);
        !          28913: d642 1
        !          28914: a642 1
        !          28915:                outb(   port+DREG,
        !          28916: a657 4
        !          28917:                
        !          28918:        case MS_INTR:
        !          28919:                AL_MSR_DELTAS |= inb(port+MSR);
        !          28920:                goto rescan;
        !          28921: a658 9
        !          28922:        /*
        !          28923:         * Some UARTs need the following on edge-triggered interrupt systems.
        !          28924:         */
        !          28925:        { 
        !          28926:                char ier_save;
        !          28927:                ier_save=inb(port+IER);
        !          28928:                outb(port+IER,0);
        !          28929:                outb(port+IER,ier_save);
        !          28930:        }       
        !          28931: @
        !          28932: 
        !          28933: 
        !          28934: 1.2.1.1
        !          28935: log
        !          28936: @Preliminary Enahancements for Esa Ahola
        !          28937: @
        !          28938: text
        !          28939: @a6 3
        !          28940:  * Revision 1.2        91/02/21  11:21:40      hal
        !          28941:  * Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          28942:  * 
        !          28943: a9 7
        !          28944:  * Add IE_ALL bit mask and use it when checking for UART existence.
        !          28945:  * Save delta status of CD - but not on per port basis.
        !          28946:  * Fix unconditional "hupcl" bug in 3.1.0 version.
        !          28947:  * Add RTS handshaking.
        !          28948:  * Add CTS handshaking.
        !          28949:  * Save and restore IER during alxioctl() call as well as alxparam().
        !          28950:  *
        !          28951: a32 1
        !          28952: #define IE_ALL (IE_RxI|IE_TxI|IE_LSI|IE_MSI)
        !          28953: a36 4
        !          28954: static int drlsd;      /* delta carrier detect - set by alxintr(), read
        !          28955:                           by alxcycle() */
        !          28956: static int rawin_ct;   /* number of characters in input silo */                           
        !          28957: static int want_rts;
        !          28958: d143 1
        !          28959: a143 1
        !          28960:        if ( inb(b+IER) & ~IE_ALL ) { /* chip not found */
        !          28961: a197 1
        !          28962:                want_rts = 1;
        !          28963: a207 1
        !          28964:                                        want_rts = 0;
        !          28965: a300 1
        !          28966:                want_rts = 0;
        !          28967: d324 1
        !          28968: a324 4
        !          28969:        /*
        !          28970:         * Turn off MC_OUT2 so IRQ can be used by other port.
        !          28971:         */
        !          28972:        outb(b+MCR, inb(b+MCR)&(~MC_OUT2));
        !          28973: a350 1
        !          28974:        char ier_save;
        !          28975: a352 1
        !          28976:        ier_save=inb(b+IER);    /* some chips need this */
        !          28977: a391 1
        !          28978:        outb(b+IER, ier_save);
        !          28979: a415 1
        !          28980:                        want_rts = 0;
        !          28981: d474 1
        !          28982: a474 2
        !          28983:                if ((b & MS_DRLSD) || drlsd) {
        !          28984:                        drlsd = 0;
        !          28985: a489 1
        !          28986:                                rawin_ct = 0;
        !          28987: a504 3
        !          28988:        rawin_ct = 0;
        !          28989:        if (want_rts)
        !          28990:                outb(b+MCR, inb(b+MCR) | MC_RTS);
        !          28991: d627 1
        !          28992: a627 8
        !          28993:                        rawin_ct++;
        !          28994:                /*
        !          28995:                 * Preliminary code!
        !          28996:                 * De-assert RTS if we are close to filling the input silo.
        !          28997:                 */     
        !          28998:                if (want_rts && (sizeof(tp->t_rawin.si_buf) - rawin_ct < 4))
        !          28999:                        outb(b+MCR, inb(b+MCR) & ~MC_RTS);
        !          29000:                        goto rescan;
        !          29001: a657 16
        !          29002:                
        !          29003:        case MS_INTR:
        !          29004:                /*
        !          29005:                 * This is preliminary code - use delta of CTS from
        !          29006:                 * modem to implement flow control.
        !          29007:                 *
        !          29008:                 * Sense delta of RLSD for use by alxcycle().
        !          29009:                 */
        !          29010:                b = inb(ALPORT+MSR);
        !          29011:                if (b & MS_DCTS)
        !          29012:                        if (b & MS_CTS)
        !          29013:                                tp->t_flags &= ~T_STOP;
        !          29014:                        else
        !          29015:                                tp->t_flags |= T_STOP;
        !          29016:                if (b & MS_DRLSD)
        !          29017:                        drlsd = 1;              
        !          29018: @
        !          29019: 
        !          29020: 
        !          29021: 1.1
        !          29022: log
        !          29023: @Used in COH Release 3.0.0 - no COM3/COM4
        !          29024: @
        !          29025: text
        !          29026: @d1 10
        !          29027: a12 42
        !          29028:  *
        !          29029:  * $Log$
        !          29030:  * Revision 1.2        90/06/07  14:10:04      bin
        !          29031:  * steve 6/7/90
        !          29032:  * On last line of alxopen(), changed dev_t argument in ttsetgrp() call
        !          29033:  * from "dev&~NMODC" to "dev".  The old version masked off the modem control
        !          29034:  * bit, so e.g. opening /dev/com2l set the process tty field p_ttdev to
        !          29035:  * /dev/com2r instead of com2l;  then a subsequent open of /dev/tty would
        !          29036:  * fail, because alxopen() would find the device already open with modem control
        !          29037:  * and return ENXIO; thus, /dev/tty would not work on the serial port.
        !          29038:  * 
        !          29039:  * Revision 1.1        90/06/07  14:06:13      bin
        !          29040:  * Initial MWC RCS revision, as received from Inetco.
        !          29041:  * 
        !          29042:  * Revision 2.3        89/08/01  14:21:52      src
        !          29043:  * Bug:        #include <timeout.h> not accurate; timeout.h now in /usr/include/sys.
        !          29044:  * Fix:        #include <sys/timeout.h> now used. (ABC)
        !          29045:  * 
        !          29046:  * Revision 2.2        89/03/31  15:28:43      src
        !          29047:  * Bug:        Break interrupt not always received properly in CBREAK mode.
        !          29048:  * Fix:        Line status register is read during output check as well
        !          29049:  *     as during interrupts.  Reading the register clears the break
        !          29050:  *     indication.  Output check now services break indication (ABC).
        !          29051:  * 
        !          29052:  * Revision 2.1        88/09/03  13:02:35      src
        !          29053:  * *** empty log message ***
        !          29054:  * 
        !          29055:  * Revision 1.1        88/03/24  17:04:11      src
        !          29056:  * Initial revision
        !          29057:  * 
        !          29058:  * 87/07/08    Allan Cornish           /usr/src/sys/i8086/drv/alx.c
        !          29059:  * alxcycle() now programs timeout in HZ/10 seconds, rather than 1 clock tick.
        !          29060:  *
        !          29061:  * 86/11/24    Allan Cornish           /usr/src/sys/i8086/drv/alx.c
        !          29062:  * alxcycle(), alxstart(), and alxintr() routines added.
        !          29063:  *
        !          29064:  * 86/07/27    Allan Cornish           /usr/src/sys/i8086/drv/alx.c
        !          29065:  * Revised to use ins8250.h header file rather than wd8250.h.
        !          29066:  *
        !          29067:  * 85/07/18    Allan Cornish
        !          29068:  * Created al_sg_set and al_sg_clr variables, which contain sg_flag bits
        !          29069:  * to be set and cleared, respectively, on first open of al[01][m].
        !          29070: d16 1
        !          29071: d27 4
        !          29072: a30 2
        !          29073: #define ALPORT ((unsigned)tp->t_ddp)
        !          29074: #define minor_st(dev)  (dev&0177)
        !          29075: d34 3
        !          29076: a36 2
        !          29077: int al_sg_set = 0;
        !          29078: int al_sg_clr = 0;
        !          29079: d39 16
        !          29080: a54 1
        !          29081:  * Baud rate table.
        !          29082: d80 27
        !          29083: d108 23
        !          29084: a130 1
        !          29085: alxopen(dev, mode, tp)
        !          29086: d133 1
        !          29087: a133 1
        !          29088: register TTY   *tp;
        !          29089: d141 1
        !          29090: a141 4
        !          29091:        if (minor_st(dev) >= 1) {       /* minor without high bit */
        !          29092:                u.u_error = ENXIO;
        !          29093:                return;
        !          29094:        }
        !          29095: a142 2
        !          29096:        b = ALPORT;
        !          29097: 
        !          29098: d148 2
        !          29099: a149 2
        !          29100:        if ((tp->t_flags & T_EXCL) && !super()) 
        !          29101:        {       u.u_error = ENODEV;
        !          29102: d152 3
        !          29103: a154 2
        !          29104:        if (drvl[major(dev)].d_time != 0)       /* Modem settling */
        !          29105:        {       u.u_error = EDBUSY;
        !          29106: a156 2
        !          29107:        if (tp->t_open == 0) {        /* not already open */
        !          29108:           s = sphi();
        !          29109: d158 7
        !          29110: a164 2
        !          29111:           /* Raise basic modem control lines even if modem */
        !          29112:           /* control hasn't been specified.                */
        !          29113: d166 17
        !          29114: a182 2
        !          29115:           outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);   /* raise lines (yes, MC_OUT2!) */
        !          29116:           outb(b+IER, IENABLE);        /* enable interrupts */
        !          29117: d184 40
        !          29118: a223 2
        !          29119:           if ((minor_h & NMODC) == 0) {  /* want modem control? */
        !          29120:              tp->t_flags |= T_MODC | T_HOPEN;  /* yes, set flags */
        !          29121: d225 19
        !          29122: a243 26
        !          29123:              while ((inb(b+MSR) & MS_RLSD) == 0) {  /* no carrier? */
        !          29124:                 sleep((char *)(&tp->t_open), CVTTOUT, IVTTOUT,
        !          29125:                        SVTTOUT);  /* wait for carrier */
        !          29126:                 if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          29127:                    outb(b+MCR, MC_OUT2);    /* make sure port is hungup */
        !          29128:                    outb(b+IER, IE_TxI);     /* disable all ints but TxI */
        !          29129:                    u.u_error = EINTR;
        !          29130:                    spl(s);
        !          29131:                    return;
        !          29132:                 }
        !          29133:              }
        !          29134:              tp->t_flags &= ~T_HOPEN;   /* no longer hanging in open */
        !          29135:           }
        !          29136:           else
        !          29137:               tp->t_flags &= ~T_MODC;    /* no modem control */ 
        !          29138: 
        !          29139:            tp->t_flags |= T_CARR;        /* carrier on */
        !          29140: 
        !          29141:           ttopen(tp);                   /* stty inits */
        !          29142:           /*
        !          29143:            * Allow custom modification of defaults.
        !          29144:            */
        !          29145:           tp->t_sgttyb.sg_flags |=  al_sg_set;
        !          29146:           tp->t_sgttyb.sg_flags &= ~al_sg_clr;
        !          29147:           alxparam(tp);
        !          29148:           spl(s);
        !          29149: a244 13
        !          29150:        else                             /* already open */
        !          29151:        {  if ((minor_h & NMODC) == 0)   /* want modem control? */
        !          29152:           {  if ((tp->t_flags & T_MODC)==0)  /* already not modem control? */
        !          29153:              {  u.u_error = ENODEV;     /* yes, don't allow open */    
        !          29154:                 return;
        !          29155:              }
        !          29156:           }
        !          29157:           else                          /* don't want modem control */
        !          29158:              if (tp->t_flags & T_MODC)  /* already modem control? */
        !          29159:              {  u.u_error = ENODEV;     /* yes, don't allow open */       
        !          29160:                 return;
        !          29161:              }    
        !          29162:        }
        !          29163: d247 13
        !          29164: d269 1
        !          29165: d286 1
        !          29166: a286 2
        !          29167:        }
        !          29168:        else {
        !          29169: d300 1
        !          29170: a300 2
        !          29171:                outb(b+MCR, MC_OUT2);
        !          29172: 
        !          29173: d304 4
        !          29174: a307 4
        !          29175:                b = major(dev);
        !          29176:                drvl[b].d_time = 1;
        !          29177:                sleep((char *)&drvl[b].d_time, CVTTOUT, IVTTOUT, SVTTOUT);
        !          29178:                drvl[b].d_time = 0;
        !          29179: d309 19
        !          29180: d354 2
        !          29181: a355 2
        !          29182:        stat1 = inb(b+MCR);      /* get current MCR register status */
        !          29183:        stat2 = inb(b+LCR);      /* get current LCR register status */
        !          29184: d358 1
        !          29185: a358 1
        !          29186:        case TIOCSBRK:          /* set BREAK */         
        !          29187: d361 1
        !          29188: a361 1
        !          29189:        case TIOCCBRK:          /* clear BREAK */
        !          29190: d364 1
        !          29191: a364 1
        !          29192:        case TIOCSDTR:          /* set DTR */
        !          29193: d367 1
        !          29194: a367 1
        !          29195:        case TIOCCDTR:          /* clear DTR */
        !          29196: d370 1
        !          29197: a370 1
        !          29198:        case TIOCSRTS:          /* set RTS */
        !          29199: d373 1
        !          29200: a373 1
        !          29201:        case TIOCCRTS:          /* clear RTS */
        !          29202: d376 1
        !          29203: a376 1
        !          29204:        case TIOCRSPEED:        /* set "raw" I/O speed divisor */
        !          29205: d400 1
        !          29206: d404 3
        !          29207: a406 1
        !          29208:        /* error if input speed not the same as output speed */
        !          29209: d408 2
        !          29210: a409 2
        !          29211:           u.u_error = ENODEV;    
        !          29212:           return;
        !          29213: d412 5
        !          29214: a416 6
        !          29215:        if ((baud = albaud[tp->t_sgttyb.sg_ispeed]) == 0) 
        !          29216:        {  if (tp->t_flags & T_MODC)    /* modem control? */
        !          29217:           {   tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          29218:               outb(b+MCR, MC_OUT2);       /* hangup */
        !          29219:           }
        !          29220:           return;
        !          29221: d419 2
        !          29222: a420 7
        !          29223:        outb(b+LCR, LC_DLAB);
        !          29224:        outb(b+DLL, baud);
        !          29225:        outb(b+DLH, baud >> 8);
        !          29226:        switch (tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW)) {
        !          29227:        case EVENP:
        !          29228:                outb(b+LCR, LC_CS7 + LC_PARENB + LC_PAREVEN );
        !          29229:                return;
        !          29230: d422 8
        !          29231: a429 3
        !          29232:        case ODDP:
        !          29233:                outb(b+LCR, LC_CS7 + LC_PARENB );
        !          29234:                return;
        !          29235: d431 10
        !          29236: a440 3
        !          29237:        default:
        !          29238:                outb(b+LCR, LC_CS8 );
        !          29239:                return;
        !          29240: d442 1
        !          29241: a474 1
        !          29242: 
        !          29243: a498 1
        !          29244: 
        !          29245: a499 1
        !          29246: 
        !          29247: a516 1
        !          29248: 
        !          29249: a517 1
        !          29250: 
        !          29251: a561 1
        !          29252: 
        !          29253: a563 1
        !          29254: 
        !          29255: a596 1
        !          29256: 
        !          29257: a598 1
        !          29258: 
        !          29259: a603 1
        !          29260: 
        !          29261: a624 1
        !          29262: 
        !          29263: d633 1
        !          29264: a633 1
        !          29265:                if ( tp->t_rawout.si_ix == tp->t_rawout.si_ox )
        !          29266: d635 1
        !          29267: d654 1
        !          29268: a654 1
        !          29269:                if ( tp->t_rawout.si_ox == tp->t_rawout.si_ix )
        !          29270: d656 1
        !          29271: d660 60
        !          29272: @
        !          29273: 0707070064030104351004440000030000030000011777770507310650300005400000075311/newbits/kernel/USRSRC/i8086/drv/RCS/at.c,vhead     1.8;
        !          29274: branch   ;
        !          29275: access   ;
        !          29276: symbols  ;
        !          29277: locks    bin:1.8;
        !          29278: comment  @ * @;
        !          29279: 
        !          29280: 
        !          29281: 1.8
        !          29282: date     91.06.20.14.47.50;  author bin;  state Exp;
        !          29283: branches ;
        !          29284: next     1.7;
        !          29285: 
        !          29286: 1.7
        !          29287: date     91.06.18.08.10.54;  author bin;  state Exp;
        !          29288: branches ;
        !          29289: next     1.6;
        !          29290: 
        !          29291: 1.6
        !          29292: date     91.06.17.12.28.56;  author bin;  state Exp;
        !          29293: branches ;
        !          29294: next     1.5;
        !          29295: 
        !          29296: 1.5
        !          29297: date     91.05.22.15.06.59;  author hal;  state Exp;
        !          29298: branches ;
        !          29299: next     1.4;
        !          29300: 
        !          29301: 1.4
        !          29302: date     91.03.14.14.22.32;  author root;  state Exp;
        !          29303: branches ;
        !          29304: next     1.3;
        !          29305: 
        !          29306: 1.3
        !          29307: date     91.03.05.08.56.39;  author root;  state Exp;
        !          29308: branches ;
        !          29309: next     1.2;
        !          29310: 
        !          29311: 1.2
        !          29312: date     91.03.05.08.55.18;  author root;  state Exp;
        !          29313: branches ;
        !          29314: next     1.1;
        !          29315: 
        !          29316: 1.1
        !          29317: date     91.03.05.08.53.51;  author root;  state Exp;
        !          29318: branches ;
        !          29319: next     ;
        !          29320: 
        !          29321: 
        !          29322: desc
        !          29323: @Device driver for ST506 AT-style hard drive controller.
        !          29324: @
        !          29325: 
        !          29326: 
        !          29327: 1.8
        !          29328: log
        !          29329: @update provided by hal
        !          29330: @
        !          29331: text
        !          29332: @/* (-lgl
        !          29333:  *     COHERENT Driver Kit Version 1.1.0
        !          29334:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          29335:  *     All rights reserved. May not be copied without permission.
        !          29336:  *
        !          29337:  * $Log:       at.c,v $
        !          29338:  * Revision 1.5  91/05/22  15:06:59  hal
        !          29339:  * Don't force 8's bit of control byte.
        !          29340:  * 
        !          29341:  * Revision 1.4        91/03/14  14:22:32      hal
        !          29342:  *
        !          29343:  -lgl) */
        !          29344: /*
        !          29345:  * This is a driver for the
        !          29346:  * hard disk on the AT.
        !          29347:  *
        !          29348:  * Reads drive characteristics from ROM (thru interrupt vector 0x41 and 0x46).
        !          29349:  * Reads partition information from disk.
        !          29350:  */
        !          29351: #include       <sys/coherent.h>
        !          29352: #include       <sys/fdisk.h>
        !          29353: #include       <sys/hdioctl.h>
        !          29354: #include       <sys/buf.h>
        !          29355: #include       <sys/con.h>
        !          29356: #include       <sys/stat.h>
        !          29357: #include       <sys/uproc.h>
        !          29358: #include       <errno.h>
        !          29359: 
        !          29360: extern saddr_t sds;            /* System Data Selector */
        !          29361: 
        !          29362: /*
        !          29363:  * Configurable parameters
        !          29364:  */
        !          29365: #define        HDMAJOR 11                      /* Major Device Number */
        !          29366: #define        HDIRQ   14                      /* Level 14 */
        !          29367: #define        HDBASE  0x01F0                  /* Port base */
        !          29368: #define NDRIVE 2                       /* only two drives supported */
        !          29369: #define        SOFTLIM 6                       /*  (7) num of retrys before diag */
        !          29370: #define        HARDLIM 8                       /* number of retrys before fail */
        !          29371: #define        BADLIM  100                     /* num to stop recov if flagged bad */
        !          29372: 
        !          29373: #define        BIT(n)          (1 << (n))
        !          29374: 
        !          29375: #define        CMOSA   0x70                    /* write cmos address to this port */
        !          29376: #define        CMOSD   0x71                    /* read cmos data through this port */
        !          29377: 
        !          29378: #ifndef        ATCACHE
        !          29379: #      if VERBOSE > 0
        !          29380: #              define  ATCACHE 2       /* local cache size in blocks */
        !          29381: #      else
        !          29382: #              define  ATCACHE 0       /* no cache for small code */
        !          29383: #      endif
        !          29384: #endif
        !          29385: 
        !          29386: /*
        !          29387:  * Driver configuration.
        !          29388:  */
        !          29389: void   atload();
        !          29390: void   atunload();
        !          29391: void   atopen();
        !          29392: void   atread();
        !          29393: void   atwrite();
        !          29394: int    atioctl();
        !          29395: void   atwatch();
        !          29396: void   atblock();
        !          29397: int    nulldev();
        !          29398: int    nonedev();
        !          29399: 
        !          29400: CON    atcon   = {
        !          29401:        DFBLK|DFCHR,                    /* Flags */
        !          29402:        HDMAJOR,                        /* Major index */
        !          29403:        atopen,                         /* Open */
        !          29404:        nulldev,                        /* Close */
        !          29405:        atblock,                        /* Block */
        !          29406:        atread,                         /* Read */
        !          29407:        atwrite,                        /* Write */
        !          29408:        atioctl,                        /* Ioctl */
        !          29409:        nulldev,                        /* Powerfail */
        !          29410:        atwatch,                        /* Timeout */
        !          29411:        atload,                         /* Load */
        !          29412:        atunload                        /* Unload */
        !          29413: };
        !          29414: 
        !          29415: /*
        !          29416:  * Forward Referenced Functions.
        !          29417:  */
        !          29418: void   atreset();
        !          29419: int    atdequeue();
        !          29420: void   atstart();
        !          29421: void   atintr();
        !          29422: void   atdefer();
        !          29423: int    aterror();
        !          29424: void   atrecov();
        !          29425: void   atdone();
        !          29426: 
        !          29427: /*
        !          29428:  * I/O Port Addresses
        !          29429:  */
        !          29430: #define        DATA_REG        (HDBASE+0)      /* data (r/w) */
        !          29431: #define        AUX_REG         (HDBASE+1)      /* error(r), write precomp cyl/4 (w) */
        !          29432: #define        NSEC_REG        (HDBASE+2)      /* sector count (r/w) */
        !          29433: #define        SEC_REG         (HDBASE+3)      /* sector number (r/w) */
        !          29434: #define        LCYL_REG        (HDBASE+4)      /* low cylinder (r/w) */
        !          29435: #define        HCYL_REG        (HDBASE+5)      /* high cylinder (r/w) */
        !          29436: #define        HDRV_REG        (HDBASE+6)      /* drive/head (r/w) (D<<4)+(1<<H) */
        !          29437: #define        CSR_REG         (HDBASE+7)      /* status (r), command (w) */
        !          29438: #define        HF_REG          0x3F6
        !          29439: 
        !          29440: /*
        !          29441:  * Error from AUX_REG (r)
        !          29442:  */
        !          29443: #define        DAM_ERR         BIT(0)          /* data address mark not found */
        !          29444: #define        TR0_ERR         BIT(1)          /* track 000 not found */
        !          29445: #define        ABT_ERR         BIT(2)          /* aborted command */
        !          29446: #define        ID_ERR          BIT(4)          /* id not found */
        !          29447: #define        ECC_ERR         BIT(6)          /* data ecc error */
        !          29448: #define        BAD_ERR         BIT(7)          /* bad block detect */
        !          29449: 
        !          29450: /*
        !          29451:  * Status from CSR_REG (r)
        !          29452:  */
        !          29453: #define        ERR_ST          BIT(0)          /* error occurred */
        !          29454: #define        INDEX_ST        BIT(1)          /* index pulse */
        !          29455: #define        SOFT_ST         BIT(2)          /* soft (corrected) ECC error */
        !          29456: #define        DRQ_ST          BIT(3)          /* data request */
        !          29457: #define        SKC_ST          BIT(4)          /* seek complete */
        !          29458: #define        WFLT_ST         BIT(5)          /* improper drive operation */
        !          29459: #define        RDY_ST          BIT(6)          /* drive is ready */
        !          29460: #define        BSY_ST          BIT(7)          /* controller is busy */
        !          29461: 
        !          29462: 
        !          29463: /*
        !          29464:  * Commands to CSR_REG (w)
        !          29465:  */
        !          29466: #define        RESTORE(rate)   (0x10+(rate))   /* X */
        !          29467: #define        SEEK(rate)      (0x70+(rate))   /* X */
        !          29468: #define        READ_CMD        (0x20)          /* X */
        !          29469: #define        WRITE_CMD       (0x30)          /* X */
        !          29470: #define        FORMAT_CMD      (0x50)          /* X */
        !          29471: #define        VERIFY_CMD      (0x40)          /* X */
        !          29472: #define        DIAGNOSE_CMD    (0x90)          /* X */
        !          29473: #define        SETPARM_CMD     (0x91)          /* X */
        !          29474: 
        !          29475: /*
        !          29476:  * Device States.
        !          29477:  */
        !          29478: #define        SIDLE   0                       /* controller idle */
        !          29479: #define        SRETRY  1                       /* seeking */
        !          29480: #define        SREAD   2                       /* reading */
        !          29481: #define        SWRITE  3                       /* writing */
        !          29482: 
        !          29483: /*
        !          29484:  * Drive Parameters - copied from ROM.
        !          29485:  * If patched, use the given values instead of reading from the ROM.
        !          29486:  * NOTE: Exactly duplicates hdparm_s struct.
        !          29487:  */
        !          29488: struct dparm_s {
        !          29489:        unsigned short  d_ncyl;         /* number of cylinders */
        !          29490:        unsigned char   d_nhead;        /* number of heads */
        !          29491:        unsigned short  d_rwcc;         /* reduced write current cyl */
        !          29492:        unsigned short  d_wpcc;         /* write pre-compensation cyl */
        !          29493:        unsigned char   d_eccl;         /* max ecc data length */
        !          29494:        unsigned char   d_ctrl;         /* control byte */
        !          29495:        unsigned char   d_fill2[3];
        !          29496:        unsigned short  d_landc;        /* landing zone cylinder */
        !          29497:        unsigned char   d_nspt;         /* number of sectors per track */
        !          29498:        unsigned char   d_fill3;
        !          29499: 
        !          29500: }      atparm[ NDRIVE ] = {
        !          29501:        0                               /* Initialized to allow patching */
        !          29502: };
        !          29503: 
        !          29504: /*
        !          29505:  * Partition Parameters - copied from disk.
        !          29506:  *
        !          29507:  *     There are NDRIVE * NPARTN positions for the user partitions,
        !          29508:  *     plus NDRIVE additional partitions to span each drive.
        !          29509:  *
        !          29510:  *     Aligning partitions on cylinder boundaries:
        !          29511:  *     Optimal partition size: 2 * 3 * 4 * 5 * 7 * 17 = 14280 blocks
        !          29512:  *     Acceptable partition size:  3 * 4 * 5 * 7 * 17 =  7140 blocks
        !          29513:  */
        !          29514: static
        !          29515: struct fdisk_s pparm[NDRIVE*NPARTN + NDRIVE];
        !          29516: 
        !          29517: /*
        !          29518:  * Per disk controller data.
        !          29519:  * Only one controller; no more, no less.
        !          29520:  */
        !          29521: static
        !          29522: struct at      {
        !          29523:        BUF             *at_actf;       /* Link to first */
        !          29524:        BUF             *at_actl;       /* Link to last */
        !          29525:        faddr_t         at_faddr;       /* Source/Dest virtual address */
        !          29526:        daddr_t         at_bno;         /* Block # on disk */
        !          29527:        unsigned        at_nsec;        /* # of sectors on current transfer */
        !          29528:        unsigned        at_drv;
        !          29529:        unsigned        at_head;
        !          29530:        unsigned        at_cyl;
        !          29531:        unsigned        at_sec;
        !          29532:        unsigned        at_partn;
        !          29533:        unsigned char   at_dtype[ NDRIVE ];     /* drive type, 0 if unused */
        !          29534:        unsigned char   at_tries;
        !          29535:        unsigned char   at_state;
        !          29536:        unsigned char   at_caching;             /* caching in progress */
        !          29537: #if    ATCACHE > 0
        !          29538:        unsigned char   at_cdrv[ ATCACHE ];     /* cached drive */
        !          29539:        daddr_t         at_cbno[ ATCACHE ];     /* cached block number */
        !          29540:        unsigned char * at_cbuf[ ATCACHE ];     /* cached block */
        !          29541: #endif
        !          29542:        unsigned        at_bad_drv;
        !          29543:        unsigned        at_bad_head;
        !          29544:        unsigned        at_bad_cyl;
        !          29545: }      at;
        !          29546: 
        !          29547: static BUF     dbuf;                   /* For raw I/O */
        !          29548: 
        !          29549: int    ATBSYW = 50;                    /* patchable */
        !          29550: static char timeout_msg[] = "at%d: TO\n";
        !          29551: 
        !          29552: /**
        !          29553:  *
        !          29554:  * void
        !          29555:  * atload()    - load routine.
        !          29556:  *
        !          29557:  *     Action: The controller is reset and the interrupt vector is grabbed.
        !          29558:  *             The drive characteristics are set up at this time.
        !          29559:  */
        !          29560: static void
        !          29561: atload()
        !          29562: {
        !          29563:        register int u;
        !          29564:        register struct dparm_s * dp;
        !          29565:        struct { unsigned off, seg; } p;
        !          29566: 
        !          29567:        /*
        !          29568:         * Obtain Drive Types.
        !          29569:         *
        !          29570:         *      High nibble of CMOS 0x12 is drive 0's type.
        !          29571:         *      Low  nibble of CMOS 0x12 is drive 1's type.
        !          29572:         */
        !          29573:        outb( CMOSA, 0x12 );
        !          29574:        /* delay */
        !          29575:        u = inb(CMOSD);
        !          29576:        at.at_dtype[0] = u >> 4;
        !          29577:        at.at_dtype[1] = u & 15;
        !          29578: 
        !          29579:        /*
        !          29580:         * Interrupt Vector 0x41 points to Drive 0 Characteristics.
        !          29581:         */
        !          29582:        pkcopy( (paddr_t) (0x41*4), &p, sizeof p );
        !          29583: 
        !          29584:        /*
        !          29585:         * Obtain Drive Characteristics.
        !          29586:         */
        !          29587:        for ( u = 0, dp = &atparm[0]; u < NDRIVE; ++dp, ++u ) {
        !          29588: 
        !          29589:                if ( dp->d_ncyl == 0 ) {
        !          29590:                        /* Not patched, use the ROM drive table values. */
        !          29591:                        pkcopy( (paddr_t) (p.seg << 4L) + p.off,
        !          29592:                                dp, sizeof(*dp) );
        !          29593:                }
        !          29594:                else {
        !          29595:                        /*
        !          29596:                         * Avoid incomplete patching.
        !          29597:                         */
        !          29598:                        if (at.at_dtype[u] == 0)
        !          29599:                                at.at_dtype[u] = 1;
        !          29600:                        if ( dp->d_nspt == 0 )
        !          29601:                                dp->d_nspt = 17;
        !          29602: #if FORCE_CTRL_8
        !          29603:                        if ( dp->d_nhead > 8 )
        !          29604:                                dp->d_ctrl |= 8;
        !          29605: #endif
        !          29606: 
        !          29607: #if VERBOSE > 0
        !          29608:                        printf(
        !          29609:        "at%d: ncyl=%d nhead=%d wpcc=%d eccl=%d ctrl=%d landc=%d nspt=%d\n",
        !          29610:                                u,
        !          29611:                                dp->d_ncyl,
        !          29612:                                dp->d_nhead,
        !          29613:                                dp->d_wpcc,
        !          29614:                                dp->d_eccl,
        !          29615:                                dp->d_ctrl,
        !          29616:                                dp->d_landc,
        !          29617:                                dp->d_nspt );
        !          29618: #endif
        !          29619:                }
        !          29620: 
        !          29621:                /*
        !          29622:                 * Interrupt Vector 0x46 points to Drive 1 Characteristics.
        !          29623:                 */
        !          29624:                pkcopy( (paddr_t) (0x46*4), &p, sizeof p );
        !          29625:        }
        !          29626: 
        !          29627:        /*
        !          29628:         * Initialize Drive Size.
        !          29629:         */
        !          29630:        for ( u = 0, dp = &atparm[0]; u < NDRIVE; ++dp, ++u ) {
        !          29631: 
        !          29632:                if ( at.at_dtype[u] == 0 )
        !          29633:                        continue;
        !          29634: 
        !          29635:                pparm[NDRIVE*NPARTN + u].p_size =
        !          29636:                        (long) dp->d_ncyl * dp->d_nhead * dp->d_nspt;
        !          29637:        }
        !          29638: 
        !          29639:        /*
        !          29640:         * Initialize Drive Controller.
        !          29641:         */
        !          29642:        atreset();
        !          29643: 
        !          29644:        setivec( HDIRQ, atintr );
        !          29645: 
        !          29646: #if ATCACHE > 0
        !          29647:        at.at_cdrv[0] = -1;
        !          29648:        at.at_cbuf[0] = kalloc( BSIZE );
        !          29649: #endif
        !          29650: 
        !          29651: #if ATCACHE > 1
        !          29652:        at.at_cdrv[1] = -1;
        !          29653:        at.at_cbuf[1] = kalloc( BSIZE );
        !          29654: #endif
        !          29655: 
        !          29656:        at.at_bad_drv = -1;
        !          29657: }
        !          29658: 
        !          29659: /**
        !          29660:  *
        !          29661:  * void
        !          29662:  * atunload()  - unload routine.
        !          29663:  */
        !          29664: static void
        !          29665: atunload()
        !          29666: {
        !          29667:        clrivec( HDIRQ );
        !          29668: }
        !          29669: 
        !          29670: /**
        !          29671:  *
        !          29672:  * void
        !          29673:  * atreset()   -- reset hard disk controller, define drive characteristics.
        !          29674:  */
        !          29675: static void
        !          29676: atreset()
        !          29677: {
        !          29678:        register int u;
        !          29679:        register struct dparm_s * dp;
        !          29680: 
        !          29681:        /*
        !          29682:         * Reset controller for a minimum of 4.8 microseconds.
        !          29683:         */
        !          29684:        outb( HF_REG, 4 );
        !          29685:        for ( u = 100; --u != 0; )
        !          29686:                ;
        !          29687:        outb( HF_REG, atparm[0].d_ctrl & 0x0F );
        !          29688:        myatbsyw(0);
        !          29689:        if ( inb(AUX_REG) != 0x01 )
        !          29690:                printf("at: AT disk controller not present (reset)\n");
        !          29691: 
        !          29692:        /*
        !          29693:         * Initialize drive parameters.
        !          29694:         */
        !          29695:        for ( u = 0, dp = &atparm[0]; u < NDRIVE; ++dp, ++u ) {
        !          29696: 
        !          29697:                if ( at.at_dtype[u] == 0 )
        !          29698:                        continue;
        !          29699: 
        !          29700:                myatbsyw(u);
        !          29701: 
        !          29702:                /*
        !          29703:                 * Set drive characteristics.
        !          29704:                 * 0x1F1 - AUX_REG
        !          29705:                 * 0x1F2 - NSEC_REG
        !          29706:                 * 0x1F3 - SEC_REG
        !          29707:                 * 0x1F4 - LCYL_REG
        !          29708:                 * 0x1F5 - HCYL_REG
        !          29709:                 * 0x1F6 - HDRV_REG
        !          29710:                 * 0x1F7 - CSR_REG
        !          29711:                 */
        !          29712:                outb( HF_REG,   dp->d_ctrl );
        !          29713:                outb( AUX_REG,  dp->d_wpcc / 4 );
        !          29714:                outb( NSEC_REG, dp->d_nspt );
        !          29715:                outb( SEC_REG, 0x01 );
        !          29716:                outb( LCYL_REG, (char)(dp->d_ncyl) );
        !          29717:                outb( HCYL_REG, (char)(dp->d_ncyl >> 8) );
        !          29718:                outb( HDRV_REG, 0xA0 + (u<<4) + dp->d_nhead - 1 );
        !          29719:                outb( CSR_REG,  SETPARM_CMD );
        !          29720:                myatbsyw(u);
        !          29721: 
        !          29722:                /*
        !          29723:                 * Restore heads.
        !          29724:                 */
        !          29725:                outb( CSR_REG, RESTORE(0) );
        !          29726:                myatbsyw(u);
        !          29727:        }
        !          29728: }
        !          29729: 
        !          29730: /**
        !          29731:  *
        !          29732:  * void
        !          29733:  * atopen( dev, mode )
        !          29734:  * dev_t dev;
        !          29735:  * int mode;
        !          29736:  *
        !          29737:  *     Input:  dev = disk device to be opened.
        !          29738:  *             mode = access mode [IPR,IPW, IPR+IPW].
        !          29739:  *
        !          29740:  *     Action: Validate the minor device.
        !          29741:  *             Update the paritition table if necessary.
        !          29742:  */
        !          29743: static void
        !          29744: atopen( dev, mode )
        !          29745: register dev_t dev;
        !          29746: {
        !          29747:        register int d;         /* drive */
        !          29748:        register int p;         /* partition */
        !          29749: 
        !          29750:        p = minor(dev) % (NDRIVE*NPARTN);
        !          29751: 
        !          29752:        if ( minor(dev) & SDEV ) {
        !          29753:                d = minor(dev) % NDRIVE;
        !          29754:                p += NDRIVE * NPARTN;
        !          29755:        }
        !          29756:        else
        !          29757:                d = minor(dev) / NPARTN;
        !          29758: 
        !          29759:        if ( (d >= NDRIVE) || (at.at_dtype[d] == 0) ) {
        !          29760:                u.u_error = ENXIO;
        !          29761:                return;
        !          29762:        }
        !          29763: 
        !          29764:        if ( minor(dev) & SDEV )
        !          29765:                return;
        !          29766: 
        !          29767:        /*
        !          29768:         * If partition not defined read partition characteristics.
        !          29769:         */
        !          29770:        if ( pparm[p].p_size == 0 )
        !          29771:                fdisk( makedev( major(dev), SDEV + d), &pparm[ d * NPARTN ] );
        !          29772: 
        !          29773:        /*
        !          29774:         * Ensure partition lies within drive boundaries and is non-zero size.
        !          29775:         */
        !          29776:        if ((pparm[p].p_base+pparm[p].p_size) > pparm[d+NDRIVE*NPARTN].p_size)
        !          29777:                u.u_error = EBADFMT;
        !          29778:        else if ( pparm[p].p_size == 0 )
        !          29779:                u.u_error = ENODEV;
        !          29780: }
        !          29781: 
        !          29782: /**
        !          29783:  *
        !          29784:  * void
        !          29785:  * atread( dev, iop )  - write a block to the raw disk
        !          29786:  * dev_t dev;
        !          29787:  * IO * iop;
        !          29788:  *
        !          29789:  *     Input:  dev = disk device to be written to.
        !          29790:  *             iop = pointer to source I/O structure.
        !          29791:  *
        !          29792:  *     Action: Invoke the common raw I/O processing code.
        !          29793:  */
        !          29794: static void
        !          29795: atread( dev, iop )
        !          29796: dev_t  dev;
        !          29797: IO     *iop;
        !          29798: {
        !          29799:        ioreq( &dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC );
        !          29800: }
        !          29801: 
        !          29802: /**
        !          29803:  *
        !          29804:  * void
        !          29805:  * atwrite( dev, iop ) - write a block to the raw disk
        !          29806:  * dev_t dev;
        !          29807:  * IO * iop;
        !          29808:  *
        !          29809:  *     Input:  dev = disk device to be written to.
        !          29810:  *             iop = pointer to source I/O structure.
        !          29811:  *
        !          29812:  *     Action: Invoke the common raw I/O processing code.
        !          29813:  */
        !          29814: static void
        !          29815: atwrite( dev, iop )
        !          29816: dev_t  dev;
        !          29817: IO     *iop;
        !          29818: {
        !          29819:        ioreq( &dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC );
        !          29820: }
        !          29821: 
        !          29822: /**
        !          29823:  *
        !          29824:  * int
        !          29825:  * atioctl( dev, cmd, arg )
        !          29826:  * dev_t dev;
        !          29827:  * int cmd;
        !          29828:  * char * vec;
        !          29829:  *
        !          29830:  *     Input:  dev = disk device to be operated on.
        !          29831:  *             cmd = input/output request to be performed.
        !          29832:  *             vec = (pointer to) optional argument.
        !          29833:  *
        !          29834:  *     Action: Validate the minor device.
        !          29835:  *             Update the paritition table if necessary.
        !          29836:  */
        !          29837: static int
        !          29838: atioctl( dev, cmd, vec )
        !          29839: register dev_t dev;
        !          29840: int cmd;
        !          29841: char * vec;
        !          29842: {
        !          29843:        int d;
        !          29844: 
        !          29845:        /*
        !          29846:         * Identify drive number.
        !          29847:         */
        !          29848:        if ( minor(dev) & SDEV )
        !          29849:                d = minor(dev) % NDRIVE;
        !          29850:        else
        !          29851:                d = minor(dev) / NPARTN;
        !          29852: 
        !          29853:        /*
        !          29854:         * Identify input/output request.
        !          29855:         */
        !          29856:        switch ( cmd ) {
        !          29857: 
        !          29858:        case HDGETA:
        !          29859:                /*
        !          29860:                 * Get hard disk attributes.
        !          29861:                 */
        !          29862:                kucopy( &atparm[d], vec, sizeof(atparm[0]) );
        !          29863:                return( 0 );
        !          29864: 
        !          29865:        case HDSETA:
        !          29866:                /* Set hard disk attributes. */
        !          29867:                ukcopy(vec, &atparm[d], sizeof(atparm[0]));
        !          29868:                at.at_dtype[d] = 1;             /* set drive type nonzero */
        !          29869:                pparm[NDRIVE * NPARTN + d].p_size =
        !          29870:                        (long) atparm[d].d_ncyl * atparm[d].d_nhead * atparm[d].d_nspt;
        !          29871:                atreset();
        !          29872:                return 0;
        !          29873: 
        !          29874:        default:
        !          29875:                u.u_error = EINVAL;
        !          29876:                return( -1 );
        !          29877:        }
        !          29878: }
        !          29879: 
        !          29880: /**
        !          29881:  *
        !          29882:  * void
        !          29883:  * atwatch()           - guard against lost interrupt
        !          29884:  *
        !          29885:  *     Action: If drvl[HDMAJOR] is greater than zero, decrement it.
        !          29886:  *             If it decrements to zero, simulate a hardware interrupt.
        !          29887:  */
        !          29888: static void
        !          29889: atwatch()
        !          29890: {
        !          29891:        register BUF * bp = at.at_actf;
        !          29892:        register int s;
        !          29893: 
        !          29894:        s = sphi();
        !          29895:        if ( --drvl[HDMAJOR].d_time > 0 ) {
        !          29896:                spl(s);
        !          29897:                return;
        !          29898:        }
        !          29899:        printf("at%d%c: bno=%U head=%u cyl=%u <Watchdog Timeout>\n",
        !          29900:                at.at_drv,
        !          29901:                (bp->b_dev & SDEV) ? 'x' : at.at_partn % NPARTN + 'a',
        !          29902:                bp->b_bno, at.at_head, at.at_cyl );
        !          29903: 
        !          29904:        /*
        !          29905:         * Reset hard disk controller.
        !          29906:         *
        !          29907:         * Mark current cylinder as bad so atstart() will fail.
        !          29908:         * Otherwise would lock up if this track NEVER gives enough IRQ's.
        !          29909:         */
        !          29910:        at.at_bad_drv   = at.at_drv;
        !          29911:        at.at_bad_head  = at.at_head;
        !          29912:        at.at_bad_cyl   = at.at_cyl;
        !          29913:        atreset();
        !          29914:        atstart();
        !          29915:        spl(s);
        !          29916: }
        !          29917: 
        !          29918: /**
        !          29919:  *
        !          29920:  * void
        !          29921:  * atblock( bp )       - queue a block to the disk
        !          29922:  *
        !          29923:  *     Input:  bp = pointer to block to be queued.
        !          29924:  *
        !          29925:  *     Action: Queue a block to the disk.
        !          29926:  *             Make sure that the transfer is within the disk partition.
        !          29927:  */
        !          29928: static void
        !          29929: atblock(bp)
        !          29930: register BUF   *bp;
        !          29931: {
        !          29932:        register struct fdisk_s *pp;
        !          29933:        int partn = minor(bp->b_dev) % (NDRIVE*NPARTN);
        !          29934: 
        !          29935:        bp->b_resid = bp->b_count;
        !          29936: 
        !          29937:        if ( minor(bp->b_dev) & SDEV )
        !          29938:                partn += NDRIVE * NPARTN;
        !          29939: 
        !          29940:        pp = &pparm[ partn ];
        !          29941: 
        !          29942:        /*
        !          29943:         * Check for read at end of partition.
        !          29944:         */
        !          29945:        if ( (bp->b_req == BREAD) && (bp->b_bno == pp->p_size) ) {
        !          29946:                bdone(bp);
        !          29947:                return;
        !          29948:        }
        !          29949: 
        !          29950:        /*
        !          29951:         * Range check disk region.
        !          29952:         */
        !          29953:        if ( ((bp->b_bno + (bp->b_count/BSIZE)) > pp->p_size)
        !          29954:        || (bp->b_count % BSIZE) || bp->b_count == 0) {
        !          29955:                bp->b_flag |= BFERR;
        !          29956:                bdone(bp);
        !          29957:                return;
        !          29958:        }
        !          29959: 
        !          29960:        bp->b_actf = NULL;
        !          29961:        if (at.at_actf == NULL)
        !          29962:                at.at_actf = bp;
        !          29963:        else
        !          29964:                at.at_actl->b_actf = bp;
        !          29965:        at.at_actl = bp;
        !          29966: 
        !          29967:        if ( at.at_state == SIDLE )
        !          29968:                if ( atdequeue() )
        !          29969:                        atstart();
        !          29970: }
        !          29971: 
        !          29972: /**
        !          29973:  *
        !          29974:  * int
        !          29975:  * atdequeue()         - obtain next disk read/write operation
        !          29976:  *
        !          29977:  *     Action: Pull some work from the disk queue.
        !          29978:  *
        !          29979:  *     Return: 0 = no work.
        !          29980:  *             * = work to do.
        !          29981:  */
        !          29982: static int
        !          29983: atdequeue()
        !          29984: {
        !          29985:        register BUF * bp;
        !          29986:        register struct fdisk_s * pp;
        !          29987:        unsigned int nspt;
        !          29988: 
        !          29989:        for (;;) {
        !          29990:                at.at_caching = 0;
        !          29991:                at.at_tries   = 0;
        !          29992: 
        !          29993:                if ( (bp = at.at_actf) == NULL )
        !          29994:                        return (0);
        !          29995: 
        !          29996:                at.at_partn = minor( bp->b_dev ) % (NDRIVE*NPARTN);
        !          29997: 
        !          29998:                if ( minor(bp->b_dev) & SDEV ) {
        !          29999:                        at.at_partn += (NDRIVE*NPARTN);
        !          30000:                        at.at_drv  = minor( bp->b_dev ) % NDRIVE;
        !          30001:                }
        !          30002:                else
        !          30003:                        at.at_drv = minor( bp->b_dev ) / NPARTN;
        !          30004:                nspt = atparm[at.at_drv].d_nspt;
        !          30005: 
        !          30006:                pp = &pparm[ at.at_partn ];
        !          30007:                at.at_bno   = pp->p_base + bp->b_bno;
        !          30008:                at.at_nsec  = bp->b_count / BSIZE;
        !          30009:                at.at_faddr = bp->b_faddr;
        !          30010: 
        !          30011: #if ATCACHE > 0
        !          30012:                if ( bp->b_req == BWRITE ) {
        !          30013: 
        !          30014:                        /*
        !          30015:                         * Invalidate cache if write might overlap.
        !          30016:                         */
        !          30017:                        if ( at.at_nsec > 1 ) {
        !          30018:                                at.at_cdrv[0] = -1;
        !          30019: #if ATCACHE > 1
        !          30020:                                at.at_cdrv[1] = -1;
        !          30021: #endif
        !          30022:                        }
        !          30023:                        else if ( at.at_bno == at.at_cbno[0] )
        !          30024:                                at.at_cdrv[0] = -1;
        !          30025: #if ATCACHE > 1
        !          30026:                        else if ( at.at_bno == at.at_cbno[1] )
        !          30027:                                at.at_cdrv[1] = -1;
        !          30028: #endif
        !          30029:                }
        !          30030:                else if ( at.at_nsec == 1 ) {
        !          30031: 
        !          30032:                        /*
        !          30033:                         * Test for cache hit on block 0.
        !          30034:                         */
        !          30035:                        if ( (at.at_drv == at.at_cdrv[0])
        !          30036:                        &&   (at.at_bno == at.at_cbno[0]) ) {
        !          30037: 
        !          30038:                                kpcopy( at.at_cbuf[0],
        !          30039:                                        bp->b_paddr, BSIZE );
        !          30040:                                at.at_actf  = bp->b_actf;
        !          30041:                                bp->b_resid = 0;
        !          30042:                                bdone(bp);
        !          30043:                                continue;
        !          30044:                        }
        !          30045: 
        !          30046: #if ATCACHE > 1
        !          30047:                        /*
        !          30048:                         * Test for cache hit on block 1.
        !          30049:                         */
        !          30050:                        if ( (at.at_drv == at.at_cdrv[1])
        !          30051:                        &&   (at.at_bno == at.at_cbno[1]) ) {
        !          30052: 
        !          30053:                                kpcopy( at.at_cbuf[1],
        !          30054:                                        bp->b_paddr, BSIZE );
        !          30055:                                at.at_actf  = bp->b_actf;
        !          30056:                                bp->b_resid = 0;
        !          30057:                                bdone(bp);
        !          30058:                                continue;
        !          30059:                        }
        !          30060: #endif
        !          30061: 
        !          30062:                        /*
        !          30063:                         * Enable caching if no backlog for disk i/o.
        !          30064:                         */
        !          30065:                        if ( bp->b_actf == NULL ) {
        !          30066:                                /*
        !          30067:                                 * Enable caching on single block reads
        !          30068:                                 * when at least one block left on same track.
        !          30069:                                 */
        !          30070:                                at.at_caching = nspt - 1 - (at.at_bno % nspt);
        !          30071: #if ATCACHE > 1
        !          30072:                                if ( at.at_caching >= 2 ) {
        !          30073:                                        at.at_caching   = 2;
        !          30074:                                        at.at_cdrv[2-1] = -1;
        !          30075:                                }
        !          30076: #endif
        !          30077: 
        !          30078:                                if ( at.at_caching ) {
        !          30079:                                        at.at_nsec  += at.at_caching;
        !          30080:                                        at.at_cdrv[1-1] = -1;
        !          30081:                                }
        !          30082:                        }
        !          30083:                }
        !          30084: #endif
        !          30085: 
        !          30086:                return (1);
        !          30087:        }
        !          30088: }
        !          30089: 
        !          30090: /**
        !          30091:  *
        !          30092:  * void
        !          30093:  * atstart()   - start or restart next disk read/write operation.
        !          30094:  *
        !          30095:  *     Action: Initiate disk read/write operation.
        !          30096:  */
        !          30097: static void
        !          30098: atstart()
        !          30099: {
        !          30100:        register struct dparm_s *dp;
        !          30101: 
        !          30102:        dp = &atparm[ at.at_drv ];
        !          30103: 
        !          30104:        at.at_cyl  = (at.at_bno / dp->d_nspt) / dp->d_nhead;
        !          30105:        at.at_head = (at.at_bno / dp->d_nspt) % dp->d_nhead;
        !          30106:        at.at_sec  = (at.at_bno % dp->d_nspt) + 1;
        !          30107: 
        !          30108:        /*
        !          30109:         * Check for repeated access to most recently identified bad track.
        !          30110:         */
        !          30111:        if ( (at.at_drv  == at.at_bad_drv )
        !          30112:          && (at.at_cyl  == at.at_bad_cyl )
        !          30113:          && (at.at_head == at.at_bad_head) ) {
        !          30114:                BUF * bp = at.at_actf;
        !          30115:                printf( "at%d%c: bno=%U head=%u cyl=%u <Track Flagged Bad>\n",
        !          30116:                        at.at_drv,
        !          30117:                        (bp->b_dev & SDEV) ? 'x' : at.at_partn % NPARTN + 'a',
        !          30118:                        bp->b_bno,
        !          30119:                        at.at_head,
        !          30120:                        at.at_cyl );
        !          30121:                bp->b_flag |= BFERR;
        !          30122:                atdone(bp);
        !          30123:                return;
        !          30124:        }
        !          30125: 
        !          30126:        myatbsyw(at.at_drv);
        !          30127: 
        !          30128:        outb( HF_REG,   dp->d_ctrl );
        !          30129:        outb( AUX_REG,  dp->d_wpcc / 4 );
        !          30130:        outb( NSEC_REG, at.at_nsec );
        !          30131:        outb( SEC_REG,  at.at_sec );
        !          30132:        outb( LCYL_REG, at.at_cyl );
        !          30133:        outb( HCYL_REG, at.at_cyl >> 8 );
        !          30134:        outb( HDRV_REG, (at.at_drv << 4) + at.at_head + 0xA0 );
        !          30135: 
        !          30136:        if ( at.at_actf->b_req == BWRITE ) {
        !          30137: 
        !          30138:                outb( CSR_REG, WRITE_CMD );
        !          30139: 
        !          30140:                while ( atdrqw() == 0 )
        !          30141:                        printf( timeout_msg, at.at_drv );
        !          30142: 
        !          30143:                atsend( at.at_faddr );
        !          30144:                at.at_state = SWRITE;
        !          30145:        }
        !          30146:        else {
        !          30147:                outb( CSR_REG, READ_CMD );
        !          30148:                at.at_state = SREAD;
        !          30149:        }
        !          30150:        drvl[HDMAJOR].d_time = 2;
        !          30151: }
        !          30152: 
        !          30153: /**
        !          30154:  *
        !          30155:  * void
        !          30156:  * atintr()    - Interrupt routine.
        !          30157:  *
        !          30158:  */
        !          30159: static void
        !          30160: atintr()
        !          30161: {
        !          30162:        defer( atdefer, 0 );
        !          30163: }
        !          30164: 
        !          30165: /**
        !          30166:  *
        !          30167:  * void
        !          30168:  * atdefer()   - Deferred service of hard disk interrupt.
        !          30169:  *
        !          30170:  *     Action: Service disk interrupt.
        !          30171:  *             Transfer required data.
        !          30172:  *             Update state.
        !          30173:  */
        !          30174: static void
        !          30175: atdefer()
        !          30176: {
        !          30177:        register BUF * bp = at.at_actf;
        !          30178: 
        !          30179:        switch ( at.at_state ) {
        !          30180: 
        !          30181:        case SRETRY:
        !          30182:                atstart();
        !          30183:                break;
        !          30184: 
        !          30185:        case SREAD:
        !          30186:                /*
        !          30187:                 * Check for I/O error before waiting for data.
        !          30188:                 */
        !          30189:                if ( aterror() ) {
        !          30190:                        atrecov();
        !          30191:                        break;
        !          30192:                }
        !          30193: 
        !          30194:                /*
        !          30195:                 * Wait for data, or forever.
        !          30196:                 */
        !          30197:                if ( atdrqw() == 0 )
        !          30198:                        printf( timeout_msg, at.at_drv );
        !          30199: 
        !          30200: #if ATCACHE > 0
        !          30201:                /*
        !          30202:                 * Cache data block.
        !          30203:                 */
        !          30204:                if ( at.at_caching == at.at_nsec )
        !          30205:                        atrecv( at.at_cbuf[ at.at_nsec - 1 ], sds );
        !          30206:                else
        !          30207: #endif
        !          30208: 
        !          30209:                /*
        !          30210:                 * Read data block.
        !          30211:                 */
        !          30212:                        atrecv( at.at_faddr );
        !          30213: 
        !          30214:                /*
        !          30215:                 * Check for I/O error after reading data.
        !          30216:                 */
        !          30217:                if ( aterror() ) {
        !          30218:                        atrecov();
        !          30219:                        break;
        !          30220:                }
        !          30221: 
        !          30222: #if ATCACHE > 0
        !          30223:                /*
        !          30224:                 * Validate cached blocks.
        !          30225:                 */
        !          30226:                if ( at.at_caching == at.at_nsec ) {
        !          30227:                        at.at_cbno[ at.at_nsec - 1 ] = at.at_bno;
        !          30228:                        at.at_cdrv[ at.at_nsec - 1 ] = at.at_drv;
        !          30229:                        at.at_caching--;
        !          30230:                }
        !          30231:                else
        !          30232: #endif
        !          30233:                {
        !          30234:                        FP_OFF(at.at_faddr) += BSIZE;
        !          30235:                        bp->b_resid -= BSIZE;
        !          30236:                }
        !          30237: 
        !          30238:                at.at_tries = 0;
        !          30239:                at.at_bno++;
        !          30240: 
        !          30241:                /*
        !          30242:                 * Check for end of transfer.
        !          30243:                 */
        !          30244:                if ( --at.at_nsec == 0 )
        !          30245:                        atdone( bp );
        !          30246:                break;
        !          30247: 
        !          30248:        case SWRITE:
        !          30249:                /*
        !          30250:                 * Check for I/O error.
        !          30251:                 */
        !          30252:                if ( aterror() ) {
        !          30253:                        atrecov();
        !          30254:                        break;
        !          30255:                }
        !          30256: 
        !          30257:                FP_OFF(at.at_faddr) += BSIZE;
        !          30258:                bp->b_resid -= BSIZE;
        !          30259:                at.at_tries  = 0;
        !          30260:                at.at_bno++;
        !          30261: 
        !          30262:                /*
        !          30263:                 * Check for end of transfer.
        !          30264:                 */
        !          30265:                if ( --at.at_nsec == 0 ) {
        !          30266:                        atdone( bp );
        !          30267:                        break;
        !          30268:                }
        !          30269: 
        !          30270:                /*
        !          30271:                 * Wait for ability to send data, or forever.
        !          30272:                 */
        !          30273:                while ( atdrqw() == 0 )
        !          30274:                        printf( timeout_msg, at.at_drv );
        !          30275: 
        !          30276:                /*
        !          30277:                 * Send data block.
        !          30278:                 */
        !          30279:                atsend( at.at_faddr );
        !          30280:        }
        !          30281: }
        !          30282: 
        !          30283: /**
        !          30284:  *
        !          30285:  * int
        !          30286:  * aterror()
        !          30287:  *
        !          30288:  *     Action: Check for drive error.
        !          30289:  *             If found, increment error count and report it.
        !          30290:  *
        !          30291:  *     Return: 0 = No error found.
        !          30292:  *             1 = Error occurred.
        !          30293:  */
        !          30294: static int
        !          30295: aterror()
        !          30296: {
        !          30297:        register BUF * bp = at.at_actf;
        !          30298:        register int csr;
        !          30299:        register int aux;
        !          30300: 
        !          30301:        if ( (csr = inb(CSR_REG)) & (ERR_ST|WFLT_ST) ) {
        !          30302: 
        !          30303:                aux = inb(AUX_REG);
        !          30304: 
        !          30305:                /*
        !          30306:                 * Don't retry or report failures on cache reads.
        !          30307:                 */
        !          30308: #if ATCACHE > 0
        !          30309:                if ((at.at_state == SREAD) && (at.at_caching == at.at_nsec)) {
        !          30310:                        at.at_tries = BADLIM;
        !          30311:                        return 1;
        !          30312:                }
        !          30313: #endif
        !          30314: 
        !          30315:                if ( aux & BAD_ERR ) {
        !          30316:                        at.at_tries     = BADLIM;
        !          30317:                        at.at_bad_drv   = at.at_drv;
        !          30318:                        at.at_bad_head  = at.at_head;
        !          30319:                        at.at_bad_cyl   = at.at_cyl;
        !          30320:                }
        !          30321:                else if ( ++at.at_tries < SOFTLIM )
        !          30322:                        return 1;
        !          30323: 
        !          30324:                printf( "at%d%c: bno=%U head=%u cyl=%u",
        !          30325:                        at.at_drv,
        !          30326:                        (bp->b_dev & SDEV) ? 'x' : at.at_partn % NPARTN + 'a',
        !          30327:                        (bp->b_count/BSIZE) + bp->b_bno
        !          30328:                                + at.at_caching - at.at_nsec,
        !          30329:                        at.at_head, at.at_cyl );
        !          30330: 
        !          30331: #if VERBOSE > 0
        !          30332:                if ( (csr & RDY_ST) == 0 )
        !          30333:                        printf(" <Drive Not Ready>");
        !          30334:                if ( csr & WFLT_ST )
        !          30335:                        printf(" <Write Fault>");
        !          30336: 
        !          30337:                if ( aux & DAM_ERR )
        !          30338:                        printf(" <No Data Addr Mark>");
        !          30339:                if ( aux & TR0_ERR )
        !          30340:                        printf(" <Track 0 Not Found>" );
        !          30341:                if ( aux & ID_ERR )
        !          30342:                        printf(" <ID Not Found>" );
        !          30343:                if ( aux & ECC_ERR )
        !          30344:                        printf(" <Bad Data Checksum>" );
        !          30345:                if ( aux & ABT_ERR )
        !          30346:                        printf(" <Command Aborted>" );
        !          30347: #else
        !          30348:                if ( (csr & (RDY_ST|WFLT_ST)) != RDY_ST )
        !          30349:                        printf( " csr=%x", csr );
        !          30350:                if ( aux & (DAM_ERR|TR0_ERR|ID_ERR|ECC_ERR|ABT_ERR) )
        !          30351:                        printf( " aux=%x", aux );
        !          30352: #endif
        !          30353:                if ( aux & BAD_ERR )
        !          30354:                        printf(" <Block Flagged Bad>" );
        !          30355: 
        !          30356:                if ( at.at_tries < HARDLIM )
        !          30357:                        printf(" retrying...");
        !          30358:                printf("\n");
        !          30359:                return 1;
        !          30360:        }
        !          30361:        return 0;
        !          30362: }
        !          30363: 
        !          30364: /**
        !          30365:  *
        !          30366:  * void
        !          30367:  * atrecov()
        !          30368:  *
        !          30369:  *     Action: Attempt recovery.
        !          30370:  */
        !          30371: static void
        !          30372: atrecov()
        !          30373: {
        !          30374:        register BUF *bp = at.at_actf;
        !          30375:        register int cmd = SEEK(0);
        !          30376:        register int cyl = at.at_cyl;
        !          30377: 
        !          30378:        switch ( at.at_tries ) {
        !          30379: 
        !          30380:        case 1:
        !          30381:        case 2:
        !          30382:                /*
        !          30383:                 * Move in 1 cylinder, then retry operation
        !          30384:                 */
        !          30385:                if ( --cyl < 0 )
        !          30386:                        cyl += 2;
        !          30387:                break;
        !          30388: 
        !          30389:        case 3:
        !          30390:        case 4:
        !          30391:                /*
        !          30392:                 * Move out 1 cylinder, then retry operation
        !          30393:                 */
        !          30394:                if ( ++cyl >= atparm[ at.at_drv ].d_ncyl )
        !          30395:                        cyl -= 2;
        !          30396:                break;
        !          30397: 
        !          30398:        case 5:
        !          30399:        case 6:
        !          30400:                /*
        !          30401:                 * Seek to cylinder 0, then retry operation
        !          30402:                 */
        !          30403:                cyl = 0;
        !          30404:                break;
        !          30405: 
        !          30406:        default:
        !          30407:                /*
        !          30408:                 * Restore drive, then retry operation
        !          30409:                 */
        !          30410:                cmd = RESTORE(0);
        !          30411:                cyl = 0;
        !          30412:                break;
        !          30413:        }
        !          30414: 
        !          30415:        /*
        !          30416:         * Retry operation [after repositioning head]
        !          30417:         */
        !          30418:        if ( at.at_tries < HARDLIM ) {
        !          30419:                drvl[HDMAJOR].d_time = (cmd == RESTORE(0)) ? 5 : 2;
        !          30420:                outb( LCYL_REG, cyl );
        !          30421:                outb( HCYL_REG, cyl >> 8 );
        !          30422:                outb( HDRV_REG, (at.at_drv << 4) + 0xA0 );
        !          30423:                outb( CSR_REG, cmd );
        !          30424:                at.at_state = SRETRY;
        !          30425:        }
        !          30426: 
        !          30427:        /*
        !          30428:         * Give up on block.
        !          30429:         */
        !          30430:        else {
        !          30431:                /*
        !          30432:                 * Not a cache-read error.
        !          30433:                 */
        !          30434: #if ATCACHE > 0
        !          30435:                if ( (at.at_state != SREAD) || (at.at_caching != at.at_nsec) )
        !          30436: #endif
        !          30437:                        bp->b_flag |= BFERR;
        !          30438: 
        !          30439:                atdone(bp);
        !          30440:        }
        !          30441: }
        !          30442: 
        !          30443: /**
        !          30444:  *
        !          30445:  * void
        !          30446:  * atdone( bp )
        !          30447:  * BUF * bp;
        !          30448:  *
        !          30449:  *     Action: Release current i/o buffer to the O/S.
        !          30450:  */
        !          30451: static void
        !          30452: atdone( bp )
        !          30453: register BUF * bp;
        !          30454: {
        !          30455:        drvl[HDMAJOR].d_time = 0;
        !          30456:        at.at_state = SIDLE;
        !          30457:        at.at_actf  = bp->b_actf;
        !          30458:        bdone(bp);
        !          30459: 
        !          30460:        if ( atdequeue() )
        !          30461:                atstart();
        !          30462: }
        !          30463: 
        !          30464: int
        !          30465: myatbsyw(unit) int unit;
        !          30466: {
        !          30467:        register int n, status;
        !          30468: 
        !          30469:        for (n = ATBSYW; n > 0; --n)
        !          30470:                if ((status = atbsyw()) != 0)
        !          30471:                        return status;
        !          30472:        printf(timeout_msg, unit);
        !          30473:        return 0;
        !          30474: }
        !          30475: @
        !          30476: 
        !          30477: 
        !          30478: 1.7
        !          30479: log
        !          30480: @update provided by hal
        !          30481: @
        !          30482: text
        !          30483: @d20 1
        !          30484: a20 1
        !          30485: #include       <coherent.h>
        !          30486: @
        !          30487: 
        !          30488: 
        !          30489: 1.6
        !          30490: log
        !          30491: @new version provided y hal for v321
        !          30492: @
        !          30493: text
        !          30494: @d748 396
        !          30495: @
        !          30496: 
        !          30497: 
        !          30498: 1.5
        !          30499: log
        !          30500: @Don't force 8's bit of control byte.
        !          30501: @
        !          30502: text
        !          30503: @d6 4
        !          30504: a9 1
        !          30505:  * $Log:       /usr/src/sys/i8086/drv/RCS/at.c,v $
        !          30506: a747 396
        !          30507:                                        at.at_nsec  += at.at_caching;
        !          30508:                                        at.at_cdrv[1-1] = -1;
        !          30509:                                }
        !          30510:                        }
        !          30511:                }
        !          30512: #endif
        !          30513: 
        !          30514:                return (1);
        !          30515:        }
        !          30516: }
        !          30517: 
        !          30518: /**
        !          30519:  *
        !          30520:  * void
        !          30521:  * atstart()   - start or restart next disk read/write operation.
        !          30522:  *
        !          30523:  *     Action: Initiate disk read/write operation.
        !          30524:  */
        !          30525: static void
        !          30526: atstart()
        !          30527: {
        !          30528:        register struct dparm_s *dp;
        !          30529: 
        !          30530:        dp = &atparm[ at.at_drv ];
        !          30531: 
        !          30532:        at.at_cyl  = (at.at_bno / dp->d_nspt) / dp->d_nhead;
        !          30533:        at.at_head = (at.at_bno / dp->d_nspt) % dp->d_nhead;
        !          30534:        at.at_sec  = (at.at_bno % dp->d_nspt) + 1;
        !          30535: 
        !          30536:        /*
        !          30537:         * Check for repeated access to most recently identified bad track.
        !          30538:         */
        !          30539:        if ( (at.at_drv  == at.at_bad_drv )
        !          30540:          && (at.at_cyl  == at.at_bad_cyl )
        !          30541:          && (at.at_head == at.at_bad_head) ) {
        !          30542:                BUF * bp = at.at_actf;
        !          30543:                printf( "at%d%c: bno=%U head=%u cyl=%u <Track Flagged Bad>\n",
        !          30544:                        at.at_drv,
        !          30545:                        (bp->b_dev & SDEV) ? 'x' : at.at_partn % NPARTN + 'a',
        !          30546:                        bp->b_bno,
        !          30547:                        at.at_head,
        !          30548:                        at.at_cyl );
        !          30549:                bp->b_flag |= BFERR;
        !          30550:                atdone(bp);
        !          30551:                return;
        !          30552:        }
        !          30553: 
        !          30554:        myatbsyw(at.at_drv);
        !          30555: 
        !          30556:        outb( HF_REG,   dp->d_ctrl );
        !          30557:        outb( AUX_REG,  dp->d_wpcc / 4 );
        !          30558:        outb( NSEC_REG, at.at_nsec );
        !          30559:        outb( SEC_REG,  at.at_sec );
        !          30560:        outb( LCYL_REG, at.at_cyl );
        !          30561:        outb( HCYL_REG, at.at_cyl >> 8 );
        !          30562:        outb( HDRV_REG, (at.at_drv << 4) + at.at_head + 0xA0 );
        !          30563: 
        !          30564:        if ( at.at_actf->b_req == BWRITE ) {
        !          30565: 
        !          30566:                outb( CSR_REG, WRITE_CMD );
        !          30567: 
        !          30568:                while ( atdrqw() == 0 )
        !          30569:                        printf( timeout_msg, at.at_drv );
        !          30570: 
        !          30571:                atsend( at.at_faddr );
        !          30572:                at.at_state = SWRITE;
        !          30573:        }
        !          30574:        else {
        !          30575:                outb( CSR_REG, READ_CMD );
        !          30576:                at.at_state = SREAD;
        !          30577:        }
        !          30578:        drvl[HDMAJOR].d_time = 2;
        !          30579: }
        !          30580: 
        !          30581: /**
        !          30582:  *
        !          30583:  * void
        !          30584:  * atintr()    - Interrupt routine.
        !          30585:  *
        !          30586:  */
        !          30587: static void
        !          30588: atintr()
        !          30589: {
        !          30590:        defer( atdefer, 0 );
        !          30591: }
        !          30592: 
        !          30593: /**
        !          30594:  *
        !          30595:  * void
        !          30596:  * atdefer()   - Deferred service of hard disk interrupt.
        !          30597:  *
        !          30598:  *     Action: Service disk interrupt.
        !          30599:  *             Transfer required data.
        !          30600:  *             Update state.
        !          30601:  */
        !          30602: static void
        !          30603: atdefer()
        !          30604: {
        !          30605:        register BUF * bp = at.at_actf;
        !          30606: 
        !          30607:        switch ( at.at_state ) {
        !          30608: 
        !          30609:        case SRETRY:
        !          30610:                atstart();
        !          30611:                break;
        !          30612: 
        !          30613:        case SREAD:
        !          30614:                /*
        !          30615:                 * Check for I/O error before waiting for data.
        !          30616:                 */
        !          30617:                if ( aterror() ) {
        !          30618:                        atrecov();
        !          30619:                        break;
        !          30620:                }
        !          30621: 
        !          30622:                /*
        !          30623:                 * Wait for data, or forever.
        !          30624:                 */
        !          30625:                if ( atdrqw() == 0 )
        !          30626:                        printf( timeout_msg, at.at_drv );
        !          30627: 
        !          30628: #if ATCACHE > 0
        !          30629:                /*
        !          30630:                 * Cache data block.
        !          30631:                 */
        !          30632:                if ( at.at_caching == at.at_nsec )
        !          30633:                        atrecv( at.at_cbuf[ at.at_nsec - 1 ], sds );
        !          30634:                else
        !          30635: #endif
        !          30636: 
        !          30637:                /*
        !          30638:                 * Read data block.
        !          30639:                 */
        !          30640:                        atrecv( at.at_faddr );
        !          30641: 
        !          30642:                /*
        !          30643:                 * Check for I/O error after reading data.
        !          30644:                 */
        !          30645:                if ( aterror() ) {
        !          30646:                        atrecov();
        !          30647:                        break;
        !          30648:                }
        !          30649: 
        !          30650: #if ATCACHE > 0
        !          30651:                /*
        !          30652:                 * Validate cached blocks.
        !          30653:                 */
        !          30654:                if ( at.at_caching == at.at_nsec ) {
        !          30655:                        at.at_cbno[ at.at_nsec - 1 ] = at.at_bno;
        !          30656:                        at.at_cdrv[ at.at_nsec - 1 ] = at.at_drv;
        !          30657:                        at.at_caching--;
        !          30658:                }
        !          30659:                else
        !          30660: #endif
        !          30661:                {
        !          30662:                        FP_OFF(at.at_faddr) += BSIZE;
        !          30663:                        bp->b_resid -= BSIZE;
        !          30664:                }
        !          30665: 
        !          30666:                at.at_tries = 0;
        !          30667:                at.at_bno++;
        !          30668: 
        !          30669:                /*
        !          30670:                 * Check for end of transfer.
        !          30671:                 */
        !          30672:                if ( --at.at_nsec == 0 )
        !          30673:                        atdone( bp );
        !          30674:                break;
        !          30675: 
        !          30676:        case SWRITE:
        !          30677:                /*
        !          30678:                 * Check for I/O error.
        !          30679:                 */
        !          30680:                if ( aterror() ) {
        !          30681:                        atrecov();
        !          30682:                        break;
        !          30683:                }
        !          30684: 
        !          30685:                FP_OFF(at.at_faddr) += BSIZE;
        !          30686:                bp->b_resid -= BSIZE;
        !          30687:                at.at_tries  = 0;
        !          30688:                at.at_bno++;
        !          30689: 
        !          30690:                /*
        !          30691:                 * Check for end of transfer.
        !          30692:                 */
        !          30693:                if ( --at.at_nsec == 0 ) {
        !          30694:                        atdone( bp );
        !          30695:                        break;
        !          30696:                }
        !          30697: 
        !          30698:                /*
        !          30699:                 * Wait for ability to send data, or forever.
        !          30700:                 */
        !          30701:                while ( atdrqw() == 0 )
        !          30702:                        printf( timeout_msg, at.at_drv );
        !          30703: 
        !          30704:                /*
        !          30705:                 * Send data block.
        !          30706:                 */
        !          30707:                atsend( at.at_faddr );
        !          30708:        }
        !          30709: }
        !          30710: 
        !          30711: /**
        !          30712:  *
        !          30713:  * int
        !          30714:  * aterror()
        !          30715:  *
        !          30716:  *     Action: Check for drive error.
        !          30717:  *             If found, increment error count and report it.
        !          30718:  *
        !          30719:  *     Return: 0 = No error found.
        !          30720:  *             1 = Error occurred.
        !          30721:  */
        !          30722: static int
        !          30723: aterror()
        !          30724: {
        !          30725:        register BUF * bp = at.at_actf;
        !          30726:        register int csr;
        !          30727:        register int aux;
        !          30728: 
        !          30729:        if ( (csr = inb(CSR_REG)) & (ERR_ST|WFLT_ST) ) {
        !          30730: 
        !          30731:                aux = inb(AUX_REG);
        !          30732: 
        !          30733:                /*
        !          30734:                 * Don't retry or report failures on cache reads.
        !          30735:                 */
        !          30736: #if ATCACHE > 0
        !          30737:                if ((at.at_state == SREAD) && (at.at_caching == at.at_nsec)) {
        !          30738:                        at.at_tries = BADLIM;
        !          30739:                        return 1;
        !          30740:                }
        !          30741: #endif
        !          30742: 
        !          30743:                if ( aux & BAD_ERR ) {
        !          30744:                        at.at_tries     = BADLIM;
        !          30745:                        at.at_bad_drv   = at.at_drv;
        !          30746:                        at.at_bad_head  = at.at_head;
        !          30747:                        at.at_bad_cyl   = at.at_cyl;
        !          30748:                }
        !          30749:                else if ( ++at.at_tries < SOFTLIM )
        !          30750:                        return 1;
        !          30751: 
        !          30752:                printf( "at%d%c: bno=%U head=%u cyl=%u",
        !          30753:                        at.at_drv,
        !          30754:                        (bp->b_dev & SDEV) ? 'x' : at.at_partn % NPARTN + 'a',
        !          30755:                        (bp->b_count/BSIZE) + bp->b_bno
        !          30756:                                + at.at_caching - at.at_nsec,
        !          30757:                        at.at_head, at.at_cyl );
        !          30758: 
        !          30759: #if VERBOSE > 0
        !          30760:                if ( (csr & RDY_ST) == 0 )
        !          30761:                        printf(" <Drive Not Ready>");
        !          30762:                if ( csr & WFLT_ST )
        !          30763:                        printf(" <Write Fault>");
        !          30764: 
        !          30765:                if ( aux & DAM_ERR )
        !          30766:                        printf(" <No Data Addr Mark>");
        !          30767:                if ( aux & TR0_ERR )
        !          30768:                        printf(" <Track 0 Not Found>" );
        !          30769:                if ( aux & ID_ERR )
        !          30770:                        printf(" <ID Not Found>" );
        !          30771:                if ( aux & ECC_ERR )
        !          30772:                        printf(" <Bad Data Checksum>" );
        !          30773:                if ( aux & ABT_ERR )
        !          30774:                        printf(" <Command Aborted>" );
        !          30775: #else
        !          30776:                if ( (csr & (RDY_ST|WFLT_ST)) != RDY_ST )
        !          30777:                        printf( " csr=%x", csr );
        !          30778:                if ( aux & (DAM_ERR|TR0_ERR|ID_ERR|ECC_ERR|ABT_ERR) )
        !          30779:                        printf( " aux=%x", aux );
        !          30780: #endif
        !          30781:                if ( aux & BAD_ERR )
        !          30782:                        printf(" <Block Flagged Bad>" );
        !          30783: 
        !          30784:                if ( at.at_tries < HARDLIM )
        !          30785:                        printf(" retrying...");
        !          30786:                printf("\n");
        !          30787:                return 1;
        !          30788:        }
        !          30789:        return 0;
        !          30790: }
        !          30791: 
        !          30792: /**
        !          30793:  *
        !          30794:  * void
        !          30795:  * atrecov()
        !          30796:  *
        !          30797:  *     Action: Attempt recovery.
        !          30798:  */
        !          30799: static void
        !          30800: atrecov()
        !          30801: {
        !          30802:        register BUF *bp = at.at_actf;
        !          30803:        register int cmd = SEEK(0);
        !          30804:        register int cyl = at.at_cyl;
        !          30805: 
        !          30806:        switch ( at.at_tries ) {
        !          30807: 
        !          30808:        case 1:
        !          30809:        case 2:
        !          30810:                /*
        !          30811:                 * Move in 1 cylinder, then retry operation
        !          30812:                 */
        !          30813:                if ( --cyl < 0 )
        !          30814:                        cyl += 2;
        !          30815:                break;
        !          30816: 
        !          30817:        case 3:
        !          30818:        case 4:
        !          30819:                /*
        !          30820:                 * Move out 1 cylinder, then retry operation
        !          30821:                 */
        !          30822:                if ( ++cyl >= atparm[ at.at_drv ].d_ncyl )
        !          30823:                        cyl -= 2;
        !          30824:                break;
        !          30825: 
        !          30826:        case 5:
        !          30827:        case 6:
        !          30828:                /*
        !          30829:                 * Seek to cylinder 0, then retry operation
        !          30830:                 */
        !          30831:                cyl = 0;
        !          30832:                break;
        !          30833: 
        !          30834:        default:
        !          30835:                /*
        !          30836:                 * Restore drive, then retry operation
        !          30837:                 */
        !          30838:                cmd = RESTORE(0);
        !          30839:                cyl = 0;
        !          30840:                break;
        !          30841:        }
        !          30842: 
        !          30843:        /*
        !          30844:         * Retry operation [after repositioning head]
        !          30845:         */
        !          30846:        if ( at.at_tries < HARDLIM ) {
        !          30847:                drvl[HDMAJOR].d_time = (cmd == RESTORE(0)) ? 5 : 2;
        !          30848:                outb( LCYL_REG, cyl );
        !          30849:                outb( HCYL_REG, cyl >> 8 );
        !          30850:                outb( HDRV_REG, (at.at_drv << 4) + 0xA0 );
        !          30851:                outb( CSR_REG, cmd );
        !          30852:                at.at_state = SRETRY;
        !          30853:        }
        !          30854: 
        !          30855:        /*
        !          30856:         * Give up on block.
        !          30857:         */
        !          30858:        else {
        !          30859:                /*
        !          30860:                 * Not a cache-read error.
        !          30861:                 */
        !          30862: #if ATCACHE > 0
        !          30863:                if ( (at.at_state != SREAD) || (at.at_caching != at.at_nsec) )
        !          30864: #endif
        !          30865:                        bp->b_flag |= BFERR;
        !          30866: 
        !          30867:                atdone(bp);
        !          30868:        }
        !          30869: }
        !          30870: 
        !          30871: /**
        !          30872:  *
        !          30873:  * void
        !          30874:  * atdone( bp )
        !          30875:  * BUF * bp;
        !          30876:  *
        !          30877:  *     Action: Release current i/o buffer to the O/S.
        !          30878:  */
        !          30879: static void
        !          30880: atdone( bp )
        !          30881: register BUF * bp;
        !          30882: {
        !          30883:        drvl[HDMAJOR].d_time = 0;
        !          30884:        at.at_state = SIDLE;
        !          30885:        at.at_actf  = bp->b_actf;
        !          30886:        bdone(bp);
        !          30887: 
        !          30888:        if ( atdequeue() )
        !          30889:                atstart();
        !          30890: }
        !          30891: 
        !          30892: int
        !          30893: myatbsyw(unit) int unit;
        !          30894: {
        !          30895:        register int n, status;
        !          30896: 
        !          30897:        for (n = ATBSYW; n > 0; --n)
        !          30898:                if ((status = atbsyw()) != 0)
        !          30899:                        return status;
        !          30900:        printf(timeout_msg, unit);
        !          30901:        return 0;
        !          30902: }
        !          30903: @
        !          30904: 
        !          30905: 
        !          30906: 1.4
        !          30907: log
        !          30908: @Don't barf if trying to read part of a block in raw device
        !          30909: @
        !          30910: text
        !          30911: @d6 2
        !          30912: a7 1
        !          30913:  * $Log$
        !          30914: d268 1
        !          30915: d271 1
        !          30916: @
        !          30917: 
        !          30918: 
        !          30919: 1.3
        !          30920: log
        !          30921: @General fixes added so we also work with Perstor PS180-16FN HDC
        !          30922: @
        !          30923: text
        !          30924: @d5 3
        !          30925: d616 2
        !          30926: a617 1
        !          30927:        if ( (bp->b_bno + (bp->b_count/BSIZE)) > pp->p_size ) {
        !          30928: @
        !          30929: 
        !          30930: 
        !          30931: 1.2
        !          30932: log
        !          30933: @Shipped with COHERENT driver kit 1.1.0
        !          30934: @
        !          30935: text
        !          30936: @d364 7
        !          30937: d375 3
        !          30938: d380 1
        !          30939: a381 2
        !          30940:                myatbsyw(u);
        !          30941: 
        !          30942: d383 1
        !          30943: a383 1
        !          30944:                 * Seek to cylinder 0, set step rate to 35 microseconds.
        !          30945: d385 1
        !          30946: a385 5
        !          30947:                outb( LCYL_REG, 0 );
        !          30948:                outb( HCYL_REG, 0 );
        !          30949:                outb( HDRV_REG, (u << 4) + 0xA0 );
        !          30950:                outb( CSR_REG, SEEK(0) );
        !          30951: 
        !          30952: d559 1
        !          30953: a559 3
        !          30954: 
        !          30955: #if EBUG > 0
        !          30956:        printf("at%d%c: bno=%U head=%u cyl=%u reset controller\n",
        !          30957: d562 1
        !          30958: a562 3
        !          30959:                bp->b_bno,
        !          30960:                at.at_head, at.at_cyl );
        !          30961: #endif
        !          30962: d566 3
        !          30963: a568 1
        !          30964:         * Retry operation.
        !          30965: d570 3
        !          30966: a979 2
        !          30967: 
        !          30968: #if EBUG == 0
        !          30969: a981 1
        !          30970: #endif
        !          30971: @
        !          30972: 
        !          30973: 
        !          30974: 1.1
        !          30975: log
        !          30976: @Released with COHERENT 3.0.0
        !          30977: @
        !          30978: text
        !          30979: @d1 5
        !          30980: d8 1
        !          30981: a8 1
        !          30982:  * hard disk on the IBM AT machine.
        !          30983: a11 1
        !          30984:  *
        !          30985: d147 1
        !          30986: d195 1
        !          30987: a195 1
        !          30988:        unsigned char   at_dtype[ NDRIVE ];
        !          30989: d252 1
        !          30990: d260 2
        !          30991: d350 1
        !          30992: a350 1
        !          30993:                printf("at: reset failure\n" );
        !          30994: d517 1
        !          30995: a517 1
        !          30996:                kucopy( &atparm[d], vec, sizeof(hdparm_t) );
        !          30997: d520 9
        !          30998: d640 1
        !          30999: d657 1
        !          31000: d723 1
        !          31001: a723 1
        !          31002:                                at.at_caching = 16 - (at.at_bno % 17);
        !          31003: @
        !          31004: 0707070064030104331004440000030000030000011777770507310651300005600000005060/newbits/kernel/USRSRC/i8086/drv/RCS/atas.s,vhead     1.2;
        !          31005: branch   ;
        !          31006: access   ;
        !          31007: symbols  ;
        !          31008: locks    ;
        !          31009: comment  @@;
        !          31010: 
        !          31011: 
        !          31012: 1.2
        !          31013: date     91.05.30.09.19.35;  author hal;  state Exp;
        !          31014: branches ;
        !          31015: next     1.1;
        !          31016: 
        !          31017: 1.1
        !          31018: date     91.05.30.09.17.53;  author hal;  state Exp;
        !          31019: branches ;
        !          31020: next     ;
        !          31021: 
        !          31022: 
        !          31023: desc
        !          31024: @Assembler i/o for "at" driver.
        !          31025: @
        !          31026: 
        !          31027: 
        !          31028: 1.2
        !          31029: log
        !          31030: @Extend loop timers for faster 486's.
        !          31031: @
        !          31032: text
        !          31033: @/ (lgl-
        !          31034: /      COHERENT Driver Kit Version 1.1.0
        !          31035: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          31036: /      All rights reserved. May not be copied without permission.
        !          31037: / -lgl)
        !          31038: ////////
        !          31039: /
        !          31040: / AT Hard Disk Assembler Support
        !          31041: /
        !          31042: / atsend( off, seg ) - send 512 bytes from seg:off into hard disk buffer
        !          31043: / atrecv( off, seg ) - receive 512 bytes from hard disk buffer into seg:off.
        !          31044: / DRQ is not checked.  DRQ must be true before atsend/atrecv are called.
        !          31045: /
        !          31046: / atbsyw()          - wait while controller is busy
        !          31047: / atdrqw()          - wait for controller to request data transfer
        !          31048: /
        !          31049: ////////
        !          31050: 
        !          31051:        .globl  atsend_
        !          31052:        .globl  atrecv_
        !          31053:        .globl  atbsyw_
        !          31054:        .globl  atdrqw_
        !          31055: 
        !          31056:        CSR_REG = 0x01F7
        !          31057:        BSY_ST  = 0x80
        !          31058:        DRQ_ST  = 0x08
        !          31059: 
        !          31060: ////////
        !          31061: /
        !          31062: / void
        !          31063: / atsend( fp ) -- send 512 bytes to AT disk controller.
        !          31064: / faddr_t fp;
        !          31065: /
        !          31066: /      Input:  fp = far pointer [sel:off] to data buffer.
        !          31067: /
        !          31068: /      Action: Transfer 512 bytes to AT disk controller from buffer.
        !          31069: /
        !          31070: ////////
        !          31071: 
        !          31072: atsend_:
        !          31073:        push    si
        !          31074:        push    ds
        !          31075:        push    bp
        !          31076:        mov     bp, sp
        !          31077:        lds     si, 8(bp)
        !          31078:        mov     cx, $256
        !          31079:        mov     dx, $0x1F0
        !          31080:        cld
        !          31081:        rep
        !          31082:        outs
        !          31083:        pop     bp
        !          31084:        pop     ds
        !          31085:        pop     si
        !          31086:        ret
        !          31087: 
        !          31088: ////////
        !          31089: /
        !          31090: / void
        !          31091: / atrecv( fp ) -- receive 512 bytes from AT disk controller.
        !          31092: / faddr_t fp;
        !          31093: /
        !          31094: /      Input:  fp = far pointer [sel:off] to data buffer.
        !          31095: /
        !          31096: /      Action: Transfer 512 bytes from AT disk controller to buffer.
        !          31097: /
        !          31098: ////////
        !          31099: 
        !          31100: atrecv_:
        !          31101:        push    di
        !          31102:        push    es
        !          31103:        push    bp
        !          31104:        mov     bp, sp
        !          31105:        les     di, 8(bp)
        !          31106:        mov     cx, $256
        !          31107:        mov     dx, $0x1F0
        !          31108:        cld
        !          31109:        rep
        !          31110:        ins
        !          31111:        pop     bp
        !          31112:        pop     es
        !          31113:        pop     di
        !          31114:        ret
        !          31115: 
        !          31116: ////////
        !          31117: /
        !          31118: / atbsyw()     -- wait for AT disk controller to become not busy
        !          31119: /
        !          31120: /      Return: 0 = timeout
        !          31121: /              * = not busy
        !          31122: /
        !          31123: ////////
        !          31124: 
        !          31125: atbsyw_:
        !          31126:        mov     dx, $CSR_REG
        !          31127:        mov     bx, $4          / add another layer of iteration for 486's
        !          31128: 0:     mov     cx, $-1
        !          31129: 1:     inb     al, dx
        !          31130:        testb   al, $BSY_ST
        !          31131:        loopne  1b
        !          31132:        je      2f              / not busy - return nonzero value
        !          31133:        dec     bx
        !          31134:        jne     0b
        !          31135: 2:     mov     ax, cx
        !          31136:        ret
        !          31137: 
        !          31138: ////////
        !          31139: /
        !          31140: / atdrqw()     -- wait for AT disk controller to initiate data request
        !          31141: /
        !          31142: /      Return: 0 = timeout
        !          31143: /              * = data requested
        !          31144: /
        !          31145: ////////
        !          31146: 
        !          31147: atdrqw_:
        !          31148:        mov     dx, $CSR_REG
        !          31149:        mov     bx, $4
        !          31150: 0:     mov     cx, $-1
        !          31151: 1:     inb     al, dx
        !          31152:        testb   al, $DRQ_ST
        !          31153:        loope   1b
        !          31154:        jne     2f              / not busy - return nonzero value
        !          31155:        dec     bx
        !          31156:        jne     0b
        !          31157: 2:     mov     ax, cx
        !          31158:        ret
        !          31159: @
        !          31160: 
        !          31161: 
        !          31162: 1.1
        !          31163: log
        !          31164: @Shipped with COH 3.0.0 and 3.1.0.
        !          31165: @
        !          31166: text
        !          31167: @a93 1
        !          31168:        mov     cx, $-1
        !          31169: d95 3
        !          31170: a97 1
        !          31171: 0:     inb     al, dx
        !          31172: d99 5
        !          31173: a103 2
        !          31174:        loopne  0b
        !          31175:        mov     ax, cx
        !          31176: a115 1
        !          31177:        mov     cx, $-1
        !          31178: d117 3
        !          31179: a119 1
        !          31180: 0:     inb     al, dx
        !          31181: d121 5
        !          31182: a125 2
        !          31183:        loope   0b
        !          31184:        mov     ax, cx
        !          31185: @
        !          31186: 0707070064030104341004440000030000030000011777770507310651300005600000007607/newbits/kernel/USRSRC/i8086/drv/RCS/bufq.c,vhead     1.3;
        !          31187: branch   ;
        !          31188: access   ;
        !          31189: symbols  ;
        !          31190: locks    bin:1.3;
        !          31191: comment  @ * @;
        !          31192: 
        !          31193: 
        !          31194: 1.3
        !          31195: date     91.06.20.14.48.32;  author bin;  state Exp;
        !          31196: branches ;
        !          31197: next     1.2;
        !          31198: 
        !          31199: 1.2
        !          31200: date     91.05.21.23.23.36;  author hal;  state Exp;
        !          31201: branches ;
        !          31202: next     1.1;
        !          31203: 
        !          31204: 1.1
        !          31205: date     91.05.21.13.54.11;  author root;  state Exp;
        !          31206: branches ;
        !          31207: next     ;
        !          31208: 
        !          31209: 
        !          31210: desc
        !          31211: @Generic block device queueing.
        !          31212: @
        !          31213: 
        !          31214: 
        !          31215: 1.3
        !          31216: log
        !          31217: @update provided by hal
        !          31218: @
        !          31219: text
        !          31220: @/*
        !          31221:  * File:       bufq.c
        !          31222:  *
        !          31223:  * Purpose:
        !          31224:  *     Queueing routines for SCSI driver.
        !          31225:  *     Should be generalizable for other hard drives.
        !          31226:  *
        !          31227:  * $Log:       bufq.c,v $
        !          31228:  * Revision 1.2  91/05/21  23:23:36  hal
        !          31229:  * Enhanced debug printout.
        !          31230:  * 
        !          31231:  * Revision 1.1  91/05/21  13:54:11  root
        !          31232:  * First running version.
        !          31233:  * 
        !          31234:  */
        !          31235: 
        !          31236: /*
        !          31237:  * Includes.
        !          31238:  */
        !          31239: #include <sys/coherent.h>
        !          31240: #include <sys/buf.h>
        !          31241: 
        !          31242: /*
        !          31243:  * Definitions.
        !          31244:  *     Constants.
        !          31245:  *     Macros with argument lists.
        !          31246:  *     Typedefs.
        !          31247:  *     Enums.
        !          31248:  */
        !          31249: typedef struct {
        !          31250:        BUF     * head; /* point to first node */
        !          31251:        BUF     * tail; /* point to last node */
        !          31252:        int     count;  /* number of nodes in the queue */
        !          31253: } bufq_type;
        !          31254: 
        !          31255: /*
        !          31256:  * Global Data.
        !          31257:  *     Import Variables.
        !          31258:  *     Export Variables.
        !          31259:  *     Local Variables.
        !          31260:  */
        !          31261: static int     num_q;          /* number of queues in use */
        !          31262: static bufq_type  * bufq_q;    /* pointer to allocated queue structs */
        !          31263: 
        !          31264: /*
        !          31265:  * Functions.
        !          31266:  *     Import Functions.
        !          31267:  *     Export Functions.
        !          31268:  *     Local Functions.
        !          31269:  */
        !          31270: int bufq_init();
        !          31271: void bufq_rlse();
        !          31272: void bufq_wr_tail();
        !          31273: BUF * bufq_rd_head();
        !          31274: BUF * bufq_rm_head();
        !          31275: 
        !          31276: /*
        !          31277:  * Debug macros.
        !          31278:  */
        !          31279: #if (DEBUG >= 3)
        !          31280: #define QSIZE  printf("Q%d:%d ", s_id, bqp->count)
        !          31281: #else
        !          31282: #if (DEBUG >= 2)
        !          31283: #define QSIZE  {if (bqp->count>1)printf("Q%d:%d ", s_id, bqp->count);}
        !          31284: #else
        !          31285: #define QSIZE
        !          31286: #endif
        !          31287: #endif
        !          31288: 
        !          31289: /*
        !          31290:  * bufq_init()
        !          31291:  *
        !          31292:  * Set up the desired number of queues.
        !          31293:  *
        !          31294:  * Return 1 if ok, 0 if kalloc() failed.
        !          31295:  */
        !          31296: int bufq_init(qcount)
        !          31297: int qcount;
        !          31298: {
        !          31299:        int ret;
        !          31300: 
        !          31301:        if (qcount > 0 && (bufq_q = kalloc(qcount*sizeof(bufq_type)))) {
        !          31302:                ret = 1;
        !          31303:                kclear(bufq_q, qcount*sizeof(bufq_type));
        !          31304:                num_q = qcount;
        !          31305: #if (DEBUG >= 2)
        !          31306: printf("%d queues allocated\n", qcount);
        !          31307: #endif
        !          31308:        } else
        !          31309:                ret = 0;
        !          31310: 
        !          31311:        return ret;
        !          31312: }
        !          31313: 
        !          31314: /*
        !          31315:  * bufq_rlse()
        !          31316:  *
        !          31317:  * Deallocate buffer queue structs.
        !          31318:  */
        !          31319: void bufq_rlse()
        !          31320: {
        !          31321:        num_q = 0;
        !          31322:        if (bufq_q)
        !          31323:                kfree(bufq_q);
        !          31324: }
        !          31325: 
        !          31326: /*
        !          31327:  * bufq_wr_tail()
        !          31328:  *
        !          31329:  * Append a BUF object to the doubly-linked queue.
        !          31330:  * Object to be inserted has been allocated by the caller.
        !          31331:  * Run at high priority.
        !          31332:  */
        !          31333: void bufq_wr_tail(s_id, bp)
        !          31334: int s_id;
        !          31335: BUF * bp;
        !          31336: {
        !          31337:        int s;
        !          31338:        bufq_type * bqp;
        !          31339: 
        !          31340:        if (s_id < num_q) {
        !          31341:                bqp = bufq_q + s_id;
        !          31342:                s = sphi();
        !          31343:                if (bqp->count == 0) {
        !          31344:                        bqp->head = bqp->tail = bp;
        !          31345:                        bp->b_actf = bp->b_actl = NULL;
        !          31346:                } else {
        !          31347:                        bqp->tail->b_actf = bp;
        !          31348:                        bp->b_actf = NULL;
        !          31349:                        bp->b_actl = bqp->tail;
        !          31350:                        bqp->tail = bp;
        !          31351:                }
        !          31352:                bqp->count++;
        !          31353: QSIZE;
        !          31354:                spl(s);
        !          31355:        }
        !          31356: }
        !          31357: 
        !          31358: /*
        !          31359:  * bufq_rd_head()
        !          31360:  *
        !          31361:  * Nondestructively fetch the head entry in the queue - i.e., this routine
        !          31362:  * does not remove an entry from the queue (see ss_rm_head() for that).
        !          31363:  * Return NULL if queue is empty, else return pointer to head item.
        !          31364:  */
        !          31365: BUF * bufq_rd_head(s_id)
        !          31366: int s_id;
        !          31367: {
        !          31368:        bufq_type * bqp;
        !          31369: 
        !          31370:        if (s_id < num_q) {
        !          31371:                bqp = bufq_q + s_id;
        !          31372:                return bqp->head;
        !          31373:        } else
        !          31374:                return NULL;
        !          31375: }
        !          31376: 
        !          31377: /*
        !          31378:  * bufq_rm_head()
        !          31379:  *
        !          31380:  * Delete head item from the queue.  Return a pointer to the node deleted,
        !          31381:  * or NULL if the queue was already empty.
        !          31382:  * Run at high priority.
        !          31383:  *
        !          31384:  * This routine does NOT deallocate the node.  That must be done by the
        !          31385:  * calling function after this routine runs.
        !          31386:  */
        !          31387: BUF * bufq_rm_head(s_id)
        !          31388: int s_id;
        !          31389: {
        !          31390:        BUF * ret;
        !          31391:        int s;
        !          31392:        bufq_type * bqp;
        !          31393: 
        !          31394:        if (s_id < num_q) {
        !          31395:                bqp = bufq_q + s_id;
        !          31396:                s = sphi();
        !          31397:                if (bqp->count > 0) {
        !          31398:                        ret = bqp->head;
        !          31399:                        if (bqp->count == 1) {
        !          31400:                                bqp->head = bqp->tail = NULL;
        !          31401:                        } else {
        !          31402:                                bqp->head = bqp->head->b_actf;
        !          31403:                                bqp->head->b_actl = NULL;
        !          31404:                        }
        !          31405:                        bqp->count--;
        !          31406: QSIZE;
        !          31407:                } else
        !          31408:                        ret = NULL;
        !          31409:                spl(s);
        !          31410:        } else
        !          31411:                ret = NULL;
        !          31412: 
        !          31413:        return ret;
        !          31414: }
        !          31415: @
        !          31416: 
        !          31417: 
        !          31418: 1.2
        !          31419: log
        !          31420: @Enhanced debug printout.
        !          31421: @
        !          31422: text
        !          31423: @d9 3
        !          31424: d20 1
        !          31425: a20 1
        !          31426: #include <coherent.h>
        !          31427: @
        !          31428: 
        !          31429: 
        !          31430: 1.1
        !          31431: log
        !          31432: @First running version.
        !          31433: @
        !          31434: text
        !          31435: @d8 4
        !          31436: a11 1
        !          31437:  * $Log$
        !          31438: d57 1
        !          31439: a57 1
        !          31440: #if (DEBUG >= 2)
        !          31441: d60 3
        !          31442: d65 1
        !          31443: @
        !          31444: 0707070064030104311004440000030000030000011777770507310651400005400000040371/newbits/kernel/USRSRC/i8086/drv/RCS/dg.c,vhead     1.3;
        !          31445: access   ;
        !          31446: symbols  ;
        !          31447: locks    ;
        !          31448: comment  @ * @;
        !          31449: 
        !          31450: 
        !          31451: 1.3
        !          31452: date     91.03.05.12.23.42;  author root;  state Exp;
        !          31453: branches ;
        !          31454: next   1.2;
        !          31455: 
        !          31456: 1.2
        !          31457: date     91.03.01.13.29.12;  author root;  state Exp;
        !          31458: branches ;
        !          31459: next   1.1;
        !          31460: 
        !          31461: 1.1
        !          31462: date     91.02.28.14.53.22;  author root;  state Exp;
        !          31463: branches ;
        !          31464: next   ;
        !          31465: 
        !          31466: 
        !          31467: desc
        !          31468: @Device driver for Digiboard PC/Xe intelligent multiport controller.
        !          31469: @
        !          31470: 
        !          31471: 
        !          31472: 1.3
        !          31473: log
        !          31474: @Fix cast on dg_ram_base
        !          31475: @
        !          31476: text
        !          31477: @/*
        !          31478:  * dg - device driver for Digiboard PC/Xe intelligent multiport controller
        !          31479:  *
        !          31480:  * $Header: /usr/src/sys/i8086/drv/RCS/dg.c,v 1.2 91/03/01 13:29:12 root Exp $
        !          31481:  *
        !          31482:  * $Log$
        !          31483:  */
        !          31484:  
        !          31485: /*
        !          31486:  * Various notes:
        !          31487:  *
        !          31488:  *     FEP = front-end-processor (the 80186 on the Digiboard)
        !          31489:  *
        !          31490:  *     At port DG_IOB:
        !          31491:  *             the 2's bit is 1 to enable DPRAM, 0 to disable
        !          31492:  *             the 4's bit is 1 to reset FEP, 0 to clear reset 
        !          31493:  *
        !          31494:  *     There is a bug in the current ldlib.a version of setivec and clrivec:
        !          31495:  *     they only work during xxload() and xxunload() due to use of "ucs"
        !          31496:  *     instead of "getcs()" to determine the CS for the interrupt routine.
        !          31497:  */
        !          31498: 
        !          31499: /*
        !          31500:  * Definitions.
        !          31501:  *
        !          31502:  */
        !          31503: #define        DG_RAM_LENGTH   0x10000L
        !          31504: #define DG_MEMORY_SEG  0xF000          /* dual-port ram base on FEP side */
        !          31505: #define DG_BIOS_ADDR   0xF800
        !          31506: #define DG_FEPOS_ADDR  0x2000
        !          31507: #define DG_BIOS_LOADER 0x80            /* minor number to write to BIOS */
        !          31508: #define DG_FEPOS_LOADER        0x40            /* minor number to write to FEPOS */
        !          31509: #define DG_BIOS_LENGTH 0x800           /* PC/Xe BIOS is 2k bytes */
        !          31510: #define DG_BIOS_CONFIRM        0x0C00          /* look for "GD" here */
        !          31511: #define DG_FEP_CONFIRM 0x0D20          /* look for "OS" here */
        !          31512: #define DG_BIOS_REQ    0x0C40          /* Start FEP BIOS requests here */
        !          31513: #define BIOS_GOOD      ('G' + ('D'<<8))        /* "GD" */
        !          31514: #define FEPOS_GOOD     ('O' + ('S'<<8))        /* "OS" */
        !          31515: 
        !          31516: #define CSTART         0x400           /* start addr of command queue */
        !          31517: #define NPORT          0x0C22          /* addr of # of ports */
        !          31518: #define CIN            0x0D10          /* addr for command in pointer */
        !          31519: #define COUT           0x0D12          /* addr for command out pointer */
        !          31520: #define ISTART         0x800           /* start addr of event queue */
        !          31521: #define EIN            0x0D18          /* addr for event in pointer */
        !          31522: #define EOUT           0x0D1A          /* addr for event out pointer */
        !          31523: #define INTERVAL       0x0E04          /* addr for ticks between irpts */
        !          31524: #define EVENT_LEN      4               /* bytes per FEP event */
        !          31525: #define COMMAND_LEN    4               /* bytes per FEP command */
        !          31526: 
        !          31527: /*
        !          31528:  * Includes.
        !          31529:  */
        !          31530: #include "coherent.h" 
        !          31531: #include <sys/io.h>            /* IO */
        !          31532: #include <sys/sched.h>         /* [CIS]VPAUSE */
        !          31533: #include <sys/uproc.h>         /* u.u_error */
        !          31534: #include <sys/proc.h>          /* wakeup();
        !          31535:                                   includes sys/types.h - faddr_t, paddr_t
        !          31536:                                   and sys/timeout.h - TIM
        !          31537:                                   needs coherent.h for KERNEL */
        !          31538: #include <sys/con.h>           /* CON */
        !          31539: #include <sys/stat.h>          /* minor(dev) */
        !          31540: #include <devices.h>           /* device major numbers, including PE_MAJOR */
        !          31541: #include <errno.h>
        !          31542: 
        !          31543: /*
        !          31544:  * Export Functions.
        !          31545:  */
        !          31546: 
        !          31547: /*
        !          31548:  * Export variables - these may be patched in order to configure the driver.
        !          31549:  */
        !          31550: long   DG_RAM = 0xF0000L;      /* segment for 64k of dual-port RAM */
        !          31551: int    DG_IOB = 0x200;         /* address of i/o byte for controller */
        !          31552: int    DG_INT = 15;            /* IRQ number for board's interrupt */
        !          31553: 
        !          31554: /*
        !          31555:  * Import Functions
        !          31556:  */
        !          31557: int    nulldev();
        !          31558: int    nonedev();
        !          31559: 
        !          31560: /*
        !          31561:  * Local functions.
        !          31562:  */
        !          31563: static dgload();
        !          31564: static dgunload();
        !          31565: static dgopen();
        !          31566: static dgclose();
        !          31567: static dgread();
        !          31568: static dgwrite();
        !          31569: static void dgdelay();
        !          31570: static dg_start_timing();
        !          31571: static dg_stop_timing();
        !          31572: static int dginit2();
        !          31573: static int dginit3();
        !          31574: static void dgintr();
        !          31575:  
        !          31576: /*
        !          31577:  * Local variables.
        !          31578:  */
        !          31579: static faddr_t dg_ram_fp;      /* (far *) to access screen */
        !          31580: static paddr_t dg_ram_base;    /* physical address of screen base */
        !          31581: static TIM     delay_tim;      /* needed for calls to timeout() */
        !          31582: static TIM     timeout_tim;    /* needed for calls to timeout() */
        !          31583: static int     dg_expired;     /* TRUE after local timeout */
        !          31584: static int     bios_loading;   /* TRUE if minor device for BIOS load open */
        !          31585: static int     fepos_loading;  /* TRUE if minor device for FEPOS load open */
        !          31586: static int     load_byte_ct;   /* place-holder for BIOS/FEPOS load */
        !          31587: static int     board_ready;    /* TRUE when all board initialization done */
        !          31588: static int     dg_bios_wait;   /* TRUE if waiting for BIOS to be loaded */
        !          31589: static int     dg_fepos_wait;  /* TRUE if waiting for FEPOS to be loaded */
        !          31590: static int     nport;          /* number of ports on the Digiboard */
        !          31591: static int     test_irq;       /* TRUE during startup */
        !          31592: 
        !          31593: /*
        !          31594:  * Configuration table - another export variable.
        !          31595:  */
        !          31596: CON dgcon ={
        !          31597:        DFCHR,                          /* Flags */
        !          31598:        PE_MAJOR,                       /* Major index */
        !          31599:        dgopen,                         /* Open */
        !          31600:        dgclose,                        /* Close */
        !          31601:        nulldev,                        /* Block */
        !          31602:        dgread,                         /* Read */
        !          31603:        dgwrite,                        /* Write */
        !          31604:        nulldev,                        /* Ioctl */
        !          31605:        nulldev,                        /* Powerfail */
        !          31606:        nulldev,                        /* Timeout */
        !          31607:        dgload,                         /* Load */
        !          31608:        dgunload,                       /* Unload */
        !          31609:        nulldev                         /* Poll */
        !          31610: };
        !          31611: 
        !          31612: /*
        !          31613:  * Load Routine.
        !          31614:  */
        !          31615: static dgload()
        !          31616: {
        !          31617:        char v;
        !          31618: 
        !          31619:        setivec(DG_INT, dgintr);
        !          31620:        /*
        !          31621:         * Allocate a selector to map onto the dual-port RAM.  ptov() will
        !          31622:         * return the first available selector of the 8,192 possible.
        !          31623:         */
        !          31624:        dg_ram_base = (paddr_t)((long)(unsigned)DG_RAM << 4);
        !          31625:        dg_ram_fp = ptov(dg_ram_base, (fsize_t)DG_RAM_LENGTH);
        !          31626:        
        !          31627:        /*
        !          31628:         * Reset the board and wait.
        !          31629:         * Actual delay is a tick = 0.01 sec; only need 1msec.
        !          31630:         */
        !          31631:        outb(DG_IOB, 0x04);
        !          31632:        dgdelay(1);
        !          31633:        
        !          31634:        /*
        !          31635:         * Read board ID.
        !          31636:         */
        !          31637:        v = inb(DG_IOB);
        !          31638:        if ((v & 0x01) == 0x01) {
        !          31639:                printf("Error - board type is PC/Xi\n");
        !          31640:                return;
        !          31641:        } else {
        !          31642:                outb(DG_IOB, 0x05);     /* hold FEP reset */
        !          31643:                v = inb(DG_IOB);
        !          31644:                if ((v & 0x01) == 0x01) {
        !          31645:                        printf("Error - board type is PC/Xm\n");
        !          31646:                        return;
        !          31647:                } else
        !          31648:                        printf("PC/Xe ID found\n");
        !          31649:        }
        !          31650:        
        !          31651:        /*
        !          31652:         * Board Reset.
        !          31653:         */
        !          31654:        outb(DG_IOB, 0x04);     /* reset board */
        !          31655:        dg_start_timing(100);   /* start 1-second timer */
        !          31656:        while ((inb(DG_IOB) & 0x0E) != 0x04) {
        !          31657:                if (dg_expired) {
        !          31658:                        printf("Error - PC/Xe failed to reset\n");
        !          31659:                        return;
        !          31660:                }
        !          31661:                dgdelay(10);
        !          31662:        }
        !          31663:        outb(DG_IOB, 0x06);     /* enable memory */
        !          31664:        printf("PC/Xe passed reset\n");
        !          31665: 
        !          31666:        /*
        !          31667:         * Minimal test of PC/Xe's 64k of dual-ported RAM.
        !          31668:         */
        !          31669:        sfword(dg_ram_fp, 0xA55A);              /* store a "far" word */
        !          31670:        sfword(dg_ram_fp + 2, 0x3CC3);
        !          31671:        sfword(dg_ram_fp + 0xFFFC, 0xA55A);
        !          31672:        sfword(dg_ram_fp + 0xFFFE, 0x3CC3);
        !          31673:        if (ffword(dg_ram_fp) != 0xA55A         /* fetch a "far" word */
        !          31674:        ||  ffword(dg_ram_fp + 2) != 0x3CC3
        !          31675:        ||  ffword(dg_ram_fp + 0xFFFC) != 0xA55A
        !          31676:        ||  ffword(dg_ram_fp + 0xFFFE) != 0x3CC3) {
        !          31677:                printf("Error - PC/Xe failed memory test\n");
        !          31678:                return;
        !          31679:        } else
        !          31680:                printf("PC/Xe passed memory test\n");
        !          31681:                
        !          31682:        /*
        !          31683:         * Load and execute the PC/Xe BIOS
        !          31684:         */
        !          31685:        outb(DG_IOB, 0x06);     /* enable memory */
        !          31686:        dg_bios_wait = 1;
        !          31687:        printf("PC/Xe waiting for BIOS load\n");
        !          31688: }
        !          31689: 
        !          31690: static dgunload()
        !          31691: {
        !          31692:        if (board_ready) {
        !          31693:                board_ready = 0;
        !          31694:        }
        !          31695:        
        !          31696:        /*
        !          31697:         * Turn off and unhook interrupts from FEPOS
        !          31698:         */
        !          31699:        sfword(dg_ram_fp+INTERVAL, 0);  /* stop host interrupts */
        !          31700:        outb(DG_IOB, 0x04);             /* Disable DPRAM and hold FEP reset */
        !          31701:        clrivec(DG_INT);
        !          31702: 
        !          31703:        /*
        !          31704:         * We have to free up the selector now that we're done using it.
        !          31705:         */
        !          31706:        vrelse(dg_ram_fp);
        !          31707: }
        !          31708: 
        !          31709: /*
        !          31710:  * Open Routine.
        !          31711:  */
        !          31712: static dgopen( dev, mode )
        !          31713: dev_t dev;
        !          31714: {
        !          31715:        /*
        !          31716:         * If minor number has 128's bit set to 1, this is an attempt to
        !          31717:         * transfer the BIOS to the FEP.
        !          31718:         */
        !          31719:        if (minor(dev) & DG_BIOS_LOADER) {
        !          31720:                if (bios_loading) {
        !          31721:                        u.u_error = EDBUSY;
        !          31722:                        return;
        !          31723:                } else {
        !          31724:                        /*
        !          31725:                         * Only allow BIOS xfer if we are waiting for it.
        !          31726:                         */
        !          31727:                        if (dg_bios_wait) {
        !          31728:                                bios_loading = 1;
        !          31729:                                load_byte_ct = 0;
        !          31730:                        } else {
        !          31731:                                u.u_error = EIO;
        !          31732:                                return;
        !          31733:                        }
        !          31734:                }
        !          31735:        /*
        !          31736:         * If minor number has 64's bit set to 1, this is an attempt to
        !          31737:         * transfer the FEPOS to the FEP.
        !          31738:         */
        !          31739:        } else if (minor(dev) & DG_FEPOS_LOADER) {
        !          31740:                if (fepos_loading) {
        !          31741:                        u.u_error = EDBUSY;
        !          31742:                        return;
        !          31743:                } else {
        !          31744:                        /*
        !          31745:                         * Only allow FEPOS xfer if we are waiting for it.
        !          31746:                         */
        !          31747:                        if (dg_fepos_wait) {
        !          31748:                                fepos_loading = 1;
        !          31749:                                load_byte_ct = 0;
        !          31750:                        } else {
        !          31751:                                u.u_error = EIO;
        !          31752:                                return;
        !          31753:                        }
        !          31754:                }
        !          31755:        } else {
        !          31756:        }
        !          31757: }
        !          31758: 
        !          31759: /*
        !          31760:  * Close Routine.
        !          31761:  */
        !          31762: static dgclose( dev )
        !          31763: dev_t dev;
        !          31764: {
        !          31765:        /*
        !          31766:         * If minor number has 128's bit set to 1, this is an attempt to
        !          31767:         * transfer the BIOS to the FEP.
        !          31768:         */
        !          31769:        if (minor(dev) & DG_BIOS_LOADER) {
        !          31770:                bios_loading = 0;
        !          31771:                /*
        !          31772:                 * Only set dg_fepos_wait if enough bytes got written.
        !          31773:                 */
        !          31774:                if (load_byte_ct == DG_BIOS_LENGTH) {
        !          31775:                        /*
        !          31776:                         * After BIOS is xferred, try to finish
        !          31777:                         * PC/Xe initialization.
        !          31778:                         */
        !          31779:                        if (dginit2()) {
        !          31780:                                dg_bios_wait = 0;
        !          31781:                                dg_fepos_wait = 1;
        !          31782:                                printf("PC/Xe waiting for FEPOS load\n");
        !          31783:                        }
        !          31784:                }
        !          31785:        /*
        !          31786:         * If minor number has 64's bit set to 1, this is an attempt to
        !          31787:         * transfer the FEPOS to the FEP.
        !          31788:         */
        !          31789:        } else if (minor(dev) & DG_FEPOS_LOADER) {
        !          31790:                fepos_loading = 0;
        !          31791:                /*
        !          31792:                 * After BIOS is xferred, try to finish
        !          31793:                 * PC/Xe initialization.
        !          31794:                 */
        !          31795:                if (dginit3()) {
        !          31796:                        dg_fepos_wait = 0;
        !          31797:                        board_ready = 1;
        !          31798:                        printf("PC/Xe ready for use\n");
        !          31799:                }
        !          31800:        } else {
        !          31801:        }
        !          31802: }
        !          31803: 
        !          31804: /*
        !          31805:  * Read Routine.
        !          31806:  */
        !          31807: static dgread( dev, iop )
        !          31808: dev_t dev;
        !          31809: register IO * iop;
        !          31810: {
        !          31811: #if 0
        !          31812:        static int offset;
        !          31813:        int c;
        !          31814:        /*
        !          31815:         * Read a character code from video RAM
        !          31816:         * Start reading RAM just after where previous read ended
        !          31817:         *
        !          31818:         * Note that "offset" is the value of the displacement into
        !          31819:         * the screen RAM. Any expression which results in a value
        !          31820:         * which is less than DG_RAM_LENGTH is OK here.
        !          31821:         */
        !          31822:        while(iop->io_ioc) {
        !          31823:                c = ffbyte(dg_ram_fp + offset); /* fetch a "far" byte */
        !          31824:                if(ioputc(c, iop) == -1)
        !          31825:                        break;
        !          31826:                offset += 2;
        !          31827:                offset %= DG_RAM_LENGTH;
        !          31828:        }
        !          31829: #endif 
        !          31830: }
        !          31831: 
        !          31832: /*
        !          31833:  * Write Routine.
        !          31834:  */
        !          31835: static dgwrite( dev, iop )
        !          31836: dev_t dev;
        !          31837: register IO * iop;
        !          31838: {
        !          31839:        /*
        !          31840:         * If minor number has 128's bit set to 1, this is an attempt to
        !          31841:         * transfer the BIOS to the FEP.
        !          31842:         */
        !          31843:        if (minor(dev) & DG_BIOS_LOADER) {
        !          31844:                int c;
        !          31845: 
        !          31846:                while ((c = iogetc(iop)) >= 0 && load_byte_ct < DG_BIOS_LENGTH) {
        !          31847:                        sfbyte(dg_ram_fp + DG_BIOS_ADDR + load_byte_ct, c);
        !          31848:                        load_byte_ct++;
        !          31849:                }
        !          31850:        /*
        !          31851:         * If minor number has 64's bit set to 1, this is an attempt to
        !          31852:         * transfer the FEPOS to the FEP.
        !          31853:         */
        !          31854:        } else if (minor(dev) & DG_FEPOS_LOADER) {
        !          31855:                int c;
        !          31856: 
        !          31857:                while ((c = iogetc(iop)) >= 0) {
        !          31858:                        sfbyte(dg_ram_fp + DG_FEPOS_ADDR + load_byte_ct, c);
        !          31859:                        load_byte_ct++;
        !          31860:                }
        !          31861:        } else {
        !          31862:        }
        !          31863: }
        !          31864: 
        !          31865: /*
        !          31866:  * Delay for some number of clock ticks.
        !          31867:  * 286/386 kernel ticks are at 100Hz
        !          31868:  * Use kernel function sleep(), which is NOT the system call by that name.
        !          31869:  */
        !          31870: static void dgdelay(ticks)
        !          31871: int ticks;
        !          31872: {
        !          31873:        timeout(&delay_tim, ticks, wakeup, (int)&delay_tim);
        !          31874:        sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
        !          31875: }
        !          31876: 
        !          31877: /*
        !          31878:  * Start a timeout for some number of ticks.
        !          31879:  * Caller knows timer has expired when "dg_expired" goes to 1.
        !          31880:  *
        !          31881:  * Sample invocation:
        !          31882:  *     dg_start_timing(n);
        !          31883:  *     while (check for desired event fails) {
        !          31884:  *             if (dg_expired) {
        !          31885:  *                     ...failure stuff..
        !          31886:  *                     break;
        !          31887:  *             }
        !          31888:  *             dgdelay(m); <= needed to allow kernel to update timers
        !          31889:  *     }
        !          31890:  */
        !          31891: static dg_start_timing(ticks)
        !          31892: int ticks;
        !          31893: {
        !          31894:        dg_expired = 0;
        !          31895:        timeout(&timeout_tim, ticks, dg_stop_timing, 1);
        !          31896: }
        !          31897: 
        !          31898: /*
        !          31899:  * Stub function called only by dg_start_timing()
        !          31900:  */
        !          31901: static dg_stop_timing(flagval)
        !          31902: int flagval;
        !          31903: {
        !          31904:        dg_expired = flagval;
        !          31905: }
        !          31906: 
        !          31907: /*
        !          31908:  * Second part of PC/Xe initialization - done after the BIOS has been
        !          31909:  * written to dual-ported RAM.
        !          31910:  */
        !          31911: static int dginit2()
        !          31912: {
        !          31913:        /*
        !          31914:         * Execute FEP BIOS
        !          31915:         */
        !          31916:        sfword(dg_ram_fp + DG_BIOS_CONFIRM, 0); /* clear confirm word */
        !          31917:        outb(DG_IOB, 0x02);                     /* Release reset */
        !          31918:        dg_start_timing(1000);                  /* start 10-second timer */
        !          31919: 
        !          31920:        while (ffword(dg_ram_fp + DG_BIOS_CONFIRM) != BIOS_GOOD) {
        !          31921:                if (dg_expired) {
        !          31922:                        printf("Error - PC/Xe BIOS won't start\n");
        !          31923:                        return 0;
        !          31924:                }
        !          31925:                dgdelay(10);
        !          31926:        }
        !          31927:        printf("PC/Xe BIOS started\n");
        !          31928: 
        !          31929:        return 1;
        !          31930: }
        !          31931: 
        !          31932: /*
        !          31933:  * Third part of PC/Xe initialization - done after the FEPOS has been
        !          31934:  * written to dual-ported RAM.
        !          31935:  */
        !          31936: static int dginit3()
        !          31937: {
        !          31938:        int cmd;
        !          31939: 
        !          31940:        /*
        !          31941:         * Ask FEP BIOS to move FEPOS into host memory.
        !          31942:         */
        !          31943:        sfword(dg_ram_fp + DG_BIOS_REQ, 0x0002);
        !          31944:        sfword(dg_ram_fp + DG_BIOS_REQ+2, DG_MEMORY_SEG+0x200);
        !          31945:        sfword(dg_ram_fp + DG_BIOS_REQ+4, 0x0000);
        !          31946:        sfword(dg_ram_fp + DG_BIOS_REQ+6, 0x0200);
        !          31947:        sfword(dg_ram_fp + DG_BIOS_REQ+8, 0x0000);
        !          31948:        sfword(dg_ram_fp + DG_BIOS_REQ+0xA, 0x2000);
        !          31949:        outb(DG_IOB, 0x0A);                     /* Toggle interrupt */
        !          31950:        outb(DG_IOB, 0x02);
        !          31951:        dg_start_timing(100);                   /* start 1-second timer */
        !          31952:        while (ffword(dg_ram_fp + DG_BIOS_REQ) != 0) {
        !          31953:                if (dg_expired) {
        !          31954:                        printf("Error - PC/Xe FEPOS move failed\n");
        !          31955:                        return;
        !          31956:                }
        !          31957:                dgdelay(10);
        !          31958:        }
        !          31959:        printf("PC/Xe FEPOS relocated to host RAM\n");
        !          31960: 
        !          31961:        /*
        !          31962:         * Execute FEPOS
        !          31963:         */
        !          31964:        sfword(dg_ram_fp + DG_BIOS_REQ, 0x0001);
        !          31965:        sfword(dg_ram_fp + DG_BIOS_REQ+2, 0x0200);
        !          31966:        sfword(dg_ram_fp + DG_BIOS_REQ+4, 0x0004);
        !          31967:        sfword(dg_ram_fp + DG_FEP_CONFIRM, 0);  /* clear confirm word */
        !          31968:        outb(DG_IOB, 0x0A);                     /* Toggle interrupt */
        !          31969:        outb(DG_IOB, 0x02);
        !          31970:        dg_start_timing(500);                   /* start 5-second timer */
        !          31971:        while (ffword(dg_ram_fp + DG_FEP_CONFIRM) != FEPOS_GOOD) {
        !          31972:                if (dg_expired) {
        !          31973:                        printf("Error - PC/Xe FEPOS won't start\n");
        !          31974:                        printf("Failure code (%x)\n",
        !          31975:                                ffword(dg_ram_fp + DG_BIOS_REQ));
        !          31976:                        return 0;
        !          31977:                }
        !          31978:                dgdelay(10);
        !          31979:        }
        !          31980:        printf("PC/Xe FEPOS started\n");
        !          31981:        nport = ffbyte(dg_ram_fp+NPORT);
        !          31982: 
        !          31983:        /*
        !          31984:         * Enable and test interrupts from FEP
        !          31985:         */
        !          31986:        sfword(dg_ram_fp+INTERVAL, 1);          /* request host interrupts */
        !          31987:        cmd = ffword(dg_ram_fp+CIN);            /* get command pointer */
        !          31988:        sfword(dg_ram_fp+CSTART+cmd, 0xA1FF);   /* send an invalid command */
        !          31989:        sfword(dg_ram_fp+CSTART+cmd+2, 0xC3B2);
        !          31990:        sfword(dg_ram_fp+CIN, (cmd+4)&0x3ff);   /* update command pointer */
        !          31991:        dg_start_timing(100);                   /* start 1-second timer */
        !          31992:        test_irq = 1;
        !          31993:        while (test_irq) {
        !          31994:                if (dg_expired) {
        !          31995:                        printf("Error - PC/Xe no FEPOS interrupts\n");
        !          31996:                        return 0;
        !          31997:                }
        !          31998:                dgdelay(10);
        !          31999:        }
        !          32000:        printf("PC/Xe interrupts working\n");
        !          32001:        
        !          32002:        return 1;
        !          32003: }
        !          32004: 
        !          32005: /*
        !          32006:  * Interrupt handler.
        !          32007:  *
        !          32008:  * No specific action is needed to clear the interrupt
        !          32009:  * as it was a pulse sent from the FEPOS to host's IRQ line.
        !          32010:  */
        !          32011: static void dgintr()
        !          32012: {
        !          32013:        int cin, cout, ein, eout;
        !          32014:        unsigned char event[EVENT_LEN];
        !          32015:        int i;
        !          32016: 
        !          32017:        cin = ffword(dg_ram_fp+CIN);
        !          32018:        cout = ffword(dg_ram_fp+COUT);
        !          32019:        ein = ffword(dg_ram_fp+EIN);
        !          32020:        eout = ffword(dg_ram_fp+EOUT);
        !          32021: 
        !          32022:        if (board_ready) {
        !          32023:                /*
        !          32024:                 * Remove all packets from event queue.
        !          32025:                 */
        !          32026:                while (ffword(dg_ram_fp+EIN) != ffword(dg_ram_fp+EOUT)) {
        !          32027:                        eout = ffword(dg_ram_fp+EOUT);
        !          32028:                        for (i = 0; i < EVENT_LEN; i++)
        !          32029:                                event[i] = ffbyte(dg_ram_fp+ISTART+eout+i);
        !          32030:                        printf("%x %x %x %x\n", event[0],event[1],event[2],event[3]);   
        !          32031:                        sfword(dg_ram_fp+EOUT, (eout+4)&0x3ff);
        !          32032:                }
        !          32033:        } else {        /* e.g., if test_irq is TRUE */
        !          32034:                test_irq = 0;
        !          32035:                /*
        !          32036:                 * Attempt to clear the IRQ condition in the FEP.
        !          32037:                 */
        !          32038:                sfword(dg_ram_fp+EOUT, ffword(dg_ram_fp+EIN));
        !          32039:        }
        !          32040: }
        !          32041: @
        !          32042: 
        !          32043: 
        !          32044: 1.2
        !          32045: log
        !          32046: @Fully initializes O.K. but no functional I/O yet
        !          32047: @
        !          32048: text
        !          32049: @d4 1
        !          32050: a4 1
        !          32051:  * $Header$
        !          32052: d6 1
        !          32053: d148 1
        !          32054: a148 1
        !          32055:        dg_ram_base = (paddr_t)DG_RAM << 4;
        !          32056: @
        !          32057: 
        !          32058: 
        !          32059: 1.1
        !          32060: log
        !          32061: @starts FEPOS ok but first IRQ causes panic
        !          32062: @
        !          32063: text
        !          32064: @d4 2
        !          32065: d7 14
        !          32066: a27 2
        !          32067: #define DG_BIOS_FILE   "/drv/xabios.bin"
        !          32068: #define DG_FEPOS_FILE  "/drv/xafep.bin"
        !          32069: d75 1
        !          32070: a75 1
        !          32071: int    DG_INT = 12;            /* IRQ number for board's interrupt */
        !          32072: d114 1
        !          32073: d142 1
        !          32074: d171 1
        !          32075: a171 1
        !          32076:                        printf("Digiboard PC/Xe ID found\n");
        !          32077: d181 1
        !          32078: a181 1
        !          32079:                        printf("Error - Digiboard failed to reset\n");
        !          32080: d200 1
        !          32081: a200 1
        !          32082:                printf("Error - Digiboard failed memory test\n");
        !          32083: a216 15
        !          32084:                /*
        !          32085:                 * Turn off and unhook interrupts from FEPOS
        !          32086:                 */
        !          32087: #if 0           
        !          32088:                clrivec(DG_INT);
        !          32089: #else
        !          32090:        clrivec(03);    
        !          32091:        clrivec(04);    
        !          32092:        clrivec(05);    
        !          32093:        clrivec(07);    
        !          32094:        clrivec(10);    
        !          32095:        clrivec(11);    
        !          32096:        clrivec(12);    
        !          32097:        clrivec(15);    
        !          32098: #endif 
        !          32099: d218 7
        !          32100: d445 1
        !          32101: a445 1
        !          32102:                        printf("Error - Digiboard BIOS won't start\n");
        !          32103: d451 1
        !          32104: a451 1
        !          32105:        
        !          32106: d477 1
        !          32107: a477 1
        !          32108:                        printf("Error - Digiboard FEPOS move failed\n");
        !          32109: d496 1
        !          32110: a496 1
        !          32111:                        printf("Error - Digiboard FEPOS won't start\n");
        !          32112: a504 1
        !          32113:        printf("Board is PC/%de\n", nport);
        !          32114: a508 15
        !          32115: 
        !          32116: printf("about to setivec\n");
        !          32117: #if 0
        !          32118:        setivec(DG_INT, dgintr);
        !          32119: #else
        !          32120:        setivec(03,dgintr);     
        !          32121:        setivec(04,dgintr);     
        !          32122:        setivec(05,dgintr);     
        !          32123:        setivec(07,dgintr);     
        !          32124:        setivec(10,dgintr);     
        !          32125:        setivec(11,dgintr);     
        !          32126:        setivec(12,dgintr);     
        !          32127:        setivec(15,dgintr);     
        !          32128: #endif 
        !          32129: printf("about to enable host irq's\n");        
        !          32130: a509 1
        !          32131: printf("getting command pointer\n");   
        !          32132: a510 1
        !          32133: printf("about to send invalid command\n");     
        !          32134: d514 11
        !          32135: a524 15
        !          32136: printf("invalid command sent\n");      
        !          32137:        dgdelay(100);                           /* wait 1 second */
        !          32138:        sfword(dg_ram_fp+INTERVAL, 0);          /* stop host interrupts */
        !          32139: #if 0
        !          32140: { int t;
        !          32141:        sfword(dg_ram_fp+INTERVAL, 1);          /* request host interrupts */
        !          32142:        t = ffword(dg_ram_fp+0x0D18);           /* get command pointer */
        !          32143:        sfword(dg_ram_fp+0x400+t, 0xA1FF);      /* send an invalid command */
        !          32144:        sfword(dg_ram_fp+0x402+t, 0xC3B2);
        !          32145:        sfword(dg_ram_fp+0xD18, (t+4)&0x3ff);   /* update command pointer */
        !          32146:        dgdelay(1000);                          /* wait 10 seconds */
        !          32147:        sfword(dg_ram_fp+INTERVAL, 0);          /* stop host interrupts */
        !          32148:        dgintr();
        !          32149: }      
        !          32150: #endif
        !          32151: d537 2
        !          32152: a538 3
        !          32153:        char event[EVENT_LEN];
        !          32154:        int i,j=0;
        !          32155: #define ILIMIT 5       
        !          32156: a539 1
        !          32157:        printf("Interrupt handler called\n");
        !          32158: a543 1
        !          32159:        printf("cin=%x cout=%x ein=%x eout=%x\n",cin,cout,ein,eout);
        !          32160: d545 17
        !          32161: a561 7
        !          32162:        while (ffword(dg_ram_fp+EIN) != ffword(dg_ram_fp+EOUT)&&j < ILIMIT) {
        !          32163:                eout = ffword(dg_ram_fp+EOUT);
        !          32164:                for (i = 0; i < EVENT_LEN; i++)
        !          32165:                        event[i] = ffbyte(dg_ram_fp+ISTART+eout+i);
        !          32166:                printf("%x %x %x %x\n", event[0],event[1],event[2],event[3]);   
        !          32167:                sfword(dg_ram_fp+EOUT, (eout+4)&0x3ff);
        !          32168:                j++;
        !          32169: @
        !          32170: 0707070064030103711004440000030000030000011777770507310652000005700000005452/newbits/kernel/USRSRC/i8086/drv/RCS/fdisk.c,vhead     1.3;
        !          32171: branch   ;
        !          32172: access   ;
        !          32173: symbols  ;
        !          32174: locks    bin:1.3;
        !          32175: comment  @ * @;
        !          32176: 
        !          32177: 
        !          32178: 1.3
        !          32179: date     91.06.20.14.48.58;  author bin;  state Exp;
        !          32180: branches ;
        !          32181: next     1.2;
        !          32182: 
        !          32183: 1.2
        !          32184: date     91.06.18.08.18.56;  author bin;  state Exp;
        !          32185: branches ;
        !          32186: next     1.1;
        !          32187: 
        !          32188: 1.1
        !          32189: date     91.03.25.19.09.17;  author root;  state Exp;
        !          32190: branches 1.1.1.1;
        !          32191: next     ;
        !          32192: 
        !          32193: 1.1.1.1
        !          32194: date     91.03.25.19.24.46;  author root;  state Exp;
        !          32195: branches ;
        !          32196: next     1.1.1.2;
        !          32197: 
        !          32198: 1.1.1.2
        !          32199: date     91.04.19.10.16.50;  author root;  state Exp;
        !          32200: branches ;
        !          32201: next     ;
        !          32202: 
        !          32203: 
        !          32204: desc
        !          32205: @function called by device drivers to load partition table
        !          32206: @
        !          32207: 
        !          32208: 
        !          32209: 1.3
        !          32210: log
        !          32211: @update provided by hal
        !          32212: @
        !          32213: text
        !          32214: @/* (-lgl
        !          32215:  *     COHERENT Driver Kit Version 1.1.0
        !          32216:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          32217:  *     All rights reserved. May not be copied without permission.
        !          32218:  -lgl) */
        !          32219: /**
        !          32220:  *
        !          32221:  * fdisk( dev, fp )    --      Fixed Disk Configuration
        !          32222:  * dev_t dev;
        !          32223:  * struct fdisk_s *fp;
        !          32224:  *
        !          32225:  *     Input:  dev = special device to read partition information from
        !          32226:  *             fp  = pointer to memory-resident partition info (to update)
        !          32227:  *
        !          32228:  *     Action: Open special device for reading.
        !          32229:  *             Read first block from the device.
        !          32230:  *             If valid signature present on block,
        !          32231:  *                     copy partition information to memory
        !          32232:  *
        !          32233:  *     Return: 1 = partition information successfully updated
        !          32234:  *             0 = failure (could not read block, or bad signature)
        !          32235:  */
        !          32236: 
        !          32237: #include <sys/coherent.h>
        !          32238: #include <sys/uproc.h>
        !          32239: #include <errno.h>
        !          32240: #include <sys/inode.h>
        !          32241: #include <sys/fdisk.h>
        !          32242: #include <sys/buf.h>
        !          32243: #include <sys/con.h>
        !          32244: 
        !          32245: fdisk( dev, fp )
        !          32246: dev_t dev;
        !          32247: register struct fdisk_s *fp;
        !          32248: {
        !          32249:        register struct hdisk_s *hp;
        !          32250:        BUF *bp;
        !          32251:        int s, i;
        !          32252:        int ret = 0;
        !          32253: 
        !          32254:        s = sphi( );
        !          32255:        dopen( dev, IPR, DFBLK );
        !          32256: 
        !          32257:        if ( u.u_error == 0 ) {         /* special device now open */
        !          32258: 
        !          32259:                if (bp = bread(dev, (daddr_t) 0, 1)) {  /* data read */
        !          32260: 
        !          32261:                        /* buffer cache is in kernel data space */
        !          32262:                        hp = FP_OFF(bp->b_faddr);
        !          32263: 
        !          32264:                        if ( hp->hd_sig == HDSIG ) {    /* valid data */
        !          32265: 
        !          32266:                                for (i=0; i < NPARTN; ++i)
        !          32267:                                        *fp++ = hp->hd_partn[i];
        !          32268: 
        !          32269:                                ret   = 1;
        !          32270:                        }
        !          32271:                        brelease( bp );
        !          32272:                }
        !          32273:                dclose( dev );
        !          32274:        }
        !          32275:        spl( s );
        !          32276:        return ret;
        !          32277: }
        !          32278: @
        !          32279: 
        !          32280: 
        !          32281: 1.2
        !          32282: log
        !          32283: @update provided by hal
        !          32284: @
        !          32285: text
        !          32286: @d24 1
        !          32287: a24 1
        !          32288: #include "coherent.h"
        !          32289: @
        !          32290: 
        !          32291: 
        !          32292: 1.1
        !          32293: log
        !          32294: @used in COHERENT 3.1.0
        !          32295: @
        !          32296: text
        !          32297: @d24 2
        !          32298: a25 2
        !          32299: #include <coherent.h>
        !          32300: #include <uproc.h>
        !          32301: d27 1
        !          32302: a27 1
        !          32303: #include <inode.h>
        !          32304: d29 2
        !          32305: a30 2
        !          32306: #include <buf.h>
        !          32307: #include <con.h>
        !          32308: @
        !          32309: 
        !          32310: 
        !          32311: 1.1.1.1
        !          32312: log
        !          32313: @debug printf's added
        !          32314: @
        !          32315: text
        !          32316: @a5 3
        !          32317: /*
        !          32318:  * $Log$
        !          32319:  */
        !          32320: a39 1
        !          32321: int erf = -1;
        !          32322: a57 1
        !          32323: else erf=1;
        !          32324: a61 1
        !          32325: else erf=0;
        !          32326: d63 1
        !          32327: a63 7
        !          32328: switch (erf) {
        !          32329: case 0:
        !          32330:        devmsg(dev, "fdisk: open failed");
        !          32331:        break;
        !          32332: case 1:
        !          32333:        devmsg(dev, "fdisk: bad signature");
        !          32334:        break;
        !          32335: a64 2
        !          32336:        return ret;
        !          32337: }
        !          32338: @
        !          32339: 
        !          32340: 
        !          32341: 1.1.1.2
        !          32342: log
        !          32343: @Debug printf's added.
        !          32344: @
        !          32345: text
        !          32346: @d45 1
        !          32347: a45 1
        !          32348: printf("fdisk(): special dev open\n");
        !          32349: a56 2
        !          32350:                        } else {
        !          32351: printf("fdisk(): sig=%x, want=%x\n", hp->hd_sig, HDSIG);
        !          32352: a58 2
        !          32353:                } else {
        !          32354: printf("fdisk(): bread failed\n");
        !          32355: a60 2
        !          32356:        } else {
        !          32357: printf("fdisk(): special dev not open\n");
        !          32358: d63 8
        !          32359: d73 6
        !          32360: @
        !          32361: 0707070064030106721004440000030000030000011777770507310652100005400000041042/newbits/kernel/USRSRC/i8086/drv/RCS/hs.c,vhead     1.3;
        !          32362: branch   ;
        !          32363: access   ;
        !          32364: symbols  ;
        !          32365: locks    bin:1.3;
        !          32366: comment  @ * @;
        !          32367: 
        !          32368: 
        !          32369: 1.3
        !          32370: date     91.06.20.14.49.59;  author bin;  state Exp;
        !          32371: branches ;
        !          32372: next     1.2;
        !          32373: 
        !          32374: 1.2
        !          32375: date     91.06.17.12.31.30;  author bin;  state Exp;
        !          32376: branches ;
        !          32377: next     1.1;
        !          32378: 
        !          32379: 1.1
        !          32380: date     91.02.25.16.05.15;  author root;  state Exp;
        !          32381: branches 1.1.1.1;
        !          32382: next     ;
        !          32383: 
        !          32384: 1.1.1.1
        !          32385: date     91.02.25.16.11.56;  author root;  state Exp;
        !          32386: branches ;
        !          32387: next     ;
        !          32388: 
        !          32389: 
        !          32390: desc
        !          32391: @Multiport (8250-type) serial driver.
        !          32392: @
        !          32393: 
        !          32394: 
        !          32395: 1.3
        !          32396: log
        !          32397: @update provided by hal
        !          32398: @
        !          32399: text
        !          32400: @/* (-lgl
        !          32401:  *     COHERENT Driver Kit Version 1.1.0
        !          32402:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          32403:  *     All rights reserved. May not be copied without permission.
        !          32404:  -lgl) */
        !          32405: /*
        !          32406:  * Polled Serial Port Device Driver.
        !          32407:  * - supports version 7 compatible ioctl
        !          32408:  */
        !          32409: 
        !          32410: #include <sys/coherent.h>
        !          32411: #include <sys/ins8250.h>
        !          32412: #include <sys/stat.h>
        !          32413: #include <sys/uproc.h>
        !          32414: #include <sys/proc.h>
        !          32415: #include <sys/tty.h>           /* indirectly includes sgtty.h */
        !          32416: #include <sys/con.h>
        !          32417: #include <errno.h>
        !          32418: #include <sys/sched.h>         /* CVTTOUT, IVTTOUT, SVTTOUT */
        !          32419: #include <sys/poll_clk.h>
        !          32420: 
        !          32421: /*
        !          32422:  * Definitions.
        !          32423:  *
        !          32424:  * HSBAUD is the highest baud rate supported by this driver
        !          32425:  * HS_HZ is the polling rate, i.e. the number of times per second
        !          32426:  *   at which all open ports are checked for input, output, and
        !          32427:  *   line status changes
        !          32428:  * MAX_HSNUM is the maximum number of devices that can be polled
        !          32429:  *   using this driver and can be revised up or down
        !          32430:  * PORT is a convenience macro for the base address of a port
        !          32431:  * port_config is the structure of the initial configuration for each
        !          32432:  *   polled port;  note that "speed" is NOT the actual baud rate, but
        !          32433:  *   the value of the symbol for that baud rate as defined in
        !          32434:  *   /usr/include/sgtty.h
        !          32435:  */
        !          32436: #define        HSBAUD  9600
        !          32437: #define        HS_HZ   (HSBAUD/6)
        !          32438: #define MAX_HSNUM      8
        !          32439: #define        PORT    ((int)(tp->t_ddp))
        !          32440: struct port_config {
        !          32441:        int     addr;   /* base address of the 8250-family UART */
        !          32442:        int     speed;  /* B0..B19200 */
        !          32443: };
        !          32444: 
        !          32445: /*
        !          32446:  * Export Variables - these can be patched without recompiling and linking
        !          32447:  *
        !          32448:  * HSNUM is the actual number of polled serial ports, and should be
        !          32449:  *   less than or equal to MAX_HSNUM
        !          32450:  * HS_PORTS is an array of address/speed pairs, one for each port
        !          32451:  */
        !          32452: int    HSNUM = 4;
        !          32453: struct port_config HS_PORTS[MAX_HSNUM] = {
        !          32454:        { 0x3F8, B9600 },
        !          32455:        { 0x2F8, B9600 },
        !          32456:        { 0x3E8, B9600 },
        !          32457:        { 0x2E8, B9600 }
        !          32458: };
        !          32459: 
        !          32460: /*
        !          32461:  * Export Functions.
        !          32462:  */
        !          32463: int    hsload();
        !          32464: int    hsopen();
        !          32465: int    hsclose();
        !          32466: int    hsread();
        !          32467: int    hswrite();
        !          32468: int    hsioctl();
        !          32469: int    hsunload();
        !          32470: int    hspoll();
        !          32471: 
        !          32472: int    hscycle();
        !          32473: int    hsintr();
        !          32474: int    hsparam();
        !          32475: int    hsstart();
        !          32476: int    hsclk();
        !          32477: int    set_poll_rate();
        !          32478: 
        !          32479: /*
        !          32480:  * Import Functions
        !          32481:  */
        !          32482: int    nulldev();
        !          32483: int    nonedev();
        !          32484: 
        !          32485: /*
        !          32486:  * Configuration table.
        !          32487:  */
        !          32488: CON hscon ={
        !          32489:        DFCHR|DFPOL,                    /* Flags */
        !          32490:        7,                              /* Major index */
        !          32491:        hsopen,                         /* Open */
        !          32492:        hsclose,                        /* Close */
        !          32493:        nulldev,                        /* Block */
        !          32494:        hsread,                         /* Read */
        !          32495:        hswrite,                        /* Write */
        !          32496:        hsioctl,                        /* Ioctl */
        !          32497:        nulldev,                        /* Powerfail */
        !          32498:        nulldev,                        /* Timeout */
        !          32499:        hsload,                         /* Load */
        !          32500:        hsunload,                       /* Unload */
        !          32501:        hspoll                          /* Poll */
        !          32502: };
        !          32503: 
        !          32504: /*
        !          32505:  * Local variables.
        !          32506:  */
        !          32507: static TTY *hstty;
        !          32508: static TTY *hslimtty;
        !          32509: static TIM hstim;
        !          32510: static int poll_divisor;       /* used in hsclk() and set_poll_rate() */
        !          32511: 
        !          32512: /*
        !          32513:  * Time constant table.
        !          32514:  * Indexed by ioctl baud rate.
        !          32515:  */
        !          32516: static
        !          32517: int timeconst[] = {
        !          32518:        0,                              /* 0 */
        !          32519:        2304,                           /* 50 */
        !          32520:        1536,                           /* 75 */
        !          32521:        1047,                           /* 110 */
        !          32522:        857,                            /* 134.5 */
        !          32523:        768,                            /* 150 */
        !          32524:        576,                            /* 200 */
        !          32525:        384,                            /* 300 */
        !          32526:        192,                            /* 600 */
        !          32527:        96,                             /* 1200 */
        !          32528:        64,                             /* 1800 */
        !          32529:        58,                             /* 2000 */
        !          32530:        48,                             /* 2400 */
        !          32531:        32,                             /* 3600 */
        !          32532:        24,                             /* 4800 */
        !          32533:        16,                             /* 7200 */
        !          32534:        12,                             /* 9600 */
        !          32535:        6,                              /* 19200 */
        !          32536:        6,                              /* EXTA */
        !          32537:        6                               /* EXTB */
        !          32538: };
        !          32539: 
        !          32540: /*
        !          32541:  * poll_hz[] is tied to timeconst[] - it gives the minimum polling
        !          32542:  *     rate for the corresponding port speed; it must be a multiple
        !          32543:  *     of 100 (system clock Hz) and >= baud/6
        !          32544:  */
        !          32545: int poll_hz[] ={
        !          32546:        0,                              /* 0 */
        !          32547:        1*HZ,                           /* 50 */
        !          32548:        1*HZ,                           /* 75 */
        !          32549:        1*HZ,                           /* 110 */
        !          32550:        1*HZ,                           /* 134.5 */
        !          32551:        1*HZ,                           /* 150 */
        !          32552:        1*HZ,                           /* 200 */
        !          32553:        1*HZ,                           /* 300 */
        !          32554:        1*HZ,                           /* 600 */
        !          32555:        2*HZ,                           /* 1200 */
        !          32556:        3*HZ,                           /* 1800 */
        !          32557:        4*HZ,                           /* 2000 */
        !          32558:        4*HZ,                           /* 2400 */
        !          32559:        6*HZ,                           /* 3600 */
        !          32560:        8*HZ,                           /* 4800 */
        !          32561:        12*HZ,                          /* 7200 */
        !          32562:        16*HZ,                          /* 9600 */
        !          32563:        0,                              /* 19200 */
        !          32564:        0,                              /* EXTA */
        !          32565:        0                               /* EXTB */
        !          32566: };
        !          32567: 
        !          32568: /*
        !          32569:  * Load Routine.
        !          32570:  */
        !          32571: static hsload()
        !          32572: {
        !          32573:        register TTY * tp;
        !          32574:        register int port;
        !          32575:        int i, b;
        !          32576: 
        !          32577:        if ((hstty = (TTY *)kalloc(HSNUM*sizeof(TTY))) == 0) {
        !          32578:                printf("hsload: can't allocate tty's\n");
        !          32579:                return;
        !          32580:        }
        !          32581:        kclear(hstty, HSNUM*sizeof(TTY));
        !          32582: 
        !          32583:        for (i = 0; i < HSNUM; i++) {
        !          32584:                port = HS_PORTS[i].addr;
        !          32585:                tp = hstty + i;
        !          32586: 
        !          32587:                outb( port+MCR, 0 );
        !          32588:                outb( port+IER, 0 );
        !          32589: 
        !          32590:                if ( inb( port+IER ) )
        !          32591:                        break;
        !          32592: 
        !          32593:                tp->t_cs_sel  = cs_sel();
        !          32594:                tp->t_start   = hsstart;
        !          32595:                tp->t_param   = hsparam;
        !          32596:                tp->t_sgttyb.sg_ospeed = tp->t_sgttyb.sg_ispeed = 
        !          32597:                tp->t_dispeed = tp->t_dospeed = HS_PORTS[i].speed;
        !          32598:                tp->t_ddp     = port;
        !          32599: 
        !          32600:                b = timeconst[ tp->t_sgttyb.sg_ospeed ];
        !          32601:                outb( port+LCR, LC_DLAB );
        !          32602:                outb( port+DLL, b );
        !          32603:                outb( port+DLH, b >> 8);
        !          32604:                outb( port+LCR, LC_CS8);
        !          32605: 
        !          32606:                hslimtty = tp;
        !          32607:        }
        !          32608: }
        !          32609: 
        !          32610: static hsunload()
        !          32611: {
        !          32612:        if (hstty != (TTY *)0)
        !          32613:                kfree(hstty);
        !          32614: }
        !          32615: 
        !          32616: /*
        !          32617:  * Open Routine.
        !          32618:  */
        !          32619: hsopen( dev, mode )
        !          32620: dev_t dev;
        !          32621: {
        !          32622:        register TTY * tp = &hstty[ dev & 15 ];
        !          32623:        register int b;
        !          32624:        int s;
        !          32625: 
        !          32626:        /*
        !          32627:         * Verify hardware exists.
        !          32628:         */
        !          32629:        if ( (PORT == 0) || (inb(PORT+IER) & ~IE_TxI) ) {
        !          32630:                u.u_error = ENXIO;
        !          32631:                return;
        !          32632:        }
        !          32633: 
        !          32634:        /*
        !          32635:         * Can't open if another driver is using polling
        !          32636:         */
        !          32637:        if (poll_owner & ~ POLL_HS) {
        !          32638:                u.u_error = EDBUSY;
        !          32639:                return;
        !          32640:        }
        !          32641: 
        !          32642:        /*
        !          32643:         * Initialize if not already open.
        !          32644:         */
        !          32645:        if ( ++tp->t_open == 1 ) {
        !          32646:                ttopen( tp );
        !          32647: 
        !          32648:                if ( dev & 0x80 ) {
        !          32649:                        s = sphi();
        !          32650:                        b = inb(PORT+MSR);
        !          32651:                        tp->t_flags |= T_MODC + T_STOP;
        !          32652:                        if ( b & MS_CTS )
        !          32653:                                tp->t_flags &= ~T_STOP;
        !          32654:                        if ( b & MS_DSR )
        !          32655:                                tp->t_flags |=  T_CARR;
        !          32656:                        spl( s );
        !          32657:                } else  {
        !          32658:                        tp->t_flags &= ~T_MODC;
        !          32659:                        tp->t_flags |=  T_CARR;
        !          32660:                }
        !          32661:                hscycle( tp );
        !          32662:        }
        !          32663:        ttsetgrp( tp, dev );
        !          32664:        set_poll_rate();
        !          32665: }
        !          32666: 
        !          32667: /*
        !          32668:  * Close Routine.
        !          32669:  */
        !          32670: hsclose( dev )
        !          32671: dev_t dev;
        !          32672: {
        !          32673:        register TTY * tp = &hstty[ dev & 15 ];
        !          32674: 
        !          32675:        /*
        !          32676:         * Reset if last close.
        !          32677:         */
        !          32678:        if ( tp->t_open == 1 ) {
        !          32679:                int state;
        !          32680: 
        !          32681:                ttclose( tp );
        !          32682:                /*
        !          32683:                 * ttclose() only emptied the output queue tp->t_oq;
        !          32684:                 * now wait 0.1 sec for the silo tp->rawout to empty
        !          32685:                 * and allow a delay for the UART on-chip xmit buffer to empty
        !          32686:                 *
        !          32687:                 * state 2: waiting for silo to empty
        !          32688:                 * state 1: stalling so UART can empty xmit buffer
        !          32689:                 * state 0: done!
        !          32690:                 */
        !          32691:                state = 2;
        !          32692:                while (state) {
        !          32693:                        timeout(&hstim, 10, wakeup, (int)&hstim);
        !          32694:                        sleep((char *)&hstim, CVTTOUT, IVTTOUT, SVTTOUT);
        !          32695:                        if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          32696:                                state--;
        !          32697:                }
        !          32698:        }
        !          32699: 
        !          32700:        --tp->t_open;
        !          32701:        set_poll_rate();
        !          32702: }
        !          32703: 
        !          32704: /*
        !          32705:  * Read Routine.
        !          32706:  */
        !          32707: hsread( dev, iop )
        !          32708: dev_t dev;
        !          32709: register IO * iop;
        !          32710: {
        !          32711:        ttread( &hstty[ dev & 15 ], iop, 0 );
        !          32712: }
        !          32713: 
        !          32714: /*
        !          32715:  * Write Routine.
        !          32716:  */
        !          32717: hswrite( dev, iop )
        !          32718: dev_t dev;
        !          32719: register IO * iop;
        !          32720: {
        !          32721:        ttwrite( &hstty[ dev & 15 ], iop, 0 );
        !          32722: }
        !          32723: 
        !          32724: /*
        !          32725:  * Ioctl Routine.
        !          32726:  */
        !          32727: hsioctl( dev, com, vec )
        !          32728: dev_t dev;
        !          32729: int com;
        !          32730: struct sgttyb * vec;
        !          32731: {
        !          32732:        ttioctl( &hstty[ dev & 15 ], com, vec );
        !          32733: }
        !          32734: 
        !          32735: /*
        !          32736:  * Polling Routine.
        !          32737:  */
        !          32738: hspoll( dev, ev, msec )
        !          32739: dev_t dev;
        !          32740: int ev;
        !          32741: int msec;
        !          32742: {
        !          32743:        return ttpoll( &hstty[ dev & 15 ], ev, msec );
        !          32744: }
        !          32745: 
        !          32746: /*
        !          32747:  * Cyclic routine - invoked every clock tick to perform raw input/output.
        !          32748:  *
        !          32749:  *     Notes:  Invoked 10 times per second.
        !          32750:  */
        !          32751: hscycle( tp )
        !          32752: register TTY * tp;
        !          32753: {
        !          32754:        register int resid;
        !          32755:        register int c;
        !          32756: 
        !          32757:        /*
        !          32758:         * Process rawin buf.
        !          32759:         */
        !          32760:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          32761: 
        !          32762:                ttin( tp, tp->t_rawin.si_buf[ tp->t_rawin.si_ox ] );
        !          32763: 
        !          32764:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          32765:                        tp->t_rawin.si_ox = 0;
        !          32766:                else
        !          32767:                        tp->t_rawin.si_ox++;
        !          32768:        }
        !          32769: 
        !          32770:        /*
        !          32771:         * Calculate free output slot count.
        !          32772:         */
        !          32773:        resid  = sizeof(tp->t_rawout.si_buf) - 1;
        !          32774:        resid += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          32775:        resid %= sizeof(tp->t_rawout.si_buf);
        !          32776: 
        !          32777:        /*
        !          32778:         * Fill raw output buffer.
        !          32779:         */
        !          32780:        while ( (--resid >= 0) && ((c = ttout(tp)) >= 0) ) {
        !          32781: 
        !          32782:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = c;
        !          32783: 
        !          32784:                if ( tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1 )
        !          32785:                        tp->t_rawout.si_ix = 0;
        !          32786:                else
        !          32787:                        tp->t_rawout.si_ix++;
        !          32788:        }
        !          32789: 
        !          32790:        /*
        !          32791:         * (Re)start output, waking processes waiting to output, etc.
        !          32792:         */
        !          32793:        ttstart( tp );
        !          32794: 
        !          32795:        /*
        !          32796:         * Schedule next cycle.
        !          32797:         */
        !          32798:        if ( tp->t_open != 0 )
        !          32799:                timeout( &tp->t_rawtim, HZ/10, hscycle, tp );
        !          32800: }
        !          32801: 
        !          32802: /*
        !          32803:  * Clock Interrupt driven Polling routine.
        !          32804:  */
        !          32805: hsintr()
        !          32806: {
        !          32807:        register TTY * tp = &hstty[0];
        !          32808:        register int b;
        !          32809: 
        !          32810:        do {
        !          32811:                if ( tp->t_open == 0 )
        !          32812:                        continue;
        !          32813: 
        !          32814:                /*
        !          32815:                 * Check modem status if modem control is enabled.
        !          32816:                 */
        !          32817:                if ( tp->t_flags & T_MODC ) {
        !          32818: 
        !          32819:                        b = inb( PORT+MSR );
        !          32820: 
        !          32821:                        if ( b & (MS_DCTS|MS_DDSR) ) {
        !          32822: 
        !          32823:                                if ( b & MS_DCTS ) {
        !          32824:                                        if ( b & MS_CTS )
        !          32825:                                                tp->t_flags &= ~T_STOP;
        !          32826:                                        else
        !          32827:                                                tp->t_flags |=  T_STOP;
        !          32828:                                }
        !          32829:                                if ( b & MS_DDSR ) {
        !          32830:                                        if ( b & MS_DSR )
        !          32831:                                                tp->t_flags |=  T_CARR;
        !          32832:                                        else {
        !          32833:                                                tp->t_flags &= ~T_CARR;
        !          32834:                                                tthup( tp );
        !          32835:                                        }
        !          32836:                                }
        !          32837:                        }
        !          32838:                }
        !          32839: 
        !          32840:                b = inb( PORT+LSR );
        !          32841: 
        !          32842:                if ( (b & LS_BREAK) && (tp->t_flags & T_CARR) )
        !          32843:                        ttsignal( tp, SIGINT );
        !          32844: 
        !          32845:                /*
        !          32846:                 * Receive ready.
        !          32847:                 */
        !          32848:                if ( b & LS_RxRDY ) {
        !          32849: 
        !          32850:                        tp->t_rawin.si_buf[tp->t_rawin.si_ix] = inb(PORT+DREG);
        !          32851: 
        !          32852:                        if ( tp->t_flags & T_CARR ) {
        !          32853: 
        !          32854:                                if ( ++(tp->t_rawin.si_ix) >=
        !          32855:                                                sizeof(tp->t_rawin.si_buf) )
        !          32856:                                        tp->t_rawin.si_ix = 0;
        !          32857:                        }
        !          32858:                }
        !          32859: 
        !          32860:                /*
        !          32861:                 * Transmit ready and raw output data exists.
        !          32862:                 */
        !          32863:                if ( (b & LS_TxRDY) && ((tp->t_flags & T_STOP) == 0)
        !          32864:                  && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          32865: 
        !          32866:                        outb(   PORT+DREG,
        !          32867:                                tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          32868: 
        !          32869:                        if ( ++(tp->t_rawout.si_ox) >=
        !          32870:                                        sizeof(tp->t_rawout.si_buf) )
        !          32871:                                tp->t_rawout.si_ox = 0;
        !          32872:                }
        !          32873: 
        !          32874:        } while ( ++tp <= hslimtty );
        !          32875: }
        !          32876: 
        !          32877: /*
        !          32878:  * Set hardware parameters.
        !          32879:  */
        !          32880: hsparam( tp )
        !          32881: register TTY * tp;
        !          32882: {
        !          32883:        register int b;
        !          32884:        int s;
        !          32885: 
        !          32886:        s = sphi();
        !          32887:        /*
        !          32888:         * Assert required modem control lines (DTR, RTS).
        !          32889:         */
        !          32890:        b = 0;
        !          32891:        if ( tp->t_sgttyb.sg_ospeed != B0 )
        !          32892:                b |=  MC_DTR | MC_RTS;
        !          32893:        outb( PORT+MCR, b );
        !          32894: 
        !          32895:        /*
        !          32896:         * Program baud rate.
        !          32897:         */
        !          32898:        if (b = timeconst[ tp->t_sgttyb.sg_ospeed ]) {
        !          32899:                outb( PORT+LCR, LC_DLAB );
        !          32900:                outb( PORT+DLL, b );
        !          32901:                outb( PORT+DLH, b >> 8 );
        !          32902:        }
        !          32903: 
        !          32904:        /*
        !          32905:         * Program character size, parity.
        !          32906:         */
        !          32907:        switch ( tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW) ) {
        !          32908:        case ODDP:              b = LC_CS7|LC_PARENB;            break;
        !          32909:        case EVENP:             b = LC_CS7|LC_PARENB|LC_PAREVEN; break;
        !          32910:        default:                b = LC_CS8;                      break;
        !          32911:        }
        !          32912:        outb( PORT+LCR, b );
        !          32913: 
        !          32914:        /*
        !          32915:         * Enable Transmit Buffer Empty Interrupts.
        !          32916:         */
        !          32917:        outb( PORT+IER, IE_TxI );
        !          32918: 
        !          32919:        spl(s);
        !          32920:        set_poll_rate();
        !          32921: }
        !          32922: 
        !          32923: /*
        !          32924:  * Start Routine.
        !          32925:  */
        !          32926: hsstart( tp )
        !          32927: register TTY * tp;
        !          32928: {
        !          32929:        register int s;
        !          32930: 
        !          32931:        /*
        !          32932:         * Transmit buffer is empty, and raw output buffer is not.
        !          32933:         */
        !          32934:        s = sphi();
        !          32935:        if ( (inb( PORT+LSR ) & LS_TxRDY)
        !          32936:          && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          32937: 
        !          32938:                /*
        !          32939:                 * Send next char from raw output buffer.
        !          32940:                 */
        !          32941:                outb( PORT+DREG, tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          32942: 
        !          32943:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          32944:                        tp->t_rawout.si_ox = 0;
        !          32945:        }
        !          32946:        spl( s );
        !          32947: }
        !          32948: 
        !          32949: /*
        !          32950:  * hsclk will be called every time T0 interrupts - if it returns 0,
        !          32951:  * the usual system timer interrupt stuff is done
        !          32952:  */
        !          32953: static int hsclk()
        !          32954: {
        !          32955:   static int count;
        !          32956: 
        !          32957:   hsintr();
        !          32958:   count++;
        !          32959:   if (count >= poll_divisor)
        !          32960:     count = 0;
        !          32961:   return count;
        !          32962: }
        !          32963: 
        !          32964: /*
        !          32965:  * set_poll_rate is called when a port is opened or closed or changes speed
        !          32966:  * it sets the polling rate only as fast as needed, and shuts off polling
        !          32967:  * whenever possible
        !          32968:  */
        !          32969: static set_poll_rate()
        !          32970: {
        !          32971:        int port_num, max_rate, port_rate;
        !          32972: 
        !          32973:        /*
        !          32974:         * If another driver has the polling clock, do nothing.
        !          32975:         */
        !          32976:        if (poll_owner & ~ POLL_HS)
        !          32977:                return;
        !          32978: 
        !          32979:        /*
        !          32980:         * find highest valid polling rate in units of HZ/10
        !          32981:         */
        !          32982:        max_rate = 0;
        !          32983:        for (port_num = 0; port_num < HSNUM; port_num++) {
        !          32984:                if (hstty[port_num].t_open) {
        !          32985:                  port_rate = poll_hz[hstty[port_num].t_sgttyb.sg_ispeed];
        !          32986:                  if (max_rate < port_rate)
        !          32987:                        max_rate = port_rate;
        !          32988:                }
        !          32989:        }
        !          32990:        /*
        !          32991:         * if max_rate is not current rate, adjust the system clock
        !          32992:         */
        !          32993:        if (max_rate != poll_rate) {
        !          32994:                poll_rate = max_rate;
        !          32995:                poll_divisor = poll_rate/HZ;  /* used in hsclk() */
        !          32996:                altclk_out();           /* stop previous polling */
        !          32997:                poll_owner &= ~POLL_HS;
        !          32998:                if (max_rate) { /* resume polling at new rate if needed */
        !          32999:                        altclk_in(poll_rate, hsclk);
        !          33000:                        poll_owner |= POLL_HS;
        !          33001:                }
        !          33002:        }
        !          33003: }
        !          33004: @
        !          33005: 
        !          33006: 
        !          33007: 1.2
        !          33008: log
        !          33009: @new version provided y hal for v321
        !          33010: @
        !          33011: text
        !          33012: @d11 2
        !          33013: a12 2
        !          33014: #include "coherent.h"
        !          33015: #include "ins8250.h"
        !          33016: a18 1
        !          33017: #include <sys/timeout.h>       /* TIM */
        !          33018: d20 1
        !          33019: a20 1
        !          33020: #include <poll_clk.h>
        !          33021: @
        !          33022: 
        !          33023: 
        !          33024: 1.1
        !          33025: log
        !          33026: @Shipped with COHERENT 3.1.0
        !          33027: @
        !          33028: text
        !          33029: @d20 1
        !          33030: a20 1
        !          33031: #include <sched.h>             /* CVTTOUT, IVTTOUT, SVTTOUT */
        !          33032: @
        !          33033: 
        !          33034: 
        !          33035: 1.1.1.1
        !          33036: log
        !          33037: @Add MSR delta save and modem control.  Doesn't work.
        !          33038: @
        !          33039: text
        !          33040: @a4 2
        !          33041:  *
        !          33042:  *     $Header: /usr/src/sys/i8086/drv/RCS/hs.c,v 1.2 91/02/13 15:54:29 root Exp $
        !          33043: a36 3
        !          33044:  *
        !          33045:  * "PORT" is a macro yielding the 8250 base address, given the "tp" pointer.
        !          33046:  * "PORT_NUM" is a macro yielding the port index (0..MAX_HSNUM-1) given "tp".
        !          33047: d41 1
        !          33048: a41 3
        !          33049: #define        PORT            (HS_PORTS[(int)(tp->t_ddp)].addr)
        !          33050: #define        PORT_NUM        ((int)(tp->t_ddp))
        !          33051: #define MSR_DELTAS     (MS_DCTS | MS_DDSR | MS_TERI | MS_DRLSD)
        !          33052: d63 1
        !          33053: a63 3
        !          33054:  * 8250's MSR delta bits are cleared each time the MSR is read.
        !          33055:  * But different parts of the driver look for deltas of different bits.
        !          33056:  * Array msr[] saves delta bits until they are needed.
        !          33057: a64 4
        !          33058: static char msr[MAX_HSNUM];
        !          33059: /*
        !          33060:  * Export Functions.
        !          33061:  */
        !          33062: d200 1
        !          33063: a200 1
        !          33064:                tp->t_ddp     = i;
        !          33065: d225 1
        !          33066: a225 1
        !          33067:        int port = PORT;
        !          33068: d227 1
        !          33069: a227 2
        !          33070:        char msr_ch;
        !          33071: printf("hsopen #%d: enter, count=%d\n", PORT_NUM, tp->t_open);
        !          33072: d231 1
        !          33073: a231 1
        !          33074:        if ( (port == 0) || (inb(port+IER) & ~IE_TxI) ) {
        !          33075: d235 1
        !          33076: a235 1
        !          33077:        
        !          33078: d237 1
        !          33079: a237 1
        !          33080:         * Don't allow open if flagged for exclusive use and not super-user.
        !          33081: a238 16
        !          33082:        if ((tp->t_flags & T_EXCL) && !super()) {
        !          33083:                u.u_error = ENODEV;
        !          33084:                return;
        !          33085:        }
        !          33086: 
        !          33087:        /*
        !          33088:         * Don't open if modem is settling from previous close.
        !          33089:         */
        !          33090:        if (drvl[major(dev)].d_time != 0) {     /* Modem settling */
        !          33091:                u.u_error = EDBUSY;
        !          33092:                return;
        !          33093:        }
        !          33094: 
        !          33095:        /*
        !          33096:         * Can't open if another driver is using polling
        !          33097:         */
        !          33098: d247 1
        !          33099: a247 6
        !          33100:        if ( tp->t_open++ == 0 ) {
        !          33101:                hscycle( tp );
        !          33102:                /*
        !          33103:                 * ttopen() will call hsparam()
        !          33104:                 * hsparam() asserts DTR and RTS and sets polling rate
        !          33105:                 */
        !          33106: d250 1
        !          33107: a250 1
        !          33108:                if (dev & 0x80) { /* if modem control... */
        !          33109: d252 3
        !          33110: a254 23
        !          33111:                        tp->t_flags |= T_MODC + T_STOP + T_HOPEN;
        !          33112:                        /*
        !          33113:                         * Sleep while waiting for carrier.
        !          33114:                         */
        !          33115:                        while(1) {
        !          33116:                                msr_ch = inb(port + MSR);
        !          33117:                                msr[PORT_NUM] |= msr_ch & MSR_DELTAS; 
        !          33118:                                if (msr_ch & MS_RLSD)
        !          33119:                                        break;
        !          33120:                                sleep((char *)(&tp->t_open), CVTTOUT, IVTTOUT,
        !          33121:                                        SVTTOUT);       /* wait for carrier */
        !          33122:                                if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          33123:                                        outb(port+MCR, 0);  /* kill RTS/DTR */
        !          33124:                                        u.u_error = EINTR;
        !          33125:                                        spl(s);
        !          33126:                                        tp->t_open = 0;
        !          33127:                                        return;
        !          33128:                                }
        !          33129:                        }
        !          33130:                        tp->t_flags &= ~T_HOPEN; /* no longer hanging in open */
        !          33131:                        msr_ch = inb(port + MSR);
        !          33132:                        msr[PORT_NUM] |= msr_ch & MSR_DELTAS; 
        !          33133:                        if (msr_ch & MS_CTS)
        !          33134: d256 2
        !          33135: d263 1
        !          33136: d266 1
        !          33137: a266 1
        !          33138: printf("hsopen #%d: leave, count=%d\n", PORT_NUM, tp->t_open);
        !          33139: d276 1
        !          33140: a276 1
        !          33141: printf("hsclose #%d: enter, count=%d\n", PORT_NUM, tp->t_open);
        !          33142: a281 2
        !          33143:                int holdflags = tp->t_flags;    /* save flags */
        !          33144:                int port = PORT;
        !          33145: d283 1
        !          33146: a283 10
        !          33147:                ttclose( tp );                  /* clears flags */
        !          33148: 
        !          33149:                if (holdflags & T_HOPEN) {  /* if waiting for RLSD... */
        !          33150:                        /*
        !          33151:                         * Flags for first open
        !          33152:                         * (clear T_HPCL)
        !          33153:                         */
        !          33154:                        tp->t_flags = T_MODC | T_HOPEN;
        !          33155:                }
        !          33156: 
        !          33157: a284 18
        !          33158:                 * If hupcls
        !          33159:                 */
        !          33160:                if (holdflags & T_HPCL) {
        !          33161:                        int maj;
        !          33162:                        /*
        !          33163:                         * Hangup port
        !          33164:                         */
        !          33165:                        outb(port+MCR, 0);
        !          33166:                        /*
        !          33167:                         * Hold dtr low for timeout
        !          33168:                         */
        !          33169:                        maj = major(dev);
        !          33170:                        drvl[maj].d_time = 1;
        !          33171:                        sleep((char *)&drvl[maj].d_time, CVTTOUT, IVTTOUT, SVTTOUT);
        !          33172:                        drvl[maj].d_time = 0;
        !          33173:                }
        !          33174:                
        !          33175:                /*
        !          33176: a303 1
        !          33177: printf("hsclose #%d: leave, count=%d\n", PORT_NUM, tp->t_open);
        !          33178: a357 1
        !          33179:        int msr_ch;
        !          33180: d360 1
        !          33181: a360 1
        !          33182:         * Check modem status every clock tick.
        !          33183: a361 40
        !          33184:        if ( tp->t_flags & T_MODC ) {
        !          33185:                /*
        !          33186:                 * Get status
        !          33187:                 */
        !          33188:                msr_ch = inb(PORT + MSR);
        !          33189:                msr[PORT_NUM] |= msr_ch & MSR_DELTAS; 
        !          33190: 
        !          33191:                /*
        !          33192:                 * Carrier changed.
        !          33193:                 */
        !          33194:                if ( msr[PORT_NUM] & MS_DRLSD ) {
        !          33195:                        if (msr_ch & MS_RLSD)
        !          33196:                                tp->t_flags |= T_CARR;  /* carrier on */
        !          33197:                        else
        !          33198:                                tp->t_flags &= ~T_CARR; /* no carrier */
        !          33199: 
        !          33200:                        msr[PORT_NUM] &= ~MS_DRLSD;
        !          33201:                        /*
        !          33202:                         * wakeup open
        !          33203:                         */
        !          33204:                        if ( tp->t_open == 0 ) {
        !          33205:                                wakeup((char *)(&tp->t_open));
        !          33206:                        }
        !          33207: 
        !          33208:                        /*
        !          33209:                         * carrier off?
        !          33210:                         */
        !          33211:                        else if ( (msr_ch & MS_RLSD) == 0 ) {
        !          33212:                                /*
        !          33213:                                 * clear carrier flag; send hangup signal
        !          33214:                                 */
        !          33215:                                tp->t_rawin.si_ox = tp->t_rawin.si_ix;
        !          33216:                                tthup( tp );
        !          33217:                        }
        !          33218:                }
        !          33219:        }
        !          33220: 
        !          33221:        /*
        !          33222:         * Process rawin buf.
        !          33223:         */
        !          33224: a410 1
        !          33225:        char msr_ch;
        !          33226: a412 2
        !          33227:                int port = PORT, port_num = PORT_NUM;   /* for speed */
        !          33228: 
        !          33229: d421 1
        !          33230: a421 2
        !          33231:                        msr_ch = inb(port + MSR);
        !          33232:                        msr[port_num] |= msr_ch & MSR_DELTAS; 
        !          33233: d423 16
        !          33234: a438 6
        !          33235:                        if ( msr[port_num] & MS_DCTS ) {
        !          33236:                                msr[port_num] &= ~MS_DCTS;
        !          33237:                                if ( msr_ch & MS_CTS )
        !          33238:                                        tp->t_flags &= ~T_STOP;
        !          33239:                                else
        !          33240:                                        tp->t_flags |=  T_STOP;
        !          33241: d442 1
        !          33242: a442 1
        !          33243:                b = inb( port+LSR );
        !          33244: d452 1
        !          33245: a452 1
        !          33246:                        tp->t_rawin.si_buf[tp->t_rawin.si_ix] = inb(port+DREG);
        !          33247: d468 1
        !          33248: a468 1
        !          33249:                        outb(port+DREG,
        !          33250: a573 1
        !          33251: printf("set_poll_rate()\n");
        !          33252: a587 1
        !          33253: printf("port %d  rate=%d\n", port_num, port_rate);               
        !          33254: a598 1
        !          33255: printf("altclk_out()\n");              
        !          33256: a601 1
        !          33257: printf("altclk_in(%d, hsclk)\n", poll_rate);                   
        !          33258: @
        !          33259: 0707070064030106661004440000030000030000011777770507310652500005400000020361/newbits/kernel/USRSRC/i8086/drv/RCS/lp.c,vhead     1.4;
        !          33260: branch   ;
        !          33261: access   ;
        !          33262: symbols  ;
        !          33263: locks    bin:1.4;
        !          33264: comment  @ * @;
        !          33265: 
        !          33266: 
        !          33267: 1.4
        !          33268: date     91.06.20.14.50.37;  author bin;  state Exp;
        !          33269: branches ;
        !          33270: next     1.3;
        !          33271: 
        !          33272: 1.3
        !          33273: date     91.06.17.12.32.34;  author bin;  state Exp;
        !          33274: branches ;
        !          33275: next     1.2;
        !          33276: 
        !          33277: 1.2
        !          33278: date     91.06.06.18.23.34;  author norm;  state Exp;
        !          33279: branches ;
        !          33280: next     1.1;
        !          33281: 
        !          33282: 1.1
        !          33283: date     91.06.06.18.22.30;  author hal;  state Exp;
        !          33284: branches ;
        !          33285: next     ;
        !          33286: 
        !          33287: 
        !          33288: desc
        !          33289: @Parallel printer driver - no interrupts!
        !          33290: @
        !          33291: 
        !          33292: 
        !          33293: 1.4
        !          33294: log
        !          33295: @update provided by hal
        !          33296: @
        !          33297: text
        !          33298: @/*
        !          33299:  * This is a driver for PC parallel printers.
        !          33300:  * It has been tested on an EPSON MX-80, Printronix P300, HP LaserJet II.
        !          33301:  * Supports up to three line printers.
        !          33302:  */
        !          33303: #include <sys/coherent.h>
        !          33304: #include <sys/i8086.h>
        !          33305: #include <sys/con.h>
        !          33306: #include <errno.h>
        !          33307: #include <sys/io.h>
        !          33308: #include <sys/proc.h>
        !          33309: #include <sys/uproc.h>
        !          33310: #include <sys/stat.h>
        !          33311: 
        !          33312: #define        LPMAJ   3                               /* major device # */
        !          33313: 
        !          33314: /*
        !          33315:  * Patchable parameters.
        !          33316:  *
        !          33317:  *     LP0_OK specifies whether LP0 is always THERE.
        !          33318:  *     LPTIME specifies number of ticks between polls.
        !          33319:  *     LPWAIT specifies loop counter to wait in poll.
        !          33320:  *     LPTEST specifies whether or not to test for on-line conditition.
        !          33321:  */
        !          33322: int    LP0_OK = 0;
        !          33323: int    LPTIME = 4;
        !          33324: int    LPWAIT = 400;
        !          33325: int    LPTEST = 1;
        !          33326: 
        !          33327: /*
        !          33328:  * Driver configuration.
        !          33329:  */
        !          33330: int    lpload();
        !          33331: int    lpunload();
        !          33332: int    lpwrite();
        !          33333: int    lpopen();
        !          33334: int    lpclose();
        !          33335: int    lpintr();
        !          33336: int    nulldev();
        !          33337: int    nonedev();
        !          33338: 
        !          33339: CON    lpcon = {
        !          33340:        DFCHR,                          /* Flags */
        !          33341:        LPMAJ,                          /* Major index */
        !          33342:        lpopen,                         /* Open */
        !          33343:        lpclose,                        /* Close */
        !          33344:        nulldev,                        /* Block */
        !          33345:        nonedev,                        /* Read */
        !          33346:        lpwrite,                        /* Write */
        !          33347:        nonedev,                        /* Ioctl */
        !          33348:        nulldev,                        /* Powerfail */
        !          33349:        nulldev,                        /* Timeout */
        !          33350:        lpload,                         /* Load */
        !          33351:        lpunload                        /* Unload */
        !          33352: };
        !          33353: 
        !          33354: /*
        !          33355:  * Line Printer Registers.
        !          33356:  */
        !          33357: #define        LPDAT   (0)                     /* Data port, lpbase + 0 */
        !          33358: #define        LPSTR   (1)                     /* Status port, lpbase + 1 */
        !          33359: #define        LPCSR   (2)                     /* Control port, lpbase + 2 */
        !          33360: 
        !          33361: /*
        !          33362:  * LP Flag Bits.
        !          33363:  */
        !          33364: #define        LPTHERE 0x01                    /* Interface actually there */
        !          33365: #define        LPOPEN  0x02                    /* Printer is open */
        !          33366: #define        LPSLEEP 0x04                    /* Sleeping on buffer event */
        !          33367: #define        LPRAW   0x80                    /* Raw mode */
        !          33368: 
        !          33369: /*
        !          33370:  * Printer database.
        !          33371:  * Terminated by lpbase = 0.
        !          33372:  * NLP = # entries - 1.
        !          33373:  */
        !          33374: static struct  lpinfo  {
        !          33375:        int     lpbase;                 /* I/O Base address */
        !          33376:        int     lpflag;                 /* Flags */
        !          33377:        int     lpcol;                  /* Current horizontal position */
        !          33378: }      lpinfo[] = {
        !          33379:        {       0x3BC   },
        !          33380:        {       0x378   },
        !          33381:        {       0x278   },
        !          33382:        {       0x000   }
        !          33383: };
        !          33384: #define        NLP     (sizeof(lpinfo) / sizeof(lpinfo[0]) - 1)
        !          33385: 
        !          33386: /*
        !          33387:  * LP Status Register Bits.
        !          33388:  */
        !          33389: #define        ACK     0x80                    /* Ack (active high) */
        !          33390: #define        BUSY    0x40                    /* Busy (active high) */
        !          33391: #define        NOPAPER 0x20                    /* No paper */
        !          33392: #define        ONLINE  0x10                    /* On line */
        !          33393: #define        NERROR  0x08                    /* Error (active low) */
        !          33394: 
        !          33395: /* IBM cable */
        !          33396: #define        IBMNBSY 0x80                    /* Busy (active low) */
        !          33397: #define        IBMNACK 0x40                    /* Ack (active low) */
        !          33398: 
        !          33399: /*
        !          33400:  * LP Control Register Bits.
        !          33401:  */
        !          33402: #define        IENABLE 0x10                    /* Interrupt enable */
        !          33403: #define        SEL     0x08                    /* Select input */
        !          33404: #define        NINIT   0x04                    /* Initialise printer (active low) */
        !          33405: #define        AFEED   0x02                    /* Auto line feed */
        !          33406: #define        STROBE  0x01                    /* Strobe */
        !          33407: 
        !          33408: /*
        !          33409:  * On load
        !          33410:  * compute the port addresses,
        !          33411:  * reset the printer, and select it.
        !          33412:  */
        !          33413: static
        !          33414: lpload()
        !          33415: {
        !          33416:        register struct lpinfo * p;
        !          33417:        register int delay;
        !          33418:        static int notfirst;
        !          33419: 
        !          33420:        /*
        !          33421:         * Only initialize hardware on first invocation.
        !          33422:         * Necessary if used as console device [condev].
        !          33423:         */
        !          33424:        if ( notfirst )
        !          33425:                return;
        !          33426:        notfirst = 1;
        !          33427: 
        !          33428:        /*
        !          33429:         * Note: since some PC clones lp ports can't be read,
        !          33430:         * their lpflag field has to be patched to 'LPTHERE'.
        !          33431:         */
        !          33432:        if ( LP0_OK & 1 )
        !          33433:                lpinfo[0].lpflag |= LPTHERE;
        !          33434:        if ( LP0_OK & 2 )
        !          33435:                lpinfo[1].lpflag |= LPTHERE;
        !          33436:        if ( LP0_OK & 4 )
        !          33437:                lpinfo[2].lpflag |= LPTHERE;
        !          33438: 
        !          33439:        for ( p = lpinfo; p->lpbase ; ++p ) {
        !          33440: 
        !          33441:                /*
        !          33442:                 * Check printer port existence.
        !          33443:                 */
        !          33444:                if ( (p->lpflag & LPTHERE) == 0 ) {
        !          33445:                        outb( p->lpbase+LPDAT, 0xA5 );
        !          33446:                        delay = LPWAIT; do {
        !          33447:                        } while (--delay);
        !          33448:                        if ( inb(p->lpbase+LPDAT) == 0xA5 )
        !          33449:                                p->lpflag |= LPTHERE;
        !          33450:                }
        !          33451: 
        !          33452:                /*
        !          33453:                 * Initialize and select printer.
        !          33454:                 */
        !          33455:                outb( p->lpbase+LPCSR, SEL );
        !          33456:                delay = LPWAIT; do {
        !          33457:                } while (--delay);
        !          33458:                outb( p->lpbase+LPCSR, SEL|NINIT );
        !          33459:        }
        !          33460: }
        !          33461: 
        !          33462: /*
        !          33463:  * On unload
        !          33464:  * cancel any timed functions.
        !          33465:  */
        !          33466: static
        !          33467: lpunload()
        !          33468: {
        !          33469:        lptimer();
        !          33470: }
        !          33471: 
        !          33472: /*
        !          33473:  * The open routine makes sure that
        !          33474:  * only one process has the printer open
        !          33475:  * at one time, and not too much else.
        !          33476:  */
        !          33477: static
        !          33478: lpopen(dev, mode)
        !          33479: dev_t  dev;
        !          33480: {
        !          33481:        register struct lpinfo * p;
        !          33482: 
        !          33483:        /*
        !          33484:         * Illegal printer port.
        !          33485:         */
        !          33486:        if ( (minor(dev) & ~LPRAW) >= NLP ) {
        !          33487:                u.u_error = ENXIO;
        !          33488:                return;
        !          33489:        }
        !          33490: 
        !          33491:        /*
        !          33492:         * Access attributes.
        !          33493:         */
        !          33494:        p = &lpinfo[ minor(dev) & ~LPRAW ];
        !          33495: 
        !          33496:        /*
        !          33497:         * Attempt initialization if printer port not found.
        !          33498:         */
        !          33499:        if ( (p->lpflag&LPTHERE) == 0 )
        !          33500:                lpload();
        !          33501: 
        !          33502:        /*
        !          33503:         * Printer port not found.
        !          33504:         */
        !          33505:        if ( (p->lpflag&LPTHERE) == 0 ) {
        !          33506:                u.u_error = ENXIO;
        !          33507:                return;
        !          33508:        }
        !          33509: 
        !          33510:        /*
        !          33511:         * Printer port already open.
        !          33512:         */
        !          33513:        if ( (p->lpflag&LPOPEN) != 0 ) {
        !          33514:                u.u_error = EDBUSY;
        !          33515:                return;
        !          33516:        }
        !          33517: 
        !          33518:        /*
        !          33519:         * Printer powered off or off-line
        !          33520:         */
        !          33521:        if (LPTEST && !(inb(p->lpbase+LPSTR) & ONLINE)) {
        !          33522:                u.u_error = EDATTN;
        !          33523:                return;
        !          33524:        }
        !          33525: 
        !          33526:        /*
        !          33527:         * Flag port as being open.
        !          33528:         */
        !          33529:        p->lpflag &= ~LPRAW;
        !          33530:        p->lpflag |= LPOPEN | minor(dev) & LPRAW;
        !          33531: 
        !          33532:        /*
        !          33533:         * Initiate periodic printer scan if user open.
        !          33534:         */
        !          33535:        if ( (SELF != NULL) && (SELF->p_pid != 0) )
        !          33536:                lptimer();
        !          33537: }
        !          33538: 
        !          33539: /*
        !          33540:  * The close routine marks the device as no longer open.
        !          33541:  */
        !          33542: static
        !          33543: lpclose(dev)
        !          33544: dev_t  dev;
        !          33545: {
        !          33546:        lpinfo[ minor(dev) & ~LPRAW ].lpflag &= ~LPOPEN;
        !          33547: }
        !          33548: 
        !          33549: /*
        !          33550:  * The write routine copies the
        !          33551:  * characters from the user buffer to
        !          33552:  * the printer buffer, expanding tabs and
        !          33553:  * keeping track of the current horizontal
        !          33554:  * position of the print head.
        !          33555:  */
        !          33556: static
        !          33557: lpwrite( dev, iop )
        !          33558: dev_t  dev;
        !          33559: IO     *iop;
        !          33560: {
        !          33561:        register struct lpinfo * p;
        !          33562:        register int    c;
        !          33563: 
        !          33564:        p = &lpinfo[ minor(dev) & ~LPRAW ];
        !          33565: 
        !          33566:        /*
        !          33567:         * Writes from kernel are handled via busy-waits instead of timeouts.
        !          33568:         */
        !          33569:        if (iop->io_seg == IOSYS) {
        !          33570: 
        !          33571:                while ( (c=iogetc(iop)) >= 0 ) {
        !          33572: 
        !          33573:                        while ( (inb(p->lpbase+LPSTR) & IBMNBSY) == 0 )
        !          33574:                                ;
        !          33575: 
        !          33576:                        outb( p->lpbase+LPDAT, c );
        !          33577:                        outb( p->lpbase+LPCSR, SEL|NINIT|STROBE );
        !          33578:                        outb( p->lpbase+LPCSR, SEL|NINIT );
        !          33579:                }
        !          33580:                return;
        !          33581:        }
        !          33582: 
        !          33583:        /*
        !          33584:         * Writes from user are handled via lpchar() which uses timeouts.
        !          33585:         */
        !          33586:        while ( (c=iogetc(iop)) >= 0 ) {
        !          33587: 
        !          33588:                if ( (p->lpflag&LPRAW) == 0 ) {
        !          33589: 
        !          33590:                        switch (c) {
        !          33591: 
        !          33592:                        case '\t':
        !          33593:                                do {
        !          33594:                                        lpchar( p, ' ');
        !          33595:                                } while ((++p->lpcol&07) != 0);
        !          33596:                                continue;
        !          33597:        
        !          33598:                        case '\n':
        !          33599:                                lpchar( p, '\r');
        !          33600:                                /* no break */
        !          33601: 
        !          33602:                        case '\r':
        !          33603:                        case '\f':
        !          33604:                                p->lpcol = 0;
        !          33605:                                break;
        !          33606:        
        !          33607:                        case '\b':
        !          33608:                                --p->lpcol;
        !          33609:                                break;
        !          33610:        
        !          33611:                        default:
        !          33612:                                ++p->lpcol;
        !          33613:                        }
        !          33614:                }
        !          33615:                lpchar( p, c );
        !          33616: 
        !          33617:                if ( SELF->p_ssig!=0 && nondsig() ) {
        !          33618:                        u.u_error = EINTR;
        !          33619:                        break;
        !          33620:                }
        !          33621:        }
        !          33622: }
        !          33623: 
        !          33624: /*
        !          33625:  * Put a character into the printer buffer.
        !          33626:  * If the printer doesn't respond ready in a reasonable time
        !          33627:  * sleep for a while.
        !          33628:  */
        !          33629: static
        !          33630: lpchar( p, c )
        !          33631: register struct lpinfo *p;
        !          33632: int c;
        !          33633: {
        !          33634:        register int    s;
        !          33635: 
        !          33636:        s = LPWAIT;
        !          33637:        while ( (inb(p->lpbase+LPSTR) & IBMNBSY) == 0 ) {
        !          33638:                if ( --s == 0 ) {
        !          33639:                        s = sphi();
        !          33640:                        p->lpflag |= LPSLEEP;
        !          33641:                        sleep((char *)p, 0, 0, 0);
        !          33642:                        spl(s);
        !          33643:                        s = LPWAIT;
        !          33644:                }
        !          33645:        }
        !          33646: 
        !          33647:        outb( p->lpbase+LPDAT, c );
        !          33648:        outb( p->lpbase+LPCSR, SEL|NINIT|STROBE );
        !          33649:        outb( p->lpbase+LPCSR, SEL|NINIT );
        !          33650: }
        !          33651: 
        !          33652: /*
        !          33653:  * Poll the line printer interface from the clock.
        !          33654:  * Turn it off when there is nothing left to do.
        !          33655:  */
        !          33656: static
        !          33657: lptimer()
        !          33658: {
        !          33659:        register struct lpinfo *p;
        !          33660:        int isopen = 0;
        !          33661:        static TIM tim;
        !          33662: 
        !          33663:        /*
        !          33664:         * Scan all printers.
        !          33665:         */
        !          33666:        for ( p = lpinfo; p->lpbase; ++p ) {
        !          33667: 
        !          33668:                /*
        !          33669:                 * Ignore unopened printers.
        !          33670:                 */
        !          33671:                if ( (p->lpflag & LPOPEN) == 0 )
        !          33672:                        continue;
        !          33673: 
        !          33674:                ++isopen;
        !          33675: 
        !          33676:                /*
        !          33677:                 * Check for sleeping process on ready printer.
        !          33678:                 */
        !          33679:                if((p->lpflag & LPSLEEP) && (inb(p->lpbase+LPSTR) & IBMNBSY)){
        !          33680:                        p->lpflag &= ~LPSLEEP;
        !          33681:                        wakeup((char *)p);
        !          33682:                }
        !          33683:        }
        !          33684: 
        !          33685:        /*
        !          33686:         * Reschedule timer function if at least 1 printer is still open.
        !          33687:         */
        !          33688:        if ( isopen )
        !          33689:                timeout( &tim, LPTIME, lptimer, &tim );
        !          33690: }
        !          33691: @
        !          33692: 
        !          33693: 
        !          33694: 1.3
        !          33695: log
        !          33696: @new version provided y hal for v321
        !          33697: @
        !          33698: text
        !          33699: @d6 2
        !          33700: a7 2
        !          33701: #include <coherent.h>
        !          33702: #include <i8086.h>
        !          33703: a13 1
        !          33704: #include <sys/timeout.h>
        !          33705: @
        !          33706: 
        !          33707: 
        !          33708: 1.2
        !          33709: log
        !          33710: @Add patchable variable LPTEST for 3.0.0 compatibility.
        !          33711: @
        !          33712: text
        !          33713: @d8 1
        !          33714: a8 1
        !          33715: #include <con.h>
        !          33716: d10 4
        !          33717: a13 4
        !          33718: #include <io.h>
        !          33719: #include <proc.h>
        !          33720: #include <uproc.h>
        !          33721: #include <stat.h>
        !          33722: @
        !          33723: 
        !          33724: 
        !          33725: 1.1
        !          33726: log
        !          33727: @Shipped with 3.1.0
        !          33728: @
        !          33729: text
        !          33730: @a0 5
        !          33731: /* (-lgl
        !          33732:  *     COHERENT Driver Kit Version 1.1.0
        !          33733:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          33734:  *     All rights reserved. May not be copied without permission.
        !          33735:  -lgl) */
        !          33736: d24 1
        !          33737: d26 4
        !          33738: a29 3
        !          33739: int LP0_OK = 0;
        !          33740: int LPTIME = 4;
        !          33741: int LPWAIT = 400;
        !          33742: d225 1
        !          33743: a225 1
        !          33744:        if ((inb(p->lpbase+LPSTR) & ONLINE) == 0) {
        !          33745: @
        !          33746: 0707070064030104251004440000030000030000011777770507310652700005700000004225/newbits/kernel/USRSRC/i8086/drv/RCS/msgop.c,vhead     1.2;
        !          33747: branch   ;
        !          33748: access   ;
        !          33749: symbols  ;
        !          33750: locks    ;
        !          33751: comment  @ * @;
        !          33752: 
        !          33753: 
        !          33754: 1.2
        !          33755: date     91.06.03.19.53.53;  author hal;  state Exp;
        !          33756: branches ;
        !          33757: next     1.1;
        !          33758: 
        !          33759: 1.1
        !          33760: date     91.06.03.19.52.40;  author hal;  state Exp;
        !          33761: branches ;
        !          33762: next     ;
        !          33763: 
        !          33764: 
        !          33765: desc
        !          33766: @Original, nfg with COH 3.X.X.
        !          33767: @
        !          33768: 
        !          33769: 
        !          33770: 1.2
        !          33771: log
        !          33772: @fixed to run with COH 3.1.0+
        !          33773: @
        !          33774: text
        !          33775: @/*
        !          33776:  * User Message Functions.
        !          33777:  *
        !          33778:  *     Note: msgget() must be first function called.
        !          33779:  *
        !          33780:  *     91/02/07        Hal Snyder      mwchwc!/u/libc/sys/msgop.c
        !          33781:  *     msgget():  sizeof(key_t) is 4, not 2.
        !          33782:  */
        !          33783: #include <sys/msg.h>
        !          33784: #include <errno.h>
        !          33785: 
        !          33786: static int  msgfno   = -1;
        !          33787: static char msgdev[] = "/dev/msg";
        !          33788: 
        !          33789: /*
        !          33790:  * Message Control Operations.
        !          33791:  */
        !          33792: 
        !          33793: msgctl( msqid, cmd, buf )
        !          33794: 
        !          33795: int msqid;
        !          33796: int cmd;
        !          33797: struct msqid_ds * buf;
        !          33798: 
        !          33799: {
        !          33800:        int parm[4];
        !          33801: 
        !          33802:        if ( msgfno < 0 ) {
        !          33803:                errno = ENODEV;
        !          33804:                return -1;
        !          33805:        }
        !          33806: 
        !          33807:        parm[0] = -1;
        !          33808:        parm[1] = msqid;
        !          33809:        parm[2] = cmd;
        !          33810:        parm[3] = (int) buf;
        !          33811: 
        !          33812:        ioctl( msgfno, MSGCTL, parm );
        !          33813:        return parm[0];
        !          33814: }
        !          33815: 
        !          33816: /*
        !          33817:  * Get Message Queue.
        !          33818:  */
        !          33819: 
        !          33820: msgget( key, msgflg )
        !          33821: 
        !          33822: key_t key;
        !          33823: int msgflg;
        !          33824: 
        !          33825: {
        !          33826:        int parm[4];
        !          33827: 
        !          33828:        if ( msgfno < 0 ) {
        !          33829: 
        !          33830:                msgfno = open(msgdev, 0);
        !          33831: 
        !          33832:                if ( msgfno < 0 ) {
        !          33833:                        perror(msgdev);
        !          33834:                        errno = ENODEV;
        !          33835:                        return -1;
        !          33836:                }
        !          33837:        }
        !          33838: 
        !          33839:        parm[0] = -1;
        !          33840:        parm[1] = key;
        !          33841:        parm[2] = key >> 16;
        !          33842:        parm[3] = msgflg;
        !          33843: 
        !          33844:        ioctl( msgfno, MSGGET, parm );
        !          33845:        return parm[0];
        !          33846: }
        !          33847: 
        !          33848: /*
        !          33849:  * Send Message.
        !          33850:  */
        !          33851:  
        !          33852: msgsnd( msqid, msgp, msgsz, msgflg )
        !          33853: 
        !          33854: int msqid;
        !          33855: struct msgbuf *msgp;
        !          33856: int msgsz;
        !          33857: int msgflg;
        !          33858: 
        !          33859: {
        !          33860:        int parm[5];
        !          33861: 
        !          33862:        if ( msgfno < 0 ) {
        !          33863:                errno = ENODEV;
        !          33864:                return -1;
        !          33865:        }
        !          33866: 
        !          33867:        parm[0] = -1;
        !          33868:        parm[1] = msqid;
        !          33869:        parm[2] = (int) msgp;
        !          33870:        parm[3] = msgsz;
        !          33871:        parm[4] = msgflg;
        !          33872: 
        !          33873:        ioctl( msgfno, MSGSND, parm );
        !          33874:        return parm[0];
        !          33875: }
        !          33876: 
        !          33877: /*
        !          33878:  * Receive Message.
        !          33879:  */
        !          33880:  
        !          33881: msgrcv( msqid, msgp, msgsz, msgtyp, msgflg )
        !          33882: 
        !          33883: int msqid;
        !          33884: struct msgbuf *msgp;
        !          33885: int msgsz;
        !          33886: long msgtyp;
        !          33887: int msgflg;
        !          33888: 
        !          33889: {
        !          33890:        int parm[7];
        !          33891: 
        !          33892:        if ( msgfno < 0 ) {
        !          33893:                errno = ENODEV;
        !          33894:                return -1;
        !          33895:        }
        !          33896: 
        !          33897:        parm[0] = -1;
        !          33898:        parm[1] = msqid;
        !          33899:        parm[2] = (int) msgp;
        !          33900:        parm[3] = msgsz;
        !          33901:        parm[4] = (int) msgtyp;
        !          33902:        parm[5] = (int) (msgtyp >> 16);
        !          33903:        parm[6] = msgflg;
        !          33904: 
        !          33905:        ioctl( msgfno, MSGRCV, parm );
        !          33906:        return parm[0];
        !          33907: }
        !          33908: @
        !          33909: 
        !          33910: 
        !          33911: 1.1
        !          33912: log
        !          33913: @Initial revision
        !          33914: @
        !          33915: text
        !          33916: @d5 3
        !          33917: a8 1
        !          33918:  
        !          33919: d52 1
        !          33920: a52 1
        !          33921:        int parm[3];
        !          33922: d56 1
        !          33923: a56 1
        !          33924:                if ( (msgfno = open(msgdev, 0)) < 0 ) {
        !          33925: d58 1
        !          33926: d67 2
        !          33927: a68 1
        !          33928:        parm[2] = msgflg;
        !          33929: @
        !          33930: 0707070064030106531004440000030000030000011777770507310652700005400000012137/newbits/kernel/USRSRC/i8086/drv/RCS/rm.c,vhead     1.4;
        !          33931: branch   ;
        !          33932: access   ;
        !          33933: symbols  ;
        !          33934: locks    bin:1.4;
        !          33935: comment  @ * @;
        !          33936: 
        !          33937: 
        !          33938: 1.4
        !          33939: date     91.06.20.14.52.16;  author bin;  state Exp;
        !          33940: branches ;
        !          33941: next     1.3;
        !          33942: 
        !          33943: 1.3
        !          33944: date     91.06.18.15.10.01;  author bin;  state Exp;
        !          33945: branches ;
        !          33946: next     1.2;
        !          33947: 
        !          33948: 1.2
        !          33949: date     91.06.06.18.25.45;  author norm;  state Exp;
        !          33950: branches ;
        !          33951: next     1.1;
        !          33952: 
        !          33953: 1.1
        !          33954: date     91.06.06.18.24.51;  author hal;  state Exp;
        !          33955: branches ;
        !          33956: next     ;
        !          33957: 
        !          33958: 
        !          33959: desc
        !          33960: @Ram disk driver.
        !          33961: @
        !          33962: 
        !          33963: 
        !          33964: 1.4
        !          33965: log
        !          33966: @update provided by hal
        !          33967: @
        !          33968: text
        !          33969: @/*
        !          33970:  * Block or character device RAM disk driver.
        !          33971:  */
        !          33972: 
        !          33973: #include       <sys/coherent.h>
        !          33974: #include       <sys/buf.h>
        !          33975: #include       <errno.h>
        !          33976: #include       <sys/uproc.h>
        !          33977: #include       <sys/seg.h>
        !          33978: #include       <sys/con.h>
        !          33979: #include       <sys/inode.h>
        !          33980: #include       <sys/stat.h>
        !          33981: 
        !          33982: /*
        !          33983:  * Minor number encoding: dsssssss
        !          33984:  * d       drive number (0 or 1)
        !          33985:  * sssssss allocation size: 0 to free, 1-127 allocsize (n*ASIZE*BSIZE bytes)
        !          33986:  */
        !          33987: #define        rm_drive(dev)   (minor(dev) >> 7)
        !          33988: #define        rm_asize(dev)   (minor(dev) & 0x7F)
        !          33989: #define        ASIZE           128     /* allocation chunk size in blocks (64KB) */
        !          33990: #define        RMMAJ           8       /* major # for driver */
        !          33991: #define NUM_RM         2       /* number of ram disks */
        !          33992:                                /* - tied to dev encoding (see above) */
        !          33993: 
        !          33994: int    nulldev();
        !          33995: int    nonedev();
        !          33996: int    rmload();
        !          33997: int    rmuload();
        !          33998: int    rmopen();
        !          33999: int    rmclose();
        !          34000: int    rmread();
        !          34001: int    rmwrite();
        !          34002: int    rmblock();
        !          34003: 
        !          34004: CON    rmcon   = {
        !          34005:        DFBLK|DFCHR,
        !          34006:        RMMAJ,
        !          34007:        rmopen,                 /* Open */
        !          34008:        rmclose,                /* Close */
        !          34009:        rmblock,                /* Block */
        !          34010:        rmread,                 /* Read */
        !          34011:        rmwrite,                /* Write */
        !          34012:        nonedev,
        !          34013:        nulldev,
        !          34014:        nulldev,
        !          34015:        rmload,                 /* Load */
        !          34016:        rmuload                 /* Unload */
        !          34017: };
        !          34018: 
        !          34019: typedef struct rm {
        !          34020:        fsize_t rm_size;        /* Size in allocation chunks */
        !          34021:        paddr_t rm_paddr;       /* Physical base of ram disc segment */
        !          34022:        SEG     *rm_segp;       /* Segment pointer of ram device */
        !          34023:        BUF     rm_buf;         /* Static buffer for raw requests */
        !          34024:        int     rm_nopen;       /* Open count to avoid blowups */
        !          34025: } RM;
        !          34026: static RM      rm[NUM_RM];
        !          34027: 
        !          34028: /*
        !          34029:  * Load.
        !          34030:  */
        !          34031: static
        !          34032: rmload()
        !          34033: {
        !          34034: }
        !          34035: 
        !          34036: /*
        !          34037:  * Unload.
        !          34038:  * Release the allocated buffers.
        !          34039:  */
        !          34040: static
        !          34041: rmuload()
        !          34042: {
        !          34043:        int i;
        !          34044: 
        !          34045:        for (i = 0; i < NUM_RM; i++){
        !          34046:                if (rm[i].rm_size != 0)
        !          34047:                        sfree(rm[i].rm_segp);
        !          34048:        }
        !          34049: }
        !          34050: 
        !          34051: /*
        !          34052:  * Open.
        !          34053:  * Allocate on the first call.
        !          34054:  * Increment the open count.
        !          34055:  */
        !          34056: static
        !          34057: rmopen(dev, mode) dev_t dev; int mode;
        !          34058: {
        !          34059:        register RM *rmp;
        !          34060:        register fsize_t asize, osize;
        !          34061:        register SEG *segp;
        !          34062: 
        !          34063:        rmp = &rm[rm_drive(dev)];
        !          34064:        asize = rm_asize(dev);
        !          34065:        osize = rmp->rm_size;
        !          34066: 
        !          34067:        /* Fail on read before creation or bogus size. */
        !          34068:        if ((mode == IPR && osize == 0)
        !          34069:         || (asize != 0 && osize != 0 && asize != osize)
        !          34070:         || (asize == 0 && osize == 0)) {
        !          34071:                u.u_error = ENXIO;
        !          34072:                return;
        !          34073:        }
        !          34074: 
        !          34075:        /*
        !          34076:         * Allocate as required.
        !          34077:         * Ignore case asize==0 && osize!=0, handled by rmclose().
        !          34078:         * If asize!=0 && asize==osize, just bump the open count.
        !          34079:         */
        !          34080:        if (asize != 0 && osize == 0) {
        !          34081:                segp = rmp->rm_segp = salloc((fsize_t)ASIZE*BSIZE*asize,
        !          34082:                        SFSYST|SFNSWP|SFNCLR|SFHIGH);
        !          34083:                if (segp == NULL) {
        !          34084:                        u.u_error = ENOMEM;
        !          34085:                        return;
        !          34086:                }
        !          34087:                rmp->rm_size = asize;
        !          34088:                rmp->rm_paddr = segp->s_paddr;
        !          34089:                rmp->rm_nopen = 0;
        !          34090:                pclear(rmp->rm_paddr, 1024L);   /* clear 1st 2 blocks */
        !          34091:        }
        !          34092:        rmp->rm_nopen++;
        !          34093: }
        !          34094: 
        !          34095: /*
        !          34096:  * Close.
        !          34097:  * Decrement the open count.
        !          34098:  * Release the allocated buffer if minor number is 0.
        !          34099:  */
        !          34100: static
        !          34101: rmclose(dev) dev_t dev;
        !          34102: {
        !          34103:        register RM *rmp;
        !          34104:        register fsize_t asize, osize;
        !          34105: 
        !          34106:        rmp = &rm[rm_drive(dev)];
        !          34107:        asize = rm_asize(dev);
        !          34108:        osize = rmp->rm_size;
        !          34109: 
        !          34110:        if (osize == 0
        !          34111:         || (asize != 0 && asize != osize)
        !          34112:         || rmp->rm_nopen == 0) {
        !          34113:                u.u_error = ENXIO;
        !          34114:                return;
        !          34115:        }
        !          34116:        rmp->rm_nopen--;
        !          34117:        if (asize == 0) {
        !          34118:                if (rmp->rm_nopen != 0) {
        !          34119:                        u.u_error = EDBUSY;
        !          34120:                        return;
        !          34121:                }
        !          34122:                sfree(rmp->rm_segp);
        !          34123:                rmp->rm_size = 0;
        !          34124:        }
        !          34125: }
        !          34126: 
        !          34127: static
        !          34128: rmblock(bp) register BUF *bp;
        !          34129: {
        !          34130:        paddr_t base;
        !          34131:        dev_t dev;
        !          34132:        register RM *rmp;
        !          34133:        register fsize_t asize, osize;
        !          34134: 
        !          34135:        dev = bp->b_dev;
        !          34136:        rmp = &rm[rm_drive(dev)];
        !          34137:        asize = rm_asize(dev);
        !          34138:        osize = rmp->rm_size;
        !          34139:        if (osize == 0 || asize != osize)
        !          34140:                bp->b_flag |= BFERR;
        !          34141:        else if (bp->b_bno >= asize*ASIZE)
        !          34142:                bp->b_flag |= BFERR;
        !          34143:        else {
        !          34144:                base = rmp->rm_paddr + (paddr_t)bp->b_bno * BSIZE;
        !          34145:                if (bp->b_req == BREAD)
        !          34146:                        plrcopy(base, bp->b_paddr, (fsize_t)BSIZE);
        !          34147:                else
        !          34148:                        plrcopy(bp->b_paddr, base, (fsize_t)BSIZE);
        !          34149:        }
        !          34150:        bdone(bp);
        !          34151: }
        !          34152: 
        !          34153: /*
        !          34154:  * The read routine calls the common raw I/O processing code,
        !          34155:  * using a static buffer header in the driver.
        !          34156:  */
        !          34157: static
        !          34158: rmread(dev, iop) register dev_t dev; IO *iop;
        !          34159: {
        !          34160:        register BUF *bufp;
        !          34161: 
        !          34162:        bufp = &rm[rm_drive(dev)].rm_buf;
        !          34163:        ioreq(bufp, iop, dev, BREAD, BFIOC|BFRAW);
        !          34164: }
        !          34165: 
        !          34166: /*
        !          34167:  * The write routine is just like the read routine,
        !          34168:  * except that the function code is write instead of read.
        !          34169:  */
        !          34170: static
        !          34171: rmwrite(dev, iop) register dev_t dev; IO *iop;
        !          34172: {
        !          34173:        register BUF *bufp;
        !          34174: 
        !          34175:        bufp = &rm[rm_drive(dev)].rm_buf;
        !          34176:        ioreq(bufp, iop, dev, BWRITE, BFIOC|BFRAW);
        !          34177: }
        !          34178: 
        !          34179: /* end of rm.c */
        !          34180: @
        !          34181: 
        !          34182: 
        !          34183: 1.3
        !          34184: log
        !          34185: @bob h changed <header> references to include sys/ for con.h, uproc.h,
        !          34186: buf.h and seg.h
        !          34187: @
        !          34188: text
        !          34189: @d5 1
        !          34190: a5 1
        !          34191: #include       <coherent.h>
        !          34192: @
        !          34193: 
        !          34194: 
        !          34195: 1.2
        !          34196: log
        !          34197: @Do salloc with SFHIGH.
        !          34198: @
        !          34199: text
        !          34200: @d6 1
        !          34201: a6 1
        !          34202: #include       <buf.h>
        !          34203: d8 3
        !          34204: a10 3
        !          34205: #include       <uproc.h>
        !          34206: #include       <seg.h>
        !          34207: #include       <con.h>
        !          34208: @
        !          34209: 
        !          34210: 
        !          34211: 1.1
        !          34212: log
        !          34213: @Shipped with 3.1.0.
        !          34214: @
        !          34215: text
        !          34216: @a0 5
        !          34217: /* (-lgl
        !          34218:  *     COHERENT Driver Kit Version 1.1.0
        !          34219:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          34220:  *     All rights reserved. May not be copied without permission.
        !          34221:  -lgl) */
        !          34222: d113 2
        !          34223: a114 1
        !          34224:                segp = rmp->rm_segp = salloc((fsize_t)ASIZE*BSIZE*asize, SFSYST|SFNSWP|SFNCLR);
        !          34225: @
        !          34226: 0707070064030106461004440000030000030000011777770507310653100005600000041322/newbits/kernel/USRSRC/i8086/drv/RCS/scsi.c,vhead     1.8;
        !          34227: branch   ;
        !          34228: access   ;
        !          34229: symbols  ;
        !          34230: locks    bin:1.8;
        !          34231: comment  @ * @;
        !          34232: 
        !          34233: 
        !          34234: 1.8
        !          34235: date     91.06.20.14.52.50;  author bin;  state Exp;
        !          34236: branches ;
        !          34237: next     1.7;
        !          34238: 
        !          34239: 1.7
        !          34240: date     91.06.18.08.14.13;  author bin;  state Exp;
        !          34241: branches ;
        !          34242: next     1.6;
        !          34243: 
        !          34244: 1.6
        !          34245: date     91.06.17.12.35.18;  author bin;  state Exp;
        !          34246: branches ;
        !          34247: next     1.5;
        !          34248: 
        !          34249: 1.5
        !          34250: date     91.06.10.10.25.03;  author bin;  state Exp;
        !          34251: branches ;
        !          34252: next     1.4;
        !          34253: 
        !          34254: 1.4
        !          34255: date     91.06.03.13.50.06;  author hal;  state Exp;
        !          34256: branches ;
        !          34257: next     1.3;
        !          34258: 
        !          34259: 1.3
        !          34260: date     91.05.08.11.00.30;  author root;  state Exp;
        !          34261: branches 1.3.1.1;
        !          34262: next     1.2;
        !          34263: 
        !          34264: 1.2
        !          34265: date     91.05.01.04.50.11;  author root;  state Exp;
        !          34266: branches ;
        !          34267: next     1.1;
        !          34268: 
        !          34269: 1.1
        !          34270: date     91.04.30.11.02.22;  author root;  state Exp;
        !          34271: branches ;
        !          34272: next     ;
        !          34273: 
        !          34274: 1.3.1.1
        !          34275: date     91.05.08.11.01.47;  author root;  state Exp;
        !          34276: branches ;
        !          34277: next     ;
        !          34278: 
        !          34279: 
        !          34280: desc
        !          34281: @Somewhat Adaptec-independent code for "sd" driver.
        !          34282: @
        !          34283: 
        !          34284: 
        !          34285: 1.8
        !          34286: log
        !          34287: @update provided by hal
        !          34288: @
        !          34289: text
        !          34290: @/*
        !          34291:  * This is the generic SCSI part of the
        !          34292:  * Adaptec AHA154x host adapter driver for the AT.
        !          34293:  *
        !          34294:  * $Log:       scsi.c,v $
        !          34295:  * Revision 1.6  91/06/10  13:28:11  hal
        !          34296:  * Refix startup problem with HDGETA.  Text cleanup.
        !          34297:  * 
        !          34298:  * Revision 1.5  91/06/10  12:58:04  hal
        !          34299:  * Partial fix for HDGETA failing if partition table absent.
        !          34300:  * 
        !          34301:  * Revision 1.4  91/06/03  13:50:06  hal
        !          34302:  * Add HDSETA.
        !          34303:  * 
        !          34304:  * Revision 1.3        91/05/08  11:00:30      root
        !          34305:  * Make number of heads - SD_HDS - patchable for Tandy.
        !          34306:  * 
        !          34307:  * Revision 1.2        91/05/01  04:50:11      root
        !          34308:  * Debug code and d_time/sw_active imbalance fixed.
        !          34309:  * 
        !          34310:  * Revision 1.1        91/04/30  11:02:22      root
        !          34311:  * Shipped with COH 3.1.0
        !          34312:  * 
        !          34313:  */
        !          34314: 
        !          34315: #include       <sys/coherent.h>
        !          34316: #include       <sys/fdisk.h>
        !          34317: #include       <sys/hdioctl.h>
        !          34318: #include       <sys/sdioctl.h>
        !          34319: #include       <sys/buf.h>
        !          34320: #include       <sys/con.h>
        !          34321: #include       <sys/stat.h>
        !          34322: #include       <sys/uproc.h>
        !          34323: #include       <errno.h>
        !          34324: #include       <sys/scsiwork.h>
        !          34325: 
        !          34326: extern saddr_t sds;
        !          34327: 
        !          34328: /*
        !          34329:  * Configurable parameters
        !          34330:  *
        !          34331:  * Adaptec ROM translates at 64 heads, except the Tandy version, which
        !          34332:  * uses 16 heads.  Kernel variable SD_HDS is patchable for this reason.
        !          34333:  */
        !          34334: #ifdef TANDY
        !          34335: int SD_HDS = 16;
        !          34336: #else
        !          34337: int SD_HDS = 64;
        !          34338: #endif
        !          34339: int SD_SPT = 32;
        !          34340: 
        !          34341: #define NDRIVE (8 * 4)                 /* 8 SCSI ids and 4 LUNs */
        !          34342: #define        SDMAJOR 13                      /* Major Device Number */
        !          34343: #define        SDDMA   5                       /* Used for first party DMA */
        !          34344: 
        !          34345: /*
        !          34346:  * user configurable paramters
        !          34347:  */
        !          34348: int    SDIRQ   = 11;                   /* Interrupt */
        !          34349: int    SDBASE  = 0x0330;               /* Port base */
        !          34350: 
        !          34351: /*
        !          34352:  *                                     LUN --------++
        !          34353:  * device macros                       Special-+   ||
        !          34354:  * minor device bits are of the form:          76543210
        !          34355:  *                                              |||  ||
        !          34356:  *                                     SCSI ID--+++  ||
        !          34357:  *                                     Partition ----++
        !          34358:  * Partition mapping:
        !          34359:  *
        !          34360:  * Description    Special Bit     Partition #          Device          Type
        !          34361:  * -----------    -----------     -----------          ------          ----
        !          34362:  * partition a         0               00              /dev/sd??a      disk
        !          34363:  * partition b         0               01              /dev/sd??b      disk
        !          34364:  * partition c         0               10              /dev/sd??c      disk
        !          34365:  * partition d         0               11              /dev/sd??d      disk
        !          34366:  * partition table     1               00              /dev/sd??x      disk
        !          34367:  * no rewind tape      1               01              /dev/sd??n      tape
        !          34368:  * UNALLOCATED         1               10                ---           ????
        !          34369:  * rewind tape device  1               11              /dev/sd??       tape
        !          34370:  */
        !          34371: #define        DRIVENO(minor)  (((minor) >> 2) & 0x1F) /* SCSI ID + LUN */
        !          34372: #define        SCSIID(minor)   (((minor) >> 4) & 0x7)  /* SCSI ID */
        !          34373: #define        LUN(minor)      (((minor) >> 2) & 0x3)  /* Logical Unit Number */
        !          34374: #define        PARTITION(minor) ((minor) & 0x3)        /* Partition */
        !          34375: #define        sdmkdev(maj, s, drv)    makedev((maj), ((s)|((drv)<<2)))
        !          34376: 
        !          34377: /*
        !          34378:  * Driver configuration.
        !          34379:  */
        !          34380: void   sdload();
        !          34381: void   sdunload();
        !          34382: void   sdopen();
        !          34383: void   sdclose();
        !          34384: void   sdread();
        !          34385: void   sdwrite();
        !          34386: int    sdioctl();
        !          34387: void   sdblock();
        !          34388: int    sdwatch();
        !          34389: int    nulldev();
        !          34390: int    nonedev();
        !          34391: 
        !          34392: CON    sdcon   = {
        !          34393:        DFBLK|DFCHR,                    /* Flags */
        !          34394:        SDMAJOR,                        /* Major index */
        !          34395:        sdopen,                         /* Open */
        !          34396:        sdclose,                        /* Close */
        !          34397:        sdblock,                        /* Block */
        !          34398:        sdread,                         /* Read */
        !          34399:        sdwrite,                        /* Write */
        !          34400:        sdioctl,                        /* Ioctl */
        !          34401:        nulldev,                        /* Powerfail */
        !          34402:        sdwatch,                        /* Timeout */
        !          34403:        sdload,                         /* Load */
        !          34404:        sdunload                        /* Unload */
        !          34405: };
        !          34406: 
        !          34407: /*
        !          34408:  *     host adapter routines
        !          34409:  */
        !          34410: int    aha_load();             /* initialize host adapter, DMA */
        !          34411: void   aha_unload();           /* shutdown the host adapter */
        !          34412: int    aha_start();            /* see if there's work */
        !          34413: int    aha_command();
        !          34414: 
        !          34415: /*
        !          34416:  * Partition Parameters - copied from disk.
        !          34417:  *
        !          34418:  *     There are NPARTN positions for the user partitions in array PPARM,
        !          34419:  *     plus 1 additional position to span the entire drive.
        !          34420:  *     Array pparmp[] contains a pointer to a kalloc()'ed PPARM
        !          34421:  *     entry if the drive actually exists, is a disk drive and if someone
        !          34422:  *     has attmpted to read a partition table from the drive.
        !          34423:  */
        !          34424: typedef        struct  fdisk_s PPARM[NPARTN + 1];      /* 4 partitions + whole drive */
        !          34425: static PPARM *pparmp[NDRIVE];                  /* one per possible drive */
        !          34426: #define        WHOLE_DRIVE     NPARTN                  /* index for whole drive */
        !          34427: #define        PNULL   ((PPARM *)0)
        !          34428: 
        !          34429: /*
        !          34430:  * Per disk controller data.
        !          34431:  * Only one host adapter; no more, no less.
        !          34432:  */
        !          34433: static
        !          34434: scsi_work_t    sd;
        !          34435: 
        !          34436: static BUF     dbuf;                   /* For raw I/O */
        !          34437: static int     sw_active;
        !          34438: 
        !          34439: /**
        !          34440:  *
        !          34441:  * void
        !          34442:  * sdload()    - load routine.
        !          34443:  *
        !          34444:  *     Action: The controller is reset and the interrupt vector is grabbed.
        !          34445:  *             The drive characteristics are set up at this time.
        !          34446:  */
        !          34447: static void
        !          34448: sdload()
        !          34449: {
        !          34450:        /*
        !          34451:         * Initialize Drive Controller.
        !          34452:         */
        !          34453:        sw_active = 0;
        !          34454:        if (aha_load(SDDMA, SDIRQ, SDBASE, &sd) < 0) {
        !          34455:                u.u_error = ENXIO;
        !          34456:                return;
        !          34457:        }
        !          34458: /*     aha_device_info(); */           /* enable after this gets fixed */
        !          34459: }
        !          34460: 
        !          34461: /**
        !          34462:  *
        !          34463:  * void
        !          34464:  * sdunload()  - unload routine.
        !          34465:  */
        !          34466: static void
        !          34467: sdunload()
        !          34468: {
        !          34469:        register int i;
        !          34470: 
        !          34471:        if (sw_active > 0)
        !          34472:                printf("aha154x: sdunload() athough %d active\n", sw_active);
        !          34473:        aha_unload(SDIRQ);
        !          34474:        for (i = 0; i < NDRIVE; ++i)
        !          34475:                if (pparmp[i] != PNULL)
        !          34476:                        kfree(pparmp[i]);       /* free any partition tables */
        !          34477: }
        !          34478: 
        !          34479: /*
        !          34480:  * int
        !          34481:  * sdgetpartitions(dev)        - load partition table for specified drive
        !          34482:  *
        !          34483:  *                     - return 1 on success and 0 on failure
        !          34484:  */
        !          34485: int sdgetpartitions(dev)
        !          34486: dev_t  dev;
        !          34487: {
        !          34488:        register int    i;
        !          34489:        scsi_cmd_t      sc;
        !          34490:        unsigned char   *buffer;
        !          34491:        struct fdisk_s  *fdp;
        !          34492:        int     d = DRIVENO(minor(dev));
        !          34493: 
        !          34494:        pparmp[d] = kalloc(sizeof *pparmp[0]);
        !          34495:        fdp = (struct fdisk_s *) pparmp[d];     /* point to first entry */
        !          34496:        buffer = kalloc(36+1);
        !          34497:        if (buffer == NULL || pparmp[d] == PNULL) {
        !          34498:                printf("aha154x: out of kernel memory\n");
        !          34499:                u.u_error = EKSPACE;
        !          34500:                return 0;
        !          34501:        }
        !          34502:        kclear(pparmp[d], sizeof *pparmp[0]);
        !          34503:        sc.unit = d;
        !          34504:        sc.block = 0L;
        !          34505:        sc.blklen = 0;
        !          34506: 
        !          34507:        sc.buffer = VTOP2(buffer, sds);
        !          34508:        ++drvl[SDMAJOR].d_time; 
        !          34509: #if    0
        !          34510:        sc.cmd = ScmdINQUIRY;
        !          34511:        sc.buflen = 36;
        !          34512:        aha_command(&sc);
        !          34513:        aha_command(&sc);
        !          34514:        buffer[36] = 0;
        !          34515:        printf("SCSI Disk %s", &buffer[8]);
        !          34516: #endif
        !          34517:        sc.cmd = ScmdREADCAPACITY;
        !          34518:        sc.buflen = 8;
        !          34519: 
        !          34520:        for(i = 0; i < sc.buflen; ++i)
        !          34521:                buffer[i] = 0;
        !          34522:        aha_command(&sc);
        !          34523:        aha_command(&sc);
        !          34524: #if    VERBOSE
        !          34525:        printf("buffer =");
        !          34526:        for(i = 0; i < sc.buflen; ++i)
        !          34527:                printf(" %x", buffer[i]);
        !          34528:        printf("\n");
        !          34529: #endif
        !          34530:        sc.block = (buffer[0]<<8) | buffer[1];
        !          34531:        sc.block <<= 16;
        !          34532:        sc.block |= (buffer[2]<<8) | buffer[3];
        !          34533: 
        !          34534:        sc.blklen = (buffer[6]<<8) | buffer[7];
        !          34535: #if    VERBOSE
        !          34536:        printf("SCSI %D. blocks of size %d\n", sc.block, sc.blklen);
        !          34537: #endif
        !          34538:        kfree(buffer);
        !          34539:        fdp[WHOLE_DRIVE].p_size = sc.block;
        !          34540:        --drvl[SDMAJOR].d_time; 
        !          34541:        return fdisk(sdmkdev(major(dev), SDEV, d), pparmp[d]);
        !          34542: }
        !          34543: 
        !          34544: /**
        !          34545:  *
        !          34546:  * void
        !          34547:  * sdopen(dev, mode)
        !          34548:  * dev_t dev;
        !          34549:  * int mode;
        !          34550:  *
        !          34551:  *     Input:  dev = disk device to be opened.
        !          34552:  *             mode = access mode [IPR,IPW, IPR+IPW].
        !          34553:  *
        !          34554:  *     Action: Validate the minor device.
        !          34555:  *             Update the paritition table if necessary.
        !          34556:  */
        !          34557: static void
        !          34558: sdopen(dev, mode)
        !          34559: register dev_t dev;
        !          34560: {
        !          34561:        register int p;                 /* partition */
        !          34562:        register int d;                 /* drive (SCSI ID + LUN) */
        !          34563:        struct fdisk_s  *fdp;           /* one partition entry */
        !          34564: 
        !          34565:        if (minor(dev) & SDEV) {
        !          34566:                if (PARTITION(minor(dev)) != 0) {       /* tape device ? */
        !          34567:                        u.u_error = ENXIO;              /* not yet! */
        !          34568: devmsg(dev, "No tape yet");
        !          34569:                } else {
        !          34570:                        ++drvl[SDMAJOR].d_time; 
        !          34571:                        ++sw_active;
        !          34572:                }
        !          34573:                return;
        !          34574:        }
        !          34575: 
        !          34576:        d = DRIVENO(minor(dev));
        !          34577:        p = PARTITION(minor(dev));
        !          34578: 
        !          34579:        /*
        !          34580:         * If partition not defined read partition characteristics.
        !          34581:         */
        !          34582:        if (pparmp[d] == PNULL)   /* no entry yet for this drive ? */
        !          34583:                if (!sdgetpartitions(dev)) {
        !          34584:                        u.u_error = ENXIO;
        !          34585:                        return;
        !          34586:                }
        !          34587:        /*
        !          34588:         * Ensure partition lies within drive boundaries and is non-zero size.
        !          34589:         */
        !          34590:        fdp = (struct fdisk_s *) pparmp[d];
        !          34591:        if ((fdp[p].p_base+fdp[p].p_size) > fdp[WHOLE_DRIVE].p_size) {
        !          34592:                u.u_error = EBADFMT;
        !          34593:        } else if (fdp[p].p_size == 0) {
        !          34594:                u.u_error = ENODEV;
        !          34595:        } else {
        !          34596:                ++drvl[SDMAJOR].d_time; 
        !          34597:                ++sw_active;
        !          34598:        }
        !          34599: }
        !          34600: 
        !          34601: void sdclose(dev)
        !          34602: {
        !          34603:        --drvl[SDMAJOR].d_time; 
        !          34604:        --sw_active;    
        !          34605: }
        !          34606: 
        !          34607: /**
        !          34608:  *
        !          34609:  * void
        !          34610:  * sdread(dev, iop)    - write a block to the raw disk
        !          34611:  * dev_t dev;
        !          34612:  * IO * iop;
        !          34613:  *
        !          34614:  *     Input:  dev = disk device to be written to.
        !          34615:  *             iop = pointer to source I/O structure.
        !          34616:  *
        !          34617:  *     Action: Invoke the common raw I/O processing code.
        !          34618:  */
        !          34619: static void
        !          34620: sdread(dev, iop)
        !          34621: dev_t  dev;
        !          34622: IO     *iop;
        !          34623: {
        !          34624:        ioreq(&dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC);
        !          34625: }
        !          34626: 
        !          34627: /**
        !          34628:  *
        !          34629:  * void
        !          34630:  * sdwrite(dev, iop)   - write a block to the raw disk
        !          34631:  * dev_t dev;
        !          34632:  * IO * iop;
        !          34633:  *
        !          34634:  *     Input:  dev = disk device to be written to.
        !          34635:  *             iop = pointer to source I/O structure.
        !          34636:  *
        !          34637:  *     Action: Invoke the common raw I/O processing code.
        !          34638:  */
        !          34639: static void
        !          34640: sdwrite(dev, iop)
        !          34641: dev_t  dev;
        !          34642: IO     *iop;
        !          34643: {
        !          34644:        ioreq(&dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC);
        !          34645: }
        !          34646: 
        !          34647: /**
        !          34648:  *
        !          34649:  * int
        !          34650:  * sdioctl(dev, cmd, arg)
        !          34651:  * dev_t dev;
        !          34652:  * int cmd;
        !          34653:  * char * vec;
        !          34654:  *
        !          34655:  *     Input:  dev = disk device to be operated on.
        !          34656:  *             cmd = input/output request to be performed.
        !          34657:  *             vec = (pointer to) optional argument.
        !          34658:  *
        !          34659:  *     Action: Validate the minor device.
        !          34660:  *             Update the paritition table if necessary.
        !          34661:  */
        !          34662: static int
        !          34663: sdioctl(dev, cmd, vec)
        !          34664: register dev_t dev;
        !          34665: int cmd;
        !          34666: char * vec;
        !          34667: {
        !          34668:        int d;
        !          34669:        hdparm_t hdparm;
        !          34670:        struct fdisk_s  *fdp;
        !          34671:        int do_getpt = 0;       /* 1 if need to call sdgetpartitions() */
        !          34672: 
        !          34673:        d = DRIVENO(minor(dev));
        !          34674: 
        !          34675:        /*
        !          34676:         * Identify input/output request.
        !          34677:         */
        !          34678:        switch (cmd) {
        !          34679: 
        !          34680:        case HDGETA:
        !          34681:                /*
        !          34682:                 * If haven't loaded partition table yet for this drive,
        !          34683:                 * try to do it now.  Note sdgetpartitions() will fail
        !          34684:                 * if there is a new drive (e.g. no signature).  But all
        !          34685:                 * we need is allocation of pparmp[d] and capacity read
        !          34686:                 * properly from the drive.
        !          34687:                 */
        !          34688:                if (pparmp[d] == PNULL) {
        !          34689:                        do_getpt = 1;   /* REALLY just want Read Capacity */
        !          34690:                        sdgetpartitions(dev);
        !          34691:                        if (pparmp[d] == NULL) {
        !          34692:                                u.u_error = ENXIO;
        !          34693:                                return -1;
        !          34694:                        }
        !          34695:                }
        !          34696:                fdp = (struct fdisk_s *) pparmp[d];
        !          34697:                *(short *)&hdparm.landc[0] =
        !          34698:                *(short *)&hdparm.ncyl[0] = fdp[WHOLE_DRIVE].p_size
        !          34699:                                                / (SD_HDS * SD_SPT);
        !          34700:                hdparm.nhead = SD_HDS;
        !          34701:                hdparm.nspt = SD_SPT;
        !          34702:                kucopy(&hdparm, vec, sizeof hdparm);
        !          34703:                /*
        !          34704:                 * I know it's ugly.  But it gets around startup Catch-22.
        !          34705:                 *
        !          34706:                 * The fdisk command needs HDGETA.  HDGETA invokes
        !          34707:                 * sdgetpartitions(), but we want to call it again
        !          34708:                 * after the partition table has been created by the fdisk
        !          34709:                 * command.
        !          34710:                 */
        !          34711:                if (do_getpt) {
        !          34712:                        kfree(pparmp[d]);
        !          34713:                        pparmp[d] = PNULL;      /* force re-read of p. table */
        !          34714:                }
        !          34715:                return 0;
        !          34716:        case HDSETA:
        !          34717:                /*
        !          34718:                 * Set hard disk attributes.
        !          34719:                 */
        !          34720:                fdp = (struct fdisk_s *) pparmp[d];
        !          34721:                ukcopy(vec, &hdparm, sizeof hdparm);
        !          34722:                SD_HDS = hdparm.nhead;
        !          34723:                SD_SPT = hdparm.nspt;
        !          34724:                fdp[WHOLE_DRIVE].p_size =
        !          34725:                        (long)(*(short *)&hdparm.ncyl[0])
        !          34726:                        * (long)SD_HDS * (long)SD_SPT;
        !          34727: 
        !          34728:                return 0;
        !          34729:        case SCSI_HA_CMD:
        !          34730:                return aha_ioctl(cmd, vec);
        !          34731:        case SCSI_CMD:
        !          34732:                return 0;
        !          34733:        case SCSI_CMD_IN:
        !          34734:                return 0;
        !          34735:        case SCSI_CMD_OUT:
        !          34736:                return 0;
        !          34737: 
        !          34738:        default:
        !          34739:                u.u_error = EINVAL;
        !          34740:                return -1;
        !          34741:        }
        !          34742: }
        !          34743: 
        !          34744: /**
        !          34745:  *
        !          34746:  * void
        !          34747:  * sdblock(bp) - queue a block to the disk
        !          34748:  *
        !          34749:  *     Input:  bp = pointer to block to be queued.
        !          34750:  *
        !          34751:  *     Action: Queue a block to the disk.
        !          34752:  *             Make sure that the transfer is within the disk partition.
        !          34753:  */
        !          34754: static void
        !          34755: sdblock(bp)
        !          34756: register BUF   *bp;
        !          34757: {
        !          34758:        register scsi_work_t *sw;
        !          34759:        register int s;
        !          34760:        struct  fdisk_s *fdp;
        !          34761: 
        !          34762:        int p = PARTITION(minor(bp->b_dev));
        !          34763:        int drv = DRIVENO(minor(bp->b_dev));
        !          34764: 
        !          34765:        if (minor(bp->b_dev) & SDEV)
        !          34766:                p = WHOLE_DRIVE;
        !          34767:        bp->b_resid = bp->b_count;
        !          34768:        
        !          34769:        fdp = (struct fdisk_s *) pparmp[drv];
        !          34770: 
        !          34771:        /*
        !          34772:         * Range check disk region.
        !          34773:         */
        !          34774:        if (pparmp[drv] == PNULL) {
        !          34775:                if (p == WHOLE_DRIVE) {
        !          34776:                        if ((bp->b_bno != 0) || (bp->b_count != BSIZE)) {
        !          34777:                                bp->b_flag |= BFERR;
        !          34778:                                bdone(bp);
        !          34779:                                return;
        !          34780:                        }
        !          34781:                } else {
        !          34782:                        printf("aha154x: no partition table\n");
        !          34783:                        bp->b_flag |= BFERR;
        !          34784:                        bdone(bp);
        !          34785:                        return;
        !          34786:                }
        !          34787:        } else if ((bp->b_bno + (bp->b_count/BSIZE)) > fdp[p].p_size) {
        !          34788:                bp->b_flag |= BFERR;
        !          34789:                bdone(bp);
        !          34790:                return;
        !          34791:        }
        !          34792: 
        !          34793:        bp->b_actf = NULL;
        !          34794:        sw = (scsi_work_t *)kalloc(sizeof(*sw));
        !          34795:        if (sw == (scsi_work_t *)0) {
        !          34796:                printf("aha154x: out of kernel memory\n");
        !          34797:                bp->b_flag |= BFERR;
        !          34798:                bdone(bp);
        !          34799:                return;
        !          34800:        }
        !          34801:        sw->sw_bp = bp;
        !          34802:        sw->sw_drv = drv;
        !          34803:        sw->sw_type = 0;
        !          34804:        if (p != WHOLE_DRIVE)
        !          34805:                sw->sw_bno   = fdp[p].p_base + bp->b_bno;
        !          34806:        else
        !          34807:                sw->sw_bno   = bp->b_bno;
        !          34808:        sw->sw_retry = 1;
        !          34809: 
        !          34810: #if    VERBOSE
        !          34811:        printf("sdblock: drv %x bno %x:%x  bp=%x, flag = %o\n",
        !          34812:                drv, (long)sw->sw_bno, bp, bp->b_flag);
        !          34813: #endif
        !          34814: 
        !          34815:        s = sphi();
        !          34816:        if (sd.sw_actf == NULL)
        !          34817:                sd.sw_actf = sw;
        !          34818:        else
        !          34819:                sd.sw_actl->sw_actf = sw;
        !          34820:        sd.sw_actl = sw;
        !          34821:        spl(s);
        !          34822: 
        !          34823:        aha_start();
        !          34824: }
        !          34825: 
        !          34826: sdwatch()
        !          34827: {
        !          34828:        register i;
        !          34829: 
        !          34830:        if (i = aha_start())
        !          34831: #if    VERBOSE
        !          34832:                printf("sdwatch: started %d actions\n", i);
        !          34833: #else
        !          34834:                ;
        !          34835: #endif
        !          34836:        if (i = aha_completed())
        !          34837: #if    VERBOSE
        !          34838:                printf("sdwatch: completed %d actions\n", i);
        !          34839: #else
        !          34840:                ;
        !          34841: #endif
        !          34842: }
        !          34843: @
        !          34844: 
        !          34845: 
        !          34846: 1.7
        !          34847: log
        !          34848: @update provided by hal
        !          34849: @
        !          34850: text
        !          34851: @d26 1
        !          34852: a26 1
        !          34853: #include       <coherent.h>
        !          34854: d35 1
        !          34855: a35 1
        !          34856: #include       <scsiwork.h>
        !          34857: @
        !          34858: 
        !          34859: 
        !          34860: 1.6
        !          34861: log
        !          34862: @new version provided y hal for v321
        !          34863: @
        !          34864: text
        !          34865: @@
        !          34866: 
        !          34867: 
        !          34868: 1.5
        !          34869: log
        !          34870: @initial version prov by hal
        !          34871: @
        !          34872: text
        !          34873: @d3 1
        !          34874: a3 1
        !          34875:  * Adaptec AHA154x host adaptor driver for the AT.
        !          34876: d6 6
        !          34877: d119 1
        !          34878: a119 1
        !          34879:  *     hostadaptor routines
        !          34880: d121 2
        !          34881: a122 2
        !          34882: int    aha_load();             /* initialize hostadaptor, DMA */
        !          34883: void   aha_unload();           /* shutdown the host adaptor */
        !          34884: d165 1
        !          34885: a165 1
        !          34886:        if (aha_load( SDDMA, SDIRQ, SDBASE, &sd ) < 0) {
        !          34887: d182 3
        !          34888: a184 3
        !          34889:        if( sw_active > 0 )
        !          34890:                printf( "aha154x: sdunload() athough %d active\n", sw_active );
        !          34891:        aha_unload( SDIRQ );
        !          34892: d218 1
        !          34893: a218 1
        !          34894:        sc.buffer = VTOP2( buffer, sds );
        !          34895: d223 2
        !          34896: a224 2
        !          34897:        aha_command( &sc );
        !          34898:        aha_command( &sc );
        !          34899: d226 1
        !          34900: a226 1
        !          34901:        printf( "SCSI Disk %s", &buffer[8] );
        !          34902: d231 1
        !          34903: a231 1
        !          34904:        for( i = 0; i < sc.buflen; ++i )
        !          34905: d233 2
        !          34906: a234 2
        !          34907:        aha_command( &sc );
        !          34908:        aha_command( &sc );
        !          34909: d236 4
        !          34910: a239 4
        !          34911:        printf( "buffer =" );
        !          34912:        for( i = 0; i < sc.buflen; ++i )
        !          34913:                printf( " %x", buffer[i] );
        !          34914:        printf( "\n" );
        !          34915: d247 1
        !          34916: a247 1
        !          34917:        printf( "SCSI %D. blocks of size %d\n", sc.block, sc.blklen );
        !          34918: d252 1
        !          34919: a252 1
        !          34920:        return fdisk( sdmkdev(major(dev), SDEV, d), pparmp[d]);
        !          34921: d258 1
        !          34922: a258 1
        !          34923:  * sdopen( dev, mode )
        !          34924: d269 1
        !          34925: a269 1
        !          34926: sdopen( dev, mode )
        !          34927: d276 2
        !          34928: a277 2
        !          34929:        if ( minor(dev) & SDEV ) {
        !          34930:                if ( PARTITION(minor(dev)) != 0 ) {     /* tape device ? */
        !          34931: d293 1
        !          34932: a293 1
        !          34933:        if ( pparmp[d] == PNULL )   /* no entry yet for this drive ? */
        !          34934: d304 1
        !          34935: a304 1
        !          34936:        } else if ( fdp[p].p_size == 0 ) {
        !          34937: d312 1
        !          34938: a312 1
        !          34939: void sdclose( dev )
        !          34940: d321 1
        !          34941: a321 1
        !          34942:  * sdread( dev, iop )  - write a block to the raw disk
        !          34943: d331 1
        !          34944: a331 1
        !          34945: sdread( dev, iop )
        !          34946: d335 1
        !          34947: a335 1
        !          34948:        ioreq( &dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC );
        !          34949: d341 1
        !          34950: a341 1
        !          34951:  * sdwrite( dev, iop ) - write a block to the raw disk
        !          34952: d351 1
        !          34953: a351 1
        !          34954: sdwrite( dev, iop )
        !          34955: d355 1
        !          34956: a355 1
        !          34957:        ioreq( &dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC );
        !          34958: d361 1
        !          34959: a361 1
        !          34960:  * sdioctl( dev, cmd, arg )
        !          34961: d374 1
        !          34962: a374 1
        !          34963: sdioctl( dev, cmd, vec )
        !          34964: d382 1
        !          34965: d389 1
        !          34966: a389 1
        !          34967:        switch ( cmd ) {
        !          34968: d400 1
        !          34969: d402 1
        !          34970: a402 2
        !          34971:                        if (pparmp[d] == NULL ||
        !          34972:                        ((struct fdisk_s *)pparmp[d])[WHOLE_DRIVE].p_size == 0L) {
        !          34973: d413 13
        !          34974: a425 1
        !          34975:                kucopy( &hdparm, vec, sizeof hdparm );
        !          34976: d441 1
        !          34977: a441 1
        !          34978:                return aha_ioctl( cmd, vec );
        !          34979: d458 1
        !          34980: a458 1
        !          34981:  * sdblock( bp )       - queue a block to the disk
        !          34982: d476 1
        !          34983: a476 1
        !          34984:        if ( minor(bp->b_dev) & SDEV )
        !          34985: d485 2
        !          34986: a486 2
        !          34987:        if ( pparmp[drv] == PNULL ) {
        !          34988:                if ( p == WHOLE_DRIVE ) {
        !          34989: d498 1
        !          34990: a498 1
        !          34991:        } else if ( (bp->b_bno + (bp->b_count/BSIZE)) > fdp[p].p_size ) {
        !          34992: d505 1
        !          34993: a505 1
        !          34994:        sw = (scsi_work_t *)kalloc( sizeof(*sw) );
        !          34995: d515 1
        !          34996: a515 1
        !          34997:        if ( p != WHOLE_DRIVE )
        !          34998: d522 2
        !          34999: a523 2
        !          35000:        printf( "sdblock: drv %x bno %x:%x  bp=%x, flag = %o\n",
        !          35001:                drv, (long)sw->sw_bno, bp, bp->b_flag );
        !          35002: d541 1
        !          35003: a541 1
        !          35004:        if( i = aha_start() )
        !          35005: d543 1
        !          35006: a543 1
        !          35007:                printf( "sdwatch: started %d actions\n", i );
        !          35008: d547 1
        !          35009: a547 1
        !          35010:        if( i = aha_completed() )
        !          35011: d549 1
        !          35012: a549 1
        !          35013:                printf( "sdwatch: completed %d actions\n", i );
        !          35014: @
        !          35015: 
        !          35016: 
        !          35017: 1.4
        !          35018: log
        !          35019: @Add HDSETA.
        !          35020: @
        !          35021: text
        !          35022: @d5 4
        !          35023: a8 1
        !          35024:  * $Log:       /usr/src/sys/i8086/drv/RCS/scsi.c,v $
        !          35025: d385 11
        !          35026: a395 2
        !          35027:                if (pparmp[d] == PNULL)
        !          35028:                        if (!sdgetpartitions(dev)) {
        !          35029: d399 1
        !          35030: @
        !          35031: 
        !          35032: 
        !          35033: 1.3
        !          35034: log
        !          35035: @Make number of heads - SD_HDS - patchable for Tandy.
        !          35036: @
        !          35037: text
        !          35038: @d6 3
        !          35039: d41 1
        !          35040: a44 1
        !          35041: #define        NSEC    32                      /* controller fakes this value */
        !          35042: d390 1
        !          35043: a390 1
        !          35044:                                                / (SD_HDS * NSEC);
        !          35045: d392 1
        !          35046: a392 1
        !          35047:                hdparm.nspt = NSEC;
        !          35048: d395 13
        !          35049: @
        !          35050: 
        !          35051: 
        !          35052: 1.3.1.1
        !          35053: log
        !          35054: @Print messages on open, devmsgs when open fails.
        !          35055: @
        !          35056: text
        !          35057: @a283 1
        !          35058: devmsg(dev, "sdgetpartitions() failed");
        !          35059: a289 2
        !          35060: printf("base=%ld size=%ld ", fdp[p].p_base, fdp[p].p_size);
        !          35061: printf("cap=%ld\n", fdp[WHOLE_DRIVE].p_size);
        !          35062: a291 1
        !          35063: devmsg(dev, "partition past end of drive");
        !          35064: a293 1
        !          35065: devmsg(dev, "partition size 0");
        !          35066: @
        !          35067: 
        !          35068: 
        !          35069: 1.2
        !          35070: log
        !          35071: @Debug code and d_time/sw_active imbalance fixed.
        !          35072: @
        !          35073: text
        !          35074: @d6 3
        !          35075: d29 3
        !          35076: d33 6
        !          35077: d41 1
        !          35078: a41 2
        !          35079: #define        NHEAD   64                      /* controller fakes this value */
        !          35080: #define        NSEC    32                      /* likewise... */
        !          35081: d205 1
        !          35082: a205 1
        !          35083: printf("A");
        !          35084: d267 1
        !          35085: d290 1
        !          35086: a290 1
        !          35087:        if ((fdp[p].p_base+fdp[p].p_size) > fdp[WHOLE_DRIVE].p_size)
        !          35088: d292 1
        !          35089: a292 1
        !          35090:        else if ( fdp[p].p_size == 0 )
        !          35091: d294 1
        !          35092: a294 1
        !          35093:        else {
        !          35094: d387 2
        !          35095: a388 2
        !          35096:                                                / (NHEAD * NSEC);
        !          35097:                hdparm.nhead = NHEAD;
        !          35098: a483 1
        !          35099:        ++drvl[SDMAJOR].d_time; 
        !          35100: @
        !          35101: 
        !          35102: 
        !          35103: 1.1
        !          35104: log
        !          35105: @Shipped with COH 3.1.0
        !          35106: @
        !          35107: text
        !          35108: @d5 4
        !          35109: a8 1
        !          35110:  * $Log$
        !          35111: a18 1
        !          35112: #include       <sys/mmu.h>
        !          35113: d194 2
        !          35114: a195 1
        !          35115:        sc.buffer = vtop( buffer, sds );
        !          35116: d254 1
        !          35117: a254 1
        !          35118:                if ( PARTITION(minor(dev)) != 0 )       /* tape device ? */
        !          35119: d256 4
        !          35120: @
        !          35121: 0707070064030106361004440000030000030000011777770507310653500005400000211643/newbits/kernel/USRSRC/i8086/drv/RCS/ss.c,vhead     2.16;
        !          35122: branch   ;
        !          35123: access   ;
        !          35124: symbols  ;
        !          35125: locks    bin:2.16;
        !          35126: comment  @ * @;
        !          35127: 
        !          35128: 
        !          35129: 2.16
        !          35130: date     91.06.20.14.53.35;  author bin;  state Exp;
        !          35131: branches ;
        !          35132: next     2.15;
        !          35133: 
        !          35134: 2.15
        !          35135: date     91.06.18.08.15.11;  author bin;  state Exp;
        !          35136: branches ;
        !          35137: next     2.14;
        !          35138: 
        !          35139: 2.14
        !          35140: date     91.06.17.12.36.22;  author bin;  state Exp;
        !          35141: branches ;
        !          35142: next     2.13;
        !          35143: 
        !          35144: 2.13
        !          35145: date     91.06.10.10.25.27;  author bin;  state Exp;
        !          35146: branches ;
        !          35147: next     2.12;
        !          35148: 
        !          35149: 2.12
        !          35150: date     91.05.31.13.18.39;  author hal;  state Exp;
        !          35151: branches ;
        !          35152: next     2.11;
        !          35153: 
        !          35154: 2.11
        !          35155: date     91.05.30.15.43.17;  author hal;  state Exp;
        !          35156: branches ;
        !          35157: next     2.10;
        !          35158: 
        !          35159: 2.10
        !          35160: date     91.05.29.11.14.24;  author hal;  state Exp;
        !          35161: branches ;
        !          35162: next     2.9;
        !          35163: 
        !          35164: 2.9
        !          35165: date     91.05.22.01.38.55;  author hal;  state Exp;
        !          35166: branches ;
        !          35167: next     2.8;
        !          35168: 
        !          35169: 2.8
        !          35170: date     91.05.21.23.13.15;  author hal;  state Exp;
        !          35171: branches ;
        !          35172: next     2.7;
        !          35173: 
        !          35174: 2.7
        !          35175: date     91.05.21.19.10.43;  author hal;  state Exp;
        !          35176: branches ;
        !          35177: next     2.6;
        !          35178: 
        !          35179: 2.6
        !          35180: date     91.05.21.13.53.22;  author root;  state Exp;
        !          35181: branches ;
        !          35182: next     2.5;
        !          35183: 
        !          35184: 2.5
        !          35185: date     91.05.20.18.02.52;  author root;  state Exp;
        !          35186: branches ;
        !          35187: next     2.4;
        !          35188: 
        !          35189: 2.4
        !          35190: date     91.05.20.17.22.06;  author root;  state Exp;
        !          35191: branches ;
        !          35192: next     2.3;
        !          35193: 
        !          35194: 2.3
        !          35195: date     91.05.20.16.20.33;  author root;  state Exp;
        !          35196: branches ;
        !          35197: next     2.2;
        !          35198: 
        !          35199: 2.2
        !          35200: date     91.05.20.10.23.58;  author root;  state Exp;
        !          35201: branches ;
        !          35202: next     2.1;
        !          35203: 
        !          35204: 2.1
        !          35205: date     91.05.17.14.26.12;  author root;  state Exp;
        !          35206: branches ;
        !          35207: next     ;
        !          35208: 
        !          35209: 
        !          35210: desc
        !          35211: @ST01/ST02 Device Driver.
        !          35212: @
        !          35213: 
        !          35214: 
        !          35215: 2.16
        !          35216: log
        !          35217: @update provided by hal
        !          35218: @
        !          35219: text
        !          35220: @/*
        !          35221:  * Device driver for Seagate ST01/ST02 scsi host adapters.
        !          35222:  *
        !          35223:  * To do:
        !          35224:  *     nonzero LUN's
        !          35225:  *     start new command during disconnect
        !          35226:  *     rewrite as single state machine, instead of 7 of them
        !          35227:  *     separate SCSI layer from host-dependent stuff
        !          35228:  *
        !          35229:  * $Log:       ss.c,v $
        !          35230:  * Revision 3.1  91/06/17  07:43:25  hal
        !          35231:  * Add TMC-840 code.
        !          35232:  * 
        !          35233:  * Revision 1.1  91/06/17  07:42:27  hal
        !          35234:  * Add TMC-840 code.
        !          35235:  * 
        !          35236:  * 
        !          35237:  */
        !          35238: 
        !          35239: /*
        !          35240:  * Debug levels.
        !          35241:  * DEBUG = 0   No debug output.
        !          35242:  * DEBUG = 1   Debug output on error only.
        !          35243:  * DEBUG = 2   Debug output on error and at other selected places.
        !          35244:  * DEBUG = 3   Print state machine trace.
        !          35245:  * DEBUG = 4   Print info xfer phases and msg_in values.
        !          35246:  */
        !          35247: #if (DEBUG >= 1)
        !          35248: static int s_id;
        !          35249: #define PR1(str)               printf("%s%d ", str, s_id)
        !          35250: #else
        !          35251: #define PR1(str)
        !          35252: #endif
        !          35253: #if (DEBUG >= 2)
        !          35254: #define PR2(str)               printf(str)
        !          35255: #else
        !          35256: #define PR2(str)
        !          35257: #endif
        !          35258: #if (DEBUG >= 3)
        !          35259: #define PR3(str)               printf("%s%d ", str, s_id)
        !          35260: #else
        !          35261: #define PR3(str)
        !          35262: #endif
        !          35263: #if (DEBUG >= 4)
        !          35264: #define PR4(str)               printf("%s%d ", str, s_id)
        !          35265: #else
        !          35266: #define PR4(str)
        !          35267: #endif
        !          35268: 
        !          35269: /*
        !          35270:  * Includes.
        !          35271:  */
        !          35272: #include       <sys/coherent.h>
        !          35273: #include       <sys/io.h>
        !          35274: #include       <sys/sched.h>
        !          35275: #include       <sys/uproc.h>
        !          35276: #include       <sys/proc.h>
        !          35277: #include       <sys/con.h>
        !          35278: #include       <sys/stat.h>
        !          35279: #include       <sys/devices.h>         /* SCSI_MAJOR */
        !          35280: #include       <errno.h>
        !          35281: #include       <sys/fdisk.h>
        !          35282: #include       <sys/hdioctl.h>
        !          35283: #include       <sys/buf.h>
        !          35284: #include       <sys/scsiwork.h>
        !          35285: 
        !          35286: /*
        !          35287:  * Definitions.
        !          35288:  *     Constants.
        !          35289:  *     Macros with argument lists.
        !          35290:  *     Typedefs.
        !          35291:  *     Enums.
        !          35292:  */
        !          35293: 
        !          35294: #define SS_RAM         0x1800  /* Offset of parameter RAM */
        !          35295: 
        !          35296:                                /* Future Domain */
        !          35297: #define FD_CSR         0x1C00  /* Offset of control/status register */
        !          35298: #define FD_DAT         0x1E00  /* Offset of data port */
        !          35299: 
        !          35300:                                /* Seagate */
        !          35301: #define SS_CSR         0x1A00  /* Offset of control/status register */
        !          35302: #define SS_DAT         0x1C00  /* Offset of data port */
        !          35303: 
        !          35304: #define SS_RAM_LEN     128     /* ST0x has 128 bytes of RAM */
        !          35305: #define SS_DAT_LEN     0x400   /* Byte range mapped to data port */
        !          35306: #define SS_SEL_LEN     0x2000  /* Total size of memory-mapped area */
        !          35307: 
        !          35308: #define WC_ENABLE_SCSI 0x80    /* Write Control (WC) register bits */
        !          35309: #define WC_ENABLE_IRPT 0x40
        !          35310: #define WC_ENABLE_PRTY 0x20
        !          35311: #define WC_ARBITRATE   0x10
        !          35312: #define WC_ATTENTION   0x08
        !          35313: #define WC_BUSY        0x04
        !          35314: #define WC_SELECT      0x02
        !          35315: #define WC_SCSI_RESET          0x01
        !          35316: 
        !          35317: #define RS_ARBIT_COMPL 0x80    /* Read STATUS (RS) register bits */
        !          35318: #define RS_PRTY_ERROR  0x40
        !          35319: #define RS_SELECT      0x20
        !          35320: #define RS_REQUEST     0x10
        !          35321: #define RS_CTRL_DATA   0x08
        !          35322: #define RS_I_O         0x04
        !          35323: #define RS_MESSAGE     0x02
        !          35324: #define RS_BUSY        0x01
        !          35325: 
        !          35326: #define DEV_SCSI_ID(dev)       ((dev >> 4) & 0x0007)
        !          35327: #define DEV_LUN(dev)           ((dev >> 2) & 0x0003)
        !          35328: #define DEV_DRIVE(dev)         ((dev >> 2) & 0x001F)
        !          35329: #define DEV_PARTN(dev)         (dev & 0x0003)
        !          35330: #define DEV_SPECIAL(dev)       (dev & 0x0080)
        !          35331: 
        !          35332: #define HIPRI_RETRIES  5000    /* # of times to retry while hogging CPU */
        !          35333: #define LOPRI_RETRIES  5       /* # of retries with sleep between tries */
        !          35334: #define WHOLE_DRIVE    NPARTN
        !          35335: #define RESET_TICKS    50      /* # of clock ticks for reset settling */
        !          35336: #define LOAD_DELAY     10000   /* Loop counter during ssload() only */
        !          35337: 
        !          35338: #define BUS_FREE       ((ffbyte(ss_csr) & (RS_BUSY | RS_SELECT)) == 0)
        !          35339: #define TGT_RSEL       \
        !          35340:        (  (ffbyte(ss_csr) & (RS_SELECT |  RS_I_O   )) \
        !          35341:        && (ffbyte(ss_dat) & (host_id   | (1<<s_id) )) )
        !          35342: 
        !          35343: #define DELAY_ARB      10      /* delays units are 10 msec (clock ticks) */
        !          35344: #define DELAY_BDR      30
        !          35345: #define DELAY_BSY      20
        !          35346: #define DELAY_RES      50
        !          35347: #define DELAY_RST      40
        !          35348: 
        !          35349: #define MAX_AVL_COUNT  100
        !          35350: #define MAX_BDR_COUNT  3
        !          35351: #define MAX_BSY_COUNT  3
        !          35352: #define MAX_TRY_COUNT  10
        !          35353: #define INL_MAX_REQ_POLL       100000L
        !          35354: #define WKG_MAX_REQ_POLL       5000L
        !          35355: 
        !          35356: typedef unsigned char  uchar;
        !          35357: typedef unsigned int   uint;
        !          35358: typedef unsigned long  ulong;
        !          35359: 
        !          35360: typedef enum {                 /* values for current driver state */
        !          35361:        SST_DEQUEUE =0,
        !          35362:        SST_BUS_DEV_RESET,
        !          35363:        SST_HIPRI_RESET,
        !          35364:        SST_LOPRI_RESET,
        !          35365:        SST_POLL_ARBITN,
        !          35366:        SST_POLL_BEGIN_IO,
        !          35367:        SST_POLL_RESELECT,
        !          35368:        SST_REQ_SENSE,
        !          35369:        SST_RESET_OFF
        !          35370: } SST_TYPE;
        !          35371: 
        !          35372: typedef enum {                 /* values for input to recovery routine */
        !          35373:        RV_A_TIMEOUT,
        !          35374:        RV_P_TIMEOUT,
        !          35375:        RV_R_TIMEOUT,
        !          35376:        RV_BF_TIMEOUT,
        !          35377:        RV_CS_BUSY,
        !          35378:        RV_CS_CHECK
        !          35379: } RV_TYPE;
        !          35380: 
        !          35381: typedef struct ss {
        !          35382:        ulong   capacity;
        !          35383:        ulong   blocklen;
        !          35384:        ulong   bno;
        !          35385:        int     msg_in;
        !          35386:        int     dr_watch;
        !          35387:        uchar   cmdbuf[G1CMDLEN];
        !          35388:        int     cmdlen;
        !          35389:        int     cmd_bytes_out;
        !          35390:        int     cmdstat;
        !          35391:        BUF     *bp;            /* current I/O request node, or NULL */
        !          35392:        struct  fdisk_s parmp[NPARTN+1];
        !          35393:        SST_TYPE state;
        !          35394:        TIM     tim;            /* for target-specific timers */
        !          35395:        uchar   avl_count;
        !          35396:        uchar   bdr_count;
        !          35397:        uchar   bsy_count;
        !          35398:        uchar   try_count;
        !          35399:        uint    busy:1;         /* 1 if command uses local buffer */
        !          35400:        uint    expired:1;      /* 1 if target's timer has expired */
        !          35401:        uint    ptab_read:1;    /* 1 if partition table has been read */
        !          35402:        uint    waiting:1;      /* 1 if target timer is running */
        !          35403: }      ss_type;
        !          35404: 
        !          35405: typedef struct {
        !          35406:        uint    ncyl;
        !          35407:        uchar   nhead;
        !          35408:        uchar   nspt;
        !          35409: }      drv_parm_type;
        !          35410: 
        !          35411: /*
        !          35412:  * Functions.
        !          35413:  *     Import Functions.
        !          35414:  *     Export Functions.
        !          35415:  *     Local Functions.
        !          35416:  */
        !          35417: 
        !          35418: /* functions from bufq.c */
        !          35419: extern int bufq_init();
        !          35420: extern void bufq_rlse();
        !          35421: extern void bufq_wr_tail();
        !          35422: extern BUF * bufq_rd_head();
        !          35423: extern BUF * bufq_rm_head();
        !          35424: 
        !          35425: /* functions from ssas.s */
        !          35426: extern void    ss_get();
        !          35427: extern int     ss_put();
        !          35428: extern int     nulldev();
        !          35429: extern int     nonedev();
        !          35430: extern unsigned char ffbyte();
        !          35431: 
        !          35432: static void    ssopen();               /* CON functions */
        !          35433: static void    ssclose();
        !          35434: static void    ssblock();
        !          35435: static void    ssread();
        !          35436: static void    sswrite();
        !          35437: static int     ssioctl();
        !          35438: static void    sswatch();
        !          35439: static void    ssload();
        !          35440: static void    ssunload();
        !          35441: 
        !          35442: static int     bus_dev_reset();        /* additional support functions */
        !          35443: static int     chk_reconn();
        !          35444: static void    do_connect();
        !          35445: static void    dummy_reconn();
        !          35446: static int     far_info_xfer();
        !          35447: static int     host_ident();
        !          35448: static int     init_call();
        !          35449: static void    init_pointers();
        !          35450: static int     inquiry();
        !          35451: static int     local_info_xfer();
        !          35452: static int     mode_sense();
        !          35453: static void    next_req();
        !          35454: static void    nonpolled();
        !          35455: static int     read_cap();
        !          35456: static void    recover();
        !          35457: static int     req_sense();
        !          35458: static int     rsel_handshake();
        !          35459: static void    ssdelay();
        !          35460: static void    ss_finished();
        !          35461: static void    ss_mach();
        !          35462: static void    set_timeout();
        !          35463: static int     ssinit();
        !          35464: static void    ssintr();
        !          35465: static int     start_arb();
        !          35466: static void    stop_timeout();
        !          35467: static uchar   xpmod();
        !          35468: 
        !          35469: /*
        !          35470:  * Global Data.
        !          35471:  *     Import Variables.
        !          35472:  *     Export Variables.
        !          35473:  *     Local Variables.
        !          35474:  */
        !          35475: CON    sscon   = {
        !          35476:        DFBLK|DFCHR,                    /* Flags */
        !          35477:        SCSI_MAJOR,                     /* Major index */
        !          35478:        ssopen,                         /* Open */
        !          35479:        ssclose,                        /* Close */
        !          35480:        ssblock,                        /* Block */
        !          35481:        ssread,                         /* Read */
        !          35482:        sswrite,                        /* Write */
        !          35483:        ssioctl,                        /* Ioctl */
        !          35484:        nulldev,                        /* Powerfail */
        !          35485:        sswatch,                        /* Timeout */
        !          35486:        ssload,                         /* Load */
        !          35487:        ssunload,                       /* Unload */
        !          35488:        nulldev                         /* Poll */
        !          35489: };
        !          35490: 
        !          35491:        /* Patch these Export Variables to configure the driver. */
        !          35492: /*
        !          35493:  * In the low byte of NSDRIVE, bit n is 1 if SCSI ID n is an installed target.
        !          35494:  * The high byte indicates which type of host adapter:
        !          35495:  *   00 - ST01/ST02
        !          35496:  *   80 - TMC-845/850/860/875/885
        !          35497:  *   40 - TMC-840/841/880/881
        !          35498:  */
        !          35499: uint   NSDRIVE = 0x0000;
        !          35500: uint   SS_INT = 5;             /* ST0[12] use either IRQ3 or IRQ5 */
        !          35501: uint   SS_BASE = 0xCA00;       /* Segment addr of ST0x communication area */
        !          35502: 
        !          35503: /* ncyl, nhead, nspt */
        !          35504: drv_parm_type drv_parm[MAX_SCSI_ID] = {
        !          35505:        { 0, 0, 0},
        !          35506:        { 0, 0, 0},
        !          35507:        { 0, 0, 0},
        !          35508:        { 0, 0, 0},
        !          35509:        { 0, 0, 0},
        !          35510:        { 0, 0, 0},
        !          35511:        { 0, 0, 0}
        !          35512: };
        !          35513: 
        !          35514: static BUF     dbuf;           /* For raw I/O */
        !          35515: static paddr_t ss_base;        /* physical address of ST0x comm area */
        !          35516: static faddr_t ss_fp;          /* (far *) to ST0x comm area */
        !          35517: 
        !          35518: static faddr_t ss_ram;         /* (far *) to parameter RAM */
        !          35519: static faddr_t ss_csr;         /* (far *) to control/status */
        !          35520: static faddr_t ss_dat;         /* (far *) to data port */
        !          35521: 
        !          35522: static TIM     delay_tim;      /* needed for calls to ssdelay() */
        !          35523: static int     do_sst_op;      /* 1 when state machine iteration continues */
        !          35524: static int     ss_expired;     /* 1 after local timeout */
        !          35525: 
        !          35526: static uint    max_req_poll;   /* this changes after initialization */
        !          35527: 
        !          35528: static uchar   host_id;        /* Host is SCSI ID #7 for Seagate, 6 for FD */
        !          35529: static uchar   swap_status_bits;
        !          35530: 
        !          35531: static ss_type *ss_tbl;        /* points to block of "ss" structs */
        !          35532: static ss_type  *ss[MAX_SCSI_ID];
        !          35533: 
        !          35534: /*
        !          35535:  * host_claimed is -1 if host is available, else it's the SCSI id of the
        !          35536:  *     target that claims the host.
        !          35537:  *
        !          35538:  * host is claimed at start of any of the follwoing:
        !          35539:  *     SCSI bus reset
        !          35540:  *     arbitration for block i/o request
        !          35541:  *     reselect
        !          35542:  *
        !          35543:  * host is released at:
        !          35544:  *     end of SCSI bus reset
        !          35545:  *     completion (successful or not) of block i/o request (ss_finished)
        !          35546:  *     disconnect <-- temporarily disabled
        !          35547:  */
        !          35548: static int     host_claimed;
        !          35549: 
        !          35550: /*
        !          35551:  * ssload()    - load routine.
        !          35552:  *
        !          35553:  *     Action: The controller is reset and the interrupt vector is grabbed.
        !          35554:  *             The drive characteristics are set up at this time.
        !          35555:  */
        !          35556: static void ssload()
        !          35557: {
        !          35558:        int erf = 0;  /* 1 if error occurs */
        !          35559:        int i;
        !          35560:        int max_id = -1;
        !          35561:        int num_drives = 0;
        !          35562: 
        !          35563:        /*
        !          35564:         * Allocate a selector to map into ST0x memory-mapped comm area.
        !          35565:         */
        !          35566:        ss_base = (paddr_t)((long)(unsigned)SS_BASE << 4);
        !          35567:        ss_fp = ptov(ss_base, (fsize_t)SS_SEL_LEN);
        !          35568: 
        !          35569:        ss_ram = ss_fp + SS_RAM;
        !          35570: 
        !          35571:        /*
        !          35572:         * Primitive test of ST0x RAM.
        !          35573:         */
        !          35574:        sfword(ss_ram, 0xA55A);
        !          35575:        sfword(ss_ram + 2, 0x3CC3);
        !          35576:        sfword(ss_ram + SS_RAM_LEN - 4, 0xA55A);
        !          35577:        sfword(ss_ram + SS_RAM_LEN - 2, 0x3CC3);
        !          35578:        if (ffword(ss_ram) != 0xA55A            /* fetch a "far" word */
        !          35579:        ||  ffword(ss_ram + 2) != 0x3CC3
        !          35580:        ||  ffword(ss_ram + SS_RAM_LEN - 4) != 0xA55A
        !          35581:        ||  ffword(ss_ram + SS_RAM_LEN - 2) != 0x3CC3) {
        !          35582:                printf("Error - host failed memory test\n");
        !          35583:                erf = 1;
        !          35584:        }
        !          35585: 
        !          35586:        /*
        !          35587:         * Set host-dependent constants.
        !          35588:         */
        !          35589:        switch(NSDRIVE >> 8) {
        !          35590:        case 0x00:      /* ST01/ST02 */
        !          35591:                ss_csr = ss_fp + SS_CSR;
        !          35592:                ss_dat = ss_fp + SS_DAT;
        !          35593:                host_id = 0x80;         /* host is id #7 */
        !          35594:                break;
        !          35595:        case 0x80:      /* TMC-845/850/860/875/885 */
        !          35596:                ss_csr = ss_fp + FD_CSR;
        !          35597:                ss_dat = ss_fp + FD_DAT;
        !          35598:                host_id = 0x40;         /* host is id #6 */
        !          35599:                break;
        !          35600:        case 0x40:      /* TMC-840/841/880/881 */
        !          35601:                ss_csr = ss_fp + SS_CSR;
        !          35602:                ss_dat = ss_fp + SS_DAT;
        !          35603:                host_id = 0x40;         /* host is id #6 */
        !          35604:                swap_status_bits = 1;
        !          35605:                break;
        !          35606:        }
        !          35607:        NSDRIVE &= ~(uint)host_id;
        !          35608: 
        !          35609:        /*
        !          35610:         * Allocate drive structs.
        !          35611:         *
        !          35612:         * Do a single call to kalloc() then put allocated pieces into
        !          35613:         * array ss.
        !          35614:         *
        !          35615:         * First allocate and clear storage.  Then hook up the pointers.
        !          35616:         */
        !          35617:        if (!erf) {
        !          35618:                for (i = 0; i < MAX_SCSI_ID; i++)
        !          35619:                        if ((NSDRIVE >> i) & 1) {
        !          35620:                                max_id = i;
        !          35621:                                num_drives++;
        !          35622:                        }
        !          35623:                if (num_drives == 0) {
        !          35624:                        printf("Error - ss has no valid target id's\n");
        !          35625:                        erf = 1;
        !          35626:                } else if ((ss_tbl = kalloc(num_drives*sizeof(ss_type)))
        !          35627:                == NULL) {
        !          35628:                        printf("Error - ss can't allocate structs\n");
        !          35629:                        erf = 1;
        !          35630:                } else
        !          35631:                        kclear(ss_tbl, num_drives * sizeof(ss_type));
        !          35632:        }
        !          35633:        if (!erf) {
        !          35634:                ss_type *foo = ss_tbl;
        !          35635: 
        !          35636:                for (i = 0; i < MAX_SCSI_ID; i++)
        !          35637:                        if ((NSDRIVE >> i) & 1)
        !          35638:                                ss[i] = foo++;
        !          35639:        }
        !          35640: 
        !          35641:        /*
        !          35642:         * Claim IRQ vector.
        !          35643:         */
        !          35644:        setivec(SS_INT, ssintr);
        !          35645: 
        !          35646:        /*
        !          35647:         * Initialize drives we know about (i.e. in NSDRIVE bitmap).
        !          35648:         */
        !          35649:        host_claimed = -1;
        !          35650:        bufq_init(max_id + 1);
        !          35651:        max_req_poll = INL_MAX_REQ_POLL;
        !          35652:        if (!erf) {
        !          35653:                for (i = 0; i < MAX_SCSI_ID; i++)
        !          35654:                        if ((NSDRIVE >> i) & 1)
        !          35655:                                ssinit(i);
        !          35656:        }
        !          35657:        max_req_poll = WKG_MAX_REQ_POLL;
        !          35658: }
        !          35659: 
        !          35660: /*
        !          35661:  * ssunload()  - unload routine.
        !          35662:  */
        !          35663: static void ssunload()
        !          35664: {
        !          35665:        /*
        !          35666:         * Deallocate driver heap space.
        !          35667:         */
        !          35668:        if (ss_tbl)
        !          35669:                kfree(ss_tbl);
        !          35670:        bufq_rlse();
        !          35671: 
        !          35672:        /*
        !          35673:         * Free the ST0x selector.
        !          35674:         */
        !          35675:        vrelse(ss_fp);
        !          35676: 
        !          35677:        /*
        !          35678:         * Release IRQ vector.
        !          35679:         */
        !          35680:        clrivec(SS_INT);
        !          35681: }
        !          35682: 
        !          35683: /*
        !          35684:  * ssopen()
        !          35685:  *
        !          35686:  *     Input:  dev = disk device to be opened.
        !          35687:  *             mode = access mode [IPR,IPW, IPR+IPW].
        !          35688:  *
        !          35689:  *     Action: Validate the minor device.
        !          35690:  *             Update the paritition table if necessary.
        !          35691:  */
        !          35692: static void ssopen(dev, mode)
        !          35693: register dev_t dev;
        !          35694: {
        !          35695:        int drive, partn;
        !          35696:        struct  fdisk_s *fdp;
        !          35697:        ss_type * ssp;
        !          35698:        int s_id;
        !          35699:        uchar * msg;
        !          35700: 
        !          35701:        /*
        !          35702:         * Set up local variables.
        !          35703:         */
        !          35704:        drive = DEV_SCSI_ID(dev);
        !          35705:        partn = DEV_PARTN(dev);
        !          35706:        s_id = DEV_SCSI_ID(dev);
        !          35707:        ssp = ss[s_id];
        !          35708:        fdp = ssp->parmp;
        !          35709: 
        !          35710: #if (DEBUG >= 3)
        !          35711: devmsg(dev, "ssopen");
        !          35712: #endif
        !          35713: 
        !          35714:        /*
        !          35715:         * LUN must be zero.
        !          35716:         * SCSI id must have corresponding 1 in NSDRIVE bitmapped variable.
        !          35717:         */
        !          35718:        if (DEV_LUN(dev) != 0 || ((1 << drive) & NSDRIVE) == 0) {
        !          35719:                msg = "bad LUN or SCSI id";
        !          35720:                u.u_error = ENXIO;
        !          35721:                goto bad_open;
        !          35722:        }
        !          35723: 
        !          35724:        /*
        !          35725:         * If "special" bit is set, partition field must be zero.
        !          35726:         */
        !          35727:        if (DEV_SPECIAL(dev) && partn != 0) {
        !          35728:                msg = "bad special partition";
        !          35729:                u.u_error = ENXIO;
        !          35730:                goto bad_open;
        !          35731:        }
        !          35732: 
        !          35733:        /*
        !          35734:         * Subscripting gimmick for partition table.
        !          35735:         */
        !          35736:        if (dev & SDEV)
        !          35737:                partn = WHOLE_DRIVE;
        !          35738: 
        !          35739:        /*
        !          35740:         * If not accessing whole drive and the partition table has not
        !          35741:         * been read yet, try to read it now.
        !          35742:         * Do this by calling fdisk() with partition table device on the drive
        !          35743:         * that is being accessed.
        !          35744:         */
        !          35745:        if (partn != WHOLE_DRIVE && !(ssp->ptab_read)) {
        !          35746:                int fdisk_dev;
        !          35747: 
        !          35748:                fdisk_dev = (dev | SDEV) & 0xfff0;
        !          35749: 
        !          35750: #if (DEBUG >=3)
        !          35751:                devmsg(fdisk_dev, "calling fdisk");
        !          35752:                if (fdisk(fdisk_dev, fdp)) {
        !          35753:                        int p;
        !          35754: 
        !          35755:                        fdp[WHOLE_DRIVE].p_size = ssp->capacity;
        !          35756:                        fdp[WHOLE_DRIVE].p_base = 0;
        !          35757:                        printf("fdisk() succeeded\n");
        !          35758:                        for (p=0; p<=WHOLE_DRIVE; p++)
        !          35759:        printf("p=%d base=%ld size=%ld\n", p, fdp[p].p_base, fdp[p].p_size);
        !          35760:                        ssp->ptab_read = 1;
        !          35761:                } else {
        !          35762:                        printf("fdisk() failed\n");
        !          35763:                        u.u_error = ENXIO;
        !          35764:                        goto bad_open;
        !          35765:                }
        !          35766: #else
        !          35767:                if (fdisk(fdisk_dev, fdp)) {
        !          35768:                        fdp[WHOLE_DRIVE].p_size = ssp->capacity;
        !          35769:                        fdp[WHOLE_DRIVE].p_base = 0;
        !          35770:                        ssp->ptab_read = 1;
        !          35771:                } else {
        !          35772:                        msg = "bad partition table";
        !          35773:                        u.u_error = ENXIO;
        !          35774:                        goto bad_open;
        !          35775:                }
        !          35776: #endif
        !          35777: 
        !          35778:        }
        !          35779: 
        !          35780:        /*
        !          35781:         * Ensure partition lies within drive boundaries and is non-zero size.
        !          35782:         */
        !          35783:        if (partn != WHOLE_DRIVE
        !          35784:        && (fdp[partn].p_base+fdp[partn].p_size) > fdp[WHOLE_DRIVE].p_size) {
        !          35785:                msg = "partition exceeds drive capacity";
        !          35786:                u.u_error = EBADFMT;
        !          35787:                goto bad_open;
        !          35788:        }
        !          35789: 
        !          35790:        if (partn != WHOLE_DRIVE && fdp[partn].p_size == 0) {
        !          35791:                msg = "partition not found";
        !          35792:                u.u_error = ENODEV;
        !          35793:                goto bad_open;
        !          35794:        }
        !          35795: 
        !          35796:        /*
        !          35797:         * OK to open the device.
        !          35798:         * Start watchdog timer (if not already started) for the host adapter.
        !          35799:         */
        !          35800:        ++drvl[SCSI_MAJOR].d_time;
        !          35801:        ++ssp->dr_watch;
        !          35802:        goto end_open;
        !          35803: 
        !          35804: bad_open:
        !          35805:        devmsg(dev, msg);
        !          35806: end_open:
        !          35807:        return;
        !          35808: }
        !          35809: 
        !          35810: /*
        !          35811:  * ssclose()
        !          35812:  */
        !          35813: static void ssclose(dev)
        !          35814: dev_t dev;
        !          35815: {
        !          35816:        ss_type * ssp;
        !          35817:        int s_id;
        !          35818: 
        !          35819:        s_id = DEV_SCSI_ID(dev);
        !          35820:        ssp = ss[s_id];
        !          35821: 
        !          35822:        /*
        !          35823:         * Decrement the number of watchdog timer requests open for host
        !          35824:         * adapter and for target.
        !          35825:         */
        !          35826:        --drvl[SCSI_MAJOR].d_time;      
        !          35827:        --ssp->dr_watch;
        !          35828: 
        !          35829: #if (DEBUG >= 3)
        !          35830: devmsg(dev, "ssclose");
        !          35831: #endif
        !          35832: 
        !          35833: }
        !          35834: 
        !          35835: /*
        !          35836:  * ssread()    - read a block from the raw disk
        !          35837:  *
        !          35838:  *     Input:  dev = disk device to be written to.
        !          35839:  *             iop = pointer to source I/O structure.
        !          35840:  *
        !          35841:  *     Action: Invoke the common raw I/O processing code.
        !          35842:  */
        !          35843: static void ssread(dev, iop)
        !          35844: dev_t  dev;
        !          35845: IO     *iop;
        !          35846: {
        !          35847:        ioreq( &dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC );
        !          35848: }
        !          35849: 
        !          35850: /*
        !          35851:  * sswrite()   - write a block to the raw disk
        !          35852:  *
        !          35853:  *     Input:  dev = disk device to be written to.
        !          35854:  *             iop = pointer to source I/O structure.
        !          35855:  *
        !          35856:  *     Action: Invoke the common raw I/O processing code.
        !          35857:  */
        !          35858: static void sswrite(dev, iop)
        !          35859: dev_t  dev;
        !          35860: IO     *iop;
        !          35861: {
        !          35862:        ioreq( &dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC );
        !          35863: }
        !          35864: 
        !          35865: /*
        !          35866:  * ssioctl()
        !          35867:  *
        !          35868:  *     Input:  dev = disk device to be operated on.
        !          35869:  *             cmd = input/output request to be performed.
        !          35870:  *             vec = (pointer to) optional argument.
        !          35871:  */
        !          35872: static int ssioctl(dev, cmd, vec)
        !          35873: register dev_t dev;
        !          35874: int cmd;
        !          35875: char * vec;
        !          35876: {
        !          35877:        int ret = 0;
        !          35878:        hdparm_t hdparm;
        !          35879:        struct  fdisk_s *fdp;
        !          35880:        int s_id;
        !          35881:        ss_type * ssp;
        !          35882: 
        !          35883:        s_id = DEV_SCSI_ID(dev);
        !          35884:        ssp = ss[s_id];
        !          35885:        fdp = ssp->parmp;
        !          35886: 
        !          35887:        switch(cmd) {
        !          35888:        case HDGETA:
        !          35889:                /*
        !          35890:                 * Get hard disk attributes.
        !          35891:                 */
        !          35892: PR3("HDGETA");
        !          35893:                fdp = ssp->parmp;
        !          35894:                *(short *)&hdparm.landc[0] =
        !          35895:                *(short *)&hdparm.ncyl[0] = drv_parm[s_id].ncyl;
        !          35896:                hdparm.nhead = drv_parm[s_id].nhead;
        !          35897:                hdparm.nspt = drv_parm[s_id].nspt;
        !          35898: #if (DEBUG >= 3)
        !          35899: printf("ncyl=%d nhead=%d nspt=%d\n",
        !          35900:   hdparm.ncyl[0]+((int)hdparm.ncyl[1]<<8), (int)hdparm.nhead, (int)hdparm.nspt);
        !          35901: #endif
        !          35902:                kucopy(&hdparm, vec, sizeof hdparm);
        !          35903:                ret = 0;
        !          35904:                break;
        !          35905:        case HDSETA:
        !          35906:                /*
        !          35907:                 * Set hard disk attributes.
        !          35908:                 */
        !          35909: PR3("HDSETA");
        !          35910:                fdp = ssp->parmp;
        !          35911:                ukcopy(vec, &hdparm, sizeof hdparm);
        !          35912:                drv_parm[s_id].ncyl = *(short *)&hdparm.ncyl[0];
        !          35913:                drv_parm[s_id].nhead = hdparm.nhead;
        !          35914:                drv_parm[s_id].nspt = hdparm.nspt;
        !          35915: #if (DEBUG >= 3)
        !          35916: printf("ncyl=%d nhead=%d nspt=%d\n",
        !          35917:   hdparm.ncyl[0]+((int)hdparm.ncyl[1]<<8), (int)hdparm.nhead, (int)hdparm.nspt);
        !          35918: #endif
        !          35919:                ret = 0;
        !          35920:                break;
        !          35921:        default:
        !          35922:                u.u_error = EINVAL;
        !          35923:                ret = -1;
        !          35924:        }
        !          35925: 
        !          35926:        return ret;
        !          35927: }
        !          35928: 
        !          35929: /*
        !          35930:  * ssblock()   - queue a block to the disk
        !          35931:  *
        !          35932:  *     Input:  bp = pointer to block to be queued.
        !          35933:  *
        !          35934:  *     Action: Queue a block to the disk.
        !          35935:  *             Make sure that the transfer is within the disk partition.
        !          35936:  */
        !          35937: static void ssblock(bp)
        !          35938: register BUF   *bp;
        !          35939: {
        !          35940:        struct  fdisk_s *fdp;
        !          35941:        int partition, drive, s_id;
        !          35942:        dev_t dev;
        !          35943:        ss_type * ssp;
        !          35944:        uchar * msg = NULL;
        !          35945: 
        !          35946:        /*
        !          35947:         * Set up local variables.
        !          35948:         */
        !          35949:        dev = bp->b_dev;
        !          35950:        partition = DEV_PARTN(dev);
        !          35951:        drive = DEV_DRIVE(dev);
        !          35952:        s_id = DEV_SCSI_ID(dev);
        !          35953:        ssp = ss[s_id];
        !          35954:        if (dev & SDEV)
        !          35955:                partition = WHOLE_DRIVE;
        !          35956:        fdp = ssp->parmp;
        !          35957: 
        !          35958:        bp->b_resid = bp->b_count;
        !          35959: #if (DEBUG >= 2)
        !          35960: if (bp->b_count != BSIZE)
        !          35961:        printf("b_count=%d ", bp->b_count);
        !          35962: #endif
        !          35963: 
        !          35964:        /*
        !          35965:         * Range check disk region.
        !          35966:         */
        !          35967:        if (!(ssp->ptab_read)) {
        !          35968:                if ( partition == WHOLE_DRIVE ) {
        !          35969:                        if ((bp->b_bno != 0) || (bp->b_count != BSIZE)) {
        !          35970:                                msg = "invalid request";
        !          35971:                                bp->b_flag |= BFERR;
        !          35972:                                goto bad_blk;
        !          35973:                        }
        !          35974:                } else {
        !          35975:                        msg = "no partition table";
        !          35976:                        bp->b_flag |= BFERR;
        !          35977:                        goto bad_blk;
        !          35978:                }
        !          35979:        }
        !          35980: 
        !          35981:        /*
        !          35982:         * Check for read at end of partition.
        !          35983:         * (Need to return with b_resid = BSIZE to signal end of volume.)
        !          35984:         */
        !          35985:        else if ((bp->b_req == BREAD) && (bp->b_bno == fdp[partition].p_size)) {
        !          35986:                goto bad_blk;
        !          35987:        }
        !          35988: 
        !          35989:        /*
        !          35990:         * Check for read past end of partition.
        !          35991:         */
        !          35992:        else if ( (bp->b_bno + (bp->b_count/BSIZE))
        !          35993:        > fdp[partition].p_size ) {
        !          35994:                msg = "partition overrun";
        !          35995:                bp->b_flag |= BFERR;
        !          35996:                goto bad_blk;
        !          35997:        }
        !          35998: 
        !          35999:        /*
        !          36000:         * Fail if request is for zero bytes or is not even # of blocks.
        !          36001:         */
        !          36002:        if ((bp->b_count % BSIZE) || bp->b_count == 0) {
        !          36003:                msg = "invalid byte count";
        !          36004:                bp->b_flag |= BFERR;
        !          36005:                goto bad_blk;
        !          36006:        }
        !          36007: 
        !          36008:        /*
        !          36009:         * Operation appears valid.
        !          36010:         * Fill fields in the node and queue the request.
        !          36011:         */
        !          36012:        bufq_wr_tail(s_id, bp);
        !          36013:        ss_mach(s_id);
        !          36014:        goto end_blk;
        !          36015: 
        !          36016:        /*
        !          36017:         * Operation cannot be done.  Release the kernel buffer structure.
        !          36018:         * Value of "bp->b_flag" tells caller if error occurred.
        !          36019:         */
        !          36020: bad_blk:
        !          36021:        if (msg)
        !          36022:                devmsg(dev, msg);
        !          36023:        bdone(bp);
        !          36024: 
        !          36025: end_blk:
        !          36026:        return;
        !          36027: }
        !          36028: 
        !          36029: /*
        !          36030:  * ssintr()    - Interrupt routine.
        !          36031:  *
        !          36032:  * If we have been reselected by a recognized target device
        !          36033:  *     let kernel get out of interrupt mode (defer) and do SCSI
        !          36034:  *     reconnect stuff.
        !          36035:  */
        !          36036: static void ssintr()
        !          36037: {
        !          36038:        int s_id;
        !          36039: 
        !          36040:        s_id = chk_reconn();
        !          36041:        if (s_id != -1) {
        !          36042:                if (ss[s_id]->state == SST_POLL_RESELECT)
        !          36043:                        defer(ss_mach, s_id);
        !          36044:                else
        !          36045:                        defer(dummy_reconn, s_id);
        !          36046: PR3("!");
        !          36047:        }
        !          36048: }
        !          36049: 
        !          36050: /*
        !          36051:  * dummy_reconn()
        !          36052:  *
        !          36053:  * Somehow we are in a state where the driver software does not expect
        !          36054:  * a reconnect but a device is trying one anyway.  Go thru the motions
        !          36055:  * of reconnect because not servicing a hanging reselect seems to leave
        !          36056:  * the target hung - in such a way that it fails to respond to reset
        !          36057:  * messages and to reset on the SCSI bus.
        !          36058:  */
        !          36059: static void dummy_reconn(s_id)
        !          36060: int s_id;
        !          36061: {
        !          36062:        int bus_timeout;
        !          36063:        uchar phase_type;
        !          36064:        int s;
        !          36065:        int msg_in;
        !          36066:        int cmdstat;
        !          36067:        int xfer_good = 1;
        !          36068: PR1("DUM");
        !          36069:        if (ss[s_id]->state == SST_POLL_RESELECT) {
        !          36070:                defer(ss_mach, s_id);
        !          36071:                goto dum_done;
        !          36072:        }
        !          36073:        if (!rsel_handshake())
        !          36074:                goto dum_done;
        !          36075: 
        !          36076:        s = sphi();
        !          36077:        while (req_wait(&bus_timeout) && xfer_good) {
        !          36078:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          36079:                switch (xpmod(phase_type)) {
        !          36080:                case XP_MSG_IN:
        !          36081:                        msg_in = ffbyte(ss_dat);
        !          36082:                        switch(msg_in){
        !          36083:                        case MSG_CMD_CMPLT:
        !          36084:                        case MSG_DISCONNECT:
        !          36085:                                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
        !          36086:                                break;
        !          36087:                        }
        !          36088:                        break;
        !          36089:                case XP_MSG_OUT:
        !          36090:                        sfbyte(ss_dat, MSG_NOP); 
        !          36091:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          36092:                        break;
        !          36093:                case XP_STAT_IN:
        !          36094:                        cmdstat = ffbyte(ss_dat);
        !          36095:                        break;
        !          36096:                case XP_CMD_OUT:
        !          36097:                case XP_DATA_OUT:
        !          36098:                        xfer_good = 0;
        !          36099:                        break;
        !          36100:                case XP_DATA_IN:
        !          36101:                        ffbyte(ss_dat);
        !          36102:                        break;
        !          36103:                default:
        !          36104:                        break;
        !          36105:                } /* endswitch */
        !          36106:        } /* endwhile */
        !          36107:        spl(s);
        !          36108: 
        !          36109: dum_done:
        !          36110:        return;
        !          36111: }
        !          36112: 
        !          36113: /*
        !          36114:  * sswatch()
        !          36115:  *
        !          36116:  * Invoked once per second if any devices going through this driver are open.
        !          36117:  * Poll for any reselect, in case interrupt got lost.
        !          36118:  */
        !          36119: static void sswatch()
        !          36120: {
        !          36121:        int s_id;
        !          36122:        ss_type * ssp;
        !          36123: 
        !          36124:        for (s_id = 0; s_id < MAX_SCSI_ID; s_id++) {
        !          36125:                ssp = ss[s_id];
        !          36126:                if (ssp && ssp->dr_watch)
        !          36127:                        defer(ss_mach, s_id);
        !          36128:        } /* endfor */
        !          36129: }
        !          36130: 
        !          36131: /*
        !          36132:  * bus_wait()
        !          36133:  *
        !          36134:  * Wait for specified bit values to appear in Status Register.
        !          36135:  * This uses a tight loop and does not expect to be interrupted.
        !          36136:  *
        !          36137:  * Argument "flags" is a double-byte value;  the high byte is ANDed with
        !          36138:  * status register contents, and the result is tested for equality with
        !          36139:  * the low byte.
        !          36140:  *
        !          36141:  * Return 1 if values wanted appeared, 0 if timeout occurred.
        !          36142:  */
        !          36143: static int bus_wait(flags)
        !          36144: unsigned short flags;
        !          36145: {
        !          36146:        int found, i;
        !          36147:        unsigned char status;
        !          36148: 
        !          36149:        found = 0;
        !          36150:        for ( i = 0; i < HIPRI_RETRIES; i++) {
        !          36151:                status = ffbyte(ss_csr);
        !          36152:                if ((status & (flags >> 8)) == (flags & 0xff)) {
        !          36153:                        found = 1;
        !          36154:                        break;
        !          36155:                }
        !          36156:        }
        !          36157: 
        !          36158: #if (DEBUG >= 1)
        !          36159:        if (!found)
        !          36160:                printf("TO:f=%x s=%x ", flags, status);
        !          36161: #endif
        !          36162: 
        !          36163:        return found;
        !          36164: }
        !          36165: 
        !          36166: /*
        !          36167:  * ssinit()
        !          36168:  *
        !          36169:  * Attempt to initialize the (unique) drive with a given SCSI id.
        !          36170:  * Assume only one drive per SCSI id, having LUN = 0.
        !          36171:  * 
        !          36172:  * Return 1 if success, 0 if failure.
        !          36173:  */
        !          36174: static int ssinit(s_id)
        !          36175: int s_id;
        !          36176: {
        !          36177:        int retval = 1;
        !          36178:        uchar query_buf[MODESENSELEN];
        !          36179:        ss_type * ssp = ss[s_id];
        !          36180:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          36181: 
        !          36182:        printf("SCSI ID %d  LUN 0\n", s_id);
        !          36183:        if (retval)
        !          36184:                if (init_call(inquiry, s_id, query_buf)) {
        !          36185:                        query_buf[INQUIRYLEN] = 0;
        !          36186: #if (debug >= 2)
        !          36187:                        devmsg(dev, query_buf + 8);
        !          36188: #endif
        !          36189:                        if (query_buf[0] == 0) {
        !          36190:                                retval = 1;
        !          36191:                        } else
        !          36192:                                devmsg(dev, "Not Direct Access Device");
        !          36193:                } else
        !          36194:                        devmsg(dev, "Inquiry Failed");
        !          36195: 
        !          36196:        if (retval)
        !          36197:                if (init_call(read_cap, s_id, query_buf)) {
        !          36198:                        retval = 1;
        !          36199:                        ssp->capacity = query_buf[3] | (query_buf[2] << 8)
        !          36200:                        | (((long)(query_buf[1])) << 16)
        !          36201:                        | (((long)(query_buf[0])) << 24);
        !          36202:                        ssp->blocklen = query_buf[7] | (query_buf[6] << 8)
        !          36203:                        | (((long)(query_buf[5])) << 16)
        !          36204:                        | (((long)(query_buf[4])) << 24);
        !          36205: 
        !          36206:                        printf("Capacity=%ld blocks  Block length=%ld\n",
        !          36207:                                ssp->capacity, ssp->blocklen);
        !          36208:                } else
        !          36209:                        devmsg(dev, "Read Capacity Failed");
        !          36210: 
        !          36211:        if (retval)
        !          36212:                if (init_call(mode_sense, s_id, query_buf)) {
        !          36213:                        /*
        !          36214:                         * Display physical drive parameters.
        !          36215:                         */
        !          36216: #define FMT_PG (4+8+8+12)
        !          36217: #define DDG_PG (4+8+8+12+24)
        !          36218:                        uchar heads;
        !          36219:                        unsigned short spt;
        !          36220:                        ulong cyls;
        !          36221: 
        !          36222:                        spt=((int)query_buf[FMT_PG+10]<<8)
        !          36223:                                + query_buf[FMT_PG+11];
        !          36224:                        cyls=((int)query_buf[DDG_PG+2]<<16)
        !          36225:                                + ((int)query_buf[DDG_PG+3]<<8)
        !          36226:                                + query_buf[DDG_PG+4];
        !          36227:                        heads=query_buf[DDG_PG+5];
        !          36228: 
        !          36229:                        printf("Physical:  cylinders=%ld ", cyls);
        !          36230:                        printf("heads=%d ", heads);
        !          36231:                        printf("spt=%d\n", spt);
        !          36232: 
        !          36233:                        if (drv_parm[s_id].ncyl == 0) {
        !          36234:                                drv_parm[s_id].ncyl = cyls;
        !          36235:                                drv_parm[s_id].nhead = heads;
        !          36236:                                drv_parm[s_id].nspt = spt;
        !          36237:                        } else {
        !          36238:                                printf("Logical:  cylinders=%d ",
        !          36239:                                        drv_parm[s_id].ncyl);
        !          36240:                                printf("heads=%d ", drv_parm[s_id].nhead);
        !          36241:                                printf("spt=%d\n", drv_parm[s_id].nspt);
        !          36242:                        }
        !          36243:                } else
        !          36244:                        devmsg(dev, "Mode Sense Failed");
        !          36245: 
        !          36246:        return retval;
        !          36247: }
        !          36248: 
        !          36249: /*
        !          36250:  * far_info_xfer()
        !          36251:  *
        !          36252:  * Do bus cycle information transfer phases.
        !          36253:  * This includes message in/out, command in/out, and data in/out.
        !          36254:  *
        !          36255:  * If cmdlen is nonzero, cmdbuf is an array of bytes of that length,
        !          36256:  * to be sent to the target.
        !          36257:  *
        !          36258:  * Return 1 if bus timeout did not occur, else 0.
        !          36259:  *
        !          36260:  * pseudocode:
        !          36261:  *
        !          36262:  * while (wait for REQ true or BUSY false on SCSI bus)
        !          36263:  *   if (BUSY false)
        !          36264:  *     break from while loop
        !          36265:  *   else
        !          36266:  *     switch (xfer phase = RS_CTRL_DATA|RS_I_O|RS_MESSAGE)
        !          36267:  *       case XP_MSG_IN/XP_MSG_OUT/...
        !          36268:  *         handle the indicated information transfer phase
        !          36269:  *     endswitch
        !          36270:  *   endif
        !          36271:  * endwhile
        !          36272:  */
        !          36273: static int far_info_xfer(s_id)
        !          36274: int s_id;
        !          36275: {
        !          36276:        int bus_timeout;
        !          36277:        uchar phase_type;
        !          36278:        uchar msg_in;
        !          36279:        int s;
        !          36280:        int bytes_to_send;
        !          36281:        ss_type * ssp = ss[s_id];
        !          36282:        BUF * bp = ssp->bp;
        !          36283:        int xfer_good = 1;
        !          36284:        int xfer_count = bp->b_count - bp->b_resid;
        !          36285:        int irpts_masked;
        !          36286: int block_done=0;
        !          36287: 
        !          36288:        ssp->cmd_bytes_out = 0;
        !          36289:        ssp->msg_in = -1;
        !          36290: 
        !          36291:        irpts_masked = 0;
        !          36292:        while (req_wait(&bus_timeout) && xfer_good) {
        !          36293:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          36294:                if (!irpts_masked) {
        !          36295:                        s = sphi();
        !          36296:                        irpts_masked = 1;
        !          36297:                }
        !          36298:                switch (xpmod(phase_type)) {
        !          36299:                case XP_MSG_IN:
        !          36300:                        msg_in = ffbyte(ss_dat);
        !          36301:                        switch(msg_in){
        !          36302:                        case MSG_CMD_CMPLT:
        !          36303: PR4("Mcc");
        !          36304:                                ssp->msg_in = msg_in;
        !          36305:                                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
        !          36306:                                break;
        !          36307:                        case MSG_DISCONNECT:
        !          36308: PR4("Mdc");
        !          36309:                                ssp->msg_in = msg_in;
        !          36310:                                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
        !          36311:                                break;
        !          36312:                        case MSG_SAVE_DPTR:
        !          36313: PR4("Msd");
        !          36314:                                break;
        !          36315:                        case MSG_RSTOR_DPTR:
        !          36316: PR4("Mrd");
        !          36317:                                break;
        !          36318:                        case MSG_ABORT:
        !          36319: PR4("Mab");
        !          36320:                                break;
        !          36321:                        case MSG_DEV_RESET:
        !          36322: PR4("Mdr");
        !          36323:                                break;
        !          36324:                        case MSG_IDENTIFY:
        !          36325: PR4("Mmi");
        !          36326:                                break;
        !          36327:                        case MSG_IDENT_DC:
        !          36328: PR4("Mmd");
        !          36329:                                break;
        !          36330:                        }
        !          36331:                        break;
        !          36332:                case XP_MSG_OUT:
        !          36333: PR4("MO");
        !          36334:                        /*
        !          36335:                         * This case shouldn't happen.  We weren't
        !          36336:                         * asserting ATTENTION.  Abort the bus cycle.
        !          36337:                         */
        !          36338:                        sfbyte(ss_dat, MSG_NOP); 
        !          36339:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          36340:                        break;
        !          36341:                case XP_STAT_IN:
        !          36342: PR4("SI");
        !          36343:                        ssp->cmdstat = ffbyte(ss_dat);
        !          36344:                        break;
        !          36345:                case XP_CMD_OUT:
        !          36346:                        /*
        !          36347:                         * Ship out command bytes.
        !          36348:                         * Reset SCSI bus if too many command bytes are wanted.
        !          36349:                         */
        !          36350:                        bytes_to_send = ssp->cmdlen - ssp->cmd_bytes_out;
        !          36351:                        if(bytes_to_send > 0) {
        !          36352:                                sfbyte(ss_dat, ssp->cmdbuf[ssp->cmd_bytes_out++]);
        !          36353:                                /*
        !          36354:                                 * If just sent last byte, allow interrupts.
        !          36355:                                 */
        !          36356:                                if (bytes_to_send == 1) {
        !          36357: PR4("CO");
        !          36358:                                        if (bp->b_req == BREAD) {
        !          36359:                                                if (irpts_masked) {
        !          36360:                                                        spl(s);
        !          36361:                                                        irpts_masked = 0;
        !          36362:                                                }
        !          36363:                                        }
        !          36364:                                }
        !          36365:                        } else {        /* This case should not happen. */
        !          36366:                                xfer_good = 0;
        !          36367:                        }
        !          36368:                        break;
        !          36369:                case XP_DATA_IN:
        !          36370:                        /*
        !          36371:                         * If caller's buffer has room, keep incoming
        !          36372:                         * data byte.
        !          36373:                         */
        !          36374:                        if (block_done) {
        !          36375:                                xfer_good = 0;
        !          36376: PR1("Data in overrun");
        !          36377:                        } else if (bp->b_req != BREAD) {
        !          36378:                                xfer_good = 0;
        !          36379:                        } else {
        !          36380: #if 0
        !          36381:                                int getbval;
        !          36382: 
        !          36383:                                block_done=1;
        !          36384: PR4("DI");
        !          36385:                                if(getbval = ss_getb(ss_dat,
        !          36386:                                bp->b_faddr + xfer_count)) {
        !          36387:                                        xfer_good = 0;
        !          36388: #if (DEBUG >= 1)
        !          36389: printf("getb=%d ", getbval);
        !          36390: #endif
        !          36391:                                }
        !          36392: #else
        !          36393:                                block_done=1;
        !          36394:                                ffcopy(ss_dat, bp->b_faddr + xfer_count, BSIZE);
        !          36395: #endif
        !          36396:                        }
        !          36397:                        break;
        !          36398:                case XP_DATA_OUT:
        !          36399:                        /*
        !          36400:                         * Copy output buffer bytes to data register.
        !          36401:                         */
        !          36402:                        if (block_done) {
        !          36403:                                xfer_good = 0;
        !          36404: PR1("Data out overrun");
        !          36405:                        } else if (bp->b_req != BWRITE) {
        !          36406:                                xfer_good = 0;
        !          36407:                        } else {
        !          36408: #if 0
        !          36409:                                int putbval;
        !          36410:                                block_done=1;
        !          36411: PR4("DO");
        !          36412:                                if (putbval = ss_putb(ss_dat,
        !          36413:                                bp->b_faddr + xfer_count)) {
        !          36414:                                        xfer_good = 0;
        !          36415: #if (DEBUG >= 1)
        !          36416: printf("putb=%d ", putbval);
        !          36417: #endif
        !          36418:                                }
        !          36419: #else
        !          36420:                                block_done=1;
        !          36421:                                ffcopy(bp->b_faddr + xfer_count, ss_dat, BSIZE);
        !          36422: #endif
        !          36423:                                if (irpts_masked) {
        !          36424:                                        spl(s);
        !          36425:                                        irpts_masked = 0;
        !          36426:                                }
        !          36427:                        }
        !          36428:                        break;
        !          36429:                default:
        !          36430:                        break;
        !          36431:                } /* endswitch */
        !          36432:        }
        !          36433:        if (irpts_masked)
        !          36434:                spl(s);
        !          36435: 
        !          36436: #if (DEBUG >= 1)
        !          36437:        switch(ssp->cmdstat) {
        !          36438:        case -1:
        !          36439:                if (msg_in != MSG_DISCONNECT)
        !          36440:                        printf("CS-",ssp->cmdstat);
        !          36441:                break;
        !          36442:        case CS_GOOD:
        !          36443:                break;
        !          36444:        case CS_CHECK:
        !          36445:                printf("CSK",ssp->cmdstat);
        !          36446:                break;
        !          36447:        case CS_BUSY:
        !          36448:                printf("CSY",ssp->cmdstat);
        !          36449:                break;
        !          36450:        case CS_RESERVED:
        !          36451:        default:
        !          36452:                printf("CS%x",ssp->cmdstat);
        !          36453:        }
        !          36454: #endif
        !          36455: 
        !          36456:        return (bus_timeout) ? 0 : 1 ;
        !          36457: }
        !          36458: 
        !          36459: /*
        !          36460:  * req_wait()
        !          36461:  *
        !          36462:  * This routine is called at the start of each information transfer
        !          36463:  * phase and after the last such phase.
        !          36464:  *
        !          36465:  * It returns 1 if REQ is asserted on the SCSI bus, meaning another phase
        !          36466:  * may begin, and 0 otherwise.  A REQ signal will not be seen if the function
        !          36467:  * times out or if BUSY drops.  A value of 1 is written to the pointer argument
        !          36468:  * if timeout occurred, else 0 is written.
        !          36469:  */
        !          36470: static int req_wait(to_ptr)
        !          36471: int *to_ptr;
        !          36472: {
        !          36473:        int req_found;
        !          36474:        unsigned char status;
        !          36475:        ulong poll_ct;
        !          36476: 
        !          36477:        *to_ptr = 1;
        !          36478:        req_found = 0;
        !          36479:        for (poll_ct = 0L; poll_ct < max_req_poll; poll_ct++) {
        !          36480:                status = ffbyte(ss_csr);
        !          36481:                if (status & RS_REQUEST) {
        !          36482:                        req_found = 1;
        !          36483:                        *to_ptr = 0;
        !          36484:                        break;
        !          36485:                } else if ((status & RS_BUSY) == 0) {
        !          36486:                        *to_ptr = 0;
        !          36487:                        break;
        !          36488:                }
        !          36489:        }
        !          36490: 
        !          36491: #if (DEBUG >= 1)
        !          36492:        if (*to_ptr) {
        !          36493:                printf("TX: s=%x ", status);
        !          36494:        }
        !          36495: #endif
        !          36496: 
        !          36497:        return req_found;
        !          36498: }
        !          36499: 
        !          36500: /*
        !          36501:  * req_sense()
        !          36502:  *
        !          36503:  * Request Sense for a device.  The main reason for doing this is to
        !          36504:  * clear a standing Command Status of Device Check.
        !          36505:  *
        !          36506:  * Full results are discarded.  Return 1 if Device returns No Sense or
        !          36507:  * or Unit Attention.  Else return 0.
        !          36508:  *
        !          36509:  */
        !          36510: static int req_sense(s_id)
        !          36511: int s_id;
        !          36512: {
        !          36513:        uchar sense_buf[SENSELEN];
        !          36514:        uchar cmdbuf[G0CMDLEN];
        !          36515:        int ret = 0;
        !          36516: 
        !          36517:        cmdbuf[0] = ScmdREQUESTSENSE;
        !          36518:        cmdbuf[1] = 0;
        !          36519:        cmdbuf[2] = 0;
        !          36520:        cmdbuf[3] = 0;
        !          36521:        cmdbuf[4] = SENSELEN;
        !          36522:        cmdbuf[5] = 0;
        !          36523: 
        !          36524: #if (DEBUG >= 2)
        !          36525: {int i; for (i=0; i<SENSELEN; i++) sense_buf[i]=0;}
        !          36526: #endif
        !          36527: 
        !          36528: PR2("rqs:");
        !          36529:        if (!start_arb()) {
        !          36530: PR2("NO arb");
        !          36531: #if (DEBUG >= 2)
        !          36532: printf("status=%x ", ffbyte(ss_csr));
        !          36533: #endif
        !          36534:                goto rqs_done;
        !          36535:        }
        !          36536: 
        !          36537:        if (!host_ident(s_id, 0)) {
        !          36538: PR2("NO host ident");
        !          36539: #if (DEBUG >= 2)
        !          36540: printf("status=%x ", ffbyte(ss_csr));
        !          36541: #endif
        !          36542:                goto rqs_done;
        !          36543:        }
        !          36544: 
        !          36545:        if(!local_info_xfer(cmdbuf, G0CMDLEN, sense_buf, SENSELEN, NULL, 0)) {
        !          36546: PR2("NO local xfer");
        !          36547:                goto rqs_done;
        !          36548:        } else {
        !          36549:                /*
        !          36550:                 * Return 1 if drive responded with any of these sense keys:
        !          36551:                 *      0x00    No Sense
        !          36552:                 *      0x06    Unit Attention
        !          36553:                 *      0x0B    Aborted Command
        !          36554:                 * In any of the above cases, a retry will likely succeed
        !          36555:                 * without Buse Device Reset or SCSI Bus Reset.
        !          36556:                 */
        !          36557:                switch (sense_buf[2]) {
        !          36558:                case 0x00:
        !          36559:                case 0x06:
        !          36560:                case 0x0B:
        !          36561:                        ret = 1;
        !          36562:                        break;
        !          36563:                } /* endswitch */
        !          36564:        }
        !          36565: 
        !          36566: rqs_done:
        !          36567: #if (DEBUG >= 2)
        !          36568: {
        !          36569:        int i;
        !          36570: 
        !          36571:        for (i=0; i<SENSELEN;i++)
        !          36572:                printf("%x ", sense_buf[i]);
        !          36573:        printf("\n");
        !          36574: }
        !          36575: #endif
        !          36576:        return ret;
        !          36577: }
        !          36578: 
        !          36579: /*
        !          36580:  * inquiry()
        !          36581:  *
        !          36582:  * Inquiry command for a device.
        !          36583:  * Find out if device is direct access, removable, etc.
        !          36584:  *
        !          36585:  * Put result of inquiry into supplied buffer.
        !          36586:  * Return 1 if command succeeds, else 0.
        !          36587:  */
        !          36588: static int inquiry(s_id, buf)
        !          36589: int s_id;
        !          36590: uchar * buf;
        !          36591: {
        !          36592:        int ret = 0;
        !          36593:        uchar cmdbuf[G0CMDLEN];
        !          36594: 
        !          36595:        cmdbuf[0] = ScmdINQUIRY;
        !          36596:        cmdbuf[1] = 0;
        !          36597:        cmdbuf[2] = 0;
        !          36598:        cmdbuf[3] = 0;
        !          36599:        cmdbuf[4] = INQUIRYLEN;
        !          36600:        cmdbuf[5] = 0;
        !          36601: 
        !          36602:        if (start_arb() && host_ident(s_id, 0) &&
        !          36603:        local_info_xfer(cmdbuf, G0CMDLEN, buf, INQUIRYLEN, NULL, 0))
        !          36604:                ret = 1;
        !          36605: 
        !          36606:        return ret;
        !          36607: }
        !          36608: 
        !          36609: /*
        !          36610:  * mode_sense()
        !          36611:  *
        !          36612:  * Mode Sense command for a device.
        !          36613:  * Use this to get disk parameters:
        !          36614:  *     number of cylinders
        !          36615:  *     number of heads
        !          36616:  *     number of sectors per track.
        !          36617:  *
        !          36618:  * Put result of mode sense into supplied buffer.
        !          36619:  * Return 1 if command succeeds, else 0.
        !          36620:  */
        !          36621: static int mode_sense(s_id, buf)
        !          36622: int s_id;
        !          36623: uchar * buf;
        !          36624: {
        !          36625:        int ret = 0;
        !          36626:        uchar cmdbuf[G0CMDLEN];
        !          36627: 
        !          36628:        cmdbuf[0] = ScmdMODESENSE;
        !          36629:        cmdbuf[1] = 0;
        !          36630:        cmdbuf[2] = 0x3F;
        !          36631:        cmdbuf[3] = 0;
        !          36632:        cmdbuf[4] = MODESENSELEN;
        !          36633:        cmdbuf[5] = 0;
        !          36634: 
        !          36635:        if (start_arb() && host_ident(s_id, 0) &&
        !          36636:        local_info_xfer(cmdbuf, G0CMDLEN, buf, MODESENSELEN, NULL, 0))
        !          36637:                ret = 1;
        !          36638: 
        !          36639:        return ret;
        !          36640: }
        !          36641: 
        !          36642: /*
        !          36643:  * read_cap()
        !          36644:  *
        !          36645:  * Read Capacity command for a device.
        !          36646:  *
        !          36647:  * Return 1 if command succeeds, else 0.
        !          36648:  */
        !          36649: static int read_cap(s_id, buf)
        !          36650: int s_id;
        !          36651: uchar * buf;
        !          36652: {
        !          36653:        int ret = 0;
        !          36654:        uchar cmdbuf[G1CMDLEN];
        !          36655: 
        !          36656:        cmdbuf[0] = ScmdREADCAPACITY;
        !          36657:        cmdbuf[1] = 0;
        !          36658:        cmdbuf[2] = 0;
        !          36659:        cmdbuf[3] = 0;
        !          36660:        cmdbuf[4] = 0;
        !          36661:        cmdbuf[5] = 0;
        !          36662:        cmdbuf[6] = 0;
        !          36663:        cmdbuf[7] = 0;
        !          36664:        cmdbuf[8] = 0;
        !          36665:        cmdbuf[9] = 0;
        !          36666: 
        !          36667:        if (start_arb() && host_ident(s_id, 0) &&
        !          36668:        local_info_xfer(cmdbuf, G1CMDLEN, buf, READCAPLEN, NULL, 0))
        !          36669:                ret = 1;
        !          36670: 
        !          36671:        return ret;
        !          36672: }
        !          36673: 
        !          36674: /*
        !          36675:  * bus_dev_reset()
        !          36676:  *
        !          36677:  * Send Bus Device Reset message to the given SCSI id.
        !          36678:  * Return 1 if host adapter was not busy and no obvious timeouts occurred,
        !          36679:  * else 0.
        !          36680:  */
        !          36681: static int bus_dev_reset(s_id)
        !          36682: {
        !          36683:        int bdr_ok = 1;
        !          36684:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          36685: 
        !          36686: PR1("BDR");
        !          36687:        if (bdr_ok) {
        !          36688:                /*
        !          36689:                 * Do ST0x arbitration.
        !          36690:                 *
        !          36691:                 * De-assert SCSI enable bit.
        !          36692:                 * Write my SCSI id to port.
        !          36693:                 * Start arbitration.
        !          36694:                 */
        !          36695:                sfbyte(ss_csr, WC_ENABLE_PRTY);
        !          36696:                sfbyte(ss_dat, host_id);
        !          36697:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ARBITRATE);
        !          36698: 
        !          36699:                /*
        !          36700:                 * SCSI spec says there is "no maximum" to the wait for
        !          36701:                 * arbitration complete.
        !          36702:                 */
        !          36703:                if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
        !          36704:                        bdr_ok = 0;
        !          36705:                }
        !          36706:        }
        !          36707: 
        !          36708:        /*
        !          36709:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          36710:         */
        !          36711:        if (bdr_ok) {
        !          36712:                sfbyte(ss_dat, host_id | (1 << s_id));  /* Write both SCSI id's */
        !          36713:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          36714: 
        !          36715:                if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          36716:                        bdr_ok = 0;
        !          36717:        }
        !          36718: 
        !          36719:        if (bdr_ok) {
        !          36720:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION);
        !          36721: 
        !          36722:                if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          36723:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          36724:                        bdr_ok = 0;
        !          36725:        }
        !          36726: 
        !          36727:        if (bdr_ok) {
        !          36728:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          36729:                sfbyte(ss_dat, MSG_DEV_RESET);
        !          36730:                if (!bus_wait((0xFF << 8) | 0))
        !          36731:                        bdr_ok = 0;
        !          36732:        }
        !          36733: 
        !          36734:        return bdr_ok;
        !          36735: }
        !          36736: 
        !          36737: /*
        !          36738:  * chk_reconn()
        !          36739:  *
        !          36740:  * Check SELECT to see if any SCSI device has tried to reconnect to the host
        !          36741:  * adapter.  Called if there is an interrupt, and by the timer in case
        !          36742:  * we somehow lose an interrupt.
        !          36743:  *
        !          36744:  * Return -1 if no reselect detected, or the SCSI ID of the reselecting
        !          36745:  * target if there is one.
        !          36746:  */
        !          36747: static int chk_reconn()
        !          36748: {
        !          36749:        uchar csr, dat;
        !          36750:        int s_id = -1;
        !          36751: 
        !          36752:        csr = ffbyte(ss_csr);
        !          36753:        if (csr & (RS_SELECT | RS_I_O)) {
        !          36754:                dat = ffbyte(ss_dat);
        !          36755:                if ((dat & host_id) && (dat & NSDRIVE)) {
        !          36756:                        dat &= ~host_id;
        !          36757:                        s_id = 0;
        !          36758:                        while (dat >>=1)
        !          36759:                                s_id++;
        !          36760:                }
        !          36761:        }
        !          36762: 
        !          36763:        return s_id;
        !          36764: }
        !          36765: 
        !          36766: /*
        !          36767:  * ss_mach()
        !          36768:  *
        !          36769:  *     Gives a distinct state machine for each target device.
        !          36770:  */
        !          36771: void   ss_mach(s_id)
        !          36772: int s_id;
        !          36773: {
        !          36774:        ss_type * ssp = ss[s_id];
        !          36775:        BUF * bp;
        !          36776:        int s;
        !          36777: 
        !          36778:        do_sst_op = 1; /* plan to run this routine again in most cases */
        !          36779:        while (do_sst_op) {
        !          36780:                bp = ssp->bp;  /* nonpolled() below can change ssp->bp */
        !          36781:                switch (ssp->state) {
        !          36782:                /*
        !          36783:                 * Polling states execute whether ssp->waiting or not.
        !          36784:                 */
        !          36785:                case SST_POLL_ARBITN:
        !          36786: PR3("XPAR");
        !          36787:                        if (ffbyte(ss_csr) & RS_ARBIT_COMPL) {
        !          36788:                                ssp->waiting = 0;
        !          36789:                                if (host_ident(s_id, 1))
        !          36790:                                        do_connect(s_id);
        !          36791:                                else
        !          36792:                                        recover(s_id, RV_P_TIMEOUT);
        !          36793:                        } else {
        !          36794:                                if (ssp->expired) {
        !          36795:                                        ssp->expired = 0;
        !          36796:                                        recover(s_id, RV_A_TIMEOUT);
        !          36797:                                } else
        !          36798:                                        do_sst_op = 0;
        !          36799:                        }
        !          36800:                        break;
        !          36801:                case SST_POLL_RESELECT:
        !          36802: PR3("XPRS");
        !          36803:                        if (TGT_RSEL) {
        !          36804:                                ssp->waiting = 0;
        !          36805:                                if (host_claimed == -1)
        !          36806:                                        host_claimed = s_id;
        !          36807:                                else if (host_claimed != s_id) {
        !          36808: #if (DEBUG >= 1)
        !          36809:        printf("%d->%d ", host_claimed, s_id);
        !          36810: #endif
        !          36811:                                }
        !          36812:                                if (rsel_handshake()) {
        !          36813:                                        do_connect(s_id);
        !          36814:                                } else {
        !          36815:                                        recover(s_id, RV_P_TIMEOUT);
        !          36816:                                }
        !          36817:                        } else  { /* Reselect poll is negative */
        !          36818:                                if (ssp->expired) {
        !          36819:                                        ssp->expired = 0;
        !          36820:                                        recover(s_id, RV_R_TIMEOUT);
        !          36821:                                } else
        !          36822:                                        do_sst_op = 0;
        !          36823:                        }
        !          36824:                        break;
        !          36825:                case SST_POLL_BEGIN_IO:
        !          36826: PR3("XPBI");
        !          36827:                        if (bp == NULL)
        !          36828:                                ssp->state = SST_DEQUEUE;
        !          36829:                        else {
        !          36830:                                /*
        !          36831:                                 * At this point a SCSI command is about to
        !          36832:                                 * be initiated.  It may be a retry.
        !          36833:                                 */
        !          36834:                                if (host_claimed == -1 && BUS_FREE && BUS_FREE) {
        !          36835:                                        ssp->waiting = 0;
        !          36836:                                        init_pointers(s_id);
        !          36837:                                        if (start_arb()) {
        !          36838:                                                host_claimed = s_id;
        !          36839:                                                if (host_ident(s_id, 1)) {
        !          36840:                                                        do_connect(s_id);
        !          36841:                                                } else {
        !          36842:                                                        recover(s_id, RV_P_TIMEOUT);
        !          36843:                                                }
        !          36844:                                        } else {
        !          36845:        /*
        !          36846:         * If arbitration does not succeed right away, it is usually
        !          36847:         * because another drive is trying to reselect the host.
        !          36848:         */
        !          36849:                                                set_timeout(s_id, DELAY_ARB);
        !          36850:                                        }
        !          36851:                                } else { /* host busy or bus not free */
        !          36852:                                        int o_id;
        !          36853: 
        !          36854:                                        if ((o_id = chk_reconn()) != -1)
        !          36855:                                                defer(dummy_reconn, s_id);
        !          36856:                                        ++ssp->avl_count;
        !          36857:                                        if (ssp->avl_count >= MAX_AVL_COUNT)
        !          36858:                                                recover(s_id, RV_BF_TIMEOUT);
        !          36859:                                        else
        !          36860:                                                set_timeout(s_id, DELAY_BSY);
        !          36861:                                }
        !          36862:                        }
        !          36863:                        break;
        !          36864:                default:
        !          36865:                        if (ssp->waiting)
        !          36866:                                do_sst_op = 0;
        !          36867:                        else {
        !          36868:                                /*
        !          36869:                                 * Nonpolling states execute only if no
        !          36870:                                 * target timer is running.
        !          36871:                                 */
        !          36872:                                nonpolled(s_id);
        !          36873:                        }
        !          36874:                } /* endswitch */
        !          36875:        } /* endwhile */
        !          36876: }
        !          36877: 
        !          36878: /*
        !          36879:  * nonpolled()
        !          36880:  *
        !          36881:  * Part of ss_mach() - handling of nonpolling states is taken out simply
        !          36882:  * for readability.
        !          36883:  */
        !          36884: static void nonpolled(s_id)
        !          36885: int s_id;
        !          36886: {
        !          36887:        ss_type * ssp = ss[s_id];
        !          36888:        BUF * bp = ssp->bp;
        !          36889:        struct  fdisk_s *fdp;
        !          36890:        int partition;
        !          36891:        dev_t dev;
        !          36892: 
        !          36893:        switch (ssp->state) {
        !          36894:        case SST_BUS_DEV_RESET:
        !          36895: PR3("XBDR");
        !          36896:                if (bus_dev_reset(s_id)) {
        !          36897:                        do_sst_op = 0;
        !          36898:                        set_timeout(s_id, DELAY_BDR);
        !          36899:                        ssp->state = SST_REQ_SENSE;
        !          36900:                } else
        !          36901:                        recover(s_id, RV_P_TIMEOUT);
        !          36902:                break;
        !          36903:        case SST_DEQUEUE:
        !          36904:                if(bufq_rd_head(s_id) != NULL && !ssp->busy) {
        !          36905: PR3("XDQU");
        !          36906:                        ssp->busy = 1;
        !          36907:                        bp = bufq_rm_head(s_id);
        !          36908:                        ssp->bp = bp;
        !          36909:                        dev = bp->b_dev;
        !          36910:                        partition = DEV_PARTN(dev);
        !          36911:                        if (dev & SDEV)
        !          36912:                                partition = WHOLE_DRIVE;
        !          36913:                        fdp = ssp->parmp;
        !          36914:                        if (partition != WHOLE_DRIVE)
        !          36915:                                ssp->bno = fdp[partition].p_base + bp->b_bno;
        !          36916:                        else
        !          36917:                                ssp->bno = bp->b_bno;
        !          36918:                        if (bp->b_req == BREAD)
        !          36919:                                ssp->cmdbuf[0] = ScmdREADEXTENDED;
        !          36920:                        else
        !          36921:                                ssp->cmdbuf[0] = ScmdWRITEXTENDED;
        !          36922:                        ssp->cmdbuf[1] = 0;
        !          36923:                        ssp->cmdbuf[2] = ssp->bno >> 24;
        !          36924:                        ssp->cmdbuf[3] = ssp->bno >> 16;
        !          36925:                        ssp->cmdbuf[4] = ssp->bno >>  8;
        !          36926:                        ssp->cmdbuf[5] = ssp->bno;
        !          36927:                        ssp->cmdbuf[6] = 0;
        !          36928:                        ssp->cmdbuf[7] = 0;
        !          36929:                        ssp->cmdbuf[8] = 1;
        !          36930:                        ssp->cmdbuf[9] = 0;
        !          36931:                        ssp->cmdlen = G1CMDLEN;
        !          36932:                        init_pointers(s_id);
        !          36933:                        ssp->bdr_count = 0;
        !          36934:                        ssp->bsy_count = 0;
        !          36935:                        ssp->try_count = 0;
        !          36936:                        ssp->state = SST_POLL_BEGIN_IO;
        !          36937:                } else /* queue is empty or ssp->busy */
        !          36938:                        do_sst_op = 0;
        !          36939:                break;
        !          36940:        case SST_HIPRI_RESET:
        !          36941:        case SST_LOPRI_RESET:
        !          36942: PR1("XRST");
        !          36943:                /*
        !          36944:                 * SST_LOPRI_RESET is same as SST_HIPRI_RESET for now.
        !          36945:                 * Later, can implement a delay to allow other targets to
        !          36946:                 * finish pending operations.
        !          36947:                 */
        !          36948:                if (host_claimed == s_id || host_claimed == -1) {
        !          36949:                        host_claimed = s_id;
        !          36950:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_SCSI_RESET); /* reset ON */
        !          36951:                        ssp->state = SST_RESET_OFF;
        !          36952:                        set_timeout(s_id, DELAY_RST);
        !          36953: PR1("+");
        !          36954:                } else
        !          36955:                        set_timeout(s_id, DELAY_RST);
        !          36956:                break;
        !          36957:        case SST_REQ_SENSE:
        !          36958: PR1("XRQS");
        !          36959:                /*
        !          36960:                 * Come here at end of SCSI Bus reset (and at other times).
        !          36961:                 * If we have host claimed, release it.
        !          36962:                 */
        !          36963:                if (host_claimed == s_id)
        !          36964:                        host_claimed = -1;
        !          36965:                if (req_sense(s_id))
        !          36966:                        ssp->state = SST_POLL_BEGIN_IO;
        !          36967:                else
        !          36968:                        recover(s_id, RV_P_TIMEOUT);
        !          36969:                break;
        !          36970:        case SST_RESET_OFF:
        !          36971: PR3("XRFF");
        !          36972:                sfbyte(ss_csr, WC_ENABLE_PRTY); /* reset OFF */
        !          36973:                ssp->state = SST_REQ_SENSE;
        !          36974:                set_timeout(s_id, DELAY_RST);
        !          36975:        } /* endswitch */
        !          36976: }
        !          36977: 
        !          36978: /*
        !          36979:  * start_arb()
        !          36980:  *
        !          36981:  * return 1 if host adapter returned Arbitration Complete within allotted
        !          36982:  * number of tries, else 0
        !          36983:  */
        !          36984: static int start_arb()
        !          36985: {
        !          36986:        int ret = 0;
        !          36987:        int poll_ct;
        !          36988: 
        !          36989:        sfbyte(ss_csr, WC_ENABLE_PRTY);
        !          36990:        sfbyte(ss_dat, host_id);
        !          36991:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ARBITRATE);
        !          36992: 
        !          36993:        /*
        !          36994:         * SCSI spec says there is "no maximum" to the wait for arbitration
        !          36995:         * complete.
        !          36996:         */
        !          36997:        for (poll_ct = 0; poll_ct < HIPRI_RETRIES; poll_ct++) {
        !          36998:                if (ffbyte(ss_csr) & RS_ARBIT_COMPL) {
        !          36999:                        ret = 1;
        !          37000:                        break;
        !          37001:                } else if (chk_reconn() != -1) {
        !          37002:                        sfbyte(ss_csr, WC_ENABLE_PRTY);
        !          37003:                        break;
        !          37004:                }
        !          37005:        }
        !          37006: #if (DEBUG >= 1)
        !          37007: if (!ret)
        !          37008:        PR1("oSA");
        !          37009: #endif
        !          37010:        return ret;
        !          37011: }
        !          37012: 
        !          37013: /*
        !          37014:  * host_ident()
        !          37015:  *
        !          37016:  * This routine is the bridge in a SCSI bus cycle between Abitration
        !          37017:  * Complete and the Information Transfer phases.
        !          37018:  *
        !          37019:  * return 1 if everything went ok, 0 in case of timeout
        !          37020:  */
        !          37021: static int host_ident(s_id, disconnect)
        !          37022: int s_id;
        !          37023: int disconnect;
        !          37024: {
        !          37025:        int ret = 0;
        !          37026: 
        !          37027:        /*
        !          37028:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          37029:         */
        !          37030:        sfbyte(ss_dat, host_id | (1 << s_id));  /* Write both SCSI id's */
        !          37031:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          37032: 
        !          37033:        if (bus_wait(RS_BUSY << 8 | RS_BUSY)) {
        !          37034:                /*
        !          37035:                 * Assert ATTN so target expects incoming message byte.
        !          37036:                 */
        !          37037:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION);
        !          37038: 
        !          37039:                if (bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          37040:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE))) {
        !          37041:                        if (disconnect)
        !          37042:                                sfbyte(ss_dat, MSG_IDENT_DC);
        !          37043:                        else
        !          37044:                                sfbyte(ss_dat, MSG_IDENTIFY);
        !          37045:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ENABLE_IRPT);
        !          37046:                        ret = 1;
        !          37047:                } else {
        !          37048: PR1("oHI2");
        !          37049:                }
        !          37050:        } else {
        !          37051: PR1("oHI1");
        !          37052:        }
        !          37053:        return ret;
        !          37054: }
        !          37055: 
        !          37056: /*
        !          37057:  * rsel_handshake()
        !          37058:  *
        !          37059:  * After Reselect is detected, a couple steps are needed before entering
        !          37060:  * Information Transfer phases.  This routine does those steps.
        !          37061:  *
        !          37062:  * return 1 if ok, 0 in case of timeout.
        !          37063:  */
        !          37064: static int rsel_handshake()
        !          37065: {
        !          37066:        int ret = 0;
        !          37067: 
        !          37068:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_BUSY);
        !          37069:        if (bus_wait(RS_SELECT << 8 | 0)) {
        !          37070:                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          37071:                ret = 1;
        !          37072:        }
        !          37073:        return ret;
        !          37074: }
        !          37075: 
        !          37076: /*
        !          37077:  * set_timeout()
        !          37078:  *
        !          37079:  * Start a timer so as not to wait forever in case something goes wrong while
        !          37080:  * waiting for an event.  Available delays are:
        !          37081:  *
        !          37082:  *     DELAY_ARB -     wait for arbitration complete
        !          37083:  *     DELAY_BDR -     allow settling time after Bus Device Reset
        !          37084:  *     DELAY_BSY -     wait for not HOST_BUSY and bus free
        !          37085:  *     DELAY_RES -     wait for reselect by target
        !          37086:  *     DELAY_RST -     allow settling times when doing SCSI Bus Reset
        !          37087:  *
        !          37088:  * Second argument is number of clock ticks to wait until timer expiration.
        !          37089:  */
        !          37090: static void set_timeout(s_id, delay)
        !          37091: int s_id, delay;
        !          37092: {
        !          37093:        ss_type * ssp = ss[s_id];
        !          37094: 
        !          37095:        ssp->expired = 0;
        !          37096:        ssp->waiting = 1;
        !          37097:        do_sst_op =  0;
        !          37098:        timeout(&(ssp->tim), delay, stop_timeout, s_id);
        !          37099: }
        !          37100: 
        !          37101: /*
        !          37102:  * stop_timeout()
        !          37103:  *
        !          37104:  * Called on expiration of the timer for a given target.
        !          37105:  * Don't expire a timer if it's no longer active.
        !          37106:  */
        !          37107: static void stop_timeout(s_id)
        !          37108: int s_id;
        !          37109: {
        !          37110:        ss_type * ssp = ss[s_id];
        !          37111: 
        !          37112:        if (ssp->waiting) {
        !          37113:                ssp->expired = 1;
        !          37114:                ssp->waiting = 0;
        !          37115:        }
        !          37116:        ss_mach(s_id);
        !          37117: }
        !          37118: 
        !          37119: /*
        !          37120:  * init_pointers()
        !          37121:  *
        !          37122:  * Initialize command and data pointers when starting (or restarting)
        !          37123:  * a block i/o command.
        !          37124:  */
        !          37125: static void init_pointers(s_id)
        !          37126: int s_id;
        !          37127: {
        !          37128:        ss_type * ssp = ss[s_id];
        !          37129:        BUF * bp = ssp->bp;
        !          37130: 
        !          37131:        ssp->cmdstat = -1;
        !          37132:        ssp->cmd_bytes_out = 0;
        !          37133:        ssp->avl_count = 0;
        !          37134: }
        !          37135: 
        !          37136: /*
        !          37137:  * recover()
        !          37138:  *
        !          37139:  * This routine is called directly or indirectly from ss_mach().  It
        !          37140:  * determines what to do when the interface fails to behave as desired.
        !          37141:  *
        !          37142:  * Arguments are the SCSI id of the target HDC and an error type.
        !          37143:  * Error types are:
        !          37144:  *
        !          37145:  * RV_A_TIMEOUT (arbitration timeout)
        !          37146:  * Host adapter takes too long to respond with arbitration complete.
        !          37147:  * 
        !          37148:  * RV_P_TIMEOUT (protocol timeout)
        !          37149:  * Timeout waiting for desired SCSI bus status while connected to a target.
        !          37150:  * 
        !          37151:  * RV_R_TIMEOUT (reconnect timeout)
        !          37152:  * Timeout after target disconnects, waiting for reconnect.
        !          37153:  * 
        !          37154:  * RV_BF_TIMEOUT (bus free timeout)
        !          37155:  * Waited too long for host not busy and BUS_FREE.
        !          37156:  * 
        !          37157:  * RV_CS_BUSY (target device busy)
        !          37158:  * Command status returned was Busy.
        !          37159:  * 
        !          37160:  * RV_CS_CHECK (target device check)
        !          37161:  * Command status returned was CHECK.
        !          37162:  * 
        !          37163:  * Whenever an error occurs, one of the above inputs, together with the SCSI id
        !          37164:  * of the target, is sent to the recovery process.  The recovery process in turn
        !          37165:  * programs the next state for the machine.
        !          37166:  */
        !          37167: static void recover(s_id, errtype)
        !          37168: int s_id;
        !          37169: RV_TYPE errtype;
        !          37170: {
        !          37171:        ss_type * ssp = ss[s_id];
        !          37172:        BUF * bp = ssp->bp;
        !          37173: 
        !          37174: #if (DEBUG >= 1)
        !          37175: int foo;
        !          37176: if ((foo=chk_reconn()) != -1)
        !          37177:        printf("HONK%d ", foo);
        !          37178: #endif
        !          37179: 
        !          37180:        ++ssp->try_count;
        !          37181:        if (ssp->try_count < MAX_TRY_COUNT) {
        !          37182: 
        !          37183:                switch (errtype) {
        !          37184: 
        !          37185:                case RV_CS_BUSY:
        !          37186:                        ++ssp->bsy_count;
        !          37187:                        if (ssp->bsy_count < MAX_BSY_COUNT) {
        !          37188:                                ssp->state = SST_POLL_BEGIN_IO;
        !          37189:                                set_timeout(s_id, DELAY_BSY);
        !          37190:                        } else
        !          37191:                                ssp->state = SST_BUS_DEV_RESET;
        !          37192:                        break;
        !          37193: 
        !          37194:                case RV_CS_CHECK:
        !          37195:                        ssp->state = SST_REQ_SENSE;
        !          37196:                        break;
        !          37197: 
        !          37198:                case RV_P_TIMEOUT:
        !          37199:                        /* fall thru */
        !          37200:                case RV_R_TIMEOUT:
        !          37201:                        ++ssp->bdr_count;
        !          37202:                        if (ssp->bdr_count < MAX_BDR_COUNT)
        !          37203:                                ssp->state = SST_BUS_DEV_RESET;
        !          37204:                        else
        !          37205:                                ssp->state = SST_LOPRI_RESET;
        !          37206:                        break;
        !          37207: 
        !          37208:                case RV_BF_TIMEOUT:
        !          37209:                        /* fall thru */
        !          37210:                case RV_A_TIMEOUT:
        !          37211:                        ssp->state = SST_HIPRI_RESET;
        !          37212:                }
        !          37213:        } else { /* try_count >= MAX_TRY_COUNT */
        !          37214:                if (bp) {
        !          37215:                        bp->b_flag |= BFERR;
        !          37216:                        printf("(%d,%d): ", major(bp->b_dev), minor(bp->b_dev));
        !          37217:                        printf("%s error bno=%ld\n",
        !          37218:                                (bp->b_req == BREAD) ? "read" : "write",
        !          37219:                                bp->b_bno);
        !          37220:                }
        !          37221:                ss_finished(s_id);
        !          37222:        }
        !          37223: }
        !          37224: 
        !          37225: /*
        !          37226:  * ss_finished
        !          37227:  *
        !          37228:  * Release current i/o buffer to the O/S.
        !          37229:  */
        !          37230: static void ss_finished(s_id)
        !          37231: int s_id;
        !          37232: {
        !          37233:        ss_type * ssp = ss[s_id];
        !          37234:        BUF * bp = ssp->bp;
        !          37235:        int go_again = 1;
        !          37236: 
        !          37237:        if (host_claimed == s_id)
        !          37238:                host_claimed = -1;
        !          37239:        ssp->busy = 0;
        !          37240:        if (bp) {
        !          37241:                if (!(bp->b_flag & BFERR))
        !          37242:                        bp->b_resid -= BSIZE;
        !          37243:                if ((bp->b_flag & BFERR) || bp->b_resid == 0) {
        !          37244:                        ssp->bp = NULL;
        !          37245:                        bdone(bp);
        !          37246:                        go_again = 0;
        !          37247:                }
        !          37248:        }
        !          37249:        if (go_again) {
        !          37250:                ssp->state = SST_POLL_BEGIN_IO;
        !          37251:                ssp->bdr_count = 0;
        !          37252:                ssp->bsy_count = 0;
        !          37253:                ssp->try_count = 0;
        !          37254: 
        !          37255:                ssp->bno++;
        !          37256:                ssp->cmdbuf[2] = ssp->bno >> 24;
        !          37257:                ssp->cmdbuf[3] = ssp->bno >> 16;
        !          37258:                ssp->cmdbuf[4] = ssp->bno >>  8;
        !          37259:                ssp->cmdbuf[5] = ssp->bno;
        !          37260:        } else {
        !          37261:                /*
        !          37262:                 * After processing a kernel i/o request, stop the
        !          37263:                 * state machine for the current id.  Then start
        !          37264:                 * this or some other machine which has a request
        !          37265:                 * pending.
        !          37266:                 */
        !          37267:                do_sst_op =  0;
        !          37268:                ssp->state = SST_DEQUEUE;
        !          37269:                next_req(s_id);
        !          37270:        }
        !          37271: }
        !          37272: 
        !          37273: /*
        !          37274:  * next_req()
        !          37275:  *
        !          37276:  * Given the SCSI id where an i/o request just completed, start handling
        !          37277:  * another i/o request - which may be for the same or other SCSI id.
        !          37278:  * For now, use round-robin scheduling.
        !          37279:  */
        !          37280: static void next_req(s_id)
        !          37281: int s_id;
        !          37282: {
        !          37283:        int next_id = s_id;
        !          37284: 
        !          37285:        while (1) {
        !          37286:                next_id++;
        !          37287:                if (next_id >= MAX_SCSI_ID)
        !          37288:                        next_id = 0;
        !          37289:                if (ss[next_id]
        !          37290:                && (ss[next_id]->state != SST_DEQUEUE || bufq_rd_head(next_id))) {
        !          37291:                        defer(ss_mach, next_id);
        !          37292:                        break;
        !          37293:                }
        !          37294:                if (next_id == s_id)
        !          37295:                        break;
        !          37296:        }
        !          37297: }
        !          37298: 
        !          37299: /*
        !          37300:  * do_connect()
        !          37301:  *
        !          37302:  * This function is called when the host is successfully connected to
        !          37303:  * the target.  It invokes information transfer protocol and then sets
        !          37304:  * up some sort of recovery unless the command completed successfully
        !          37305:  * or there was a normal disconnect.
        !          37306:  */
        !          37307: static void do_connect(s_id)
        !          37308: int s_id;
        !          37309: {
        !          37310:        int result;
        !          37311:        ss_type * ssp = ss[s_id];
        !          37312: 
        !          37313:        result = far_info_xfer(s_id);
        !          37314:        if (!result)
        !          37315:                recover(s_id, RV_P_TIMEOUT);
        !          37316:        else if (ssp->msg_in == MSG_DISCONNECT) {
        !          37317:                ssp->state = SST_POLL_RESELECT;
        !          37318:                set_timeout(s_id, DELAY_RES);
        !          37319: #if 0
        !          37320:                if (host_claimed == s_id)
        !          37321:                        host_claimed = -1;
        !          37322: #endif
        !          37323:        } else if (ssp->msg_in == MSG_CMD_CMPLT && ssp->cmdstat == CS_GOOD)
        !          37324:                ss_finished(s_id);
        !          37325:        else if (ssp->cmdstat == CS_BUSY)
        !          37326:                recover(s_id, RV_CS_BUSY);
        !          37327:        else if (ssp->cmdstat == CS_CHECK)
        !          37328:                recover(s_id, RV_CS_CHECK);
        !          37329:        else  /* something else went wrong */
        !          37330:                recover(s_id, RV_P_TIMEOUT);
        !          37331: }
        !          37332: 
        !          37333: /*
        !          37334:  * local_info_xfer()
        !          37335:  *
        !          37336:  * Do bus cycle information transfer phases.
        !          37337:  * Transfer is for a command which will produce local results in the driver.
        !          37338:  * Other ...info_xfer routine handles kernel block i/o commands.
        !          37339:  *
        !          37340:  * Return 1 if transfer succeeded, else 0.
        !          37341:  *
        !          37342:  */
        !          37343: static int local_info_xfer(cmdbuf, cmdlen, inbuf, inlen, outbuf, outlen)
        !          37344: uchar * cmdbuf, * inbuf, * outbuf;
        !          37345: uint cmdlen, inlen, outlen;
        !          37346: {
        !          37347:        int bus_timeout;
        !          37348:        uchar phase_type;
        !          37349:        int s;
        !          37350:        int cmd_bytes_out = 0;
        !          37351:        int data_bytes_in = 0;
        !          37352:        int data_bytes_out = 0;
        !          37353:        int ret = 0;
        !          37354:        int xfer_good = 1;
        !          37355:        int cmdstat = -1;
        !          37356:        int msg_in = -1;
        !          37357: #if (DEBUG >= 1)
        !          37358: int x, xct=0;
        !          37359: uchar xch[100];
        !          37360: #endif
        !          37361: 
        !          37362:        s = sphi();
        !          37363:        while (req_wait(&bus_timeout) && xfer_good) {
        !          37364:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          37365: #if (DEBUG >= 1)
        !          37366: if (xct < 100)
        !          37367:        xch[xct++]=phase_type;
        !          37368: #endif
        !          37369:                switch (xpmod(phase_type)) {
        !          37370:                case XP_MSG_IN:
        !          37371:                        msg_in = ffbyte(ss_dat);
        !          37372:                        switch(msg_in){
        !          37373:                        case MSG_CMD_CMPLT:
        !          37374:                        case MSG_DISCONNECT:
        !          37375:                                sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
        !          37376:                                break;
        !          37377:                        }
        !          37378:                        break;
        !          37379:                case XP_MSG_OUT:
        !          37380:                        /*
        !          37381:                         * This case shouldn't happen.  We weren't
        !          37382:                         * asserting ATTENTION.
        !          37383:                         */
        !          37384:                        sfbyte(ss_dat, MSG_NOP); 
        !          37385:                        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          37386:                        break;
        !          37387:                case XP_STAT_IN:
        !          37388:                        cmdstat = ffbyte(ss_dat);
        !          37389:                        break;
        !          37390:                case XP_CMD_OUT:
        !          37391:                        /*
        !          37392:                         * Ship out command bytes.
        !          37393:                         */
        !          37394:                        if (cmd_bytes_out < cmdlen) {
        !          37395:                                sfbyte(ss_dat, cmdbuf[cmd_bytes_out++]);
        !          37396: #if 1
        !          37397:                                /*
        !          37398:                                 * If just sent last byte, allow interrupts.
        !          37399:                                 */
        !          37400:                                if (cmd_bytes_out == cmdlen) {
        !          37401:                                        spl(s);
        !          37402:                                        s = sphi();
        !          37403:                                }
        !          37404: #endif
        !          37405:                        } else {        /* This case should not happen. */
        !          37406:                                xfer_good = 0;
        !          37407:                        }
        !          37408:                        break;
        !          37409:                case XP_DATA_IN:
        !          37410:                        /*
        !          37411:                         * If caller's buffer has room, keep incoming
        !          37412:                         * data byte.  Else toss it.
        !          37413:                         */
        !          37414:                        if (data_bytes_in < inlen) {
        !          37415: #if 0
        !          37416:                                do {
        !          37417:                                        inbuf[data_bytes_in++] = ffbyte(ss_dat);
        !          37418:                                } while (data_bytes_in < inlen);
        !          37419: #else
        !          37420:                                inbuf[data_bytes_in++] = ffbyte(ss_dat);
        !          37421: #endif
        !          37422:                        } else
        !          37423:                                xfer_good = 0;
        !          37424:                        break;
        !          37425:                case XP_DATA_OUT:
        !          37426:                        /*
        !          37427:                         * Copy output buffer bytes to data register.
        !          37428:                         */
        !          37429:                        if (data_bytes_out < outlen) {
        !          37430:                                sfbyte(outbuf[data_bytes_out++], ss_dat);
        !          37431:                        } else { /* This case should not happen. */
        !          37432:                                xfer_good = 0;
        !          37433:                        }
        !          37434:                        break;
        !          37435:                default:
        !          37436:                        break;
        !          37437:                } /* endswitch */
        !          37438:        }
        !          37439:        spl(s);
        !          37440: 
        !          37441:        if (bus_timeout) {
        !          37442: PR1("oLX1");
        !          37443:        } else if (!xfer_good) {
        !          37444: PR1("oLX2");
        !          37445:        } else if (cmdstat != CS_GOOD) {
        !          37446: PR1("oLX3");
        !          37447: #if (DEBUG >= 1)
        !          37448: printf("cmdstat=%x ", cmdstat);
        !          37449: #endif
        !          37450:        } else
        !          37451:                ret = 1;
        !          37452: #if (DEBUG >= 1)
        !          37453: if (!ret) {
        !          37454:        printf("csr=%x ", ffbyte(ss_csr));
        !          37455:        printf("xct=%d  ", xct);
        !          37456:        for (x=0; x < xct; x++)
        !          37457:                printf("%x ", xch[x]);
        !          37458: }
        !          37459: #endif
        !          37460: 
        !          37461:        return ret;
        !          37462: }
        !          37463: 
        !          37464: /*
        !          37465:  * scsireset()
        !          37466:  *
        !          37467:  * Reset the SCSI bus.
        !          37468:  * Allow settling time when turning reset on/off.
        !          37469:  * Settling times were determined empirically.
        !          37470:  * Each tick is 10 msec.
        !          37471:  */
        !          37472: static void scsireset()
        !          37473: {
        !          37474: #if (DEBUG >= 1)
        !          37475: printf("scsireset ");
        !          37476: #endif
        !          37477:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          37478:        ssdelay(RESET_TICKS);
        !          37479:        sfbyte(ss_csr, WC_ENABLE_PRTY);
        !          37480:        ssdelay(RESET_TICKS);
        !          37481: }
        !          37482: 
        !          37483: /*
        !          37484:  * ssdelay()
        !          37485:  *
        !          37486:  * Delay for some number of arbitrary ticks.
        !          37487:  *
        !          37488:  * Using sleep() causes a panic if this driver is linked to the kernel,
        !          37489:  * even though this routine is called only via ssload().
        !          37490:  */
        !          37491: static void ssdelay(ticks)
        !          37492: int ticks;
        !          37493: {
        !          37494: #if 0
        !          37495:        timeout(&delay_tim, ticks, wakeup, (int)&delay_tim);
        !          37496:        sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
        !          37497: #else
        !          37498:        int i, j;
        !          37499: 
        !          37500:        for (i = 0; i < ticks; i++)
        !          37501:                for (j = 0; j < LOAD_DELAY; j++);
        !          37502: #endif
        !          37503: }
        !          37504: 
        !          37505: /*
        !          37506:  * init_call()
        !          37507:  *
        !          37508:  * Call SCSI command function during initialization, with error recovery.
        !          37509:  * If the simple command fails, try a Bus Device Reset, then SCSI Bus reset.
        !          37510:  */
        !          37511: static int init_call(fn, s_id, buf)
        !          37512: int (*fn)();
        !          37513: int s_id;
        !          37514: uchar * buf;
        !          37515: {
        !          37516:        int ret = 1;
        !          37517:        int i;
        !          37518:        int o_id;
        !          37519: int s;
        !          37520: s=sphi();
        !          37521:        for (i = 0; i < 2; i++) {
        !          37522:                o_id = chk_reconn();
        !          37523:                if (o_id != -1)
        !          37524:                        dummy_reconn(s_id);
        !          37525:                if ((*fn)(s_id, buf))
        !          37526:                        goto init_call_done;
        !          37527: 
        !          37528:                if (bus_dev_reset(s_id)) {
        !          37529:                        ssdelay(RESET_TICKS);
        !          37530:                        req_sense(s_id);
        !          37531:                        if ((*fn)(s_id, buf))
        !          37532:                                goto init_call_done;
        !          37533:                }
        !          37534: 
        !          37535:                scsireset();
        !          37536:                req_sense(s_id);
        !          37537:                if ((*fn)(s_id, buf))
        !          37538:                        goto init_call_done;
        !          37539:        }
        !          37540: 
        !          37541:        ret = 0;
        !          37542: 
        !          37543: init_call_done:
        !          37544: spl(s);
        !          37545:        return ret;
        !          37546: }
        !          37547: 
        !          37548: /*
        !          37549:  * xpmod()
        !          37550:  *
        !          37551:  * Command/Data and Message bits are swapped on-board (outside the chip)
        !          37552:  * on older Future Domain host boards.
        !          37553:  */
        !          37554: static uchar xpmod(oldphase)
        !          37555: uchar oldphase;
        !          37556: {
        !          37557:        uchar ret = oldphase;
        !          37558: 
        !          37559:        if (swap_status_bits) {
        !          37560:                ret &= ~(RS_CTRL_DATA | RS_MESSAGE);
        !          37561:                if (oldphase & RS_MESSAGE)
        !          37562:                        ret |= RS_CTRL_DATA;
        !          37563:                if (oldphase & RS_CTRL_DATA)
        !          37564:                        ret |= RS_MESSAGE;
        !          37565:        }
        !          37566:        return ret;
        !          37567: } 
        !          37568: @
        !          37569: 
        !          37570: 
        !          37571: 2.15
        !          37572: log
        !          37573: @update provided by hal
        !          37574: @
        !          37575: text
        !          37576: @d53 1
        !          37577: a53 1
        !          37578: #include       <coherent.h>
        !          37579: a61 1
        !          37580: 
        !          37581: d65 1
        !          37582: a65 1
        !          37583: #include       <scsiwork.h>
        !          37584: @
        !          37585: 
        !          37586: 
        !          37587: 2.14
        !          37588: log
        !          37589: @new version provided y hal for v321
        !          37590: @
        !          37591: text
        !          37592: @@
        !          37593: 
        !          37594: 
        !          37595: 2.13
        !          37596: log
        !          37597: @initial version prov by hal
        !          37598: @
        !          37599: text
        !          37600: @d11 2
        !          37601: a12 3
        !          37602:  * Revision 2.12  91/05/31  13:18:39  hal
        !          37603:  * Force parity on as Conner drives act dead without it.
        !          37604:  * Slow down data in phase in local_info_xfer() for 486 + Conner.
        !          37605: d14 2
        !          37606: a15 2
        !          37607:  * Revision 2.11  91/05/30  15:43:17  hal
        !          37608:  * Add SS_DELAY and slow down delays for 486.
        !          37609: a16 2
        !          37610:  * Revision 2.10  91/05/29  11:14:24  hal
        !          37611:  * Send MSG_NOP's for slow machines.  More debug output.
        !          37612: a17 27
        !          37613:  * Revision 2.9  91/05/22  01:38:55  hal
        !          37614:  * Overlapping disconnects give bad reads.
        !          37615:  * 
        !          37616:  * Revision 2.8  91/05/21  23:13:15  hal
        !          37617:  * Round robin scheduler.  HDSETA.  Bump MAX_AVL_COUNT.
        !          37618:  * 
        !          37619:  * Revision 2.7  91/05/21  19:10:43  hal
        !          37620:  * Balance host_claimed - needs debugging.
        !          37621:  * 
        !          37622:  * Revision 2.6  91/05/21  13:53:22  root
        !          37623:  * Patch NSDRIVE for Future Domain.  Call per/id queue fns.
        !          37624:  * 
        !          37625:  * Revision 2.5  91/05/20  18:02:52  root
        !          37626:  * Remove test code.
        !          37627:  * 
        !          37628:  * Revision 2.4        91/05/20  17:22:06      root
        !          37629:  * Not using ss_put() any more.
        !          37630:  * 
        !          37631:  * Revision 2.3        91/05/20  16:20:33      root
        !          37632:  * Call to ss_putc() now works.
        !          37633:  * 
        !          37634:  * Revision 2.2        91/05/20  10:23:58      root
        !          37635:  * Modify ss_get/ss_put calls for Future Domain & drop 3rd arg.
        !          37636:  * 
        !          37637:  * Revision 2.1        91/05/17  14:26:12      root
        !          37638:  * Debug level up to 4 tracking write problem.
        !          37639:  * 
        !          37640: a107 1
        !          37641: 
        !          37642: d118 1
        !          37643: d123 1
        !          37644: a123 1
        !          37645:        && (ffbyte(ss_dat) & (SS_HOST   | (1<<s_id) )) )
        !          37646: d135 2
        !          37647: d249 1
        !          37648: d275 5
        !          37649: a279 4
        !          37650:  * Two test drives in use:
        !          37651:  *
        !          37652:  * ST1126N, SCSI 0  LUN 0  (Unit 0)
        !          37653:  * ST1201N, SCSI 1  LUN 0  (Unit 1)
        !          37654: d281 3
        !          37655: a283 6
        !          37656: int    NSDRIVE = 0x0000;       /* Bitmap of attached SCSI drives. */
        !          37657:                                /* Set NSDRIVE highest bit for Future Domain */
        !          37658: int    SS_INT = 5;             /* ST0[12] use either IRQ3 or IRQ5 */
        !          37659: int    SS_BASE = 0xDE00;       /* Segment addr of ST0x communication area */
        !          37660: int    SS_DELAY = 10000;       /* Loop counter during ssload() only */
        !          37661: int    SS_HOST = 0x80;         /* Host is SCSI ID #7 for Seagate, 6 for FD */
        !          37662: d286 1
        !          37663: a286 5
        !          37664: drv_parm_type drv_parm[MAX_SCSI_ID-1] = {
        !          37665: #if 0
        !          37666:        { 987, 20, 17},         /* Unit 0 */
        !          37667:        { 1004, 4, 52},         /* Unit 1 */
        !          37668: #endif
        !          37669: d308 5
        !          37670: d314 1
        !          37671: a314 1
        !          37672: static ss_type  *ss[MAX_SCSI_ID-1];
        !          37673: a352 8
        !          37674:        if (NSDRIVE & 0x8000) { /* Future Domain */
        !          37675:                ss_csr = ss_fp + FD_CSR;
        !          37676:                ss_dat = ss_fp + FD_DAT;
        !          37677:        } else { /* Seagate */
        !          37678:                ss_csr = ss_fp + SS_CSR;
        !          37679:                ss_dat = ss_fp + SS_DAT;
        !          37680:        }
        !          37681: 
        !          37682: d364 1
        !          37683: a364 1
        !          37684:                printf("Error - ST0x failed memory test\n");
        !          37685: d369 23
        !          37686: d400 1
        !          37687: a400 1
        !          37688:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          37689: d418 1
        !          37690: a418 1
        !          37691:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          37692: d433 1
        !          37693: d435 1
        !          37694: a435 1
        !          37695:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          37696: d439 1
        !          37697: a477 1
        !          37698:        int valid_open;
        !          37699: d481 1
        !          37700: a485 1
        !          37701:        valid_open = 1;
        !          37702: d501 1
        !          37703: a501 1
        !          37704: PR1("bad LUN or SCSI id");
        !          37705: d503 1
        !          37706: a503 1
        !          37707:                valid_open = 0;
        !          37708: d509 2
        !          37709: a510 2
        !          37710:        if (valid_open && DEV_SPECIAL(dev) && partn != 0) {
        !          37711: PR1("bad special partition");
        !          37712: d512 1
        !          37713: a512 1
        !          37714:                valid_open = 0;
        !          37715: d518 1
        !          37716: a518 1
        !          37717:        if (valid_open && dev & SDEV)
        !          37718: d520 1
        !          37719: d527 1
        !          37720: a527 1
        !          37721:        if (valid_open && partn != WHOLE_DRIVE && !(ssp->ptab_read)) {
        !          37722: d546 1
        !          37723: a546 1
        !          37724:                        valid_open = 0;
        !          37725: d554 1
        !          37726: a554 1
        !          37727: PR1("bad partition table");
        !          37728: d556 1
        !          37729: a556 1
        !          37730:                        valid_open = 0;
        !          37731: d565 1
        !          37732: a565 1
        !          37733:        if (valid_open && partn != WHOLE_DRIVE
        !          37734: d567 1
        !          37735: a567 1
        !          37736: PR1("partition overrun");
        !          37737: d569 1
        !          37738: a569 1
        !          37739:                valid_open = 0;
        !          37740: d572 2
        !          37741: a573 2
        !          37742:        if (valid_open && partn != WHOLE_DRIVE && fdp[partn].p_size == 0) {
        !          37743: PR1("partition not found");
        !          37744: d575 1
        !          37745: a575 1
        !          37746:                valid_open = 0;
        !          37747: d582 8
        !          37748: a589 4
        !          37749:        if (valid_open) {
        !          37750:                ++drvl[SCSI_MAJOR].d_time;
        !          37751:                ++ssp->dr_watch;
        !          37752:        }
        !          37753: d754 1
        !          37754: a754 1
        !          37755:                                goto bad_open;
        !          37756: d759 1
        !          37757: a759 1
        !          37758:                        goto bad_open;
        !          37759: d768 1
        !          37760: a768 1
        !          37761:                goto bad_open;
        !          37762: d778 1
        !          37763: a778 1
        !          37764:                goto bad_open;
        !          37765: d787 1
        !          37766: a787 1
        !          37767:                goto bad_open;
        !          37768: d796 1
        !          37769: a796 1
        !          37770:        goto end_open;
        !          37771: d802 1
        !          37772: a802 1
        !          37773: bad_open:
        !          37774: d807 1
        !          37775: a807 1
        !          37776: end_open:
        !          37777: d861 1
        !          37778: a861 1
        !          37779:                switch (phase_type) {
        !          37780: d906 1
        !          37781: a906 1
        !          37782:        for (s_id = 0; s_id < MAX_SCSI_ID-1; s_id++) {
        !          37783: d1080 1
        !          37784: a1080 1
        !          37785:                switch (phase_type) {
        !          37786: d1255 1
        !          37787: a1255 1
        !          37788:        int req_found, i;
        !          37789: d1257 1
        !          37790: d1261 1
        !          37791: a1261 1
        !          37792:        for (i = 0; i < HIPRI_RETRIES; i++) {
        !          37793: d1478 1
        !          37794: a1478 1
        !          37795:                sfbyte(ss_dat, SS_HOST);
        !          37796: d1494 1
        !          37797: a1494 1
        !          37798:                sfbyte(ss_dat, SS_HOST | (1 << s_id));  /* Write both SCSI id's */
        !          37799: d1537 2
        !          37800: a1538 2
        !          37801:                if ((dat & SS_HOST) && (dat & NSDRIVE)) {
        !          37802:                        dat &= ~SS_HOST;
        !          37803: d1768 2
        !          37804: a1769 1
        !          37805:        int ret;
        !          37806: d1772 1
        !          37807: a1772 1
        !          37808:        sfbyte(ss_dat, SS_HOST);
        !          37809: d1779 8
        !          37810: a1786 5
        !          37811:        if (bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL))
        !          37812:                ret = 1;
        !          37813:        else {
        !          37814:                ret = 0;
        !          37815: PR1("oSA");
        !          37816: d1788 5
        !          37817: d1812 1
        !          37818: a1812 1
        !          37819:        sfbyte(ss_dat, SS_HOST | (1 << s_id));  /* Write both SCSI id's */
        !          37820: d2069 1
        !          37821: a2069 1
        !          37822:                if (next_id >= MAX_SCSI_ID - 1)
        !          37823: d2151 1
        !          37824: a2151 1
        !          37825:                switch (phase_type) {
        !          37826: d2268 1
        !          37827: a2268 2
        !          37828:  * Delay for some number of clock ticks.
        !          37829:  * 286/386 kernel ticks are at 100Hz
        !          37830: d2270 2
        !          37831: a2271 2
        !          37832:  * WARNING:  Since this routine uses sleep(), it is callable ONLY from
        !          37833:  * ssload()/ssunload()/ssopen()/ssclose().
        !          37834: d2283 1
        !          37835: a2283 1
        !          37836:                for (j = 0; j < SS_DELAY; j++);
        !          37837: d2329 21
        !          37838: @
        !          37839: 
        !          37840: 
        !          37841: 2.12
        !          37842: log
        !          37843: @Force parity on as Conner drives act dead without it.
        !          37844: Slow down data in phase in local_info_xfer() for 486 + Conner.
        !          37845: @
        !          37846: text
        !          37847: @d11 4
        !          37848: a144 1
        !          37849: #define HOST_ID                0x80    /* Host adapter is SCSI ID #7 */
        !          37850: d153 1
        !          37851: a153 1
        !          37852:        && (ffbyte(ss_dat) & (HOST_ID   | (1<<s_id) )) )
        !          37853: d162 3
        !          37854: a164 3
        !          37855: #define MAX_BDR_COUNT  2
        !          37856: #define MAX_BSY_COUNT  2
        !          37857: #define MAX_TRY_COUNT  7
        !          37858: d312 1
        !          37859: d1017 5
        !          37860: d1026 5
        !          37861: a1031 5
        !          37862: #if (DEBUG >= 1)
        !          37863:                        printf("Physical: %d sectors per track  ", spt);
        !          37864:                        printf("%ld cylinders  ", cyls);
        !          37865:                        printf("%d heads\n\n", heads);
        !          37866: #endif
        !          37867: d1169 3
        !          37868: a1172 1
        !          37869:                                ss_get(ss_dat, bp->b_faddr + xfer_count);
        !          37870: d1174 11
        !          37871: d1197 2
        !          37872: a1199 1
        !          37873:                                ss_get(bp->b_faddr + xfer_count, ss_dat);
        !          37874: d1201 11
        !          37875: d1337 12
        !          37876: a1348 1
        !          37877:                if (sense_buf[2] == 0x00)       /* No Sense.  AOK */
        !          37878: d1350 2
        !          37879: a1351 2
        !          37880:                else if (sense_buf[2] == 0x06 && sense_buf[12] == 0x29)
        !          37881:                        ret = 1;
        !          37882: a1358 1
        !          37883:        printf("rqs: ");
        !          37884: d1484 1
        !          37885: a1484 1
        !          37886:                sfbyte(ss_dat, HOST_ID);
        !          37887: d1500 1
        !          37888: a1500 1
        !          37889:                sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          37890: d1543 2
        !          37891: a1544 2
        !          37892:                if ((dat & HOST_ID) && (dat & NSDRIVE)) {
        !          37893:                        dat &= ~HOST_ID;
        !          37894: d1777 1
        !          37895: a1777 1
        !          37896:        sfbyte(ss_dat, HOST_ID);
        !          37897: d1809 1
        !          37898: a1809 1
        !          37899:        sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          37900: d1995 4
        !          37901: a1998 1
        !          37902: PR1("BF4 ");
        !          37903: @
        !          37904: 
        !          37905: 
        !          37906: 2.11
        !          37907: log
        !          37908: @Add SS_DELAY and slow down delays for 486.
        !          37909: @
        !          37910: text
        !          37911: @d11 3
        !          37912: d870 1
        !          37913: a870 1
        !          37914:                                sfbyte(ss_csr, WC_ENABLE_IRPT);
        !          37915: d876 1
        !          37916: a876 1
        !          37917:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          37918: d1085 1
        !          37919: a1085 1
        !          37920:                                sfbyte(ss_csr, WC_ENABLE_IRPT);
        !          37921: d1090 1
        !          37922: a1090 1
        !          37923:                                sfbyte(ss_csr, WC_ENABLE_IRPT);
        !          37924: d1119 1
        !          37925: a1119 1
        !          37926:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          37927: d1434 4
        !          37928: d1439 3
        !          37929: a1441 3
        !          37930:                sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          37931:                sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          37932:                sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          37933: d1457 1
        !          37934: a1457 1
        !          37935:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          37936: d1464 1
        !          37937: a1464 1
        !          37938:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          37939: d1472 1
        !          37940: a1472 1
        !          37941:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          37942: d1694 1
        !          37943: a1694 1
        !          37944:                        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET); /* reset ON */
        !          37945: d1716 1
        !          37946: a1716 1
        !          37947:                sfbyte(ss_csr, 0); /* reset OFF */
        !          37948: d1732 3
        !          37949: a1734 3
        !          37950:        sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          37951:        sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          37952:        sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          37953: d1766 1
        !          37954: a1766 1
        !          37955:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          37956: d1772 1
        !          37957: a1772 1
        !          37958:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          37959: d1780 1
        !          37960: a1780 1
        !          37961:                        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ENABLE_IRPT);
        !          37962: d1803 1
        !          37963: a1803 1
        !          37964:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_BUSY);
        !          37965: d1805 1
        !          37966: a1805 1
        !          37967:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          37968: d2107 1
        !          37969: a2107 1
        !          37970:                                sfbyte(ss_csr, WC_ENABLE_IRPT);
        !          37971: d2117 1
        !          37972: a2117 1
        !          37973:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          37974: d2147 1
        !          37975: d2151 3
        !          37976: d2209 1
        !          37977: a2209 1
        !          37978:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          37979: d2211 1
        !          37980: a2211 1
        !          37981:        sfbyte(ss_csr, 0);
        !          37982: @
        !          37983: 
        !          37984: 
        !          37985: 2.10
        !          37986: log
        !          37987: @Send MSG_NOP's for slow machines.  More debug output.
        !          37988: @
        !          37989: text
        !          37990: @d11 3
        !          37991: d305 1
        !          37992: d752 1
        !          37993: a752 1
        !          37994:                                msg = "invlaid request";
        !          37995: d1275 25
        !          37996: a1299 2
        !          37997:        if (start_arb() && host_ident(s_id, 0) &&
        !          37998:        local_info_xfer(cmdbuf, G0CMDLEN, sense_buf, SENSELEN, NULL, 0)) {
        !          37999: d1306 11
        !          38000: d2223 1
        !          38001: a2223 1
        !          38002:                for (j = 0; j < 4000; j++);
        !          38003: @
        !          38004: 
        !          38005: 
        !          38006: 2.9
        !          38007: log
        !          38008: @Overlapping disconnects give bad reads.
        !          38009: @
        !          38010: text
        !          38011: @a4 1
        !          38012:  *     make ssinit() more rugged
        !          38013: d6 3
        !          38014: d11 3
        !          38015: d49 1
        !          38016: d246 1
        !          38017: d296 1
        !          38018: a296 1
        !          38019:  * CP340,   SCSI 3  LUN 0  (Unit 3)
        !          38020: d298 1
        !          38021: a298 1
        !          38022: int    NSDRIVE = 0x8003;       /* Bitmap of attached SCSI drives. */
        !          38023: d305 1
        !          38024: d308 1
        !          38025: a309 1
        !          38026:        { 964, 5, 17},          /* Unit 3 */
        !          38027: d312 3
        !          38028: a361 1
        !          38029: 
        !          38030: d363 1
        !          38031: a363 1
        !          38032:         * Claim IRQ vector.
        !          38033: a364 5
        !          38034:        setivec(SS_INT, ssintr);
        !          38035: 
        !          38036:        /*
        !          38037:         * Allocate a selector to map into ST0x memory-mapped comm area.
        !          38038:         */
        !          38039: d426 5
        !          38040: d502 1
        !          38041: d511 1
        !          38042: d554 1
        !          38043: d567 1
        !          38044: d573 1
        !          38045: a648 3
        !          38046:  *
        !          38047:  *     Action: Validate the minor device.
        !          38048:  *             Update the paritition table if necessary.
        !          38049: a649 1
        !          38050: 
        !          38051: d722 1
        !          38052: d748 1
        !          38053: a748 1
        !          38054: PR1("BF1");
        !          38055: d753 1
        !          38056: a753 2
        !          38057: PR1("BF2");
        !          38058:                        devmsg(dev, "no partition table");
        !          38059: d772 1
        !          38060: a772 1
        !          38061: PR1("BF3");
        !          38062: d781 1
        !          38063: d799 3
        !          38064: a801 1
        !          38065:                bdone(bp);
        !          38066: d820 4
        !          38067: a823 1
        !          38068:                defer(ss_mach, s_id);
        !          38069: d829 63
        !          38070: d960 1
        !          38071: a960 39
        !          38072: /* FOO */
        !          38073: int foo, junk, phase_type;
        !          38074:        if ((foo=chk_reconn()) != -1) {
        !          38075:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_BUSY | WC_ATTENTION);
        !          38076:                if (bus_wait(RS_SELECT << 8 | 0)) {
        !          38077:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          38078:                        if (req_wait(&junk)) {
        !          38079: phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          38080: printf("phase type=%d\n", phase_type);
        !          38081: if (phase_type == XP_MSG_IN) {
        !          38082:        junk = ffbyte(ss_dat);
        !          38083:        printf("msg in=%x\n", junk);
        !          38084:        req_wait(&junk);
        !          38085:        phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          38086: }
        !          38087: if (phase_type == XP_MSG_OUT) {
        !          38088:        sfbyte(ss_dat, MSG_ABORT);
        !          38089:        printf("MSG_ABORT sent\n");
        !          38090:        if (!req_wait(&junk))
        !          38091:                printf("req_wait failed\n");
        !          38092:        phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          38093: }
        !          38094: if (phase_type == XP_DATA_IN) {
        !          38095:        junk = ffbyte(ss_dat);
        !          38096:        printf("data_in=%x\n", junk);
        !          38097:        if (!req_wait(&junk))
        !          38098:                printf("req_wait failed\n");
        !          38099:        phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          38100: }
        !          38101: junk = ffbyte(ss_csr);
        !          38102: printf("status=%x\n", junk);
        !          38103:                        } else
        !          38104: printf("req_wait failed\n");
        !          38105:                } else {
        !          38106:                        printf("rsel_handshake failed\n");
        !          38107:                }
        !          38108:                printf("** id %d tried to reselect **\n", foo);
        !          38109:        }
        !          38110: /* FOO */
        !          38111: d983 3
        !          38112: a985 3
        !          38113: #if (DEBUG >= 3)
        !          38114: printf("capacity=%ld   block length=%ld\n", ssp->capacity, ssp->blocklen);
        !          38115: #endif
        !          38116: d991 3
        !          38117: a993 1
        !          38118: #if (DEBUG >= 3)
        !          38119: d996 3
        !          38120: d1000 15
        !          38121: a1014 10
        !          38122: uchar heads;
        !          38123: unsigned short spt;
        !          38124: ulong cyls;
        !          38125: 
        !          38126: spt=((int)query_buf[FMT_PG+10]<<8) + query_buf[FMT_PG+11];
        !          38127: cyls=((int)query_buf[DDG_PG+2]<<16) + ((int)query_buf[DDG_PG+3]<<8) + query_buf[DDG_PG+4];
        !          38128: heads=query_buf[DDG_PG+5];
        !          38129: printf("%d sectors per track\n", spt);
        !          38130: printf("%ld cylinders\n", cyls);
        !          38131: printf("%d heads\n", heads);
        !          38132: d1111 1
        !          38133: a1112 1
        !          38134:                        sfbyte(ss_dat, MSG_ABORT); 
        !          38135: a1142 1
        !          38136: PR4("DI");
        !          38137: d1147 7
        !          38138: a1153 4
        !          38139: if (block_done)
        !          38140: printf("Data in overrun ");
        !          38141: block_done=1;
        !          38142:                        if (bp->b_req == BREAD)
        !          38143: d1155 2
        !          38144: a1156 2
        !          38145:                        else
        !          38146:                                xfer_good = 0;
        !          38147: d1162 8
        !          38148: a1169 3
        !          38149:                        if (bp->b_req == BWRITE) {
        !          38150: #if 1
        !          38151:                                int res=0;
        !          38152: a1170 5
        !          38153: if (block_done)
        !          38154:        printf("Data out overrun ");
        !          38155: block_done=1;
        !          38156: /*                             res=ss_put(ss_dat, bp->b_faddr + xfer_count);*/
        !          38157:                                ss_get(bp->b_faddr + xfer_count, ss_dat);
        !          38158: d1175 1
        !          38159: a1175 11
        !          38160: #if (DEBUG >= 3)
        !          38161:                                printf("p%d ", res);
        !          38162: #else
        !          38163: #if (DEBUG >= 1)
        !          38164:                                if(res!=0)
        !          38165:                                        printf("p%d ", res);
        !          38166: #endif
        !          38167: #endif
        !          38168: #endif
        !          38169:                        } else /* This case should not happen. */
        !          38170:                                xfer_good = 0;
        !          38171: d1183 1
        !          38172: d1185 17
        !          38173: a1201 16
        !          38174: switch(ssp->cmdstat) {
        !          38175: case -1:
        !          38176:        if (msg_in != MSG_DISCONNECT)
        !          38177:                printf("CS-",ssp->cmdstat);
        !          38178:        break;
        !          38179: case CS_GOOD:
        !          38180:        break;
        !          38181: case CS_CHECK:
        !          38182:        printf("CSK",ssp->cmdstat);
        !          38183:        break;
        !          38184: case CS_BUSY:
        !          38185:        printf("CSY",ssp->cmdstat);
        !          38186:        break;
        !          38187: case CS_RESERVED:
        !          38188: default:
        !          38189:        printf("CS%x",ssp->cmdstat);
        !          38190: d1203 2
        !          38191: a1205 2
        !          38192:        return (bus_timeout) ? 0 : 1 ;
        !          38193: }
        !          38194: a1547 1
        !          38195: /*                                             ssp->state = SST_POLL_ARBITN;*/
        !          38196: d1551 4
        !          38197: d1685 2
        !          38198: d1695 6
        !          38199: a1700 1
        !          38200:        return bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL);
        !          38201: d1737 2
        !          38202: d1740 2
        !          38203: d2044 4
        !          38204: d2052 4
        !          38205: d2069 1
        !          38206: a2069 1
        !          38207:                         * asserting ATTENTION.  Abort the bus cycle.
        !          38208: d2071 1
        !          38209: a2072 1
        !          38210:                        sfbyte(ss_dat, MSG_ABORT); 
        !          38211: d2083 1
        !          38212: d2091 1
        !          38213: d2102 3
        !          38214: a2104 1
        !          38215:                                inbuf[data_bytes_in++] = ffbyte(ss_dat);
        !          38216: d2106 1
        !          38217: a2106 1
        !          38218:                                ffbyte(ss_dat);
        !          38219: d2124 10
        !          38220: a2133 1
        !          38221:        if (!bus_timeout && xfer_good && cmdstat == CS_GOOD)
        !          38222: d2135 8
        !          38223: d2178 1
        !          38224: d2181 6
        !          38225: d2202 3
        !          38226: a2204 1
        !          38227: 
        !          38228: d2206 3
        !          38229: d2228 1
        !          38230: @
        !          38231: 
        !          38232: 
        !          38233: 2.8
        !          38234: log
        !          38235: @Round robin scheduler.  HDSETA.  Bump MAX_AVL_COUNT.
        !          38236: @
        !          38237: text
        !          38238: @d9 3
        !          38239: d142 2
        !          38240: a143 2
        !          38241: #define DELAY_BSY      10
        !          38242: #define DELAY_RES      40
        !          38243: d883 1
        !          38244: a883 1
        !          38245:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_BUSY);
        !          38246: d885 1
        !          38247: a885 1
        !          38248:                        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          38249: a893 1
        !          38250:        printf("phase type=%d\n", phase_type);
        !          38251: d898 3
        !          38252: a900 3
        !          38253:        ssdelay(30);
        !          38254:        junk = ffbyte(ss_csr);
        !          38255:        printf("status=%x\n", junk);
        !          38256: d902 9
        !          38257: d1456 1
        !          38258: a1456 2
        !          38259:                        if ((host_claimed == -1 || host_claimed == s_id)
        !          38260:                        && TGT_RSEL) {
        !          38261: d1458 7
        !          38262: a1464 1
        !          38263:                                host_claimed = s_id;
        !          38264: a1487 1
        !          38265:                                        host_claimed = s_id;
        !          38266: d1491 1
        !          38267: d1498 5
        !          38268: a1502 1
        !          38269:                                                ssp->state = SST_POLL_ARBITN;
        !          38270: d1603 1
        !          38271: d1804 6
        !          38272: d1916 2
        !          38273: a1917 1
        !          38274:                if (ss[next_id] && bufq_rd_head(next_id)) {
        !          38275: d1946 1
        !          38276: a1946 1
        !          38277: #if 1
        !          38278: @
        !          38279: 
        !          38280: 
        !          38281: 2.7
        !          38282: log
        !          38283: @Balance host_claimed - needs debugging.
        !          38284: @
        !          38285: text
        !          38286: @a4 1
        !          38287:  *     set host_claimed conscientiously
        !          38288: d9 3
        !          38289: d41 1
        !          38290: a41 1
        !          38291: #define PR1(str)               printf(str)
        !          38292: d51 1
        !          38293: a51 1
        !          38294: #define PR3(str)               printf(str)
        !          38295: d56 1
        !          38296: a56 1
        !          38297: #define PR4(str)               printf(str)
        !          38298: d143 1
        !          38299: a143 1
        !          38300: #define MAX_AVL_COUNT  10
        !          38301: d239 1
        !          38302: d244 1
        !          38303: d288 1
        !          38304: a288 1
        !          38305: int    NSDRIVE = 0x8001;       /* Bitmap of attached SCSI drives. */
        !          38306: d295 1
        !          38307: a295 1
        !          38308:        { 1068, 9, 36},         /* Unit 0 */
        !          38309: d331 1
        !          38310: a331 1
        !          38311:  *     disconnect
        !          38312: d653 4
        !          38313: a656 1
        !          38314: PR3("HDGETA ");
        !          38315: d666 1
        !          38316: a666 1
        !          38317:                kucopy( &hdparm, vec, sizeof hdparm );
        !          38318: d669 16
        !          38319: d733 1
        !          38320: a733 1
        !          38321: PR1("BF1 ");
        !          38322: d738 1
        !          38323: a738 1
        !          38324: PR2("BF2 ");
        !          38325: d758 1
        !          38326: a758 1
        !          38327: PR3("BF3 ");
        !          38328: d877 31
        !          38329: d909 1
        !          38330: a909 1
        !          38331:                if (inquiry(s_id, query_buf)) {
        !          38332: d922 1
        !          38333: a922 1
        !          38334:                if (read_cap(s_id, query_buf)) {
        !          38335: d937 1
        !          38336: a937 1
        !          38337:                if (mode_sense(s_id, query_buf)) {
        !          38338: a1009 1
        !          38339: PR4("MI");
        !          38340: d1013 1
        !          38341: a1013 1
        !          38342: PR4("cc ");
        !          38343: d1018 1
        !          38344: a1018 1
        !          38345: PR4("dc ");
        !          38346: d1023 1
        !          38347: a1023 1
        !          38348: PR4("sd ");
        !          38349: d1026 1
        !          38350: a1026 1
        !          38351: PR4("rd ");
        !          38352: d1029 1
        !          38353: a1029 1
        !          38354: PR4("ab ");
        !          38355: d1032 1
        !          38356: a1032 1
        !          38357: PR4("dr ");
        !          38358: d1035 1
        !          38359: a1035 1
        !          38360: PR4("mi ");
        !          38361: d1038 1
        !          38362: a1038 1
        !          38363: PR4("md ");
        !          38364: d1043 1
        !          38365: a1043 1
        !          38366: PR4("MO ");
        !          38367: d1052 1
        !          38368: a1052 1
        !          38369: PR4("SI ");
        !          38370: d1067 1
        !          38371: a1067 1
        !          38372: PR4("CO ");
        !          38373: d1080 1
        !          38374: a1080 1
        !          38375: PR4("DI ");
        !          38376: d1100 1
        !          38377: a1100 1
        !          38378: PR4("DO ");
        !          38379: a1117 10
        !          38380: #else
        !          38381:                                uchar dat;
        !          38382: if (i==0)
        !          38383:        PR4("DO");
        !          38384: /***FOOO***/
        !          38385:                                dat = ffbyte(bp->b_faddr + xfer_count + i);
        !          38386:                                sfbyte(ss_dat, dat);
        !          38387:                                i++;
        !          38388: if (i==BSIZE)
        !          38389:        PR4("n ");
        !          38390: d1332 1
        !          38391: a1332 2
        !          38392: PR1("bdr");
        !          38393: 
        !          38394: d1428 1
        !          38395: a1428 1
        !          38396: PR3("PA ");
        !          38397: d1444 1
        !          38398: a1444 1
        !          38399: PR3("PR ");
        !          38400: d1463 1
        !          38401: a1463 1
        !          38402: PR3("PBI ");
        !          38403: d1525 1
        !          38404: a1525 1
        !          38405: PR3("BDR ");
        !          38406: d1535 1
        !          38407: a1535 1
        !          38408: PR3("DQ ");
        !          38409: d1572 1
        !          38410: a1572 1
        !          38411: PR1("rst");
        !          38412: d1578 7
        !          38413: a1584 4
        !          38414:                host_claimed = s_id;
        !          38415:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET); /* reset ON */
        !          38416:                ssp->state = SST_RESET_OFF;
        !          38417:                set_timeout(s_id, DELAY_RST);
        !          38418: d1587 1
        !          38419: a1587 1
        !          38420: PR1("RQS ");
        !          38421: d1600 1
        !          38422: a1600 1
        !          38423: PR3("RFF ");
        !          38424: d1860 8
        !          38425: a1867 1
        !          38426:        } else
        !          38427: d1869 2
        !          38428: d1874 25
        !          38429: d1918 1
        !          38430: d1921 1
        !          38431: d2040 3
        !          38432: d2064 37
        !          38433: @
        !          38434: 
        !          38435: 
        !          38436: 2.6
        !          38437: log
        !          38438: @Patch NSDRIVE for Future Domain.  Call per/id queue fns.
        !          38439: @
        !          38440: text
        !          38441: @d6 2
        !          38442: a8 3
        !          38443:  *     backoff & retry when bdr or req sense needed
        !          38444:  *     nonzero LUN's
        !          38445:  *
        !          38446: d10 3
        !          38447: d34 3
        !          38448: a36 2
        !          38449:  * DEBUG = 2   Debug output on error only and at other selected places.
        !          38450:  * DEBUG = 3   Maximum debug output.
        !          38451: a58 7
        !          38452: #if 0
        !          38453: /* TEMPORARY S**T */
        !          38454: #define bufq_rd_head(s_id)     ssq_rd_head()
        !          38455: #define bufq_rm_head(s_id)     ssq_rm_head()
        !          38456: #define bufq_wr_tail(s_id, foo)        ssq_wr_tail(foo)
        !          38457: #endif
        !          38458: 
        !          38459: d125 1
        !          38460: a125 1
        !          38461: #define HIPRI_RETRIES  4000    /* # of times to retry while hogging CPU */
        !          38462: d128 1
        !          38463: d246 1
        !          38464: d308 1
        !          38465: a308 2
        !          38466: static int     num_drives;     /* number of controller SCSI id's */
        !          38467: 
        !          38468: a309 1
        !          38469: static int     host_claimed;   /* -1 or SCSI id of target using the host */
        !          38470: d316 16
        !          38471: d342 1
        !          38472: d344 1
        !          38473: d1401 19
        !          38474: a1451 17
        !          38475:                case SST_POLL_RESELECT:
        !          38476: PR3("PR ");
        !          38477:                        if (TGT_RSEL) {
        !          38478:                                ssp->waiting = 0;
        !          38479:                                if (rsel_handshake()) {
        !          38480:                                        do_connect(s_id);
        !          38481:                                } else {
        !          38482:                                        recover(s_id, RV_P_TIMEOUT);
        !          38483:                                }
        !          38484:                        } else  { /* Reselect poll is negative */
        !          38485:                                if (ssp->expired) {
        !          38486:                                        ssp->expired = 0;
        !          38487:                                        recover(s_id, RV_R_TIMEOUT);
        !          38488:                                } else
        !          38489:                                        do_sst_op = 0;
        !          38490:                        }
        !          38491:                        break;
        !          38492: d1536 1
        !          38493: d1543 6
        !          38494: a1766 1
        !          38495:                        host_claimed = -1;
        !          38496: d1823 3
        !          38497: a1825 1
        !          38498:  * the target.
        !          38499: a1833 2
        !          38500:        if (host_claimed == s_id)
        !          38501:                host_claimed = -1;
        !          38502: d1839 2
        !          38503: a1945 1
        !          38504:        host_claimed = -1;
        !          38505: d1948 32
        !          38506: @
        !          38507: 
        !          38508: 
        !          38509: 2.5
        !          38510: log
        !          38511: @Remove test code.
        !          38512: @
        !          38513: text
        !          38514: @a0 1
        !          38515: #define FUT_DOM 0
        !          38516: a5 1
        !          38517:  *     works but hogs CPU during big dd to /dev/null
        !          38518: a6 4
        !          38519:  *     bufq_rd_head()
        !          38520:  *     bufq_rm_head()
        !          38521:  *     bufq_wr_tail()
        !          38522:  *
        !          38523: a8 1
        !          38524:  *     assembler I/O
        !          38525: d10 4
        !          38526: a13 1
        !          38527:  * $Log:       /usr/src/sys/i8086/drv/RCS/ss.c,v $
        !          38528: d56 1
        !          38529: d61 1
        !          38530: d91 5
        !          38531: a95 4
        !          38532: #if FUT_DOM
        !          38533: #define SS_CSR         0x1C00  /* Offset of control/status register */
        !          38534: #define SS_DAT         0x1E00  /* Offset of data port */
        !          38535: #else
        !          38536: a97 1
        !          38537: #endif
        !          38538: d211 6
        !          38539: a216 4
        !          38540: /* functions from ssqueue.c */
        !          38541: extern void ssq_wr_tail();
        !          38542: extern BUF * ssq_rd_head();
        !          38543: extern BUF * ssq_rm_head();
        !          38544: d286 2
        !          38545: a287 1
        !          38546: int    NSDRIVE = 1;            /* Bitmap of attached SCSI drives. */
        !          38547: d293 2
        !          38548: a294 1
        !          38549:        { 1004, 4, 52},         /* Unit 0 */
        !          38550: d296 1
        !          38551: a297 2
        !          38552:        { 964, 5, 17},          /* Unit 3 */
        !          38553:        { 0, 0, 0},
        !          38554: d329 1
        !          38555: a342 2
        !          38556:        ss_csr = ss_fp + SS_CSR;
        !          38557:        ss_dat = ss_fp + SS_DAT;
        !          38558: d344 8
        !          38559: d377 2
        !          38560: a378 1
        !          38561:                        if ((NSDRIVE >> i) & 1)
        !          38562: d380 1
        !          38563: d403 1
        !          38564: d421 1
        !          38565: @
        !          38566: 
        !          38567: 
        !          38568: 2.4
        !          38569: log
        !          38570: @Not using ss_put() any more.
        !          38571: @
        !          38572: text
        !          38573: @a0 1
        !          38574: static int rwhi;
        !          38575: d18 3
        !          38576: a916 1
        !          38577: uchar lphase=0xff;
        !          38578: a920 4
        !          38579: #if (DEBUG >= 2)
        !          38580:        rwhi=0;
        !          38581: #endif
        !          38582: 
        !          38583: a923 7
        !          38584: #if (DEBUG >= 2)
        !          38585: if (rwhi) {
        !          38586:        rwhi=0;
        !          38587:        printf("lp=%x cp=%x\n", (int)lphase, (int)phase_type);
        !          38588: }
        !          38589: lphase=phase_type;
        !          38590: #endif
        !          38591: d1118 1
        !          38592: a1118 4
        !          38593: #if (DEBUG >= 2)
        !          38594: if (i>100) {
        !          38595:        printf("rw=%d ", i);
        !          38596:        rwhi=i;
        !          38597: a1119 1
        !          38598: #endif
        !          38599: a1120 3
        !          38600:        return req_found;
        !          38601: }
        !          38602: 
        !          38603: a1387 1
        !          38604: /*                                     s=sphi();*/
        !          38605: a1390 1
        !          38606: /*                                                     spl(s);*/
        !          38607: a1391 1
        !          38608: /*                                                     spl(s);*/
        !          38609: a1394 1
        !          38610: /*                                             spl(s);*/
        !          38611: a1410 1
        !          38612: /*                             s=sphi();*/
        !          38613: a1412 1
        !          38614: /*                                     spl(s);*/
        !          38615: a1413 1
        !          38616: /*                                     spl(s);*/
        !          38617: @
        !          38618: 
        !          38619: 
        !          38620: 2.3
        !          38621: log
        !          38622: @Call to ss_putc() now works.
        !          38623: @
        !          38624: text
        !          38625: @d1 1
        !          38626: d19 3
        !          38627: d317 1
        !          38628: a318 30
        !          38629:  * ss_putC()
        !          38630:  *
        !          38631:  * return # of bytes remaining to be sent from current block
        !          38632:  * - should be 0
        !          38633:  *
        !          38634:  * temporary C code
        !          38635:  */
        !          38636: int ss_putC(ss_dat_fp, buf_fp)
        !          38637: faddr_t ss_dat_fp, buf_fp;
        !          38638: {
        !          38639:        uchar dat;
        !          38640:        int i, junk;
        !          38641: #if 0
        !          38642:        faddr_t req_waitA();
        !          38643:        printf("ss_stat=%x ", ffbyte(ss_csr));
        !          38644:        printf("ss_datA=%lx ", req_waitA(ss_dat_fp, buf_fp));
        !          38645: #endif
        !          38646:        for (i = 0; i < BSIZE; i++) {
        !          38647: /*             if (!req_wait(&junk)) */
        !          38648:                if (!req_waitA(ss_dat_fp, buf_fp))
        !          38649:                        break;
        !          38650:                dat = ffbyte(buf_fp + i);
        !          38651:                sfbyte(ss_dat_fp, dat);
        !          38652:        }
        !          38653:        return BSIZE - i;
        !          38654: }
        !          38655: 
        !          38656: /*
        !          38657:  * ssload()    - load routine.
        !          38658:  *
        !          38659: d915 1
        !          38660: a915 1
        !          38661: int i=0;
        !          38662: a918 2
        !          38663:        s = sphi();
        !          38664:        irpts_masked = 1;
        !          38665: d920 5
        !          38666: d927 11
        !          38667: d1000 4
        !          38668: a1003 2
        !          38669:                                                spl(s);
        !          38670:                                                s = sphi();
        !          38671: d1030 1
        !          38672: a1030 1
        !          38673:                                int res;
        !          38674: d1035 2
        !          38675: a1036 1
        !          38676:                                res=ss_put(ss_dat, bp->b_faddr + xfer_count);
        !          38677: d1129 1
        !          38678: a1129 1
        !          38679: if (i>100)
        !          38680: d1131 2
        !          38681: d1405 1
        !          38682: a1405 1
        !          38683:                                        s=sphi();
        !          38684: d1409 1
        !          38685: a1409 1
        !          38686:                                                        spl(s);
        !          38687: d1411 1
        !          38688: a1411 1
        !          38689:                                                        spl(s);
        !          38690: d1415 1
        !          38691: a1415 1
        !          38692:                                                spl(s);
        !          38693: d1432 1
        !          38694: a1432 1
        !          38695:                                s=sphi();
        !          38696: d1435 1
        !          38697: a1435 1
        !          38698:                                        spl(s);
        !          38699: d1437 1
        !          38700: a1437 1
        !          38701:                                        spl(s);
        !          38702: @
        !          38703: 
        !          38704: 
        !          38705: 2.2
        !          38706: log
        !          38707: @Modify ss_get/ss_put calls for Future Domain & drop 3rd arg.
        !          38708: @
        !          38709: text
        !          38710: @d18 3
        !          38711: d125 1
        !          38712: a125 1
        !          38713: #define HIPRI_RETRIES  400     /* # of times to retry while hogging CPU */
        !          38714: d313 29
        !          38715: d938 1
        !          38716: d945 2
        !          38717: d1038 1
        !          38718: a1038 1
        !          38719: #if 0
        !          38720: d1045 4
        !          38721: d1075 2
        !          38722: a1076 1
        !          38723:        spl(s);
        !          38724: d1136 5
        !          38725: @
        !          38726: 
        !          38727: 
        !          38728: 2.1
        !          38729: log
        !          38730: @Debug level up to 4 tracking write problem.
        !          38731: @
        !          38732: text
        !          38733: @d1 1
        !          38734: d17 4
        !          38735: a20 1
        !          38736:  * $Log$
        !          38737: d83 5
        !          38738: d90 1
        !          38739: d271 6
        !          38740: d281 1
        !          38741: a281 4
        !          38742: #define NCYL   1004
        !          38743: #define NHEAD  4
        !          38744: #define NSPT   52
        !          38745: 
        !          38746: d283 1
        !          38747: a283 1
        !          38748:        { NCYL, NHEAD, NSPT},
        !          38749: d286 1
        !          38750: a288 1
        !          38751:        { 0, 0, 0},
        !          38752: d994 1
        !          38753: a994 1
        !          38754:                                ss_get(ss_fp, bp->b_faddr + xfer_count, BSIZE);
        !          38755: a998 1
        !          38756: PR4("DO ");
        !          38757: d1003 1
        !          38758: a1003 1
        !          38759: #if 1
        !          38760: d1005 1
        !          38761: d1009 1
        !          38762: a1009 1
        !          38763:                                res=ss_put(ss_fp, bp->b_faddr + xfer_count, BSIZE);
        !          38764: d1020 3
        !          38765: a1022 1
        !          38766: 
        !          38767: d1026 2
        !          38768: @
        !          38769: 0707070064030104211004440000030000030000011777770507310655400005600000022727/newbits/kernel/USRSRC/i8086/drv/RCS/ss.fsa,vhead     1.4;
        !          38770: access   ;
        !          38771: symbols  ;
        !          38772: locks    ;
        !          38773: comment  @ * @;
        !          38774: 
        !          38775: 
        !          38776: 1.4
        !          38777: date     91.04.26.15.40.25;  author root;  state Exp;
        !          38778: branches ;
        !          38779: next   1.3;
        !          38780: 
        !          38781: 1.3
        !          38782: date     91.04.25.17.12.33;  author root;  state Exp;
        !          38783: branches ;
        !          38784: next   1.2;
        !          38785: 
        !          38786: 1.2
        !          38787: date     91.04.24.10.28.04;  author root;  state Exp;
        !          38788: branches ;
        !          38789: next   1.1;
        !          38790: 
        !          38791: 1.1
        !          38792: date     91.04.23.17.32.53;  author root;  state Exp;
        !          38793: branches ;
        !          38794: next   ;
        !          38795: 
        !          38796: 
        !          38797: desc
        !          38798: @Text specification for Seagate SCSI state machine.
        !          38799: @
        !          38800: 
        !          38801: 
        !          38802: 1.4
        !          38803: log
        !          38804: @Use ss.std 1.2.  Need to spell out reset recovery.
        !          38805: @
        !          38806: text
        !          38807: @$Log: /usr/src/sys/i8086/drv/RCS/ss.fsa,v $
        !          38808:  * Revision 1.3        91/04/25  17:12:33      root
        !          38809:  * Clarify, with aid of ss.std rev.1.
        !          38810:  * 
        !          38811:  * Revision 1.2        91/04/24  10:28:04      root
        !          38812:  * Case 1.a. completed.
        !          38813:  * 
        !          38814:  * Revision 1.1        91/04/23  17:32:53      root
        !          38815:  * Unfinished draft.
        !          38816:  * 
        !          38817: 
        !          38818: State Machine for ss Driver.
        !          38819: ----------------------------
        !          38820: 
        !          38821: Host States.
        !          38822:        H_IDLE.
        !          38823:                Host adapter not in use.  May be awaiting reselect on one
        !          38824:                or more devices.
        !          38825: 
        !          38826:        H_ARBITRATING.
        !          38827:                Awaiting arbitration complete on some drive.
        !          38828: 
        !          38829:        H_SCSI_RESET.
        !          38830:                The host adapter needs to do, or is in the process of doing, a
        !          38831:                SCSI bus reset.  This will occur if a target fails to respond
        !          38832:                to a Bus Device Reset message.
        !          38833: 
        !          38834: Target States.
        !          38835:        T_IDLE.
        !          38836:                Target device not in use.  No reselect pending.
        !          38837: 
        !          38838:        T_DISCONNECTED.
        !          38839:                Disconnected;  reselect is expected from this device.
        !          38840: 
        !          38841:        T_BUSY.
        !          38842:                Target device failed with Device Busy status.  Waiting to
        !          38843:                repeat previous command.
        !          38844: 
        !          38845:        T_REQ_SENSE.
        !          38846:                Need to send Request Sense command to the given target.
        !          38847:                Either the target device failed the previous command with
        !          38848:                Device Check status, or the target has just executed a Bus
        !          38849:                Device Reset, or the host has just asserted (and released)
        !          38850:                Reset on the SCSI bus.
        !          38851: 
        !          38852:        T_TIMED_OUT.
        !          38853:                Target device failed with a timeout at some point during a
        !          38854:                SCSI bus cycle.  Waiting to retry previous command.
        !          38855: 
        !          38856:        T_DEV_RESET.
        !          38857:                The try count for a request has been exhausted.  The target
        !          38858:                device should be sent a Bus Device Reset message.
        !          38859: 
        !          38860:        T_SETTLING.
        !          38861:                A Bus Device Reset has occurred or a Reselect has failed.
        !          38862:                We need to wait a certain amount of time, then return the
        !          38863:                target state to T_IDLE.
        !          38864: 
        !          38865: Inputs.
        !          38866:        I_CALL_SSBLOCK.
        !          38867:                The kernel routine dblock() has called the block routine
        !          38868:                for this drive.  The incoming block request has been appended
        !          38869:                to the request queue before the state machine is executed.
        !          38870: 
        !          38871:        I_RESELECT.
        !          38872:                An IRQ for the host has occurred, indicating that SELECT has
        !          38873:                gone active on the SCSI bus, and the interrupt handler has
        !          38874:                determined that a specific target is reconnecting.
        !          38875: 
        !          38876:        I_HOST_WATCHDOG.
        !          38877:                Started when arbitration takes a long time.  The host adapter
        !          38878:                is polled at frequent intervals for arbitration complete, using
        !          38879:                timeouts.  If this watchdog timer decrements to zero, the
        !          38880:                attempt to seize SCSI bus control has failed.  Once started,
        !          38881:                the host watchdog will be invoked once per second.  Input to
        !          38882:                state machine occurs if the timer decrements to zero.
        !          38883: 
        !          38884:        I_TGT_WATCHDOG.
        !          38885:                A target watchdog is started when the target device disconnects
        !          38886:                in the middle of a block i/o command, in order to prevent
        !          38887:                waiting forever after a disconnect.  If the timer decrements to
        !          38888:                zero, the command being executed has failed.  Once started, a
        !          38889:                target watchdog will be invoked once per second until stopped.
        !          38890: 
        !          38891:        I_HOST_TIMEOUT.
        !          38892:                A timeout set for the host adapter has expired.  Only one host
        !          38893:                timeout may be set at a time.
        !          38894: 
        !          38895:        I_TGT_TIMEOUT.
        !          38896:                A timeout set for a target device has expired.  Only one target
        !          38897:                timeout per device may be set at a time.
        !          38898: 
        !          38899: input = I_CALL_SSBLOCK (valid arguments assumed).
        !          38900:        host_state = H_IDLE.
        !          38901:                Load arguments to ssblock() into a request node and place at
        !          38902:                tail of request queue for the target.
        !          38903:                If tgt_state = T_IDLE
        !          38904:                        Read block request for this drive nondestructively from
        !          38905:                        head of request queue and load the work structure for
        !          38906:                        this drive.
        !          38907:                        device_try_count <- 0
        !          38908:                        Send control codes to start arbitration.
        !          38909:                        Go into high priority loop looking for arbitration
        !          38910:                        complete.
        !          38911:                        If arbitration not complete at end of loop
        !          38912:                                device_try_count++
        !          38913:                                if (device_try_count too high)
        !          38914:                                        Set host timeout to 0 msec.
        !          38915:                                        host_state <- H_SCSI_RESET.
        !          38916:                                else
        !          38917:                                        Set host timeout to 20 msec
        !          38918:                                        host_state <- H_ARBITRATING.
        !          38919:                                        Start host watchdog.
        !          38920:                        Else // arbitration complete
        !          38921:                                Stop host watchdog.
        !          38922:                                INFO_XFER
        !          38923:                tgt_state != T_IDLE
        !          38924:                        Drive is busy and has pending timeout or watchdog.
        !          38925:                        Do nothing.
        !          38926:        host_state != H_IDLE
        !          38927:                Host is busy with arbitration or reset.
        !          38928:                Do nothing.
        !          38929: 
        !          38930: input = I_RESELECT.
        !          38931:        host_state = H_IDLE.
        !          38932:                If tgt_state = T_DISCONNECTED
        !          38933:                        INFO_XFER
        !          38934:                tgt_state != T_DISCONNECTED
        !          38935:                        ignore the interrupt
        !          38936:        host_state != H_IDLE
        !          38937:                ignore the interrupt
        !          38938: 
        !          38939: input = I_HOST_WATCHDOG
        !          38940:        if timer count is zero
        !          38941:                shut off host watchdog timer
        !          38942:                host_state = H_ARBITRATING
        !          38943:                        Set host timeout to 0 msec.
        !          38944:                        host_state <- H_SCSI_RESET
        !          38945:                host_state != H_ARBITRATING
        !          38946:                        ignore the watchdog timeout
        !          38947:        else
        !          38948:                decrement timer count
        !          38949: 
        !          38950: input = I_TGT_WATCHDOG.
        !          38951:        if timer count is zero
        !          38952:                shut off target watchdog timer
        !          38953:                host_state = H_ARBITRATING
        !          38954:                        Set host timeout to 0 msec.
        !          38955:                        host_state <- H_SCSI_RESET
        !          38956:                host_state != H_ARBITRATING
        !          38957:                        ignore the watchdog timeout
        !          38958:        else
        !          38959:                decrement timer count
        !          38960: 
        !          38961: 
        !          38962: INFO_XFER
        !          38963:        Attempt to perform information transfer phases.
        !          38964:        Allow interrupts after last byte of command is sent.
        !          38965:        Update static byte counts for the current request.
        !          38966:        When information transfer phase ends:
        !          38967:        If disconnect message was received
        !          38968:                Start target watchdog.
        !          38969:                tgt_state <- T_DISCONNECTED.
        !          38970:        else if command status is BUSY
        !          38971:                device_try_count++
        !          38972:                if (device_try_count too high)
        !          38973:                        Set target timeout to 0 msec.
        !          38974:                        tgt_state <- T_DEV_RESET.
        !          38975:                else
        !          38976:                        Set target timeout to 250 msec.
        !          38977:                        tgt_state <- T_BUSY.
        !          38978:        else if command status is CHECK
        !          38979:                device_try_count++
        !          38980:                if (device_try_count too high)
        !          38981:                        tgt_state <- T_DEV_RESET.
        !          38982:                else
        !          38983:                        tgt_state <- T_REQ_SENSE.
        !          38984:                Set target timeout to 0 msec.
        !          38985:        else if command status is COMPLETE
        !          38986:                Turn off target watchdog.
        !          38987:                If this was a kernel block request
        !          38988:                        Update b_resid.
        !          38989:                        Release buffer to the kernel.
        !          38990:                Clear work structure for the drive.
        !          38991:                Set target timeout to 0 msec.
        !          38992:                tgt_state <- T_IDLE
        !          38993:        else // something timed out during SCSI cycle
        !          38994:                device_try_count++
        !          38995:                if (device_try_count too high)
        !          38996:                        Set target timeout to 0 msec.
        !          38997:                        tgt_state <- T_DEV_RESET.
        !          38998:                else
        !          38999:                        Set target timeout to 250 msec.
        !          39000:                        tgt_state <- T_TIMED_OUT.
        !          39001: (end INFO_XFER)
        !          39002: @
        !          39003: 
        !          39004: 
        !          39005: 1.3
        !          39006: log
        !          39007: @Clarify, with aid of ss.std rev.1.
        !          39008: @
        !          39009: text
        !          39010: @d2 3
        !          39011: d71 6
        !          39012: a76 2
        !          39013:                Once started, the host watchdog will be invoked once per second
        !          39014:                until stopped.
        !          39015: d79 5
        !          39016: a83 2
        !          39017:                Once started, a target watchdog will be invoked once per second
        !          39018:                until stopped.
        !          39019: d93 2
        !          39020: a94 2
        !          39021: 1. Host State = H_IDLE.
        !          39022:        a.  input = I_CALL_SSBLOCK (valid arguments assumed).
        !          39023: d106 9
        !          39024: a114 4
        !          39025:                                host_state <- H_ARBITRATING.
        !          39026:                                Set host timeout to 250 msec
        !          39027:                                Start host watchdog.
        !          39028:                        Else
        !          39029: d116 2
        !          39030: a117 39
        !          39031:                                Attempt to get to information transfer phases.
        !          39032:                                Allow interrupts after last byte of command
        !          39033:                                is sent.
        !          39034:                                Update static byte counts for the current
        !          39035:                                request.
        !          39036:                                When information transfer phase ends:
        !          39037:                                If disconnect message was received
        !          39038:                                        Start target watchdog.
        !          39039:                                        tgt_state <- T_DISCONNECTED.
        !          39040:                                else if command status is BUSY
        !          39041:                                        device_try_count++
        !          39042:                                        if (device_try_count too high)
        !          39043:                                                tgt_state <- T_DEV_RESET.
        !          39044:                                        else
        !          39045:                                                Set target timeout to 250 msec.
        !          39046:                                                tgt_state <- T_BUSY.
        !          39047:                                else if command status is CHECK
        !          39048:                                        device_try_count++
        !          39049:                                        if (device_try_count too high)
        !          39050:                                                tgt_state <- T_DEV_RESET.
        !          39051:                                        else
        !          39052:                                                tgt_state <- T_REQ_SENSE.
        !          39053:                                        Set target timeout to 0 msec. (defer)
        !          39054:                                else if command status is COMPLETE
        !          39055:                                        Turn off target watchdog.
        !          39056:                                        If this was a kernel block request
        !          39057:                                                Update b_resid.
        !          39058:                                                Release buffer to the kernel.
        !          39059:                                        Clear work structure for the drive.
        !          39060:                                        Set target timeout to 0 msec. (defer)
        !          39061:                                        (tgt_state is still T_IDLE)
        !          39062:                                else // something timed out during SCSI cycle
        !          39063:                                        device_try_count++
        !          39064:                                        if (device_try_count too high)
        !          39065:                                                tgt_state <- T_DEV_RESET.
        !          39066:                                        else
        !          39067:                                                Set target timeout to 250 msec.
        !          39068:                                                tgt_state <- T_TIMED_OUT.
        !          39069:                Else // tgt_state != T_IDLE
        !          39070: d120 6
        !          39071: a125 1
        !          39072:        b.  input = I_RESELECT.
        !          39073: d127 5
        !          39074: a131 6
        !          39075:                else // tgt_state != T_DISCONNECTED
        !          39076:                        (need to discard this try)
        !          39077:                        Set target timeout to 20 msec.
        !          39078:                        tgt_state <- T_SETTLING
        !          39079:        c.  input = I_WATCHDOG.
        !          39080:        d.  input = I_TO_HOST.
        !          39081: d133 10
        !          39082: a142 6
        !          39083: 2. Host State = H_ARBITRATING.
        !          39084:        a.  input = I_CALL_SSBLOCK.
        !          39085:        b.  input = I_INTERRUPT.
        !          39086:        c.  input = I_WATCHDOG.
        !          39087:                Cancel host adapter timeout.
        !          39088:        d.  input = I_TO_HOST.
        !          39089: d144 52
        !          39090: a195 5
        !          39091: 3. Host State = H_xxx.
        !          39092:        a.  input = I_CALL_SSBLOCK.
        !          39093:        b.  input = I_INTERRUPT.
        !          39094:        c.  input = I_WATCHDOG.
        !          39095:        d.  input = I_TO_HOST.
        !          39096: @
        !          39097: 
        !          39098: 
        !          39099: 1.2
        !          39100: log
        !          39101: @Case 1.a. completed.
        !          39102: @
        !          39103: text
        !          39104: @d2 3
        !          39105: d9 2
        !          39106: a10 2
        !          39107: State Machines for ss Driver.
        !          39108: -----------------------------
        !          39109: d20 5
        !          39110: d36 6
        !          39111: a41 3
        !          39112:        T_CHECK.
        !          39113:                Target device failed with Device Check status.  Need to
        !          39114:                execute Request Sense and repeat previous command.
        !          39115: d49 1
        !          39116: a49 1
        !          39117:                device should be sent a Bus Device Reset command.
        !          39118: d51 5
        !          39119: d59 2
        !          39120: a60 1
        !          39121:                for this drive.
        !          39122: d62 1
        !          39123: a62 1
        !          39124:        I_INTERRUPT.
        !          39125: d64 2
        !          39126: a65 1
        !          39127:                gone active on the SCSI bus.
        !          39128: a91 1
        !          39129:                        Start host watchdog.
        !          39130: d98 1
        !          39131: d122 2
        !          39132: a123 2
        !          39133:                                                Set target timeout to 0 msec. (defer)
        !          39134:                                                tgt_state <- T_CHECK.
        !          39135: d130 2
        !          39136: a131 1
        !          39137:                                        tgt_state <- T_IDLE.
        !          39138: d142 6
        !          39139: a147 1
        !          39140:        b.  input = I_INTERRUPT.
        !          39141: @
        !          39142: 
        !          39143: 
        !          39144: 1.1
        !          39145: log
        !          39146: @Unfinished draft.
        !          39147: @
        !          39148: text
        !          39149: @d1 4
        !          39150: a4 1
        !          39151: $Log$
        !          39152: d30 1
        !          39153: a30 1
        !          39154:                execute Request Status and repeat previous command.
        !          39155: d36 4
        !          39156: a73 1
        !          39157:                        device_reset_done  <- 0
        !          39158: d93 6
        !          39159: a98 2
        !          39160:                                        Set target timeout to 250 msec.
        !          39161:                                        tgt_state <- T_BUSY.
        !          39162: d100 6
        !          39163: a105 2
        !          39164:                                        Set target timeout to 0 msec. (defer)
        !          39165:                                        tgt_state <- T_CHECK.
        !          39166: d114 6
        !          39167: a119 2
        !          39168:                                        Set target timeout to 250 msec.
        !          39169:                                        tgt_state <- T_BUSY.
        !          39170: @
        !          39171: 0707070064030104201004440000030000030000011777770507310655700006200000004302/newbits/kernel/USRSRC/i8086/drv/RCS/ss.recover,vhead     1.1;
        !          39172: access   ;
        !          39173: symbols  ;
        !          39174: locks    ;
        !          39175: comment  @ * @;
        !          39176: 
        !          39177: 
        !          39178: 1.1
        !          39179: date     91.05.09.15.13.07;  author root;  state Exp;
        !          39180: branches ;
        !          39181: next   ;
        !          39182: 
        !          39183: 
        !          39184: desc
        !          39185: @Error recovery pseudocode.
        !          39186: @
        !          39187: 
        !          39188: 
        !          39189: 
        !          39190: 1.1
        !          39191: log
        !          39192: @initial incomplete draft
        !          39193: @
        !          39194: text
        !          39195: @/*
        !          39196:  * ss.recover - list of ST01/ST02 i/o failures and what to do when they happen.
        !          39197:  * 
        !          39198:  *
        !          39199:  * $Log$
        !          39200:  */
        !          39201: Here are the inputs to the recovery state machine:
        !          39202: 
        !          39203: A_TIMEOUT (arbitration timeout)
        !          39204: Host adapter takes too long to respond with arbitration complete.
        !          39205: 
        !          39206: P_TIMEOUT (protocol timeout)
        !          39207: Timeout waiting for desired SCSI bus status while connected to a target.
        !          39208: 
        !          39209: R_TIMEOUT (reconnect timeout)
        !          39210: Timeout after target disconnects, waiting for reconnect.
        !          39211: 
        !          39212: TGT_BUSY (target device busy)
        !          39213: Command status returned was BUSY.
        !          39214: 
        !          39215: TGT_CHECK (target device check)
        !          39216: Command status returned was CHECK.
        !          39217: 
        !          39218: For each device there are values for the current block I/O request.  These
        !          39219: include
        !          39220:        arb_count
        !          39221:        Number of times we have polled the host adapter while waiting for
        !          39222:        arbitration complete.
        !          39223: 
        !          39224:        bdr_count
        !          39225:        Number of times we have tried Bus Device Reset while attempting the
        !          39226:        current request.
        !          39227: 
        !          39228:        bsy_count
        !          39229:        Number of times we have received Device Busy status while attempting
        !          39230:        the current request.
        !          39231: 
        !          39232:        try_count
        !          39233:        Total number of times the current request has been attempted.
        !          39234: All of these are initialized to zero when a new block request is taken from
        !          39235: the queue.
        !          39236: 
        !          39237: Whenever an error occurs, one of the above inputs, together with the SCSI id
        !          39238: of the target, is sent to the recovery process.  The recovery process in turn
        !          39239: places commands on the state machine stack and invokes the state machine.
        !          39240: Here is the pseudocode for the recovery process:
        !          39241: 
        !          39242: add 1 to try_count
        !          39243: if try_count < MAX_TRY_COUNT (6)
        !          39244:        push SST_BLOCKIO
        !          39245:        switch error_type
        !          39246:        case TGT_BUSY
        !          39247:                add 1 to bsy_count
        !          39248:                if bsy_count < MAX_BSY_COUNT (2)
        !          39249:                        push SST_WAIT BSY_DELAY
        !          39250:                else
        !          39251:                        push SST_BUS_DEV_RST
        !          39252:                endif
        !          39253:        case TGT_CHECK
        !          39254:                push SST_REQ_SENSE
        !          39255:        case P_TIMEOUT, R_TIMEOUT
        !          39256:                add 1 to bdr_count
        !          39257:                if bdr_count < MAX_BDR_COUNT (2)
        !          39258:                        push SST_BUS_DEV_RST
        !          39259:                else
        !          39260:                        push SST_LOPRI_RESET
        !          39261:                endif
        !          39262:        case A_TIMEOUT
        !          39263:                push SST_HIPRI_RESET
        !          39264:        endswitch
        !          39265: else // try_count >= MAX_TRY_COUNT
        !          39266:        set BFERR in buffer from kernel
        !          39267:        target is IDLE
        !          39268:        cleanup - bdone(), etc.
        !          39269: endif
        !          39270: invoke target stack machine (defer)
        !          39271: @
        !          39272: 0707070064030104171004440000030000030000011777770507310655700005600000044236/newbits/kernel/USRSRC/i8086/drv/RCS/ss.sst,vhead     1.8;
        !          39273: access   ;
        !          39274: symbols  ;
        !          39275: locks    ;
        !          39276: comment  @ * @;
        !          39277: 
        !          39278: 
        !          39279: 1.8
        !          39280: date     91.05.15.15.34.38;  author root;  state Exp;
        !          39281: branches ;
        !          39282: next   1.7;
        !          39283: 
        !          39284: 1.7
        !          39285: date     91.05.14.10.06.56;  author root;  state Exp;
        !          39286: branches ;
        !          39287: next   1.6;
        !          39288: 
        !          39289: 1.6
        !          39290: date     91.05.13.09.58.46;  author root;  state Exp;
        !          39291: branches ;
        !          39292: next   1.5;
        !          39293: 
        !          39294: 1.5
        !          39295: date     91.05.13.06.19.28;  author root;  state Exp;
        !          39296: branches ;
        !          39297: next   1.4;
        !          39298: 
        !          39299: 1.4
        !          39300: date     91.05.12.14.20.12;  author root;  state Exp;
        !          39301: branches ;
        !          39302: next   1.3;
        !          39303: 
        !          39304: 1.3
        !          39305: date     91.05.11.14.24.56;  author root;  state Exp;
        !          39306: branches ;
        !          39307: next   1.2;
        !          39308: 
        !          39309: 1.2
        !          39310: date     91.05.11.12.28.56;  author root;  state Exp;
        !          39311: branches ;
        !          39312: next   1.1;
        !          39313: 
        !          39314: 1.1
        !          39315: date     91.05.09.15.18.32;  author root;  state Exp;
        !          39316: branches ;
        !          39317: next   ;
        !          39318: 
        !          39319: 
        !          39320: desc
        !          39321: @Stack machine pseudocode.
        !          39322: @
        !          39323: 
        !          39324: 
        !          39325: 1.8
        !          39326: log
        !          39327: @Mostly in step with ss.c.1.40.
        !          39328: @
        !          39329: text
        !          39330: @/*
        !          39331:  * ss.sst - Seagate SCSI state machine (one per target device)
        !          39332:  *
        !          39333:  * $Log:       /usr/src/sys/i8086/drv/RCS/ss.sst,v $
        !          39334:  * Revision 1.7        91/05/14  10:06:56      root
        !          39335:  * Minor revisions during coding of main state machine.
        !          39336:  * 
        !          39337:  * Revision 1.6        91/05/13  09:58:46      root
        !          39338:  * First complete draft.
        !          39339:  * 
        !          39340:  * Revision 1.5        91/05/13  06:19:28      root
        !          39341:  * Rethreading main loop.
        !          39342:  * 
        !          39343:  * Revision 1.4        91/05/12  14:20:12      root
        !          39344:  * Adding timeout logic.
        !          39345:  * 
        !          39346:  * Revision 1.3        91/05/11  14:24:56      root
        !          39347:  * Includes error recovery - still quite incomplete.
        !          39348:  *
        !          39349:  * Revision 1.2        91/05/11  12:28:56      root
        !          39350:  * Further draft as of 05/10
        !          39351:  *
        !          39352:  * Revision 1.1        91/05/09  15:18:32      root
        !          39353:  * Initial incomplete draft.
        !          39354:  */
        !          39355: 
        !          39356: Things to do.
        !          39357: =============
        !          39358:        RV_BF_TIMEOUT
        !          39359:        "special"
        !          39360: 
        !          39361: Host status.
        !          39362: ============
        !          39363:        host_busy - arbitrating or connected to a target device
        !          39364: 
        !          39365: Target status.
        !          39366: ==============
        !          39367:        TG_BUSY - processing a block i/o request.  Don't start another block
        !          39368:                i/o request.
        !          39369:        TG_WAITING - if this status is TRUE, a timer has been started.  Don't
        !          39370:                start another command until either the timer expires or the
        !          39371:                awaited condition has occurred.  Things to wait for are listed
        !          39372:                under set_timeout().
        !          39373: 
        !          39374: Commands that appear on the stack.
        !          39375: ==================================
        !          39376:        SST_BUS_DEV_RESET
        !          39377:        SST_DEQUEUE (initial value for current state)
        !          39378:        SST_HIPRI_RESET
        !          39379:        SST_LOPRI_RESET
        !          39380:        SST_POLL_ARBITN
        !          39381:        SST_POLL_BEGIN_IO
        !          39382:        SST_POLL_RESELECT
        !          39383:        SST_REQ_SENSE
        !          39384:        SST_RESET_DONE
        !          39385:        SST_RESET_OFF
        !          39386: 
        !          39387: Block I/O counters.
        !          39388: ===================
        !          39389: For each device there are values for the current block I/O request.  These
        !          39390: are
        !          39391:        avl_count
        !          39392:        Number of times we have polled for (not host_busy) and BUS_FREE
        !          39393:        (i.e., host available).
        !          39394: 
        !          39395:        bdr_count
        !          39396:        Number of times we have tried Bus Device Reset while attempting the
        !          39397:        current request.
        !          39398: 
        !          39399:        bsy_count
        !          39400:        Number of times we have received Device Busy status while attempting
        !          39401:        the current request.
        !          39402: 
        !          39403:        try_count
        !          39404:        Total number of times the current request has been attempted.
        !          39405: All of these are initialized to zero when a new block request = taken from
        !          39406: the queue.
        !          39407: 
        !          39408: Pseudocode for the machine.
        !          39409: ===========================
        !          39410: do_sst_op = TRUE  // plan to run this routine again in most cases
        !          39411: while (do_sst_op)
        !          39412:        switch (current state)
        !          39413:        // polling state execute whether TG_WAITING or not
        !          39414:        case SST_POLL_ARBITN
        !          39415:                if arbitration complete
        !          39416:                        TG_WAITING = FALSE
        !          39417:                        if host_identify succeeds
        !          39418:                                do_connect()
        !          39419:                        else
        !          39420:                                recover(RV_P_TIMEOUT)
        !          39421:                        endif
        !          39422:                else
        !          39423:                        if timer has expired
        !          39424:                                recover(RV_A_TIMEOUT)
        !          39425:                        else
        !          39426:                                do_sst_op = FALSE
        !          39427:                        endif
        !          39428:                endif
        !          39429:        case SST_POLL_BEGIN_IO
        !          39430:                if current request = NULL
        !          39431:                        target_state = SST_DEQUEUE
        !          39432:                else
        !          39433:                        if not host_busy and bus free
        !          39434:                                host_busy = TRUE
        !          39435:                                TG_WAITING = FALSE
        !          39436:                                reset data pointers
        !          39437:                                if current request is buffer i/o
        !          39438:                                        reset b_resid
        !          39439:                                endif
        !          39440:                                // may be retrying a block request
        !          39441:                                start arbitration
        !          39442:                                if arbitration complete
        !          39443:                                        if host_identify succeeds
        !          39444:                                                do_connect()
        !          39445:                                        else
        !          39446:                                                recover(RV_P_TIMEOUT)
        !          39447:                                        endif
        !          39448:                                else
        !          39449:                                        target_state = SST_POLL_ARBITN
        !          39450:                                        set_timeout(DELAY_ARB)
        !          39451:                                endif
        !          39452:                        else  // host_busy or bus not free
        !          39453:                                set_timeout(DELAY_BSY)
        !          39454:                        endif
        !          39455:                endif
        !          39456:        case SST_POLL_RESELECT
        !          39457:                if target is doing Reselect
        !          39458:                        TG_WAITING = FALSE
        !          39459:                        if reconnect handshake succeeds
        !          39460:                                do_connect()
        !          39461:                        else
        !          39462:                                recover(RV_P_TIMEOUT)
        !          39463:                        endif
        !          39464:                else  // Reselect poll = negative
        !          39465:                        if timer has expired
        !          39466:                                recover(RV_R_TIMEOUT)
        !          39467:                        else
        !          39468:                                do_sst_op = FALSE
        !          39469:                        endif
        !          39470:                endif
        !          39471:        default
        !          39472:                if TG_WAITING
        !          39473:                        do_sst_op = FALSE
        !          39474:                else
        !          39475:        // nonpolling states execute only if no target timer is running
        !          39476:                        switch (current state)
        !          39477:        case SST_BUS_DEV_RESET
        !          39478:                try sending Bus Device Reset message to target
        !          39479:                if successful
        !          39480:                        do_sst_op = FALSE
        !          39481:                        set_timeout(DELAY_BDR)
        !          39482:                        target_state = SST_REQ_SENSE
        !          39483:                else
        !          39484:                        recover(RV_P_TIMEOUT)
        !          39485:                endif
        !          39486:        case SST_DEQUEUE
        !          39487:                if block i/o queue for target not empty and not TG_BUSY
        !          39488:                        TG_BUSY = TRUE
        !          39489:                        remove head request from queue
        !          39490:                        form current block request - initialize try counts, etc.
        !          39491:                        target_state = SST_POLL_BEGIN_IO
        !          39492:                else // queue is empty or TG_BUSY
        !          39493:                        do_sst_op = FALSE
        !          39494:                endif
        !          39495:        case SST_HIPRI_RESET
        !          39496:                turn on Reset bus line
        !          39497:                target_state = SST_RESET_OFF
        !          39498:                set_timeout(DELAY_RST)
        !          39499:        case SST_LOPRI_RESET
        !          39500:                // same as SST_HIPRI_RESET for now;  later, can implement
        !          39501:                a delay to allow other targets to finish pending operations
        !          39502:        case SST_REQ_SENSE
        !          39503:                try sending Request Sense command to target (no disconnect)
        !          39504:                if successful
        !          39505:                        target_state = SST_POLL_BEGIN_IO
        !          39506:                else
        !          39507:                        recover(RV_P_TIMEOUT)
        !          39508:                endif
        !          39509:        case SST_RESET_DONE
        !          39510:                target_state = SST_POLL_BEGIN_IO
        !          39511:        case SST_RESET_OFF
        !          39512:                turn off Reset bus line
        !          39513:                target_state = SST_RESET_DONE
        !          39514:                set_timeout(DELAY_RST)
        !          39515:                        endswitch
        !          39516:                endif
        !          39517:        endswitch
        !          39518: endwhile
        !          39519: 
        !          39520: Subroutines.
        !          39521: ============
        !          39522: 
        !          39523: do_connect
        !          39524: ----------
        !          39525: if current request is buffer i/o
        !          39526:        try_info_xfer()
        !          39527: else
        !          39528:        special_xfer()
        !          39529: endif
        !          39530: host_busy = FALSE
        !          39531: if transfer timed out
        !          39532:        recover(RV_P_TIMEOUT)
        !          39533: else if Disconnect message was received
        !          39534:        target_state = SST_POLL_RESELECT
        !          39535:        set_timeout(DELAY_RES)
        !          39536: else if Command Complete
        !          39537:        cleanup - bdone(), etc.
        !          39538:        current request = NULL
        !          39539:        TG_BUSY = FALSE
        !          39540:        if current request is buffer i/o
        !          39541:                target_state = SST_DEQUEUE
        !          39542:        else
        !          39543:                special status = TRUE
        !          39544:                wakeup special
        !          39545:        endif
        !          39546: else if Busy
        !          39547:        recover(RV_CS_BUSY)
        !          39548: else if Check
        !          39549:        recover(RV_CS_CHECK)
        !          39550: else  // something else went wrong
        !          39551:        recover(RV_P_TIMEOUT)
        !          39552: endif
        !          39553: 
        !          39554: recover
        !          39555: -------
        !          39556: Here are the inputs to the error recovery process:
        !          39557: 
        !          39558: RV_A_TIMEOUT (arbitration timeout)
        !          39559: Host adapter takes too long to respond with arbitration complete.
        !          39560: 
        !          39561: RV_P_TIMEOUT (protocol timeout)
        !          39562: Timeout waiting for desired SCSI bus status while connected to a target.
        !          39563: 
        !          39564: RV_R_TIMEOUT (reconnect timeout)
        !          39565: Timeout after target disconnects, waiting for reconnect.
        !          39566: 
        !          39567: RV_CS_BUSY (target device busy)
        !          39568: Command status returned was Busy.
        !          39569: 
        !          39570: RV_CS_CHECK (target device check)
        !          39571: Command status returned was CHECK.
        !          39572: 
        !          39573: Whenever an error occurs, one of the above inputs, together with the SCSI id
        !          39574: of the target, is sent to the recovery process.  The recovery process in turn
        !          39575: programs the next state for the machine.
        !          39576: 
        !          39577: add 1 to try_count
        !          39578: if try_count < MAX_TRY_COUNT (6)
        !          39579:        switch error_type
        !          39580:        case RV_CS_BUSY
        !          39581:                add 1 to bsy_count
        !          39582:                if bsy_count < MAX_BSY_COUNT (2)
        !          39583:                        target_state = SST_POLL_BEGIN_IO
        !          39584:                        set_timeout(DELAY_BSY)
        !          39585:                else
        !          39586:                        target_state = SST_BUS_DEV_RST
        !          39587:                endif
        !          39588:        case RV_CS_CHECK
        !          39589:                target_state = SST_REQ_SENSE
        !          39590:        case RV_P_TIMEOUT, RV_R_TIMEOUT
        !          39591:                add 1 to bdr_count
        !          39592:                if bdr_count < MAX_BDR_COUNT (2)
        !          39593:                        target_state = SST_BUS_DEV_RST
        !          39594:                else
        !          39595:                        target_state = SST_LOPRI_RESET
        !          39596:                endif
        !          39597:        case RV_A_TIMEOUT
        !          39598:                target_state = SST_HIPRI_RESET
        !          39599:        endswitch
        !          39600: else // try_count >= MAX_TRY_COUNT
        !          39601:        set BFERR in buffer from kernel
        !          39602:        TG_BUSY = FALSE
        !          39603:        cleanup - bdone(), etc.
        !          39604:        current request = NULL
        !          39605:        if current request is buffer i/o
        !          39606:                target_state = SST_DEQUEUE
        !          39607:        else
        !          39608:                special status = FALSE
        !          39609:                wakeup special
        !          39610:        endif
        !          39611: endif
        !          39612: 
        !          39613: set_timeout
        !          39614: -----------
        !          39615: Start a timer so as not to wait forever in case something goes wrong while
        !          39616: waiting for an event.  Available delays are:
        !          39617:        DELAY_ARB -     wait for arbitration complete
        !          39618:        DELAY_BDR -     allow settling time after Bus Device Reset
        !          39619:        DELAY_BSY -     wait for (not host_busy) and bus free
        !          39620:        DELAY_RES -     wait for reselect by target
        !          39621:        DELAY_RST -     allow settling times when doing SCSI Bus Reset
        !          39622: 
        !          39623: TG_WAITING = TRUE
        !          39624: do_sst_op = FALSE
        !          39625: do call to kernel timeout with function that will:
        !          39626:        set TG_WAITING to FALSE
        !          39627:        invoke the state machine
        !          39628: 
        !          39629: Interrupt.
        !          39630: ==========
        !          39631: if a device is doing Reselect
        !          39632:        defer state machine
        !          39633: endif
        !          39634: 
        !          39635: Watchdog.
        !          39636: =========
        !          39637: Whenever any open is pending for the target, invoke the state machine once
        !          39638: per second.
        !          39639: 
        !          39640: Block function in CON structure.
        !          39641: ================================
        !          39642: If block request is valid
        !          39643:        create a new node
        !          39644:        put it at tail of request queue
        !          39645:        target_state = SST_DEQUEUE
        !          39646: else
        !          39647:        BFERR, etc.
        !          39648: endif
        !          39649: 
        !          39650: Special commands.
        !          39651: =================
        !          39652: This includes Inquiry, Read Capacity, and Mode Sense.
        !          39653: @
        !          39654: 
        !          39655: 
        !          39656: 1.7
        !          39657: log
        !          39658: @Minor revisions during coding of main state machine.
        !          39659: @
        !          39660: text
        !          39661: @d5 3
        !          39662: d29 2
        !          39663: d34 1
        !          39664: a34 1
        !          39665:        HOST_BUSY - arbitrating or connected to a target device
        !          39666: d61 4
        !          39667: a64 4
        !          39668: include
        !          39669:        arb_count
        !          39670:        Number of times we have polled the host adapter while waiting for
        !          39671:        arbitration complete.
        !          39672: d104 2
        !          39673: a105 2
        !          39674:                        if not HOST_BUSY and bus free
        !          39675:                                HOST_BUSY = TRUE
        !          39676: d123 1
        !          39677: a123 1
        !          39678:                        else  // HOST_BUSY or bus not free
        !          39679: d201 1
        !          39680: a201 1
        !          39681: HOST_BUSY = FALSE
        !          39682: d290 1
        !          39683: a290 1
        !          39684:        DELAY_BSY -     wait for not HOST_BUSY and bus free
        !          39685: @
        !          39686: 
        !          39687: 
        !          39688: 1.6
        !          39689: log
        !          39690: @First complete draft.
        !          39691: @
        !          39692: text
        !          39693: @d5 3
        !          39694: a25 1
        !          39695:        startup and other special commands - Inquiry, Read Capacity, etc.
        !          39696: d35 1
        !          39697: a35 1
        !          39698:        TG_WAITING - if this status = TRUE, a timer has been started.  Don't
        !          39699: d43 1
        !          39700: a43 1
        !          39701:        SST_DEQUEUE (initial value for current command)
        !          39702: d78 2
        !          39703: a79 2
        !          39704:        switch (current command)
        !          39705:        // polling commands execute whether TG_WAITING or not
        !          39706: d83 5
        !          39707: a87 1
        !          39708:                        do_connect()
        !          39709: d108 7
        !          39710: a114 1
        !          39711:                                if timeout
        !          39712: a116 2
        !          39713:                                else // arbitration complete
        !          39714:                                        do_connect()
        !          39715: d123 1
        !          39716: a123 1
        !          39717:                if target = doing Reselect
        !          39718: d126 1
        !          39719: a126 1
        !          39720:                                do_reconnect()
        !          39721: d141 2
        !          39722: a142 2
        !          39723:        // nonpolling commands execute only if no target timer is running
        !          39724:                        switch (current command)
        !          39725: d158 1
        !          39726: a158 1
        !          39727:                else // queue = empty or TG_BUSY
        !          39728: a174 2
        !          39729:                        endswitch
        !          39730:                endif
        !          39731: d181 2
        !          39732: d241 1
        !          39733: a241 1
        !          39734: places commands on the state machine stack.
        !          39735: d297 1
        !          39736: a297 1
        !          39737: if a device is doing Reselect and that device is at SST_POLL_RESELECT
        !          39738: @
        !          39739: 
        !          39740: 
        !          39741: 1.5
        !          39742: log
        !          39743: @Rethreading main loop.
        !          39744: @
        !          39745: text
        !          39746: @d2 1
        !          39747: a2 1
        !          39748:  * ss.sst - Seagate SCSI stack machine (one per target device)
        !          39749: d5 3
        !          39750: d23 1
        !          39751: a23 12
        !          39752:        startup
        !          39753:        watchdog
        !          39754:        timeouts
        !          39755:        stack machine vs. single current command - this is mainly a problem
        !          39756:                in case of error recovery where we "push" a retry under
        !          39757:                e.g. a Bus Device Reset
        !          39758:        while loop - poll for any awaited activity
        !          39759:        checklist of SST_ commands
        !          39760:        SST_DEQUEUE
        !          39761:        what if another target resets the host?
        !          39762:                rely on usual error handling
        !          39763:        when to turn off TIMING
        !          39764: d27 1
        !          39765: a27 1
        !          39766:        BUSY - arbitrating or connected to a target device
        !          39767: d31 6
        !          39768: a36 10
        !          39769:        BUSY - processing a block i/o request.  Don't start another block i/o
        !          39770:                request.
        !          39771:        DISCONNECTED - awaiting reselect to complete the pending block
        !          39772:                request.  Only pay attention to Reselect when DISCONNECTED.
        !          39773:        TIMING - in each case below, a timer has been started.  Don't start
        !          39774:                another command until either the timer expires or the awaited
        !          39775:                condition has occurred.  Things to wait for are:
        !          39776:                        arbitration complete
        !          39777:                        target not BUSY
        !          39778:                        reselect interrupt
        !          39779: a39 1
        !          39780:        SST_BEGIN_IO
        !          39781: d41 1
        !          39782: a41 1
        !          39783:        SST_DEQUEUE (initial value for current command?!)
        !          39784: d45 1
        !          39785: a45 1
        !          39786:        SST_POLL_CS_BUSY
        !          39787: d48 2
        !          39788: a50 17
        !          39789: Inputs to the error recovery process.
        !          39790: =====================================
        !          39791: A_TIMEOUT (arbitration timeout)
        !          39792: Host adapter takes too long to respond with arbitration complete.
        !          39793: 
        !          39794: P_TIMEOUT (protocol timeout)
        !          39795: Timeout waiting for desired SCSI bus status while connected to a target.
        !          39796: 
        !          39797: R_TIMEOUT (reconnect timeout)
        !          39798: Timeout after target disconnects, waiting for reconnect.
        !          39799: 
        !          39800: TGT_BUSY (target device busy)
        !          39801: Command status returned was BUSY.
        !          39802: 
        !          39803: TGT_CHECK (target device check)
        !          39804: Command status returned was CHECK.
        !          39805: 
        !          39806: d69 1
        !          39807: a69 1
        !          39808: All of these are initialized to zero when a new block request is taken from
        !          39809: a73 1
        !          39810: 
        !          39811: d77 1
        !          39812: a77 1
        !          39813:        // polling commands execute whether target is WAITING or not
        !          39814: d80 1
        !          39815: a80 1
        !          39816:                        target is not WAITING
        !          39817: d84 1
        !          39818: a84 1
        !          39819:                                recover(A_TIMEOUT)
        !          39820: d89 11
        !          39821: a99 5
        !          39822:        case SST_BEGIN_IO
        !          39823:                if host not BUSY and bus free
        !          39824:                        target is not WAITING
        !          39825:                        if current request is not NULL
        !          39826:                                reset b_resid and data pointers
        !          39827: d103 2
        !          39828: a104 2
        !          39829:                                        push SST_POLL_ARBITN
        !          39830:                                        set_timeout(ARB_DELAY)
        !          39831: d108 2
        !          39832: a110 2
        !          39833:                else  // host is BUSY or bus not free
        !          39834:                        set_timeout(BSY_DELAY)
        !          39835: d113 6
        !          39836: a118 18
        !          39837:                If target is DISCONNECTED
        !          39838:                // avoid race condition with host interrupt
        !          39839:                        target is not DISCONNECTED
        !          39840:                        // mask host interrupt
        !          39841:                        if target is doing Reselect
        !          39842:                                target is not WAITING
        !          39843:                                if reconnect handshake succeeds
        !          39844:                                        do_reconnect()
        !          39845:                                else
        !          39846:                                        recover(P_TIMEOUT)
        !          39847:                                endif
        !          39848:                        else  // Reselect poll is negative
        !          39849:                                if timer has expired
        !          39850:                                        recover(R_TIMEOUT)
        !          39851:                                else
        !          39852:                                        do_sst_op = FALSE
        !          39853:                                        target is DISCONNECTED
        !          39854:                                endif
        !          39855: d120 6
        !          39856: d128 1
        !          39857: a128 1
        !          39858:                if target is WAITING
        !          39859: d131 1
        !          39860: a131 1
        !          39861:        // nonpolling commands execute only if target is not WAITING
        !          39862: d134 8
        !          39863: d143 2
        !          39864: a144 2
        !          39865:                if block i/o queue for target not empty and target is not BUSY
        !          39866:                        target is BUSY
        !          39867: d147 2
        !          39868: a148 2
        !          39869:                        push SST_POLL_CS_BUSY
        !          39870:                else // queue is empty or target is BUSY
        !          39871: d152 3
        !          39872: d156 2
        !          39873: d159 6
        !          39874: d167 6
        !          39875: a174 27
        !          39876: ======
        !          39877: while (do_sst_op and target is not TIMING)
        !          39878:        if stack empty
        !          39879:                if block i/o queue for target not empty and target is not BUSY
        !          39880:                        target is BUSY
        !          39881:                        remove head request from queue
        !          39882:                        form current block request - initialize try counts, etc.
        !          39883:                        push SST_POLL_CS_BUSY
        !          39884:                else // queue is empty or target is BUSY
        !          39885:                        do_sst_op = FALSE
        !          39886:                endif
        !          39887:        else // stack not empty
        !          39888:                remove top command from stack
        !          39889:                switch (command)
        !          39890:                case SST_POLL_CS_BUSY
        !          39891:                        do_blockio()
        !          39892:                case SST_BUS_DEV_RESET
        !          39893:                case SST_DEQUEUE
        !          39894:                case SST_HIPRI_RESET
        !          39895:                case SST_LOPRI_RESET
        !          39896:                case SST_POLL_ARBITN
        !          39897:                case SST_REQ_SENSE
        !          39898:                case SST_POLL_RESELECT
        !          39899:                        ignore the command
        !          39900:                endswitch
        !          39901:        endif
        !          39902: endwhile // do_sst_op
        !          39903: d179 1
        !          39904: a179 1
        !          39905: do_blockio
        !          39906: d181 6
        !          39907: a186 6
        !          39908: 
        !          39909: 
        !          39910: do_connect
        !          39911: ----------
        !          39912: try_info_xfer()
        !          39913: host is not BUSY
        !          39914: d188 1
        !          39915: a188 1
        !          39916:        recover(P_TIMEOUT)
        !          39917: d190 2
        !          39918: a191 3
        !          39919:        push SST_POLL_RESELECT
        !          39920:        set_timeout(RECON_DELAY)
        !          39921:        target is DISCONNECTED
        !          39922: d194 8
        !          39923: a201 3
        !          39924:        current request is NULL
        !          39925:        push SST_DEQUEUE
        !          39926:        target is not BUSY
        !          39927: d203 1
        !          39928: a203 1
        !          39929:        recover(TGT_BUSY)
        !          39930: d205 1
        !          39931: a205 1
        !          39932:        recover(TGT_CHECK)
        !          39933: d207 1
        !          39934: a207 1
        !          39935:        recover(P_TIMEOUT)
        !          39936: d212 17
        !          39937: a234 1
        !          39938:        push SST_POLL_CS_BUSY
        !          39939: d236 1
        !          39940: a236 1
        !          39941:        case TGT_BUSY
        !          39942: d239 2
        !          39943: a240 1
        !          39944:                        set_timeout(BSY_DELAY)
        !          39945: d242 1
        !          39946: a242 1
        !          39947:                        push SST_BUS_DEV_RST
        !          39948: d244 3
        !          39949: a246 3
        !          39950:        case TGT_CHECK
        !          39951:                push SST_REQ_SENSE
        !          39952:        case P_TIMEOUT, R_TIMEOUT
        !          39953: d249 1
        !          39954: a249 1
        !          39955:                        push SST_BUS_DEV_RST
        !          39956: d251 1
        !          39957: a251 1
        !          39958:                        push SST_LOPRI_RESET
        !          39959: d253 2
        !          39960: a254 2
        !          39961:        case A_TIMEOUT
        !          39962:                push SST_HIPRI_RESET
        !          39963: d258 1
        !          39964: a258 1
        !          39965:        target is not BUSY
        !          39966: d260 7
        !          39967: a266 2
        !          39968:        current request is NULL
        !          39969:        push SST_DEQUEUE
        !          39970: d273 5
        !          39971: a277 3
        !          39972:        ARB_DELAY -     wait for arbitration complete
        !          39973:        BSY_DELAY -     wait for target not busy
        !          39974:        RECON_DELAY -   wait for reselect by target
        !          39975: d279 1
        !          39976: a279 1
        !          39977: target is TIMING
        !          39978: d281 3
        !          39979: a283 1
        !          39980: do call to kernel sleep with function that will turn off timing
        !          39981: d287 2
        !          39982: a288 2
        !          39983: if a device is doing Reselect and that device is DISCONNECTED
        !          39984:        defer stack machine
        !          39985: d290 19
        !          39986: @
        !          39987: 
        !          39988: 
        !          39989: 1.4
        !          39990: log
        !          39991: @Adding timeout logic.
        !          39992: @
        !          39993: text
        !          39994: @d5 3
        !          39995: d23 9
        !          39996: d39 4
        !          39997: a42 2
        !          39998:        BUSY - processing a block i/o request
        !          39999:        DISCONNECTED - awaiting reselect to complete the pending block request
        !          40000: d54 1
        !          40001: d58 2
        !          40002: a60 1
        !          40003:        SST_TRY_RECONNECT
        !          40004: d103 8
        !          40005: a110 7
        !          40006: do_sst_op = TRUE  // plan to run this routine again under most cases
        !          40007: If target is DISCONNECTED  // avoid race condition with host interrupt
        !          40008:        target is not DISCONNECTED  // mask host interrupt
        !          40009:        if target is doing Reselect
        !          40010:                discard all pending commands on stack
        !          40011:                if reconnect handshake succeeds
        !          40012:                        do_reconnect()
        !          40013: d112 5
        !          40014: a116 1
        !          40015:                        recover(R_TIMEOUT)
        !          40016: d118 62
        !          40017: a179 7
        !          40018:        else if stack not empty
        !          40019:                remove top command from stack
        !          40020:                switch (command)
        !          40021:                case SST_TRY_RECONNECT          // timed out if we're here
        !          40022:                endswitch
        !          40023:        endif
        !          40024: endif
        !          40025: d186 1
        !          40026: a186 1
        !          40027:                        push SST_BEGIN_IO
        !          40028: d193 1
        !          40029: a193 1
        !          40030:                case SST_BEGIN_IO
        !          40031: d196 1
        !          40032: d201 1
        !          40033: a201 1
        !          40034:                case SST_TRY_RECONNECT
        !          40035: a212 13
        !          40036: if host is BUSY or bus not free
        !          40037:        push SST_BEGIN_IO
        !          40038:        set_timeout(BSY_DELAY)
        !          40039: else // host not BUSY and bus free
        !          40040:        reset b_resid and data pointers - may be retrying a block request
        !          40041:        start arbitration
        !          40042:        if timeout
        !          40043:                push SST_POLL_ARBITN
        !          40044:                set_timeout(ARB_DELAY)
        !          40045:        else // arbitration complete
        !          40046:                do_connect()
        !          40047:        endif
        !          40048: endif
        !          40049: d221 1
        !          40050: a221 1
        !          40051:        push SST_TRY_RECONNECT
        !          40052: d245 1
        !          40053: a245 1
        !          40054:        push SST_BEGIN_IO
        !          40055: @
        !          40056: T_ARB_DELAY
        !          40057:        SST_WAIT_BSY_DELAY
        !          40058:        SST_WAIT_RECON_DELAY
        !          40059: d87 1
        !          40060: a87 1
        !          40061: defer_machine = TRUE  // plan to run this routine again under most cases
        !          40062: a100 1
        !          40063:                case SST_WAIT_RECON_DELAY       // set timer interval
        !          40064: d103 24
        !          40065: a126 8
        !          40066: else if stack empty
        !          40067:        if block i/o queue for target not empty and target is not BUSY
        !          40068:                target is BUSY
        !          40069:                remove head request from queue
        !          40070:                form current block request - initialize try counts, etc.
        !          40071:                push SST_BLOCKIO
        !          40072:        else // queue is empty or target is BUSY
        !          40073:                defer_machine = FALSE
        !          40074: d128 1
        !          40075: a128 19
        !          40076: else // stack not empty
        !          40077:        remove top command from stack
        !          40078:        switch (command)
        !          40079:        case SST_BLOCKIO
        !          40080:                do_blockio()
        !          40081:        case SST_BUS_DEV_RESET
        !          40082:        case SST_HIPRI_RESET
        !          40083:        case SST_LOPRI_RESET
        !          40084:        case SST_POLL_ARBITN
        !          40085:        case SST_REQ_SENSE
        !          40086:        case SST_TRY_RECONNECT
        !          40087:                ignore the command
        !          40088:        case SST_WAIT_ARB_DELAY
        !          40089:        case SST_WAIT_BSY_DELAY
        !          40090:        case SST_WAIT_RECON_DELAY
        !          40091:                ignore the command
        !          40092:        endswitch
        !          40093: endif
        !          40094: defer stack machine
        !          40095: d137 2
        !          40096: a138 2
        !          40097:        push SST_BLOCKIO
        !          40098:        push SST_WAIT_BSY_DELAY
        !          40099: d144 1
        !          40100: a144 1
        !          40101:                push SST_WAIT_ARB_DELAY
        !          40102: d158 1
        !          40103: a158 1
        !          40104:        push SST_WAIT_RECON_DELAY
        !          40105: d162 2
        !          40106: d181 1
        !          40107: a181 1
        !          40108:        push SST_BLOCKIO
        !          40109: d186 1
        !          40110: a186 1
        !          40111:                        push SST_WAIT BSY_DELAY
        !          40112: d204 1
        !          40113: a204 1
        !          40114:        target is IDLE
        !          40115: d206 2
        !          40116: d210 12
        !          40117: a223 1
        !          40118: 
        !          40119: @
        !          40120: hine
        !          40121: d106 1
        !          40122: a106 1
        !          40123:                 do nothing
        !          40124: a116 1
        !          40125:        case SST_RECONNECT
        !          40126: d119 1
        !          40127: d123 1
        !          40128: d126 1
        !          40129: d134 1
        !          40130: a134 1
        !          40131: if host not IDLE or bus not free
        !          40132: d137 1
        !          40133: a137 2
        !          40134:        defer stack machine
        !          40135: else // host IDLE and bus free
        !          40136: a138 1
        !          40137:        host is ARBITRATING
        !          40138: a142 1
        !          40139:                defer stack machine
        !          40140: d144 1
        !          40141: a144 21
        !          40142:                host is CONNECTED
        !          40143:                try_info_xfer()
        !          40144:                host is IDLE
        !          40145:                if transfer timed out
        !          40146:                        recover(P_TIMEOUT)
        !          40147:                else if Disconnect message was received
        !          40148:                        push SST_TRY_RECONNECT
        !          40149:                        push SST_WAIT_RECON_DELAY
        !          40150:                        target is DISCONNECTED
        !          40151:                        defer stack machine
        !          40152:                else if Command Complete
        !          40153:                        cleanup - bdone(), etc.
        !          40154:                        target is IDLE
        !          40155:                        defer stack machine
        !          40156:                else if Busy
        !          40157:                        recover(TGT_BUSY)
        !          40158:                else if Check
        !          40159:                        recover(TGT_CHECK)
        !          40160:                else  // something else went wrong
        !          40161:                        recover(P_TIMEOUT)
        !          40162:                endif
        !          40163: d148 20
        !          40164: d169 35
        !          40165: a207 2
        !          40166:        discard all pending commands on stack
        !          40167:        push SST_RECONNECT
        !          40168: @
        !          40169: 
        !          40170: 
        !          40171: 1.1
        !          40172: log
        !          40173: @initial incomplete draft
        !          40174: @
        !          40175: text
        !          40176: @d4 4
        !          40177: a7 1
        !          40178:  * $Log$
        !          40179: d17 1
        !          40180: d27 16
        !          40181: a42 5
        !          40182: "tail recur" means re-execute the stack algorithm as if the given command
        !          40183: is the top item on the stack
        !          40184: 
        !          40185: If stack empty
        !          40186:        if block i/o queue for target not empty
        !          40187: d45 4
        !          40188: a48 3
        !          40189:                tail recur SST_BLOCKIO
        !          40190:        else // queue is empty
        !          40191:                return
        !          40192: d59 1
        !          40193: d76 2
        !          40194: a77 1
        !          40195:        tail recur SST_WAIT_BSY_DELAY
        !          40196: d84 2
        !          40197: a85 1
        !          40198:                tail recur SST_WAIT_ARB_DELAY
        !          40199: d94 3
        !          40200: a96 1
        !          40201:                        tail recur SST_WAIT_RECON_DELAY
        !          40202: d99 2
        !          40203: a100 1
        !          40204:                        tail recur - no command
        !          40205: d110 10
        !          40206: @
        !          40207: 0707070064030104161004440000030000030000011777770507310656300005600000004061/newbits/kernel/USRSRC/i8086/drv/RCS/ss.std,vhead     1.2;
        !          40208: access   ;
        !          40209: symbols  ;
        !          40210: locks    ;
        !          40211: comment  @ * @;
        !          40212: 
        !          40213: 
        !          40214: 1.2
        !          40215: date     91.04.26.15.39.32;  author root;  state Exp;
        !          40216: branches ;
        !          40217: next   1.1;
        !          40218: 
        !          40219: 1.1
        !          40220: date     91.04.25.17.11.09;  author root;  state Exp;
        !          40221: branches ;
        !          40222: next   ;
        !          40223: 
        !          40224: 
        !          40225: desc
        !          40226: @State Transition "Diagram" (Table) for Seagate SCSI driver.
        !          40227: @
        !          40228: 
        !          40229: 
        !          40230: 1.2
        !          40231: log
        !          40232: @Second partial draft.
        !          40233: @
        !          40234: text
        !          40235: @$Log: /usr/src/sys/i8086/drv/RCS/ss.std,v $
        !          40236:  * Revision 1.1        91/04/25  17:11:09      root
        !          40237:  * Initial partial draft.
        !          40238:  * 
        !          40239: 
        !          40240: State Transition Diagram for ss driver.
        !          40241: ---------------------------------------
        !          40242: 
        !          40243: (H_IDLE                T_IDLE          I_CALL_SSBLOCK)
        !          40244:        (H_ARBITRATING  T_IDLE          )
        !          40245:                Arbitration fails.
        !          40246:        (H_IDLE         T_BUSY          )
        !          40247:                Command status returned is BUSY.
        !          40248:        (H_IDLE         T_DEV_RESET     )
        !          40249:                Command try count exhausted.
        !          40250:        (H_IDLE         T_DISCONNECTED  )
        !          40251:                Normal disonnect.
        !          40252:        (H_IDLE         T_IDLE          )
        !          40253:                Command status returned is COMPLETE.
        !          40254:        (H_IDLE         T_REQ_SENSE     )
        !          40255:                Command status returned is CHECK.
        !          40256:        (H_IDLE         T_TIMED_OUT     )
        !          40257:                An awaited bus phase did not occur within the required interval.
        !          40258: 
        !          40259: (H_IDLE                ~T_IDLE         I_CALL_SSBLOCK)
        !          40260:                Take no action.  Remain in current state.
        !          40261: 
        !          40262: (~H_IDLE       T_IDLE          I_CALL_SSBLOCK)
        !          40263:                Take no action.  Remain in current state.
        !          40264: 
        !          40265: (H_IDLE                T_DISCONNECTED  I_RESELECT)
        !          40266:        (H_IDLE         T_BUSY          )
        !          40267:                Command status returned is BUSY.
        !          40268:        (H_IDLE         T_DEV_RESET     )
        !          40269:                Command try count exhausted.
        !          40270:        (H_IDLE         T_DISCONNECTED  )
        !          40271:                Normal disonnect.
        !          40272:        (H_IDLE         T_IDLE          )
        !          40273:                Command status returned is COMPLETE.
        !          40274:        (H_IDLE         T_REQ_SENSE     )
        !          40275:                Command status returned is CHECK.
        !          40276:        (H_IDLE         T_TIMED_OUT     )
        !          40277:                An awaited bus phase did not occur within the required interval.
        !          40278: 
        !          40279: (H_IDLE                ~T_DISCONNECTED I_RESELECT)
        !          40280:        No change in state.
        !          40281:                Reselect was attempted when it is not expected.
        !          40282: 
        !          40283: (~H_IDLE       T_DISCONNECTED  I_RESELECT)
        !          40284:        No change in state.
        !          40285:                Reselect was attempted when it is not expected.
        !          40286: 
        !          40287: (H_ARBITRATING T_IDLE          I_HOST_WATCHDOG)
        !          40288:        (H_SCSI_RESET           T_IDLE          )
        !          40289:                The wait for arbitration complete was too long.
        !          40290: 
        !          40291: (H_ARBITRATING ~T_IDLE         I_HOST_WATCHDOG)
        !          40292:        Illegal state!
        !          40293: 
        !          40294: (~H_ARBITRATING        ~T_IDLE         I_HOST_WATCHDOG)
        !          40295:        No change in state.
        !          40296:                Watchdog unexpected.
        !          40297: @
        !          40298: 
        !          40299: 
        !          40300: 1.1
        !          40301: log
        !          40302: @Initial partial draft.
        !          40303: @
        !          40304: text
        !          40305: @d1 4
        !          40306: a4 1
        !          40307: $Log$
        !          40308: d32 12
        !          40309: d46 2
        !          40310: d50 13
        !          40311: @
        !          40312: 0707070064030104151004440000030000030000011777770507310656400006100000162754/newbits/kernel/USRSRC/i8086/drv/RCS/ss01_20.c,vhead     1.20;
        !          40313: access   ;
        !          40314: symbols  ;
        !          40315: locks    ;
        !          40316: comment  @ * @;
        !          40317: 
        !          40318: 
        !          40319: 1.20
        !          40320: date     91.04.09.14.23.49;  author root;  state Exp;
        !          40321: branches ;
        !          40322: next   1.19;
        !          40323: 
        !          40324: 1.19
        !          40325: date     91.03.26.23.15.47;  author root;  state Exp;
        !          40326: branches ;
        !          40327: next   1.18;
        !          40328: 
        !          40329: 1.18
        !          40330: date     91.03.25.20.11.30;  author root;  state Exp;
        !          40331: branches ;
        !          40332: next   1.17;
        !          40333: 
        !          40334: 1.17
        !          40335: date     91.03.25.19.06.36;  author root;  state Exp;
        !          40336: branches ;
        !          40337: next   1.16;
        !          40338: 
        !          40339: 1.16
        !          40340: date     91.03.22.17.40.03;  author root;  state Exp;
        !          40341: branches ;
        !          40342: next   1.15;
        !          40343: 
        !          40344: 1.15
        !          40345: date     91.03.21.16.44.03;  author root;  state Exp;
        !          40346: branches ;
        !          40347: next   1.14;
        !          40348: 
        !          40349: 1.14
        !          40350: date     91.03.20.17.25.14;  author root;  state Exp;
        !          40351: branches ;
        !          40352: next   1.13;
        !          40353: 
        !          40354: 1.13
        !          40355: date     91.03.18.17.43.18;  author root;  state Exp;
        !          40356: branches ;
        !          40357: next   1.12;
        !          40358: 
        !          40359: 1.12
        !          40360: date     91.03.14.17.22.28;  author root;  state Exp;
        !          40361: branches ;
        !          40362: next   1.11;
        !          40363: 
        !          40364: 1.11
        !          40365: date     91.03.14.15.45.12;  author root;  state Exp;
        !          40366: branches ;
        !          40367: next   1.10;
        !          40368: 
        !          40369: 1.10
        !          40370: date     91.03.13.17.08.03;  author root;  state Exp;
        !          40371: branches ;
        !          40372: next   1.9;
        !          40373: 
        !          40374: 1.9
        !          40375: date     91.03.12.16.08.23;  author root;  state Exp;
        !          40376: branches ;
        !          40377: next   1.8;
        !          40378: 
        !          40379: 1.8
        !          40380: date     91.03.11.17.41.10;  author root;  state Exp;
        !          40381: branches ;
        !          40382: next   1.7;
        !          40383: 
        !          40384: 1.7
        !          40385: date     91.03.08.17.07.28;  author root;  state Exp;
        !          40386: branches ;
        !          40387: next   1.6;
        !          40388: 
        !          40389: 1.6
        !          40390: date     91.03.07.16.41.31;  author root;  state Exp;
        !          40391: branches ;
        !          40392: next   1.5;
        !          40393: 
        !          40394: 1.5
        !          40395: date     91.03.07.11.48.39;  author root;  state Exp;
        !          40396: branches ;
        !          40397: next   1.4;
        !          40398: 
        !          40399: 1.4
        !          40400: date     91.03.06.16.31.45;  author root;  state Exp;
        !          40401: branches ;
        !          40402: next   1.3;
        !          40403: 
        !          40404: 1.3
        !          40405: date     91.03.05.17.03.43;  author root;  state Exp;
        !          40406: branches ;
        !          40407: next   1.2;
        !          40408: 
        !          40409: 1.2
        !          40410: date     91.03.05.12.25.20;  author root;  state Exp;
        !          40411: branches ;
        !          40412: next   1.1;
        !          40413: 
        !          40414: 1.1
        !          40415: date     91.03.04.17.51.00;  author root;  state Exp;
        !          40416: branches ;
        !          40417: next   ;
        !          40418: 
        !          40419: 
        !          40420: desc
        !          40421: @Seagate ST01/ST02 hard disk SCSI device driver.
        !          40422: @
        !          40423: 
        !          40424: 
        !          40425: 1.20
        !          40426: log
        !          40427: @Reads boot sector 100 times using IRQ on reconnect
        !          40428: @
        !          40429: text
        !          40430: @int rpt_irpt;
        !          40431: int busted;
        !          40432: /*
        !          40433:  * This is a driver for Seagate ST01/ST02 scsi hard disk controllers.
        !          40434:  *
        !          40435:  * To do:
        !          40436:  *     turn on interrupts
        !          40437:  *     figure out a better storage class for rqs
        !          40438:  *      make input buffer for commands dynamic (?)
        !          40439:  *
        !          40440:  * $Log:       /usr/src/sys/i8086/drv/RCS/ss.c,v $
        !          40441:  * Revision 1.19       91/03/26  23:15:47      root
        !          40442:  * Reads partition table in prototype code
        !          40443:  * 
        !          40444:  * Revision 1.18       91/03/25  20:11:30      root
        !          40445:  * first raw read - disconnects
        !          40446:  * 
        !          40447:  * Revision 1.17       91/03/25  19:06:36      root
        !          40448:  * calls ssqueue functions - need real i/o
        !          40449:  * 
        !          40450:  * Revision 1.16       91/03/22  17:40:03      root
        !          40451:  * Need to do more with ss_start()
        !          40452:  * 
        !          40453:  * Revision 1.15       91/03/21  16:44:03      root
        !          40454:  * getting ready to call fdisk - finish ss_start next
        !          40455:  * 
        !          40456:  * Revision 1.14       91/03/20  17:25:14      root
        !          40457:  * Inquiry and Read Capacity working
        !          40458:  * 
        !          40459:  * Revision 1.13       91/03/18  17:43:18      root
        !          40460:  * add retry logic to scsicmd(); general cleanup
        !          40461:  * 
        !          40462:  * Revision 1.12       91/03/14  17:22:28      root
        !          40463:  * Test Ready now works, including Req Sense
        !          40464:  * 
        !          40465:  * Revision 1.11       91/03/14  15:45:12      root
        !          40466:  * has trouble with Test Ready using bus_info_xfer fsa
        !          40467:  * 
        !          40468:  * Revision 1.10       91/03/13  17:08:03      root
        !          40469:  * still more to do on bus_info_xfer
        !          40470:  * 
        !          40471:  * Revision 1.9        91/03/12  16:08:23      root
        !          40472:  * need to finish bus_info_xfer()
        !          40473:  * 
        !          40474:  * Revision 1.8        91/03/11  17:41:10      root
        !          40475:  * started ssopen()/wrote stub for ssinit()
        !          40476:  * 
        !          40477:  * Revision 1.7        91/03/08  17:07:28      root
        !          40478:  * Does Test Read and Request Sense properly.
        !          40479:  * 
        !          40480:  * Revision 1.6        91/03/07  16:41:31      root
        !          40481:  * sends Test Ready, Starts to Request Sense
        !          40482:  * 
        !          40483:  * Revision 1.5        91/03/07  11:48:39      root
        !          40484:  * Now sends Identify and Abort messages & completes a SCSI bus cycle
        !          40485:  *
        !          40486:  * Revision 1.4        91/03/06  16:31:45      root
        !          40487:  * tried to send Identify message - get status 0x40 & fail
        !          40488:  *
        !          40489:  * Revision 1.3        91/03/05  17:03:43      root
        !          40490:  * Goes thru arbitration (sans IRQ) successfully
        !          40491:  *
        !          40492:  */
        !          40493: 
        !          40494: /*
        !          40495:  * Definitions.
        !          40496:  */
        !          40497: #define DEV_SCSI_ID(dev)       ((dev >> 4) & 0x0007)
        !          40498: #define DEV_LUN(dev)           ((dev >> 2) & 0x0003)
        !          40499: #define DEV_DRIVE(dev)         ((dev >> 2) & 0x001F)
        !          40500: #define DEV_PARTN(dev)         (dev & 0x0003)
        !          40501: #define DEV_SPECIAL(dev)       (dev & 0x0080)
        !          40502: 
        !          40503: #define SS_RAM         0x1800  /* Offset of parameter RAM */
        !          40504: #define SS_CSR         0x1A00  /* Offset of control/status register */
        !          40505: #define SS_DAT         0x1C00  /* Offset of data port */
        !          40506: 
        !          40507: #define SS_RAM_LEN     128     /* ST0x has 128 bytes of RAM */
        !          40508: #define SS_DAT_LEN     0x400   /* Byte range mapped to data port */
        !          40509: #define SS_SEL_LEN     0x2000  /* Total size of memory-mapped area */
        !          40510: 
        !          40511: #define WC_ENABLE_SCSI 0x80    /* Write Control (WC) register bits */
        !          40512: #define WC_ENABLE_IRPT 0x40
        !          40513: #define WC_ENABLE_PRTY 0x20
        !          40514: #define WC_ARBITRATE   0x10
        !          40515: #define WC_ATTENTION   0x08
        !          40516: #define WC_BUSY        0x04
        !          40517: #define WC_SELECT      0x02
        !          40518: #define WC_SCSI_RESET          0x01
        !          40519: 
        !          40520: #define RS_ARBIT_COMPL 0x80    /* Read STATUS (RS) register bits */
        !          40521: #define RS_PRTY_ERROR  0x40
        !          40522: #define RS_SELECT      0x20
        !          40523: #define RS_REQUEST     0x10
        !          40524: #define RS_CTRL_DATA   0x08
        !          40525: #define RS_I_O         0x04
        !          40526: #define RS_MESSAGE     0x02
        !          40527: #define RS_BUSY        0x01
        !          40528: 
        !          40529: #define HOST_ID                0x80    /* Host adapter is SCSI ID #7 */
        !          40530: #define HIPRI_RETRIES  400     /* # of times to retry while hogging CPU */
        !          40531: #define LOPRI_RETRIES  5       /* # of retries with sleep between tries */
        !          40532: #define WHOLE_DRIVE    NPARTN
        !          40533: 
        !          40534: #define G0CMDLEN       6       /* Group 0 commands are 6 bytes long  */
        !          40535: #define G1CMDLEN       10      /* Group 1 commands are 10 bytes long */
        !          40536: #define SENSELEN       22      /* number of bytes returned w/ req sense */
        !          40537: #define INQUIRYLEN     54      /* number of bytes returned w/ inquiry */
        !          40538: 
        !          40539:                                /* Message types */
        !          40540: #define MSG_CMD_CMPLT  0x00    /* Command Complete */
        !          40541: #define MSG_SAVE_DPTR  0x02    /* Save SCSI data pointer */
        !          40542: #define MSG_RSTOR_DPTR 0x03    /* Restore SCSI pointers */
        !          40543: #define MSG_DISCONNECT 0x04    /* Target is about to disconnect */
        !          40544: #define MSG_ABORT      0x06    /* End the current SCSI bus cycle */
        !          40545: #define MSG_DEV_RESET  0x0C    /* Bus Device Reset */
        !          40546: #define MSG_IDENT_DC   0xC0    /* Identify, with Disconnect allowed */
        !          40547: 
        !          40548: #define CS_GOOD                0x00    /* Command Status from the drive */
        !          40549: #define CS_CHECK       0x02
        !          40550: #define CS_BUSY                0x08
        !          40551: #define CS_RESERVED    0x18
        !          40552: 
        !          40553:                                /* Device States */
        !          40554: #define        SIDLE           0       /* controller idle */
        !          40555: #define        SRETRY          1       /* seeking */
        !          40556: #define        SREAD           2       /* reading */
        !          40557: #define        SWRITE          3       /* writing */
        !          40558: 
        !          40559: /*
        !          40560:  * Information Transfer Phase masks -
        !          40561:  * setting of RS_MESSAGE, RS_I_O, and RS_CTRL_DATA determines which of six
        !          40562:  * possible info transfer phases is occurring.
        !          40563:  */
        !          40564: #define XP_MSG_IN      (RS_MESSAGE | RS_I_O | RS_CTRL_DATA)
        !          40565: #define XP_MSG_OUT     (RS_MESSAGE          | RS_CTRL_DATA)
        !          40566: #define XP_STAT_IN     (             RS_I_O | RS_CTRL_DATA)
        !          40567: #define XP_CMD_OUT     (                      RS_CTRL_DATA)
        !          40568: #define XP_DATA_IN     (             RS_I_O               )
        !          40569: #define XP_DATA_OUT    (                                 0)
        !          40570: 
        !          40571: #define DEBUG  1
        !          40572: #if DEBUG
        !          40573: int stats[100], statsptr;
        !          40574: #define PUSHI          { if(statsptr<100)stats[statsptr++] = i; }
        !          40575: #define POPI           { printf("%d:",statsptr);while(statsptr)\
        !          40576:                                printf("%d ",stats[--statsptr]);printf("\n");}
        !          40577: #define SSTELL(foo)    printf(foo)
        !          40578: #define SSTATUS                {uchar status = ffbyte(ss_csr);printf("status=%x\n", status);}
        !          40579: #define SSDUMP(ssp, text) {int i;\
        !          40580:        printf("%s: msg_in=%x cmdstat=%x\n", text, ssp->msg_in,\
        !          40581:        ssp->cmdstat);if(ssp->cmdlen)for(i=0;i<ssp->cmdlen;i++)\
        !          40582:        printf(" %x", ssp->cmdbuf[i]);printf(" cmd_bytes_out=%d",\
        !          40583:        ssp->cmd_bytes_out);\
        !          40584:        if(ssp->data_bytes_in)for(i=0;i<ssp->data_bytes_in;i++)\
        !          40585:        printf(" %x", ssp->in_buf[i]);printf(" data_bytes_in=%d\n",\
        !          40586:        ssp->data_bytes_in);}
        !          40587: #else
        !          40588: #define PUSHI
        !          40589: #define POPI
        !          40590: #define SSTELL(foo)
        !          40591: #define SSTATUS
        !          40592: #define SSDUMP(ssp, text)
        !          40593: #endif
        !          40594: 
        !          40595: /*
        !          40596:  * Includes.
        !          40597:  */
        !          40598: #include       <coherent.h>
        !          40599: #include       <sys/io.h>
        !          40600: #include       <sys/sched.h>
        !          40601: #include       <sys/uproc.h>
        !          40602: #include       <sys/proc.h>
        !          40603: #include       <sys/con.h>
        !          40604: #include       <sys/stat.h>
        !          40605: #include       <devices.h>             /* SCSI_MAJOR */
        !          40606: #include       <errno.h>
        !          40607: 
        !          40608: #include       <sys/fdisk.h>
        !          40609: #include       <sys/hdioctl.h>
        !          40610: #include       <sys/buf.h>
        !          40611: #include       <scsiwork.h>
        !          40612: 
        !          40613: /*
        !          40614:  * Export Functions.
        !          40615:  */
        !          40616: 
        !          40617: /*
        !          40618:  * Export Variables - patch these to configure the driver.
        !          40619:  */
        !          40620: int    NSDRIVE = 1;            /* Bitmap of attached SCSI drives. */
        !          40621: int    SS_INT = 5;             /* ST0[12] use either IRQ3 or IRQ5 */
        !          40622: int    SS_BASE = 0xDE00;       /* Segment addr of ST0x communication area */
        !          40623: 
        !          40624: /*
        !          40625:  * Import Functions.
        !          40626:  */
        !          40627: extern int     nulldev();
        !          40628: extern int     nonedev();
        !          40629: extern unsigned char ffbyte();
        !          40630: 
        !          40631: extern void ssq_wr_tail();
        !          40632: extern scsi_work_t * ssq_rd_head();
        !          40633: extern scsi_work_t * ssq_rm_head();
        !          40634: 
        !          40635: /*
        !          40636:  * Local Functions.
        !          40637:  */
        !          40638: static void    ssload();
        !          40639: static void    ssunload();
        !          40640: static void    ssopen();
        !          40641: static void    ssclose();
        !          40642: static void    ssread();
        !          40643: static void    sswrite();
        !          40644: static int     ssioctl();
        !          40645: static void    sswatch();
        !          40646: static void    ssblock();
        !          40647: static int     ssinit();
        !          40648: static int     scsicmd();
        !          40649: static void    scsireset();
        !          40650: static void    ssdelay();
        !          40651: static int     bus_pre_xfer();
        !          40652: static int     bus_info_xfer();
        !          40653: static void    ss_start_timing();
        !          40654: static void    ss_stop_timing();
        !          40655: static int     req_sense();
        !          40656: static int     inquiry();
        !          40657: static int     read_cap();
        !          40658: static void    ssintr();
        !          40659: static void    ss_start();
        !          40660: static void    ss_done();
        !          40661: static void    do_ss();
        !          40662: static void    bus_dev_reset();
        !          40663: 
        !          40664: /*
        !          40665:  * Local Variables.
        !          40666:  */
        !          40667: static BUF     dbuf;           /* For raw I/O */
        !          40668: static paddr_t ss_base;        /* physical address of ST0x comm area */
        !          40669: static faddr_t ss_fp;          /* (far *) to ST0x comm area */
        !          40670: 
        !          40671: static faddr_t ss_ram;         /* (far *) to parameter RAM */
        !          40672: static faddr_t ss_csr;         /* (far *) to control/status */
        !          40673: static faddr_t ss_dat;         /* (far *) to data port */
        !          40674: 
        !          40675: static int     num_drives;     /* number of controller SCSI id's */
        !          40676: static struct ss *ss_block;    /* points to block of "ss" structs */
        !          40677: static int     st0x_busy;      /* 1 if SCSI host adapter busy */
        !          40678: 
        !          40679: static TIM     delay_tim;      /* needed for calls to ssdelay() */
        !          40680: static TIM     timeout_tim;    /* needed for calls to timeout() */
        !          40681: static int     ss_expired;     /* 1 after local timeout */
        !          40682: static int     ss_state;       /* starts at SIDLE */
        !          40683: 
        !          40684: /*
        !          40685:  * Driver CON entry - an export variable.
        !          40686:  */
        !          40687: CON    sscon   = {
        !          40688:        DFBLK|DFCHR,                    /* Flags */
        !          40689:        SCSI_MAJOR,                     /* Major index */
        !          40690:        ssopen,                         /* Open */
        !          40691:        ssclose,                        /* Close */
        !          40692:        ssblock,                        /* Block */
        !          40693:        ssread,                         /* Read */
        !          40694:        sswrite,                        /* Write */
        !          40695:        ssioctl,                        /* Ioctl */
        !          40696:        nulldev,                        /* Powerfail */
        !          40697:        sswatch,                        /* Timeout */
        !          40698:        ssload,                         /* Load */
        !          40699:        ssunload,                       /* Unload */
        !          40700:        nulldev                         /* Poll */
        !          40701: };
        !          40702: 
        !          40703: /*
        !          40704:  * A per-drive structure - ss
        !          40705:  */
        !          40706: #define IN_BUF_SIZE    512
        !          40707: typedef unsigned char  uchar;
        !          40708: 
        !          40709: static struct ss       {
        !          40710:        long    capacity;
        !          40711:        long    blocklen;
        !          40712:        int     msg_in;
        !          40713:        uchar   cmdbuf[G1CMDLEN];
        !          40714:        int     cmdlen;
        !          40715:        int     cmd_bytes_out;
        !          40716:        int     cmdstat;
        !          40717:        uchar   in_buf[IN_BUF_SIZE];
        !          40718:        int     in_buf_len;
        !          40719:        int     data_bytes_in;
        !          40720:        struct  fdisk_s parmp[NPARTN+1];
        !          40721:        unsigned int    ptab_read:1;  /* 1 if partition table has been read */
        !          40722:        unsigned int    id_busy:1;  /* 1 if device with this SCSI id busy */
        !          40723: } *ss[MAX_SCSI_ID-1], rqs;
        !          40724: 
        !          40725: /*
        !          40726:  * ssload()    - load routine.
        !          40727:  *
        !          40728:  *     Action: The controller is reset and the interrupt vector is grabbed.
        !          40729:  *             The drive characteristics are set up at this time.
        !          40730:  */
        !          40731: static void ssload()
        !          40732: {
        !          40733:        int erf = 0;  /* 1 if error occurs */
        !          40734:        int i;
        !          40735: 
        !          40736:        /*
        !          40737:         * Claim IRQ vector.
        !          40738:         */
        !          40739:        setivec(SS_INT, ssintr);
        !          40740: 
        !          40741:        /*
        !          40742:         * Allocate a selector to map into ST0x memory-mapped comm area.
        !          40743:         */
        !          40744:        ss_base = (paddr_t)((long)(unsigned)SS_BASE << 4);
        !          40745:        ss_fp = ptov(ss_base, (fsize_t)SS_SEL_LEN);
        !          40746: 
        !          40747:        ss_ram = ss_fp + SS_RAM;
        !          40748:        ss_csr = ss_fp + SS_CSR;
        !          40749:        ss_dat = ss_fp + SS_DAT;
        !          40750: 
        !          40751:        /*
        !          40752:         * Primitive test of ST0x RAM.
        !          40753:         */
        !          40754:        sfword(ss_ram, 0xA55A);
        !          40755:        sfword(ss_ram + 2, 0x3CC3);
        !          40756:        sfword(ss_ram + SS_RAM_LEN - 4, 0xA55A);
        !          40757:        sfword(ss_ram + SS_RAM_LEN - 2, 0x3CC3);
        !          40758:        if (ffword(ss_ram) != 0xA55A            /* fetch a "far" word */
        !          40759:        ||  ffword(ss_ram + 2) != 0x3CC3
        !          40760:        ||  ffword(ss_ram + SS_RAM_LEN - 4) != 0xA55A
        !          40761:        ||  ffword(ss_ram + SS_RAM_LEN - 2) != 0x3CC3) {
        !          40762:                printf("Error - ST0x failed memory test\n");
        !          40763:                erf = 1;
        !          40764:        }
        !          40765: 
        !          40766:        /*
        !          40767:         * Allocate drive structs.
        !          40768:         *
        !          40769:         * Do a single call to kalloc() then put allocated pieces into
        !          40770:         * array ss.
        !          40771:         */
        !          40772:        if (!erf) {
        !          40773:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          40774:                        if ((NSDRIVE >> i) & 1)
        !          40775:                                num_drives++;
        !          40776:                if (num_drives == 0) {
        !          40777:                        printf("Error - ss has no valid target id's\n");
        !          40778:                        erf = 1;
        !          40779:                } else if ((ss_block = kalloc(num_drives*sizeof(struct ss)))
        !          40780:                == NULL) {
        !          40781:                        printf("Error - ss can't allocate structs\n");
        !          40782:                        erf = 1;
        !          40783:                } else
        !          40784:                        kclear(ss_block, num_drives * sizeof(struct ss));
        !          40785:        }
        !          40786:        if (!erf) {
        !          40787:                struct ss *foo = ss_block;
        !          40788: 
        !          40789:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          40790:                        if ((NSDRIVE >> i) & 1)
        !          40791:                                ss[i] = foo++;
        !          40792:        }
        !          40793: 
        !          40794:        /*
        !          40795:         * Initialize drives we know about (i.e. in NSDRIVE bitmap).
        !          40796:         */
        !          40797:        if (!erf) {
        !          40798:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          40799:                        if ((NSDRIVE >> i) & 1)
        !          40800:                                ssinit(i);
        !          40801:        }
        !          40802: }
        !          40803: 
        !          40804: /*
        !          40805:  * ssunload()  - unload routine.
        !          40806:  */
        !          40807: static void ssunload()
        !          40808: {
        !          40809:        /*
        !          40810:         * Deallocate driver heap space.
        !          40811:         */
        !          40812:        if (ss_block)
        !          40813:                kfree(ss_block);
        !          40814: 
        !          40815:        /*
        !          40816:         * Free the ST0x selector.
        !          40817:         */
        !          40818:        vrelse(ss_fp);
        !          40819: 
        !          40820:        /*
        !          40821:         * Release IRQ vector.
        !          40822:         */
        !          40823:        clrivec(SS_INT);
        !          40824: }
        !          40825: 
        !          40826: /*
        !          40827:  * ssopen()
        !          40828:  *
        !          40829:  *     Input:  dev = disk device to be opened.
        !          40830:  *             mode = access mode [IPR,IPW, IPR+IPW].
        !          40831:  *
        !          40832:  *     Action: Validate the minor device.
        !          40833:  *             Update the paritition table if necessary.
        !          40834:  */
        !          40835: static void ssopen( dev, mode )
        !          40836: register dev_t dev;
        !          40837: {
        !          40838:        int drive, partn;
        !          40839:        int erf = 0;
        !          40840: 
        !          40841:        drive = DEV_SCSI_ID(dev);
        !          40842:        partn = DEV_PARTN(dev);
        !          40843: 
        !          40844:        /*
        !          40845:         * LUN must be zero.
        !          40846:         * SCSI id must have corresponding 1 in NSDRIVE bitmapped variable.
        !          40847:         */
        !          40848:        if (DEV_LUN(dev) != 0 || ((1 << drive) & NSDRIVE) == 0) {
        !          40849:                u.u_error = ENXIO;
        !          40850:                erf = 1;
        !          40851:        }
        !          40852: 
        !          40853:        /*
        !          40854:         * If "special" bit is set, partition must be zero.
        !          40855:         */
        !          40856:        if (!erf && DEV_SPECIAL(dev) && partn != 0) {
        !          40857:                u.u_error = ENXIO;
        !          40858:                erf = 1;
        !          40859:        }
        !          40860: 
        !          40861:        /*
        !          40862:         * If "special" bit is NOT set, error return for now.
        !          40863:         */
        !          40864:        if (!erf && !DEV_SPECIAL(dev)) {
        !          40865:                u.u_error = ENXIO;
        !          40866:                erf = 1;
        !          40867:        }
        !          40868: 
        !          40869:        /*
        !          40870:         * OK - open the device.
        !          40871:         */
        !          40872:        if (!erf) {
        !          40873:                ++drvl[SCSI_MAJOR].d_time;
        !          40874:        }
        !          40875: #if 0
        !          40876:        /*
        !          40877:         * Ensure partition lies within drive boundaries and is non-zero size.
        !          40878:         */
        !          40879:        if ((pparm[p].p_base+pparm[p].p_size) > pparm[d+NDRIVE*NPARTN].p_size)
        !          40880:                u.u_error = EBADFMT;
        !          40881:        else if ( pparm[p].p_size == 0 )
        !          40882:                u.u_error = ENODEV;
        !          40883: #endif
        !          40884: }
        !          40885: 
        !          40886: /*
        !          40887:  * ssclose()
        !          40888:  */
        !          40889: static void ssclose( dev )
        !          40890: dev_t dev;
        !          40891: {
        !          40892:        --drvl[SCSI_MAJOR].d_time;      
        !          40893: }
        !          40894: 
        !          40895: /*
        !          40896:  * ssread()    - write a block to the raw disk
        !          40897:  *
        !          40898:  *     Input:  dev = disk device to be written to.
        !          40899:  *             iop = pointer to source I/O structure.
        !          40900:  *
        !          40901:  *     Action: Invoke the common raw I/O processing code.
        !          40902:  */
        !          40903: static void ssread( dev, iop )
        !          40904: dev_t  dev;
        !          40905: IO     *iop;
        !          40906: {
        !          40907:        ioreq( &dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC );
        !          40908: }
        !          40909: 
        !          40910: /*
        !          40911:  * sswrite()   - write a block to the raw disk
        !          40912:  *
        !          40913:  *     Input:  dev = disk device to be written to.
        !          40914:  *             iop = pointer to source I/O structure.
        !          40915:  *
        !          40916:  *     Action: Invoke the common raw I/O processing code.
        !          40917:  */
        !          40918: static void sswrite( dev, iop )
        !          40919: dev_t  dev;
        !          40920: IO     *iop;
        !          40921: {
        !          40922:        ioreq( &dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC );
        !          40923: }
        !          40924: 
        !          40925: /*
        !          40926:  * ssioctl()
        !          40927:  *
        !          40928:  *     Input:  dev = disk device to be operated on.
        !          40929:  *             cmd = input/output request to be performed.
        !          40930:  *             vec = (pointer to) optional argument.
        !          40931:  *
        !          40932:  *     Action: Validate the minor device.
        !          40933:  *             Update the paritition table if necessary.
        !          40934:  */
        !          40935: static int ssioctl( dev, cmd, vec )
        !          40936: register dev_t dev;
        !          40937: int cmd;
        !          40938: char * vec;
        !          40939: {
        !          40940:        int ret = 0;
        !          40941: 
        !          40942:        switch(cmd) {
        !          40943:        default:
        !          40944:                u.u_error = EINVAL;
        !          40945:                ret = -1;
        !          40946:        }
        !          40947: 
        !          40948:        return ret;
        !          40949: }
        !          40950: 
        !          40951: /*
        !          40952:  * ssblock()   - queue a block to the disk
        !          40953:  *
        !          40954:  *     Input:  bp = pointer to block to be queued.
        !          40955:  *
        !          40956:  *     Action: Queue a block to the disk.
        !          40957:  *             Make sure that the transfer is within the disk partition.
        !          40958:  */
        !          40959: static void ssblock(bp)
        !          40960: register BUF   *bp;
        !          40961: {
        !          40962:        register scsi_work_t *sw;
        !          40963:        register int s;
        !          40964:        struct  fdisk_s *fdp;
        !          40965:        int partition, drive, s_id;
        !          40966:        dev_t dev;
        !          40967:        struct ss * ssp;
        !          40968: 
        !          40969:        /*
        !          40970:         * Set up local variables.
        !          40971:         */
        !          40972:        dev = bp->b_dev;
        !          40973:        partition = DEV_PARTN(dev);
        !          40974:        drive = DEV_DRIVE(dev);
        !          40975:        s_id = DEV_SCSI_ID(dev);
        !          40976:        ssp = ss[s_id];
        !          40977: 
        !          40978:        if (dev & SDEV)
        !          40979:                partition = WHOLE_DRIVE;
        !          40980:        bp->b_resid = bp->b_count;
        !          40981:        
        !          40982:        fdp = ssp->parmp;
        !          40983: 
        !          40984:        /*
        !          40985:         * Range check disk region.
        !          40986:         */
        !          40987:        if (!(ssp->ptab_read)) {
        !          40988:                if ( partition == WHOLE_DRIVE ) {
        !          40989:                        if ((bp->b_bno != 0) || (bp->b_count != BSIZE)) {
        !          40990:                                bp->b_flag |= BFERR;
        !          40991:                                bdone(bp);
        !          40992:                                return;
        !          40993:                        }
        !          40994:                } else {
        !          40995:                        devmsg(dev, "no partition table");
        !          40996:                        bp->b_flag |= BFERR;
        !          40997:                        bdone(bp);
        !          40998:                        return;
        !          40999:                }
        !          41000:        }
        !          41001:        /*
        !          41002:         * Check for read at end of partition.
        !          41003:         * (Need to return with b_resid = BSIZE to signal end of volume.)
        !          41004:         */
        !          41005:        else if ((bp->b_req == BREAD) && (bp->b_bno == fdp[partition].p_size)) {
        !          41006:                bdone(bp);
        !          41007:                return;
        !          41008:        }
        !          41009:        /*
        !          41010:         * Check for read past end of partition.
        !          41011:         */
        !          41012:        else if ( (bp->b_bno + (bp->b_count/BSIZE))
        !          41013:        > fdp[partition].p_size ) {
        !          41014:                bp->b_flag |= BFERR;
        !          41015:                bdone(bp);
        !          41016:                return;
        !          41017:        }
        !          41018: 
        !          41019:        bp->b_actf = NULL;
        !          41020:        sw = (scsi_work_t *)kalloc( sizeof(*sw) );
        !          41021:        if (sw == NULL) {
        !          41022:                devmsg(dev, "out of kernel memory");
        !          41023:                bp->b_flag |= BFERR;
        !          41024:                bdone(bp);
        !          41025:                return;
        !          41026:        }
        !          41027:        sw->sw_bp = bp;
        !          41028:        sw->sw_drv = drive;
        !          41029:        if (partition != WHOLE_DRIVE)
        !          41030:                sw->sw_bno = fdp[partition].p_base + bp->b_bno;
        !          41031:        else
        !          41032:                sw->sw_bno = bp->b_bno;
        !          41033:        sw->sw_retry = 1;
        !          41034: 
        !          41035: printf("ssblock: drv %x bno %x:%x  bp=%x, flag = %o\n",
        !          41036:        drive, (long)sw->sw_bno, bp, bp->b_flag);
        !          41037: 
        !          41038:        ssq_wr_tail(sw);
        !          41039:        if (ss_state == SIDLE)
        !          41040:                ss_start();
        !          41041: }
        !          41042: 
        !          41043: /*
        !          41044:  * ssintr()    - Interrupt routine.
        !          41045:  */
        !          41046: #if 0
        !          41047: static int irpted;
        !          41048: static long x;
        !          41049: for (x = 0, irpted = 0; x < 100000L; x++)  if (irpted) break;
        !          41050: #endif
        !          41051: 
        !          41052: static void ssintr()
        !          41053: {
        !          41054:        printf("@@");
        !          41055:        rpt_irpt=1;
        !          41056:        wakeup(&rpt_irpt);
        !          41057: }
        !          41058: 
        !          41059: /*
        !          41060:  * sswatch()
        !          41061:  */
        !          41062: static void sswatch()
        !          41063: {
        !          41064:        printf("*");
        !          41065:        busted = 1;
        !          41066:        drvl[SCSI_MAJOR].d_time=0;
        !          41067:        wakeup(&rpt_irpt);
        !          41068: }
        !          41069: 
        !          41070: /*
        !          41071:  * bus_wait()
        !          41072:  *
        !          41073:  * Wait for specified bit values to appear in Status Register.
        !          41074:  * This uses a tight loop and does not expect to be interrupted.
        !          41075:  *
        !          41076:  * Argument "flags" is a double-byte value;  the high byte is ANDed with
        !          41077:  * status register contents, and the result is tested for equality with
        !          41078:  * the low byte.
        !          41079:  *
        !          41080:  * Return 1 if values wanted appeared, 0 if timeout occurred.
        !          41081:  */
        !          41082: static int bus_wait(flags)
        !          41083: unsigned short flags;
        !          41084: {
        !          41085:        int found, i;
        !          41086:        unsigned char status;
        !          41087: 
        !          41088:        found = 0;
        !          41089:        for ( i = 0; i < HIPRI_RETRIES; i++) {
        !          41090:                status = ffbyte(ss_csr);
        !          41091:                if ((status & (flags >> 8)) == (flags & 0xff)) {
        !          41092:                        found = 1;
        !          41093:                        break;
        !          41094:                }
        !          41095:        }
        !          41096: 
        !          41097:        if (!found)
        !          41098:                printf("ST0x timeout;  flags=%x status=%x\n", flags, status);
        !          41099: 
        !          41100:        return found;
        !          41101: }
        !          41102: 
        !          41103: /*
        !          41104:  * ssinit()
        !          41105:  *
        !          41106:  * Attempt to initialize the (unique) drive with a given SCSI id.
        !          41107:  * Assume only one drive per SCSI id, having LUN = 0.
        !          41108:  * 
        !          41109:  * Return 1 if success, 0 if failure.
        !          41110:  *
        !          41111:  * Pseudocode:
        !          41112:  *
        !          41113:  * retval = 0
        !          41114:  * if Test Unit Ready command fails, even after SCSI reset and retry
        !          41115:  *   print "Test Unit Ready fails"
        !          41116:  * else if Request Sense command fails
        !          41117:  *   print "Request Sense fails"
        !          41118:  * else if Read Capacity command succeeds
        !          41119:  *   print "Read Capacity fails"
        !          41120:  * else if partition table can't be read
        !          41121:  *   print "can't get partition table"
        !          41122:  * else
        !          41123:  *   print "SCSI id #n initialized"
        !          41124:  *   retval = 1
        !          41125:  * return retval
        !          41126:  */
        !          41127: static int ssinit(s_id)
        !          41128: int s_id;
        !          41129: {
        !          41130:        int retval = 0;
        !          41131:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          41132: 
        !          41133:        if (testready(s_id))
        !          41134:                retval = 1;
        !          41135:        else {
        !          41136:                scsireset();
        !          41137:                bus_dev_reset(s_id);
        !          41138:                if (testready(s_id))
        !          41139:                        retval = 1;
        !          41140:                else
        !          41141:                        devmsg(dev, "Test Unit Ready Failed");
        !          41142:        }
        !          41143: 
        !          41144:        if (retval)
        !          41145:                if (req_sense(s_id)) {
        !          41146:                        retval = 1;
        !          41147:                } else
        !          41148:                        devmsg(dev, "Request Sense Failed");
        !          41149: 
        !          41150:        if (retval)
        !          41151:                if (inquiry(s_id)) {
        !          41152:                        ss[s_id]->in_buf[INQUIRYLEN] = 0;
        !          41153:                        devmsg(dev, ss[s_id]->in_buf + 8);
        !          41154:                        if (ss[s_id]->in_buf[0] == 0) {
        !          41155:                                retval = 1;
        !          41156:                        } else
        !          41157:                                devmsg(dev, "Not Direct Access Device");
        !          41158:                } else
        !          41159:                        devmsg(dev, "Inquiry Failed");
        !          41160: 
        !          41161:        if (retval)
        !          41162:                if (read_cap(s_id)) {
        !          41163:                        retval = 1;
        !          41164:                } else
        !          41165:                        devmsg(dev, "Read Capacity Failed");
        !          41166: 
        !          41167: #if 0
        !          41168:        if (retval) {
        !          41169:                retval = fdisk(dev, ss[s_id]->parmp);
        !          41170:                if (retval) {
        !          41171:                        printf("fdisk scsi id #%d succeeded\n", s_id);
        !          41172:                        ss[s_id]->ptab_read = 1;
        !          41173:                } else
        !          41174:                        printf("fdisk scsi id #%d failed\n", s_id);
        !          41175:        }
        !          41176: #else
        !          41177:        /*
        !          41178:         * For test purposes only, try to read the partition table.
        !          41179:         */
        !          41180:        if (retval) {
        !          41181: int foo,fof;
        !          41182: for (foo=0,fof=0;foo<100;){
        !          41183:        rpt_irpt=0;
        !          41184:        busted=0;
        !          41185:        drvl[SCSI_MAJOR].d_time=1;
        !          41186:                if (read_pt(s_id)) {
        !          41187:                        retval = 1;
        !          41188:                } else {
        !          41189:                        devmsg(dev, "Read Partition Table Failed");
        !          41190:                        break;
        !          41191:                }
        !          41192: foo++;
        !          41193:        if (!rpt_irpt){
        !          41194:                fof++;
        !          41195:                if (fof>=3) {
        !          41196:                        printf("3 irq's lost\n");
        !          41197:                        break;
        !          41198:                }
        !          41199:        }
        !          41200: } /*endfor*/
        !          41201: printf("%d read_pt's\n",foo);
        !          41202:        }
        !          41203: #endif
        !          41204: 
        !          41205:        return retval;
        !          41206: }
        !          41207: 
        !          41208: /*
        !          41209:  * Send Test Unit Ready command.
        !          41210:  * Retry after bus reset if necessary.
        !          41211:  *
        !          41212:  * Return 1 if unit is ready, 0 if not.
        !          41213:  */
        !          41214: static int testready(s_id)
        !          41215: int s_id;
        !          41216: {
        !          41217:        int retval;
        !          41218:        struct ss * ssp = ss[s_id];
        !          41219: 
        !          41220:        ssp->cmdbuf[0] = ScmdTESTREADY;
        !          41221:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] =
        !          41222:                ssp->cmdbuf[5] = 0;
        !          41223:        ssp->cmdlen = G0CMDLEN;
        !          41224:        retval = scsicmd(s_id);
        !          41225: 
        !          41226:        return retval;
        !          41227: }
        !          41228: 
        !          41229: /*
        !          41230:  * scsicmd()
        !          41231:  *
        !          41232:  * Send command packet to target device.
        !          41233:  * Start a new SCSI bus cycle when this routine is called.
        !          41234:  * If command status after sending is Device Check (CS_CHECK), do a
        !          41235:  * Request Sense to find out what happened and clear check status.
        !          41236:  *
        !          41237:  * Return 1 if command was send and status was good, else 0.
        !          41238:  */
        !          41239: static int scsicmd(s_id)
        !          41240: int s_id;
        !          41241: {
        !          41242:        int retval;
        !          41243:        struct ss *ssp = ss[s_id];
        !          41244:        int tries;
        !          41245: 
        !          41246:        tries = 0;
        !          41247:        do {
        !          41248:                if (tries > 0)
        !          41249:                        ssdelay(100);
        !          41250: 
        !          41251:                if (retval = bus_pre_xfer(s_id)) {
        !          41252:                        bus_info_xfer(ssp);
        !          41253:                        retval = (ssp->cmdlen == ssp->cmd_bytes_out
        !          41254:                                && ssp->cmdstat == CS_GOOD);
        !          41255:                }
        !          41256: 
        !          41257:                if (ssp->cmdstat == CS_CHECK) {
        !          41258:                        if (req_sense(s_id))
        !          41259:                                retval = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          41260:                }
        !          41261: 
        !          41262:                tries++;
        !          41263:        } while (ssp->cmdstat == CS_BUSY && tries < LOPRI_RETRIES);
        !          41264: 
        !          41265:        if (ssp->msg_in == MSG_DISCONNECT) {
        !          41266:                int connected = 0;
        !          41267:                uchar dat, csr;
        !          41268: 
        !          41269: printf("Disconnected ");
        !          41270: {
        !          41271:        int s;
        !          41272:        s=sphi();
        !          41273:        while(!rpt_irpt && !busted)
        !          41274:                sleep(&rpt_irpt, CVBLKIO,IVBLKIO,SVBLKIO);
        !          41275:        spl(s);
        !          41276: }
        !          41277:                for (tries = 0; tries < 10; tries++) {
        !          41278:                        csr = ffbyte(ss_csr);
        !          41279:                        if (csr & RS_SELECT) {
        !          41280:                                dat = ffbyte(ss_dat);
        !          41281:                                if (dat & HOST_ID) {
        !          41282: printf("%d tries Reconnected\n",tries);
        !          41283:                                        connected = 1;
        !          41284:                                        break;
        !          41285:                                } else {
        !          41286:                                        int t;
        !          41287: printf("Host not selected\n");
        !          41288:                                        for (t = 0; t < 10; t++) {
        !          41289:                                                if (ffbyte(ss_csr) & RS_SELECT == 0) {
        !          41290: printf("Select dropped by target\n");
        !          41291:                                                        break;
        !          41292:                                                }
        !          41293:                                                ssdelay(10);
        !          41294:                                        }
        !          41295:                                }
        !          41296:                        }
        !          41297:                        ssdelay(10);
        !          41298:                }
        !          41299:                if (connected) {
        !          41300:                        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_BUSY);
        !          41301:                        if (bus_wait(RS_SELECT << 8 | 0)) {
        !          41302: printf("Select deasserted by target\n");
        !          41303:                                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          41304:                                bus_info_xfer(ssp);
        !          41305:                                retval = (ssp->cmdstat == CS_GOOD);
        !          41306:                        }
        !          41307:                }
        !          41308:        }
        !          41309: 
        !          41310:        return retval;
        !          41311: }
        !          41312: 
        !          41313: /*
        !          41314:  * scsireset()
        !          41315:  *
        !          41316:  * Reset the SCSI bus.
        !          41317:  * Allow settling time when turning reset on/off.
        !          41318:  * Settling times were determined empirically.
        !          41319:  * Each tick is 10 msec.
        !          41320:  */
        !          41321: #define RESET_TICKS    40
        !          41322: int RESET_ON_TICKS = 40;
        !          41323: int RESET_OFF_TICKS = 40;
        !          41324: static void scsireset()
        !          41325: {
        !          41326: printf("scsireset\n");
        !          41327:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          41328:        ssdelay(RESET_ON_TICKS);
        !          41329:        sfbyte(ss_csr, 0);
        !          41330:        ssdelay(RESET_OFF_TICKS);
        !          41331: }
        !          41332: 
        !          41333: /*
        !          41334:  * ssdelay()
        !          41335:  *
        !          41336:  * Delay for some number of clock ticks.
        !          41337:  * 286/386 kernel ticks are at 100Hz
        !          41338:  */
        !          41339: static void ssdelay(ticks)
        !          41340: int ticks;
        !          41341: {
        !          41342:        timeout(&delay_tim, ticks, wakeup, (int)&delay_tim);
        !          41343:        sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
        !          41344: }
        !          41345: 
        !          41346: /*
        !          41347:  * ss_start_timing()
        !          41348:  *
        !          41349:  * Start a timeout for some number of ticks.
        !          41350:  * Caller knows timer has expired when "ss_expired" goes to 1.
        !          41351:  *
        !          41352:  * Sample invocation:
        !          41353:  *     ss_start_timing(n);
        !          41354:  *     while (check for desired event fails) {
        !          41355:  *             if (ss_expired) {
        !          41356:  *                     ...failure stuff..
        !          41357:  *                     break;
        !          41358:  *             }
        !          41359:  *             ssdelay(m); <= needed to allow kernel to update timers
        !          41360:  *     }
        !          41361:  */
        !          41362: static void ss_start_timing(ticks)
        !          41363: int ticks;
        !          41364: {
        !          41365:        ss_expired = 0;
        !          41366:        timeout(&timeout_tim, ticks, ss_stop_timing, 1);
        !          41367: }
        !          41368: 
        !          41369: /*
        !          41370:  * ss_stop_timing()
        !          41371:  *
        !          41372:  * Stub function called only by ss_start_timing()
        !          41373:  */
        !          41374: static void ss_stop_timing(flagval)
        !          41375: int flagval;
        !          41376: {
        !          41377:        ss_expired = flagval;
        !          41378: }
        !          41379: 
        !          41380: /*
        !          41381:  * bus_pre_xfer()
        !          41382:  *
        !          41383:  * Do bus cycle phases prior to the information transfer phases.
        !          41384:  * This includes arbitration and selection.
        !          41385:  */
        !          41386: static int bus_pre_xfer(s_id)
        !          41387: int s_id;
        !          41388: {
        !          41389:        int tries;
        !          41390:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          41391:        int ret;
        !          41392: 
        !          41393:        for (ret = 0, tries = 0; !ret && tries < LOPRI_RETRIES; tries++) {
        !          41394:                /*
        !          41395:                 * Do ST0x arbitration.
        !          41396:                 */
        !          41397:                sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          41398:                sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          41399:                sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          41400: 
        !          41401:                /*
        !          41402:                 * SCSI spec says there is "no maximum" to the wait for arbitration
        !          41403:                 * complete.
        !          41404:                 */
        !          41405:                if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
        !          41406:                        scsireset();
        !          41407:                        continue;
        !          41408:                }
        !          41409: 
        !          41410:                /*
        !          41411:                 * Arbitration complete.  Now select, with ATN to allow messages.
        !          41412:                 */
        !          41413:                sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          41414:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          41415: 
        !          41416:                if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          41417:                        continue;
        !          41418: 
        !          41419:                /*
        !          41420:                 * Send "Identify" Message with Disconnect allowed.
        !          41421:                 */
        !          41422:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          41423: 
        !          41424:                if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          41425:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          41426:                        continue;
        !          41427: 
        !          41428:                sfbyte(ss_dat, MSG_IDENT_DC);
        !          41429:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ENABLE_IRPT);
        !          41430:                ret = 1;
        !          41431:        }
        !          41432: 
        !          41433:        return ret;
        !          41434: }
        !          41435: 
        !          41436: /*
        !          41437:  * bus_info_xfer()
        !          41438:  *
        !          41439:  * Do bus cycle information transfer phases.
        !          41440:  * This includes message in/out, command in/out, and data in/out.
        !          41441:  *
        !          41442:  * If cmdlen is nonzero, cmdbuf is an array of bytes of that length,
        !          41443:  * to be sent to the target.
        !          41444:  *
        !          41445:  * Return 1 if bus timeout did not occur, else 0.
        !          41446:  *
        !          41447:  * pseudocode:
        !          41448:  *
        !          41449:  * while (wait for REQ true or BUSY false on SCSI bus)
        !          41450:  *   if (BUSY false)
        !          41451:  *     break from while loop
        !          41452:  *   else
        !          41453:  *     switch (xfer phase = RS_CTRL_DATA|RS_I_O|RS_MESSAGE)
        !          41454:  *       case XP_MSG_IN/XP_MSG_OUT/...
        !          41455:  *         handle the indicated information transfer phase
        !          41456:  *     endswitch
        !          41457:  *   endif
        !          41458:  * endwhile
        !          41459:  */
        !          41460: static int bus_info_xfer(ssp)
        !          41461: struct ss *ssp;
        !          41462: {
        !          41463:        int bus_timeout;
        !          41464:        uchar phase_type;
        !          41465:        uchar msg_in;
        !          41466:        int no_msg_rcvd = 1;
        !          41467:        int s;
        !          41468:        int bytes_to_send;
        !          41469: 
        !          41470:        ssp->cmdstat = -1;
        !          41471:        ssp->data_bytes_in = 0;
        !          41472:        ssp->cmd_bytes_out = 0;
        !          41473:        ssp->msg_in = -1;
        !          41474:        s = sphi();
        !          41475:        while(req_wait(&bus_timeout)) {
        !          41476:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          41477:                switch (phase_type) {
        !          41478:                case XP_MSG_IN:
        !          41479:                        /*
        !          41480:                         * Only pay attention to first msg byte in.
        !          41481:                         * Don't care about extended messages.
        !          41482:                         */
        !          41483:                        msg_in = ffbyte(ss_dat);
        !          41484: printf("msg_in = %x\n", msg_in);
        !          41485:                        switch(msg_in){
        !          41486:                        case MSG_CMD_CMPLT:
        !          41487:                                ssp->msg_in = msg_in;
        !          41488:                                break;
        !          41489:                        case MSG_SAVE_DPTR:
        !          41490:                                break;
        !          41491:                        case MSG_RSTOR_DPTR:
        !          41492:                                break;
        !          41493:                        case MSG_DISCONNECT:
        !          41494:                                ssp->msg_in = msg_in;
        !          41495:                                break;
        !          41496:                        case MSG_ABORT:
        !          41497:                                break;
        !          41498:                        case MSG_DEV_RESET:
        !          41499:                                break;
        !          41500:                        case MSG_IDENT_DC:
        !          41501:                                break;
        !          41502:                        }
        !          41503:                        break;
        !          41504:                case XP_MSG_OUT:
        !          41505:                        /*
        !          41506:                         * This case shouldn't happen.  We weren't
        !          41507:                         * asserting ATTENTION.  Abort the bus cycle.
        !          41508:                         */
        !          41509:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          41510:                        sfbyte(ss_dat, MSG_ABORT); 
        !          41511:                        break;
        !          41512:                case XP_STAT_IN:
        !          41513:                        ssp->cmdstat = ffbyte(ss_dat);
        !          41514:                        break;
        !          41515:                case XP_CMD_OUT:
        !          41516:                        /*
        !          41517:                         * Ship out command bytes.
        !          41518:                         * Reset SCSI bus if too many command bytes are wanted.
        !          41519:                         */
        !          41520:                        bytes_to_send = ssp->cmdlen - ssp->cmd_bytes_out;
        !          41521:                        if(bytes_to_send > 0) {
        !          41522:                                sfbyte(ss_dat, ssp->cmdbuf[ssp->cmd_bytes_out++]);
        !          41523:                                /*
        !          41524:                                 * If just sent last byte, allow interrupts.
        !          41525:                                 */
        !          41526:                                if (bytes_to_send == 1) {
        !          41527:                                        spl(s);
        !          41528:                                        s = sphi();
        !          41529:                                }
        !          41530:                        } else {        /* This case should not happen. */
        !          41531: SSDUMP(ssp, "Command overrun");
        !          41532:                                scsireset();
        !          41533:                        }
        !          41534:                        break;
        !          41535:                case XP_DATA_IN:
        !          41536:                        /*
        !          41537:                         * If caller's buffer has room, keep incoming
        !          41538:                         * data byte.  Else toss it.
        !          41539:                         */
        !          41540:                        if (ssp->data_bytes_in < ssp->in_buf_len)
        !          41541:                                ssp->in_buf[ssp->data_bytes_in]
        !          41542:                                = ffbyte(ss_dat);
        !          41543:                        else
        !          41544:                                ffbyte(ss_dat);
        !          41545:                        ssp->data_bytes_in++;
        !          41546:                        break;
        !          41547:                case XP_DATA_OUT:
        !          41548:                        /*
        !          41549:                         * Temporary filler.
        !          41550:                         */
        !          41551:                        sfbyte(ss_dat, 0xAA);
        !          41552:                        break;
        !          41553:                default:
        !          41554:                        break;
        !          41555:                } /* endswitch */
        !          41556:        }
        !          41557:        spl(s);
        !          41558:        return (bus_timeout) ? 0 : 1 ;
        !          41559: }
        !          41560: /*
        !          41561:  * req_wait()
        !          41562:  *
        !          41563:  * This routine is called at the start of each information transfer
        !          41564:  * phase and after the last such phase.
        !          41565:  *
        !          41566:  * It returns 1 if REQ is asserted on the SCSI bus, meaning another phase
        !          41567:  * may begin, and 0 otherwise.  A REQ signal will not be seen if the function
        !          41568:  * times out or if BUSY drops.  A value of 1 is written to the pointer argument
        !          41569:  * if timeout occurred, else 0 is written.
        !          41570:  */
        !          41571: static int req_wait(to_ptr)
        !          41572: int *to_ptr;
        !          41573: {
        !          41574:        int req_found, i;
        !          41575:        unsigned char status;
        !          41576: 
        !          41577:        *to_ptr = 1;
        !          41578:        req_found = 0;
        !          41579:        for ( i = 0; i < HIPRI_RETRIES; i++) {
        !          41580:                status = ffbyte(ss_csr);
        !          41581:                if (status & RS_REQUEST) {
        !          41582:                        req_found = 1;
        !          41583:                        *to_ptr = 0;
        !          41584:                        break;
        !          41585:                } else if ((status & RS_BUSY) == 0) {
        !          41586:                        *to_ptr = 0;
        !          41587:                        break;
        !          41588:                }
        !          41589:        }
        !          41590: 
        !          41591:        if (*to_ptr)
        !          41592:                printf("ST0x info xfer timeout;  status=%x\n", status);
        !          41593: 
        !          41594:        return req_found;
        !          41595: }
        !          41596: 
        !          41597: /*
        !          41598:  * req_sense()
        !          41599:  *
        !          41600:  * Request Sense for a device.  The main reason for doing this is to
        !          41601:  * clear a standing Command Status of Device Check.
        !          41602:  *
        !          41603:  * Full results are discarded.  Return 1 if Device returns No Sense or
        !          41604:  * or Unit Attention.  Else return 0.
        !          41605:  *
        !          41606:  */
        !          41607: static int req_sense(s_id)
        !          41608: int s_id;
        !          41609: {
        !          41610:        int ret = 0;
        !          41611: 
        !          41612:        rqs.cmdbuf[0] = ScmdREQUESTSENSE;
        !          41613:        rqs.cmdbuf[1] = rqs.cmdbuf[2] = rqs.cmdbuf[3] =
        !          41614:                rqs.cmdbuf[5] = 0;
        !          41615:                rqs.cmdbuf[4] = SENSELEN;
        !          41616:        rqs.cmdlen = G0CMDLEN;
        !          41617:        rqs.in_buf_len = SENSELEN;
        !          41618: 
        !          41619:        if (bus_pre_xfer(s_id)) {
        !          41620:                bus_info_xfer(&rqs);
        !          41621:                if (rqs.data_bytes_in == SENSELEN) {
        !          41622:                        if (rqs.in_buf[2] == 0x00)      /* No Sense.  AOK */
        !          41623:                                ret = 1;
        !          41624:                        else if (rqs.in_buf[2] == 0x06 && rqs.in_buf[12] == 0x29)
        !          41625:                                ret = 1;
        !          41626:                }
        !          41627:        }
        !          41628: 
        !          41629:        return ret;
        !          41630: }
        !          41631: 
        !          41632: /*
        !          41633:  * inquiry()
        !          41634:  *
        !          41635:  * Inquiry command for a device.
        !          41636:  * Find out if device is direct access, removable, etc.
        !          41637:  *
        !          41638:  * Return 1 if command succeeds, else 0.
        !          41639:  */
        !          41640: static int inquiry(s_id)
        !          41641: int s_id;
        !          41642: {
        !          41643:        int ret = 0;
        !          41644:        struct ss * ssp = ss[s_id];
        !          41645: 
        !          41646:        ssp->cmdbuf[0] = ScmdINQUIRY;
        !          41647:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] =
        !          41648:                ssp->cmdbuf[5] = 0;
        !          41649:                ssp->cmdbuf[4] = INQUIRYLEN;
        !          41650:        ssp->cmdlen = G0CMDLEN;
        !          41651:        ssp->in_buf_len = INQUIRYLEN;
        !          41652: 
        !          41653:        ret = scsicmd(s_id);
        !          41654: 
        !          41655:        return ret;
        !          41656: }
        !          41657: 
        !          41658: /*
        !          41659:  * read_cap()
        !          41660:  *
        !          41661:  * Read Capacity command for a device.
        !          41662:  *
        !          41663:  * Return 1 if command succeeds, else 0.
        !          41664:  */
        !          41665: static int read_cap(s_id)
        !          41666: int s_id;
        !          41667: {
        !          41668:        int ret = 0;
        !          41669:        struct ss * ssp = ss[s_id];
        !          41670: 
        !          41671:        ssp->cmdbuf[0] = ScmdREADCAPACITY;
        !          41672:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] = 0;
        !          41673:        ssp->cmdbuf[5] = ssp->cmdbuf[6] = ssp->cmdbuf[7] = ssp->cmdbuf[8] = 0;
        !          41674:        ssp->cmdbuf[9] = 0;
        !          41675:        ssp->cmdlen = G1CMDLEN;
        !          41676:        ssp->in_buf_len = 8;
        !          41677: 
        !          41678:        ret = scsicmd(s_id);
        !          41679:        if (ret) {
        !          41680:                ssp->capacity = ssp->in_buf[3] | (ssp->in_buf[2] << 8)
        !          41681:                | (((long)(ssp->in_buf[1])) << 16)
        !          41682:                | (((long)(ssp->in_buf[0])) << 24);
        !          41683:                ssp->blocklen = ssp->in_buf[7] | (ssp->in_buf[6] << 8)
        !          41684:                | (((long)(ssp->in_buf[5])) << 16)
        !          41685:                | (((long)(ssp->in_buf[4])) << 24);
        !          41686: printf("capacity=%ld   block length=%ld\n", ssp->capacity, ssp->blocklen);
        !          41687:        }
        !          41688: 
        !          41689:        return ret;
        !          41690: }
        !          41691: 
        !          41692: /*
        !          41693:  * ss_start()
        !          41694:  *
        !          41695:  * Invoked whenever there is I/O to do.  Pull first request, if any,
        !          41696:  * off the queue, send it to the drive, and delete it from the queue.
        !          41697:  *
        !          41698:  * Disallow re-entrancy in this routine (variable "locked").
        !          41699:  */
        !          41700: static void ss_start()
        !          41701: {
        !          41702:        int s;
        !          41703:        scsi_work_t *sw;
        !          41704:        static char locked;
        !          41705: 
        !          41706:        s = sphi();
        !          41707:        if(locked) {
        !          41708:                spl(s);
        !          41709:                return;
        !          41710:        }
        !          41711:        ++locked;
        !          41712:        spl(s);
        !          41713: 
        !          41714:        if((sw = ssq_rm_head()) != NULL) {
        !          41715:                if (sw->sw_bp->b_req == BWRITE)
        !          41716:                        ss_state = SWRITE;
        !          41717:                else if (sw->sw_bp->b_req == BREAD)
        !          41718:                        ss_state = SREAD;
        !          41719:                else
        !          41720:                        printf("Error:  b_req=%d\n", sw->sw_bp->b_req);
        !          41721:                do_ss(sw);
        !          41722:        }
        !          41723:        --locked;
        !          41724: }
        !          41725: 
        !          41726: /*
        !          41727:  * do_ss()
        !          41728:  *
        !          41729:  * Begin a block read or write command as found in an "sw" queue entry.
        !          41730:  */
        !          41731: static void do_ss(sw)
        !          41732: struct scsi_work_t * sw;
        !          41733: {
        !          41734:        BUF * bp;
        !          41735: 
        !          41736: printf("do_ss\n");
        !          41737:        bp = sw->sw_bp;
        !          41738:        switch(ss_state) {
        !          41739:        case SREAD:
        !          41740:                bp->b_resid -= BSIZE;
        !          41741:                ss_done(sw);
        !          41742:                break;
        !          41743:        case SWRITE:
        !          41744:                bp->b_resid -= BSIZE;
        !          41745:                ss_done(sw);
        !          41746:                break;
        !          41747:        }
        !          41748: }
        !          41749: 
        !          41750: /*
        !          41751:  * ss_done
        !          41752:  *
        !          41753:  * Release current i/o buffer to the O/S.
        !          41754:  */
        !          41755: static void ss_done(sw)
        !          41756: struct scsi_work_t * sw;
        !          41757: {
        !          41758:        BUF * bp;
        !          41759: 
        !          41760: printf("ss_done\n");
        !          41761:        bp = sw->sw_bp;
        !          41762: 
        !          41763:        ss_state = SIDLE;
        !          41764:        bdone(bp);
        !          41765:        kfree(sw);
        !          41766: 
        !          41767:        if (ssq_rd_head())
        !          41768:                ss_start();
        !          41769: }
        !          41770: 
        !          41771: /*
        !          41772:  * read_pt()
        !          41773:  *
        !          41774:  * Read partition table for a device.
        !          41775:  *
        !          41776:  * Return 1 if command succeeds, else 0.
        !          41777:  */
        !          41778: static int read_pt(s_id)
        !          41779: int s_id;
        !          41780: {
        !          41781:        int ret = 0;
        !          41782:        struct ss * ssp = ss[s_id];
        !          41783: 
        !          41784:        ssp->cmdbuf[0] = ScmdREADEXTENDED;
        !          41785:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] = 0;
        !          41786:        ssp->cmdbuf[5] = ssp->cmdbuf[6] = ssp->cmdbuf[7] = ssp->cmdbuf[9] = 0;
        !          41787:        ssp->cmdbuf[8] = 1;     /* transfer 1 block */
        !          41788:        ssp->cmdlen = G1CMDLEN;
        !          41789:        ssp->in_buf_len = BSIZE;
        !          41790: 
        !          41791:        ret = scsicmd(s_id);
        !          41792:        if (ret) {
        !          41793: printf("signature low:%x high:%x\n", ssp->in_buf[510], ssp->in_buf[511]);
        !          41794:        }
        !          41795: 
        !          41796:        return ret;
        !          41797: }
        !          41798: 
        !          41799: /*
        !          41800:  * BDR_CHECK_INTERVAL is the number of ticks to wait between checks for
        !          41801:  * SCSI Bus Free after sending Bus Device Reset.
        !          41802:  * BDR_CHECK_COUNT is the number of times to check for SCSI Bus Free
        !          41803:  * before giving up.
        !          41804:  */
        !          41805: #define BDR_CHECK_INTERVAL     10
        !          41806: #define BDR_CHECK_COUNT                100
        !          41807: 
        !          41808: /*
        !          41809:  * bus_dev_reset()
        !          41810:  *
        !          41811:  * Send Bus Device Reset message to the given SCSI id.
        !          41812:  */
        !          41813: static void    bus_dev_reset(s_id)
        !          41814: {
        !          41815:        int tries;
        !          41816:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          41817: printf("bus_dev_reset\n");
        !          41818:        for (tries = 0; tries < LOPRI_RETRIES; tries++) {
        !          41819:                /*
        !          41820:                 * Do ST0x arbitration.
        !          41821:                 */
        !          41822:                sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          41823:                sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          41824:                sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          41825: 
        !          41826:                /*
        !          41827:                 * SCSI spec says there is "no maximum" to the wait for arbitration
        !          41828:                 * complete.
        !          41829:                 */
        !          41830:                if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
        !          41831:                        scsireset();
        !          41832:                        continue;
        !          41833:                }
        !          41834: 
        !          41835:                /*
        !          41836:                 * Arbitration complete.  Now select, with ATN to allow messages.
        !          41837:                 */
        !          41838:                sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          41839:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          41840: 
        !          41841:                if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          41842:                        continue;
        !          41843: 
        !          41844:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          41845: 
        !          41846:                if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          41847:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          41848:                        continue;
        !          41849: 
        !          41850:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          41851:                sfbyte(ss_dat, MSG_DEV_RESET);
        !          41852:                break;
        !          41853:        }
        !          41854:        for (tries = 0; tries < BDR_CHECK_COUNT; tries++) {
        !          41855:                if (ffbyte(ss_csr) == 0) {
        !          41856:                        printf("bus device reset done\n");
        !          41857:                        break;
        !          41858:                }
        !          41859:                ssdelay(BDR_CHECK_INTERVAL);
        !          41860:        }
        !          41861: }
        !          41862: @
        !          41863: 
        !          41864: 
        !          41865: 1.19
        !          41866: log
        !          41867: @Reads partition table in prototype code
        !          41868: @
        !          41869: text
        !          41870: @d1 2
        !          41871: d12 3
        !          41872: d626 2
        !          41873: d635 5
        !          41874: a639 1
        !          41875:        static int calls;
        !          41876: a640 7
        !          41877:        if (calls == 0)
        !          41878:                printf("*");
        !          41879:        calls++;
        !          41880:        if (calls >= 60)
        !          41881:                calls = 0;
        !          41882: }
        !          41883: 
        !          41884: d752 5
        !          41885: d759 1
        !          41886: a759 1
        !          41887:                } else
        !          41888: d761 9
        !          41889: d771 3
        !          41890: d840 8
        !          41891: a847 1
        !          41892: printf("Disconnected\n");
        !          41893: d853 1
        !          41894: a853 1
        !          41895: printf("Reconnected\n");
        !          41896: a998 1
        !          41897:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          41898: d1000 1
        !          41899: a1128 1
        !          41900: SSDUMP(ssp, "cmd");
        !          41901: @
        !          41902: 
        !          41903: 
        !          41904: 1.18
        !          41905: log
        !          41906: @first raw read - disconnects
        !          41907: @
        !          41908: text
        !          41909: @d10 3
        !          41910: d106 6
        !          41911: a112 1
        !          41912: #define MSG_ABORT      0x06    /* End the current SCSI bus cycle */
        !          41913: d144 1
        !          41914: a144 1
        !          41915: #define SSTATUS                printf("status=%x\n", (int)(unsigned char)status)
        !          41916: d228 1
        !          41917: d666 1
        !          41918: a666 1
        !          41919: PUSHI;
        !          41920: d681 1
        !          41921: a681 1
        !          41922:  * if Test Unit Ready command fails
        !          41923: d700 1
        !          41924: a700 1
        !          41925:        if (testready(s_id)) {
        !          41926: d702 8
        !          41927: a709 2
        !          41928:        } else
        !          41929:                devmsg(dev, "Test Unit Ready Failed");
        !          41930: d794 1
        !          41931: d796 55
        !          41932: a850 4
        !          41933:        if (retval = bus_pre_xfer(s_id)) {
        !          41934:                bus_info_xfer(ssp);
        !          41935:                retval = (ssp->cmdlen == ssp->cmd_bytes_out
        !          41936:                        && ssp->cmdstat == CS_GOOD);
        !          41937: a852 5
        !          41938:        if (ssp->cmdstat == CS_CHECK) {
        !          41939:                if (req_sense(s_id))
        !          41940:                        retval = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          41941:        }
        !          41942: 
        !          41943: d865 2
        !          41944: d869 1
        !          41945: d871 1
        !          41946: a871 1
        !          41947:        ssdelay(RESET_TICKS);
        !          41948: d873 1
        !          41949: a873 1
        !          41950:        ssdelay(RESET_TICKS);
        !          41951: a1002 2
        !          41952: int zzzz;
        !          41953: 
        !          41954: d1007 2
        !          41955: a1008 1
        !          41956:        unsigned char phase_type;
        !          41957: a1011 1
        !          41958: int zzgo=0;
        !          41959: d1016 1
        !          41960: a1018 4
        !          41961: if(zzgo) {
        !          41962:        zzgo = 0;
        !          41963:        printf("zzzz=%d\n", zzzz);
        !          41964: }
        !          41965: d1026 20
        !          41966: a1045 5
        !          41967:                        if (no_msg_rcvd) {
        !          41968:                                no_msg_rcvd = 0;
        !          41969:                                ssp->msg_in = ffbyte(ss_dat);
        !          41970:                        } else
        !          41971:                                ffbyte(ss_dat);
        !          41972: a1070 1
        !          41973: zzgo=1;
        !          41974: d1101 1
        !          41975: a1101 1
        !          41976: POPI;
        !          41977: d1137 1
        !          41978: a1137 2
        !          41979: PUSHI;
        !          41980: zzzz=i;
        !          41981: d1342 64
        !          41982: @
        !          41983: 
        !          41984: 
        !          41985: 1.17
        !          41986: log
        !          41987: @calls ssqueue functions - need real i/o
        !          41988: @
        !          41989: text
        !          41990: @d10 3
        !          41991: d263 1
        !          41992: a263 1
        !          41993: #define IN_BUF_SIZE    100
        !          41994: d283 1
        !          41995: a284 3
        !          41996:  * void
        !          41997:  * ssload()    - load routine.
        !          41998:  *
        !          41999: d288 1
        !          42000: a288 2
        !          42001: static void
        !          42002: ssload()
        !          42003: a361 1
        !          42004:  * void
        !          42005: d364 1
        !          42006: a364 2
        !          42007: static void
        !          42008: ssunload()
        !          42009: d384 1
        !          42010: a384 3
        !          42011:  * ssopen( dev, mode )
        !          42012:  * dev_t dev;
        !          42013:  * int mode;
        !          42014: d392 1
        !          42015: a392 2
        !          42016: static void
        !          42017: ssopen( dev, mode )
        !          42018: d453 1
        !          42019: a454 5
        !          42020:  * void
        !          42021:  * ssread( dev, iop )  - write a block to the raw disk
        !          42022:  * dev_t dev;
        !          42023:  * IO * iop;
        !          42024:  *
        !          42025: d460 1
        !          42026: a460 2
        !          42027: static void
        !          42028: ssread( dev, iop )
        !          42029: d468 1
        !          42030: a469 5
        !          42031:  * void
        !          42032:  * sswrite( dev, iop ) - write a block to the raw disk
        !          42033:  * dev_t dev;
        !          42034:  * IO * iop;
        !          42035:  *
        !          42036: d475 1
        !          42037: a475 2
        !          42038: static void
        !          42039: sswrite( dev, iop )
        !          42040: d483 1
        !          42041: a484 6
        !          42042:  * int
        !          42043:  * ssioctl( dev, cmd, arg )
        !          42044:  * dev_t dev;
        !          42045:  * int cmd;
        !          42046:  * char * vec;
        !          42047:  *
        !          42048: d492 1
        !          42049: a492 2
        !          42050: static int
        !          42051: ssioctl( dev, cmd, vec )
        !          42052: d509 1
        !          42053: a509 1
        !          42054:  * ssblock( bp )       - queue a block to the disk
        !          42055: d516 1
        !          42056: a516 2
        !          42057: static void
        !          42058: ssblock(bp)
        !          42059: d609 1
        !          42060: a609 2
        !          42061: static void
        !          42062: ssintr()
        !          42063: d617 1
        !          42064: a617 1
        !          42065: static void    sswatch()
        !          42066: d719 1
        !          42067: d728 11
        !          42068: d1241 28
        !          42069: @
        !          42070: 
        !          42071: 
        !          42072: 1.16
        !          42073: log
        !          42074: @Need to do more with ss_start()
        !          42075: @
        !          42076: text
        !          42077: @d10 3
        !          42078: d92 1
        !          42079: d108 6
        !          42080: d182 3
        !          42081: a184 3
        !          42082: int    nulldev();
        !          42083: int    nonedev();
        !          42084: unsigned char ffbyte();
        !          42085: d186 4
        !          42086: d215 2
        !          42087: d231 2
        !          42088: d235 2
        !          42089: a237 3
        !          42090: static int     ss_expired;     /* 1 after local timeout */
        !          42091: static scsi_work_t     *scsi_work_queue;
        !          42092: 
        !          42093: d276 1
        !          42094: d454 1
        !          42095: a454 1
        !          42096:        --drvl[SDMAJOR].d_time; 
        !          42097: d522 1
        !          42098: a522 1
        !          42099:                u.uerror = EINVAL;
        !          42100: d530 1
        !          42101: a531 3
        !          42102:  * void
        !          42103:  * ssblock( bp )       - queue a block to the disk
        !          42104:  *
        !          42105: d548 3
        !          42106: d579 13
        !          42107: a591 1
        !          42108:        } else if ( (bp->b_bno + (bp->b_count/BSIZE))
        !          42109: d600 1
        !          42110: a600 1
        !          42111:        if (sw == (scsi_work_t *)0) {
        !          42112: d615 1
        !          42113: a615 1
        !          42114:        drv, (long)sw->sw_bno, bp, bp->b_flag);
        !          42115: d617 4
        !          42116: a620 7
        !          42117:        s = sphi();
        !          42118:        if (sd.sw_actf == NULL)
        !          42119:                sd.sw_actf = sw;
        !          42120:        else
        !          42121:                sd.sw_actl->sw_actf = sw;
        !          42122:        sd.sw_actl = sw;
        !          42123:        spl(s);
        !          42124: a621 3
        !          42125:        ss_start();
        !          42126: }
        !          42127: 
        !          42128: a622 2
        !          42129:  *
        !          42130:  * void
        !          42131: a623 1
        !          42132:  *
        !          42133: d685 2
        !          42134: d744 5
        !          42135: a748 4
        !          42136:                if (retval)
        !          42137:                        printf("fdisk succeeded\n");
        !          42138:                else
        !          42139:                        printf("fdisk failed\n");
        !          42140: d836 2
        !          42141: d859 2
        !          42142: d1178 1
        !          42143: a1178 2
        !          42144:  * off the queue and try to send it to the drive.
        !          42145:  * If request is sent, delete it from the queue.
        !          42146: d1189 1
        !          42147: a1189 1
        !          42148:        if( locked ) {
        !          42149: d1196 8
        !          42150: a1203 8
        !          42151:        if( (sw = scsi_work_queue->sw_actf) != NULL ) {
        !          42152:                if (do_ss(sw)) {
        !          42153:                        s = sphi();
        !          42154:                        sw = scsi_work_queue->sw_actf = sw->sw_actf;
        !          42155:                        if( sw == NULL )
        !          42156:                                scsi_work_queue->sw_actl = NULL;
        !          42157:                        spl(s);
        !          42158:                }
        !          42159: d1207 45
        !          42160: @
        !          42161: 
        !          42162: 
        !          42163: 1.15
        !          42164: log
        !          42165: @getting ready to call fdisk - finish ss_start next
        !          42166: @
        !          42167: text
        !          42168: @d10 3
        !          42169: a532 1
        !          42170: 
        !          42171: d538 1
        !          42172: a538 1
        !          42173:        if (dev & SDEV )
        !          42174: d577 2
        !          42175: a578 3
        !          42176:        sw->sw_type = 0;
        !          42177:        if ( partition != WHOLE_DRIVE )
        !          42178:                sw->sw_bno   = fdp[partition].p_base + bp->b_bno;
        !          42179: d580 1
        !          42180: a580 1
        !          42181:                sw->sw_bno   = bp->b_bno;
        !          42182: d583 2
        !          42183: a584 2
        !          42184: printf( "ssblock: drv %x bno %x:%x  bp=%x, flag = %o\n",
        !          42185:        drv, (long)sw->sw_bno, bp, bp->b_flag );
        !          42186: a591 1
        !          42187:        ++drvl[SDMAJOR].d_time; 
        !          42188: d1147 6
        !          42189: d1156 1
        !          42190: a1156 1
        !          42191:        int i, s, n = 0;
        !          42192: d1168 8
        !          42193: a1175 19
        !          42194:        while( (sw = scsi_work_queue->sw_actf) != NULL ) {
        !          42195:                for( i = MIN_MAILBOX; i < MAX_MAILBOX; ++i )
        !          42196:                        if( mailbox_out[i].cmd == MBO_IS_FREE ) {
        !          42197:                                register ccb_t *ccb;
        !          42198:                                int s;
        !          42199: 
        !          42200:                                ++n;
        !          42201: SEND SCSI COMMAND
        !          42202:                                s = sphi();
        !          42203:                                sw = scsi_work_queue->sw_actf = sw->sw_actf;
        !          42204:                                if( sw == NULL )
        !          42205:                                        scsi_work_queue->sw_actl = NULL;
        !          42206:                                spl(s);
        !          42207: 
        !          42208:                                if( sw == NULL )
        !          42209:                                        break;
        !          42210:                        }
        !          42211:                if( i == MAX_MAILBOX )
        !          42212:                        break;
        !          42213: a1177 1
        !          42214:        return n;
        !          42215: @
        !          42216: 
        !          42217: 
        !          42218: 1.14
        !          42219: log
        !          42220: @Inquiry and Read Capacity working
        !          42221: @
        !          42222: text
        !          42223: @a4 1
        !          42224:  *     run scsicmd() at hi priority
        !          42225: a5 1
        !          42226:  *     put retry logic into arbitrate, etc.
        !          42227: d10 3
        !          42228: d53 1
        !          42229: d179 1
        !          42230: d197 1
        !          42231: d216 1
        !          42232: d225 1
        !          42233: a225 1
        !          42234:        nulldev,                        /* Close */
        !          42235: d254 2
        !          42236: a364 2
        !          42237:  *
        !          42238:  * void
        !          42239: d401 7
        !          42240: a407 4
        !          42241: #if 0
        !          42242:        if ( minor(dev) & SDEV ) {
        !          42243:                d = minor(dev) % NDRIVE;
        !          42244:                p += NDRIVE * NPARTN;
        !          42245: a408 2
        !          42246:        else
        !          42247:                d = minor(dev) / NPARTN;
        !          42248: a409 7
        !          42249:        if ( (d >= NDRIVE) || (at.at_dtype[d] == 0) ) {
        !          42250:                return;
        !          42251:        }
        !          42252: 
        !          42253:        if ( minor(dev) & SDEV )
        !          42254:                return;
        !          42255: 
        !          42256: d411 1
        !          42257: a411 1
        !          42258:         * If partition not defined read partition characteristics.
        !          42259: d413 4
        !          42260: a416 3
        !          42261:        if ( pparm[p].p_size == 0 )
        !          42262:                fdisk( makedev( major(dev), SDEV + d), &pparm[ d * NPARTN ] );
        !          42263: 
        !          42264: d428 9
        !          42265: d497 9
        !          42266: d522 73
        !          42267: d615 3
        !          42268: d620 7
        !          42269: a696 1
        !          42270:                        devmsg(dev, "Sense Requested");
        !          42271: a705 1
        !          42272:                                devmsg(dev, "Inquiry Complete");
        !          42273: a713 1
        !          42274:                        devmsg(dev, "Read Capacity Done");
        !          42275: d718 8
        !          42276: d755 2
        !          42277: d758 1
        !          42278: a758 1
        !          42279:  * Return 1 if command succeeds, else 0.
        !          42280: d771 1
        !          42281: a771 1
        !          42282: SSDUMP(ssp, "command sent");
        !          42283: d920 2
        !          42284: d928 3
        !          42285: d935 1
        !          42286: d937 4
        !          42287: d966 6
        !          42288: a971 2
        !          42289: #if 0
        !          42290:                        if (ssp->cmd_bytes_out < ssp->cmdlen)
        !          42291: d973 9
        !          42292: a981 1
        !          42293:                        else {  /* This case should not happen. */
        !          42294: a984 9
        !          42295: #else
        !          42296: {int diff = ssp->cmdlen - ssp->cmd_bytes_out;
        !          42297:        if(diff > 0) {
        !          42298:                sfbyte(ss_dat, ssp->cmdbuf[ssp->cmd_bytes_out++]);
        !          42299:                if (diff == 1)
        !          42300:                        ssdelay(1);
        !          42301:        }
        !          42302: }
        !          42303: #endif
        !          42304: d1008 1
        !          42305: d1046 1
        !          42306: d1081 1
        !          42307: a1081 1
        !          42308: SSDUMP((&rqs), "sense req");
        !          42309: d1107 1
        !          42310: a1107 1
        !          42311: SSDUMP(ssp, "inquiry");
        !          42312: d1141 1
        !          42313: a1141 1
        !          42314: SSDUMP(ssp, "read_cap");
        !          42315: d1144 41
        !          42316: @
        !          42317: 
        !          42318: 
        !          42319: 1.13
        !          42320: log
        !          42321: @add retry logic to scsicmd(); general cleanup
        !          42322: @
        !          42323: text
        !          42324: @d12 3
        !          42325: d82 1
        !          42326: a82 1
        !          42327: #define HIPRI_RETRIES  100     /* # of times to retry while hogging CPU */
        !          42328: d88 1
        !          42329: d190 4
        !          42330: a194 2
        !          42331: static void    ssintr();
        !          42332: 
        !          42333: d235 1
        !          42334: a235 1
        !          42335: #define IN_BUF_SIZE    22
        !          42336: d240 1
        !          42337: d557 1
        !          42338: a557 1
        !          42339: 
        !          42340: d589 1
        !          42341: a589 4
        !          42342:        if (!testready(s_id))
        !          42343:                devmsg(dev, "Test Unit Ready failed");
        !          42344:        else {
        !          42345:                devmsg(dev, "Unit initialized");
        !          42346: d591 29
        !          42347: a619 2
        !          42348:        }
        !          42349: POPI;
        !          42350: d665 2
        !          42351: a666 14
        !          42352:                if (bus_pre_xfer(s_id)) {
        !          42353:                        rqs.cmdbuf[0] = ScmdREQUESTSENSE;
        !          42354:                        rqs.cmdbuf[1] = rqs.cmdbuf[2] = rqs.cmdbuf[3] =
        !          42355:                                rqs.cmdbuf[5] = 0;
        !          42356:                                rqs.cmdbuf[4] = SENSELEN;
        !          42357:                        rqs.cmdlen = G0CMDLEN;
        !          42358:                        rqs.in_buf_len = SENSELEN;
        !          42359:                        bus_info_xfer(&rqs);
        !          42360:                        if (rqs.data_bytes_in == SENSELEN
        !          42361:                        && (rqs.in_buf[2] & 0x0F) == 0x06
        !          42362:                        && rqs.in_buf[12] == 0x29)
        !          42363:                                retval = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          42364:                }
        !          42365: SSDUMP((&rqs), "sense req");
        !          42366: d668 1
        !          42367: d677 1
        !          42368: d848 1
        !          42369: d855 9
        !          42370: d887 1
        !          42371: d926 95
        !          42372: @
        !          42373: 
        !          42374: 
        !          42375: 1.12
        !          42376: log
        !          42377: @Test Ready now works, including Req Sense
        !          42378: @
        !          42379: text
        !          42380: @d4 7
        !          42381: d12 3
        !          42382: d79 2
        !          42383: a80 1
        !          42384: #define BUS_RETRIES    1000
        !          42385: d109 2
        !          42386: a110 2
        !          42387: int stats[40], statsptr;
        !          42388: #define PUSHI          { stats[statsptr++] = i; }
        !          42389: d118 1
        !          42390: a118 1
        !          42391:        printf(" %x", ssp->cmdbuf[i]);printf(" cmd_bytes_out=%d\n",\
        !          42392: d184 2
        !          42393: d203 1
        !          42394: d205 2
        !          42395: d505 6
        !          42396: d514 1
        !          42397: a514 1
        !          42398:        printf("ss IRPT\n");
        !          42399: d540 1
        !          42400: a540 1
        !          42401:        for ( i = 0; i < BUS_RETRIES; i++) {
        !          42402: d581 1
        !          42403: a581 3
        !          42404: #if DEBUG
        !          42405: devmsg(dev, "ssinit invoked");
        !          42406: #endif
        !          42407: d585 1
        !          42408: a585 1
        !          42409:                devmsg(dev, "Unit successfully initialized");
        !          42410: d588 1
        !          42411: d608 2
        !          42412: a609 6
        !          42413: #define XXXX
        !          42414:        if (1 || !(retval = scsicmd(s_id))) {
        !          42415: printf("First Test Unit Ready failed.  Will reset SCSI bus.\n");
        !          42416:                scsireset();
        !          42417:                retval = scsicmd(s_id);
        !          42418:        }
        !          42419: d626 1
        !          42420: a626 1
        !          42421: SSTELL("enter scsicmd\n");
        !          42422: d646 1
        !          42423: a647 1
        !          42424:                }
        !          42425: d655 3
        !          42426: a657 1
        !          42427:  * Assert reset for 1 clock tick.
        !          42428: d659 1
        !          42429: d663 1
        !          42430: a663 1
        !          42431:        ssdelay(50);
        !          42432: d665 1
        !          42433: a665 1
        !          42434:        ssdelay(50);
        !          42435: d682 30
        !          42436: d720 3
        !          42437: a722 6
        !          42438:        /*
        !          42439:         * Do ST0x arbitration.
        !          42440:         */
        !          42441:        sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          42442:        sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          42443:        sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          42444: d724 7
        !          42445: a730 2
        !          42446:        if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL))
        !          42447:                return 0;
        !          42448: d732 8
        !          42449: a739 5
        !          42450:        /*
        !          42451:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          42452:         */
        !          42453:        sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          42454:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          42455: d741 5
        !          42456: a745 2
        !          42457:        if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          42458:                return 0;
        !          42459: d747 2
        !          42460: a748 4
        !          42461:        /*
        !          42462:         * Send "Identify" Message with Disconnect allowed.
        !          42463:         */
        !          42464:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          42465: d750 4
        !          42466: a753 3
        !          42467:        if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          42468:        | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          42469:                return 0;
        !          42470: d755 3
        !          42471: a757 2
        !          42472:        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          42473:        sfbyte(ss_dat, MSG_IDENT_DC);
        !          42474: d759 6
        !          42475: a764 1
        !          42476:        return 1;
        !          42477: d812 2
        !          42478: a813 1
        !          42479:                        }
        !          42480: d829 4
        !          42481: d877 1
        !          42482: a877 1
        !          42483:        for ( i = 0; i < BUS_RETRIES; i++) {
        !          42484: d891 1
        !          42485: a891 1
        !          42486: 
        !          42487: a893 95
        !          42488: 
        !          42489: #define STUFF 0
        !          42490: /* pieces of code temporarily without a home */
        !          42491: #if STUFF
        !          42492:        for (i = 0; i < CMDLEN; i++) {
        !          42493:                bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42494:                        (RS_REQUEST|RS_CTRL_DATA));
        !          42495:                sfbyte(ss_dat, cmd[i]);
        !          42496:        }
        !          42497: 
        !          42498:        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42499:                (RS_REQUEST|RS_CTRL_DATA|RS_I_O));
        !          42500:        data1 = ffbyte(ss_dat);
        !          42501:        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42502:                (RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE));
        !          42503:        data2 = ffbyte(ss_dat);
        !          42504: bus_wait(RS_BUSY << 8 | 0);
        !          42505: status = ffbyte(ss_csr);
        !          42506: SSTATUS;
        !          42507: printf("data1=%x data2=%x\n",data1,data2);
        !          42508: POPI;
        !          42509:        /*
        !          42510:         * If there was a check condition on the previous commmand,
        !          42511:         * do a Request Sense command.
        !          42512:         */
        !          42513:        if (data1 & CS_CHECK) {
        !          42514:                sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          42515:                sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          42516:                sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          42517: 
        !          42518:                bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL);
        !          42519: 
        !          42520:                /*
        !          42521:                 * Arbitration complete.  Now select, with ATN to allow messages.
        !          42522:                 */
        !          42523:                sfbyte(ss_dat, HOST_ID | 1);    /* Write two SCSI id's to port */
        !          42524:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          42525: 
        !          42526:                bus_wait(RS_BUSY << 8 | RS_BUSY);
        !          42527: 
        !          42528:                /*
        !          42529:                 * Send "Identify" Message with Disconnect allowed.
        !          42530:                 */
        !          42531:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          42532: 
        !          42533:                bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42534:                        (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE));
        !          42535: 
        !          42536:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          42537:                sfbyte(ss_dat, MSG_IDENT_DC);
        !          42538: 
        !          42539: for (i = 0; i < CMDLEN; i++) cmd[i] = 0; /* send Request Sense command */
        !          42540: cmd[0] = 3;  cmd[4] = SENSELEN;
        !          42541: 
        !          42542:                for (i = 0; i < CMDLEN; i++) {
        !          42543:                        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42544:                                (RS_REQUEST|RS_CTRL_DATA));
        !          42545:                        sfbyte(ss_dat, cmd[i]);
        !          42546:                }
        !          42547: 
        !          42548:                for (inbytes = 0; inbytes < SENSELEN;  inbytes++) {
        !          42549:                        if (bus_wait(
        !          42550:                        ((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42551:                        (RS_I_O)))
        !          42552:                                sense[inbytes] = ffbyte(ss_dat);
        !          42553:                        else
        !          42554:                                break;
        !          42555:                }
        !          42556:                bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42557:                        (RS_REQUEST|RS_CTRL_DATA|RS_I_O));
        !          42558:                data1 = ffbyte(ss_dat);
        !          42559:                bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42560:                        (RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE));
        !          42561:                data2 = ffbyte(ss_dat);
        !          42562: bus_wait(RS_BUSY << 8 | 0);
        !          42563: status = ffbyte(ss_csr);
        !          42564: SSTATUS;
        !          42565: printf("data1=%x data2=%x\n",data1,data2);
        !          42566: printf("%d:", inbytes);
        !          42567: for (i = 0; i < inbytes; i++) printf(" %x",sense[i]);
        !          42568: printf("\n");
        !          42569: POPI;
        !          42570:        }
        !          42571: 
        !          42572: #if 0
        !          42573: bus_wait(RS_REQUEST << 8 | RS_REQUEST);
        !          42574: #endif
        !          42575:        /*
        !          42576:         * Initialize Drive Size.
        !          42577:         */
        !          42578: 
        !          42579:        /*
        !          42580:         * Initialize Drive Controller.
        !          42581:         */
        !          42582: #endif
        !          42583: @
        !          42584: 
        !          42585: 
        !          42586: 1.11
        !          42587: log
        !          42588: @has trouble with Test Ready using bus_info_xfer fsa
        !          42589: @
        !          42590: text
        !          42591: @d5 3
        !          42592: d73 1
        !          42593: d104 2
        !          42594: a105 2
        !          42595: #define SSDUMP(s_id, text) {int i;struct ss*ssp=ss[s_id];\
        !          42596:        printf("%s: s_id=%d msg_in=%x cmdstat=%x\n", text, s_id, ssp->msg_in,\
        !          42597: d117 1
        !          42598: a117 1
        !          42599: #define SSDUMP(s_id, text)
        !          42600: d226 1
        !          42601: a226 1
        !          42602: } *ss[MAX_SCSI_ID-1];
        !          42603: d289 1
        !          42604: a289 1
        !          42605:                } else {
        !          42606: a290 3
        !          42607:                        printf("kalloc'ed %d bytes at offset %x\n",
        !          42608:                                num_drives*sizeof(struct ss), ss_block);
        !          42609:                }
        !          42610: d587 2
        !          42611: a588 1
        !          42612:        if (!(retval = scsicmd(s_id))) {
        !          42613: d609 1
        !          42614: a609 1
        !          42615: SSDUMP(s_id, "enter scsicmd");
        !          42616: d611 1
        !          42617: a611 1
        !          42618:                bus_info_xfer(s_id);
        !          42619: d615 17
        !          42620: a631 1
        !          42621: SSDUMP(s_id, "leave scsicmd");
        !          42622: d643 1
        !          42623: a643 1
        !          42624:        ssdelay(1);
        !          42625: d645 1
        !          42626: d728 2
        !          42627: a729 2
        !          42628: static int bus_info_xfer(s_id)
        !          42629: int s_id;
        !          42630: a733 1
        !          42631:        struct ss * ssp = ss[s_id];
        !          42632: a741 1
        !          42633: SSTELL("MSG_IN\n");
        !          42634: a751 1
        !          42635: SSTELL("MSG_OUT\n");
        !          42636: d760 1
        !          42637: a760 3
        !          42638: SSTELL("STAT_IN\n");
        !          42639:                        ssp->cmdstat = ffbyte(ss_csr);
        !          42640: goto foo;
        !          42641: a762 1
        !          42642: SSTELL("CMD_OUT\n");
        !          42643: a766 1
        !          42644: SSTELL("DATA_IN\n");
        !          42645: a778 1
        !          42646: SSTELL("DATA_OUT\n");
        !          42647: a787 1
        !          42648: foo:;
        !          42649: d821 1
        !          42650: a821 1
        !          42651:        if (!req_found)
        !          42652: @
        !          42653: 
        !          42654: 
        !          42655: 1.10
        !          42656: log
        !          42657: @still more to do on bus_info_xfer
        !          42658: @
        !          42659: text
        !          42660: @d5 3
        !          42661: d68 3
        !          42662: a70 1
        !          42663: #define CMDLEN         6
        !          42664: d87 1
        !          42665: a87 1
        !          42666: #define XP_CMD_IN      (             RS_I_O | RS_CTRL_DATA)
        !          42667: d100 8
        !          42668: d113 1
        !          42669: d150 1
        !          42670: d164 1
        !          42671: d166 1
        !          42672: a166 1
        !          42673: static void    scsidelay();
        !          42674: d209 3
        !          42675: d213 9
        !          42676: a221 2
        !          42677:        long capacity;
        !          42678:        unsigned char do_xfer;  /* bitmapped flags;  1=xfer needed */
        !          42679: d224 1
        !          42680: a224 1
        !          42681: /**
        !          42682: d558 3
        !          42683: a560 1
        !          42684: 
        !          42685: a578 1
        !          42686:        unsigned char cmd[CMDLEN];
        !          42687: d580 1
        !          42688: d582 5
        !          42689: a586 3
        !          42690:        cmd[0] = ScmdTESTREADY;
        !          42691:        cmd[1] = cmd[2] = cmd[3] = cmd[4] = cmd[5] = 0;
        !          42692:        if (!(retval = scsicmd(s_id, cmd))) {
        !          42693: d589 1
        !          42694: a589 1
        !          42695:                retval = scsicmd(s_id, cmd);
        !          42696: d597 2
        !          42697: a598 1
        !          42698:  * Send 6-byte command packet to target device.
        !          42699: d602 1
        !          42700: a602 1
        !          42701: static int scsicmd(s_id, cmd)
        !          42702: a603 1
        !          42703: unsigned char *cmd;
        !          42704: d606 8
        !          42705: a613 3
        !          42706: 
        !          42707:        if (retval = bus_pre_xfer(s_id))
        !          42708:                retval = bus_info_xfer(cmd);
        !          42709: d625 1
        !          42710: a625 1
        !          42711:        scsidelay(1);
        !          42712: d630 1
        !          42713: a630 1
        !          42714:  * scsidelay()
        !          42715: d694 1
        !          42716: a694 1
        !          42717:  * Return 1 if command executed successfully, else 0.
        !          42718: d709 2
        !          42719: a710 3
        !          42720: static int bus_info_xfer(cmdbuf, cmdlen)
        !          42721: char * cmdbuf;
        !          42722: int cmdlen;
        !          42723: a711 1
        !          42724:        int ret;
        !          42725: d714 2
        !          42726: d717 3
        !          42727: d723 52
        !          42728: a774 14
        !          42729:                        case XP_MSG_IN:
        !          42730:                                break;
        !          42731:                        case XP_MSG_OUT:
        !          42732:                                break;
        !          42733:                        case XP_CMD_IN:
        !          42734:                                break;
        !          42735:                        case XP_CMD_OUT:
        !          42736:                                break;
        !          42737:                        case XP_DATA_IN:
        !          42738:                                break;
        !          42739:                        case XP_DATA_OUT:
        !          42740:                                break;
        !          42741:                        default:
        !          42742:                                break;
        !          42743: d777 2
        !          42744: a778 1
        !          42745:        return (cmdlen == 0);
        !          42746: @
        !          42747: 
        !          42748: 
        !          42749: 1.9
        !          42750: log
        !          42751: @need to finish bus_info_xfer()
        !          42752: @
        !          42753: text
        !          42754: @d5 3
        !          42755: d75 12
        !          42756: d151 2
        !          42757: a152 2
        !          42758: static int     bus_pre_xfer(s_id);
        !          42759: static int     bus_info_xfer(s_id);
        !          42760: d664 8
        !          42761: a671 7
        !          42762:  *  if (BUSY false)
        !          42763:  *    break from while loop
        !          42764:  *  else
        !          42765:  *    switch (xfer phase = RS_CTRL_DATA|RS_I_O|RS_MESSAGE)
        !          42766:  *      case XP_MSG_IN/XP_MSG_OUT/...
        !          42767:  *        handle the indicated information transfer phase
        !          42768:  *    endswitch
        !          42769: d680 1
        !          42770: d683 17
        !          42771: a699 1
        !          42772:                
        !          42773: @
        !          42774: 
        !          42775: 
        !          42776: 1.8
        !          42777: log
        !          42778: @started ssopen()/wrote stub for ssinit()
        !          42779: @
        !          42780: text
        !          42781: @d5 3
        !          42782: d62 1
        !          42783: d133 5
        !          42784: a137 1
        !          42785: static void    ssinit();
        !          42786: d152 3
        !          42787: a154 2
        !          42788: static int num_drives;
        !          42789: static struct ss *ss_block;            /* points to block of "ss" structs */
        !          42790: d180 1
        !          42791: a180 1
        !          42792:        char scsi_id;
        !          42793: d237 5
        !          42794: a241 1
        !          42795:                if ((ss_block = kalloc(num_drives*sizeof(struct ss))) == NULL) {
        !          42796: d244 5
        !          42797: a248 2
        !          42798:                } else
        !          42799:                        kclear(ssblock, num_drives * sizeof(struct ss));
        !          42800: d251 1
        !          42801: a251 1
        !          42802:                struct ss *foo = ssblock;
        !          42803: d278 2
        !          42804: a279 1
        !          42805:        kfree(ssblock);
        !          42806: d382 1
        !          42807: a382 1
        !          42808: /**
        !          42809: d402 1
        !          42810: a402 1
        !          42811: /**
        !          42812: d425 1
        !          42813: a425 1
        !          42814: /**
        !          42815: d441 1
        !          42816: a441 1
        !          42817: /**
        !          42818: d458 2
        !          42819: a486 1
        !          42820: PUSHI;
        !          42821: d493 18
        !          42822: d512 1
        !          42823: a512 1
        !          42824: static void ssinit(s_id)
        !          42825: d515 10
        !          42826: d527 47
        !          42827: a573 8
        !          42828: #define STUFF 0
        !          42829: /* pieces of code temporarily without a home */
        !          42830: #if STUFF
        !          42831: #if 0
        !          42832: { long x;
        !          42833:        /*
        !          42834:         * Reset the SCSI bus.
        !          42835:         */
        !          42836: d575 1
        !          42837: a575 1
        !          42838:        for (x=0; x<100000L; x++);
        !          42839: a576 1
        !          42840:        for (x=0; x<100000L; x++);
        !          42841: a577 1
        !          42842: #endif
        !          42843: d579 22
        !          42844: d608 2
        !          42845: a609 1
        !          42846:        bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL);
        !          42847: d614 1
        !          42848: a614 1
        !          42849:        sfbyte(ss_dat, HOST_ID | 1);    /* Write two SCSI id's to port */
        !          42850: d617 2
        !          42851: a618 1
        !          42852:        bus_wait(RS_BUSY << 8 | RS_BUSY);
        !          42853: d625 3
        !          42854: a627 2
        !          42855:        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42856:                (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE));
        !          42857: d629 1
        !          42858: a629 2
        !          42859: #ifdef SEND_ABORT_MESSAGE
        !          42860:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          42861: d632 2
        !          42862: a633 7
        !          42863:        /*
        !          42864:         * Second message is Abort.
        !          42865:         */
        !          42866:        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42867:                (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE));
        !          42868:        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          42869:        sfbyte(ss_dat, MSG_ABORT);
        !          42870: d635 29
        !          42871: a663 4
        !          42872:        bus_wait(RS_BUSY << 8 | RS_BUSY);
        !          42873: #else
        !          42874:        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          42875:        sfbyte(ss_dat, MSG_IDENT_DC);
        !          42876: d665 21
        !          42877: a685 1
        !          42878: for (i = 0; i < CMDLEN; i++) cmd[i] = 0; /* send Test Unit Ready command */
        !          42879: d687 23
        !          42880: a714 1
        !          42881: #endif
        !          42882: @
        !          42883: 
        !          42884: 
        !          42885: 1.7
        !          42886: log
        !          42887: @Does Test Read and Request Sense properly.
        !          42888: @
        !          42889: text
        !          42890: @d5 3
        !          42891: d25 5
        !          42892: d68 2
        !          42893: a69 1
        !          42894: #if 1
        !          42895: d108 3
        !          42896: a110 2
        !          42897: int    SS_INT = 5;             /* ST01/ST02 use either IRQ3 or IRQ5 */
        !          42898: int    SS_BASE_SEG = 0xDE00;   /* Start of memory-mapped communication area */
        !          42899: d129 1
        !          42900: a130 1
        !          42901: static void    ssreset();
        !          42902: d144 3
        !          42903: d166 8
        !          42904: d185 1
        !          42905: a186 8
        !          42906:        char status;
        !          42907:        int await_bus;
        !          42908:        int data1, data2;
        !          42909:        int inbytes;
        !          42910: #define CMDLEN         6
        !          42911: #define SENSELEN       22
        !          42912:        unsigned char cmd[CMDLEN];
        !          42913:        unsigned char sense[SENSELEN];
        !          42914: d196 1
        !          42915: a196 1
        !          42916:        ss_base = (paddr_t)((long)(unsigned)SS_BASE_SEG << 4);
        !          42917: d215 2
        !          42918: a216 3
        !          42919:                return;
        !          42920:        } else
        !          42921:                printf("ST0x passed memory test\n");
        !          42922: a217 2
        !          42923: #if 0
        !          42924: { long x;
        !          42925: d219 4
        !          42926: a222 1
        !          42927:         * Reset the SCSI bus.
        !          42928: d224 12
        !          42929: a235 6
        !          42930:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          42931:        for (x=0; x<100000L; x++);
        !          42932:        sfbyte(ss_csr, 0);
        !          42933:        for (x=0; x<100000L; x++);
        !          42934: }
        !          42935: #endif
        !          42936: d237 5
        !          42937: d243 1
        !          42938: a243 1
        !          42939:         * Do ST0x arbitration.
        !          42940: d245 6
        !          42941: a250 3
        !          42942:        sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          42943:        sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          42944:        sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          42945: a251 130
        !          42946:        bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL);
        !          42947: 
        !          42948:        /*
        !          42949:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          42950:         */
        !          42951:        sfbyte(ss_dat, HOST_ID | 1);    /* Write two SCSI id's to port */
        !          42952:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          42953: 
        !          42954:        bus_wait(RS_BUSY << 8 | RS_BUSY);
        !          42955: 
        !          42956:        /*
        !          42957:         * Send "Identify" Message with Disconnect allowed.
        !          42958:         */
        !          42959:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          42960: 
        !          42961:        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42962:                (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE));
        !          42963: 
        !          42964: #ifdef SEND_ABORT_MESSAGE
        !          42965:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          42966:        sfbyte(ss_dat, MSG_IDENT_DC);
        !          42967: 
        !          42968:        /*
        !          42969:         * Second message is Abort.
        !          42970:         */
        !          42971:        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42972:                (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE));
        !          42973:        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          42974:        sfbyte(ss_dat, MSG_ABORT);
        !          42975: 
        !          42976:        bus_wait(RS_BUSY << 8 | RS_BUSY);
        !          42977: #else
        !          42978:        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          42979:        sfbyte(ss_dat, MSG_IDENT_DC);
        !          42980: 
        !          42981: for (i = 0; i < CMDLEN; i++) cmd[i] = 0; /* send Test Unit Ready command */
        !          42982: 
        !          42983:        for (i = 0; i < CMDLEN; i++) {
        !          42984:                bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42985:                        (RS_REQUEST|RS_CTRL_DATA));
        !          42986:                sfbyte(ss_dat, cmd[i]);
        !          42987:        }
        !          42988: #endif
        !          42989: 
        !          42990:        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42991:                (RS_REQUEST|RS_CTRL_DATA|RS_I_O));
        !          42992:        data1 = ffbyte(ss_dat);
        !          42993:        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          42994:                (RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE));
        !          42995:        data2 = ffbyte(ss_dat);
        !          42996: bus_wait(RS_BUSY << 8 | 0);
        !          42997: status = ffbyte(ss_csr);
        !          42998: SSTATUS;
        !          42999: printf("data1=%x data2=%x\n",data1,data2);
        !          43000: POPI;
        !          43001:        /*
        !          43002:         * If there was a check condition on the previous commmand,
        !          43003:         * do a Request Sense command.
        !          43004:         */
        !          43005:        if (data1 & CS_CHECK) {
        !          43006:                sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          43007:                sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          43008:                sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          43009: 
        !          43010:                bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL);
        !          43011: 
        !          43012:                /*
        !          43013:                 * Arbitration complete.  Now select, with ATN to allow messages.
        !          43014:                 */
        !          43015:                sfbyte(ss_dat, HOST_ID | 1);    /* Write two SCSI id's to port */
        !          43016:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          43017: 
        !          43018:                bus_wait(RS_BUSY << 8 | RS_BUSY);
        !          43019: 
        !          43020:                /*
        !          43021:                 * Send "Identify" Message with Disconnect allowed.
        !          43022:                 */
        !          43023:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          43024: 
        !          43025:                bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          43026:                        (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE));
        !          43027: 
        !          43028:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          43029:                sfbyte(ss_dat, MSG_IDENT_DC);
        !          43030: 
        !          43031: for (i = 0; i < CMDLEN; i++) cmd[i] = 0; /* send Request Sense command */
        !          43032: cmd[0] = 3;  cmd[4] = SENSELEN;
        !          43033: 
        !          43034:                for (i = 0; i < CMDLEN; i++) {
        !          43035:                        bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          43036:                                (RS_REQUEST|RS_CTRL_DATA));
        !          43037:                        sfbyte(ss_dat, cmd[i]);
        !          43038:                }
        !          43039: 
        !          43040:                for (inbytes = 0; inbytes < SENSELEN;  inbytes++) {
        !          43041:                        if (bus_wait(
        !          43042:                        ((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          43043:                        (RS_I_O)))
        !          43044:                                sense[inbytes] = ffbyte(ss_dat);
        !          43045:                        else
        !          43046:                                break;
        !          43047:                }
        !          43048:                bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          43049:                        (RS_REQUEST|RS_CTRL_DATA|RS_I_O));
        !          43050:                data1 = ffbyte(ss_dat);
        !          43051:                bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8) |
        !          43052:                        (RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE));
        !          43053:                data2 = ffbyte(ss_dat);
        !          43054: bus_wait(RS_BUSY << 8 | 0);
        !          43055: status = ffbyte(ss_csr);
        !          43056: SSTATUS;
        !          43057: printf("data1=%x data2=%x\n",data1,data2);
        !          43058: printf("%d:", inbytes);
        !          43059: for (i = 0; i < inbytes; i++) printf(" %x",sense[i]);
        !          43060: printf("\n");
        !          43061: POPI;
        !          43062:        }
        !          43063: 
        !          43064: #if 0
        !          43065: bus_wait(RS_REQUEST << 8 | RS_REQUEST);
        !          43066: #endif
        !          43067:        /*
        !          43068:         * Initialize Drive Size.
        !          43069:         */
        !          43070: 
        !          43071:        /*
        !          43072:         * Initialize Drive Controller.
        !          43073:         */
        !          43074: }
        !          43075: 
        !          43076: d260 1
        !          43077: a260 1
        !          43078:         * Release IRQ vector.
        !          43079: d262 1
        !          43080: a262 1
        !          43081:        clrivec(SS_INT);
        !          43082: d268 5
        !          43083: d275 1
        !          43084: a275 1
        !          43085: /**
        !          43086: a277 10
        !          43087:  * ssreset()   -- reset hard disk controller, define drive characteristics.
        !          43088:  */
        !          43089: static void
        !          43090: ssreset()
        !          43091: {
        !          43092: }
        !          43093: 
        !          43094: /**
        !          43095:  *
        !          43096:  * void
        !          43097: d292 51
        !          43098: d345 1
        !          43099: a345 1
        !          43100: /**
        !          43101: d471 161
        !          43102: @
        !          43103: 
        !          43104: 
        !          43105: 1.6
        !          43106: log
        !          43107: @sends Test Ready, Starts to Request Sense
        !          43108: @
        !          43109: text
        !          43110: @d5 3
        !          43111: d168 3
        !          43112: a170 1
        !          43113: #define CMDLEN 6
        !          43114: d172 1
        !          43115: d205 1
        !          43116: a205 1
        !          43117: #if 1
        !          43118: d274 1
        !          43119: a274 1
        !          43120: bus_wait(RS_BUSY, 0);
        !          43121: d309 2
        !          43122: a310 2
        !          43123: for (i = 0; i < CMDLEN; i++) cmd[i] = 0; /* send Test Unit Ready command */
        !          43124: cmd[0] = 3;
        !          43125: d318 8
        !          43126: d332 1
        !          43127: a332 1
        !          43128: bus_wait(RS_BUSY, 0);
        !          43129: d336 3
        !          43130: @
        !          43131: 
        !          43132: 
        !          43133: 1.5
        !          43134: log
        !          43135: @Now sends Identify and Abort messages & completes a SCSI bus cycle
        !          43136: @
        !          43137: text
        !          43138: @d5 3
        !          43139: d10 1
        !          43140: a10 1
        !          43141:  * 
        !          43142: d13 1
        !          43143: a13 1
        !          43144:  * 
        !          43145: d15 1
        !          43146: a15 1
        !          43147:  
        !          43148: d35 1
        !          43149: a35 1
        !          43150:  
        !          43151: d46 3
        !          43152: a48 1
        !          43153: #define BUS_RETRIES    10000
        !          43154: d50 7
        !          43155: a56 2
        !          43156: #define MSG_ABORT      0x06    /* Identify, with Disconnect allowed */
        !          43157:  
        !          43158: d58 4
        !          43159: d65 2
        !          43160: d73 1
        !          43161: a73 1
        !          43162:  */ 
        !          43163: d92 1
        !          43164: a92 1
        !          43165:  
        !          43166: d164 3
        !          43167: d171 2
        !          43168: a172 2
        !          43169:        setivec(SS_INT, ssintr); 
        !          43170:        
        !          43171: d198 1
        !          43172: a198 1
        !          43173:                
        !          43174: d208 1
        !          43175: a208 1
        !          43176: }      
        !          43177: d210 1
        !          43178: a210 1
        !          43179:         
        !          43180: d213 1
        !          43181: a213 1
        !          43182:         */     
        !          43183: d218 1
        !          43184: a218 10
        !          43185:        for ( i = 0, await_bus = 1; await_bus && i < BUS_RETRIES; i++) {
        !          43186:                status = ffbyte(ss_csr);
        !          43187:                if (status & RS_ARBIT_COMPL) {
        !          43188:                        await_bus = 0;
        !          43189:                }
        !          43190:        }
        !          43191:        if (await_bus) {
        !          43192:                printf("Error - ST0x doesn't complete arbitration\n");
        !          43193:                return;
        !          43194:        }
        !          43195: a224 11
        !          43196:        
        !          43197:        for ( i = 0, await_bus = 1; await_bus && i < BUS_RETRIES; i++) {
        !          43198:                status = ffbyte(ss_csr);
        !          43199:                if (status & RS_BUSY) {
        !          43200:                        await_bus = 0;
        !          43201:                }
        !          43202:        }
        !          43203:        if (await_bus) {
        !          43204:                printf("Error - ST0x drive doesn't assert BUSY\n");
        !          43205:                return;
        !          43206:        }
        !          43207: d226 2
        !          43208: d230 1
        !          43209: a230 1
        !          43210:         */     
        !          43211: a231 11
        !          43212:        for ( i = 0, await_bus = 1; await_bus && i < BUS_RETRIES; i++) {
        !          43213:                status = ffbyte(ss_csr);
        !          43214:                if ((status & (RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE)) ==
        !          43215:                        (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)) {
        !          43216:                        await_bus = 0;
        !          43217:                }
        !          43218:        }
        !          43219:        if (await_bus) {
        !          43220:                printf("Error - ST0x didn't enter MSG out\n");
        !          43221:                return;
        !          43222:        }
        !          43223: d233 4
        !          43224: d239 1
        !          43225: a239 1
        !          43226:        
        !          43227: d243 2
        !          43228: a244 11
        !          43229:        for ( i = 0, await_bus = 1; await_bus && i < BUS_RETRIES; i++) {
        !          43230:                status = ffbyte(ss_csr);
        !          43231:                if ((status & (RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE)) ==
        !          43232:                        (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)) {
        !          43233:                        await_bus = 0;
        !          43234:                }
        !          43235:        }
        !          43236:        if (await_bus) {
        !          43237:                printf("Error - ST0x didn't enter MSG out 2nd time\n");
        !          43238:                return;
        !          43239:        }
        !          43240: d248 62
        !          43241: a309 4
        !          43242:        for ( i = 0, await_bus = 1; await_bus && i < BUS_RETRIES; i++) {
        !          43243:                status = ffbyte(ss_csr);
        !          43244:                if ((status & RS_BUSY) == 0) {
        !          43245:                        await_bus = 0;
        !          43246: d311 12
        !          43247: d324 1
        !          43248: a324 4
        !          43249:        if (await_bus) {
        !          43250:                printf("Error - ST0x didn't go to Bus Free state\n");
        !          43251:                return;
        !          43252:        }
        !          43253: d326 2
        !          43254: a327 14
        !          43255:        for ( i = 0, await_bus = 1; await_bus && i < BUS_RETRIES; i++) {
        !          43256:                status = ffbyte(ss_csr);
        !          43257:                if (status & RS_REQUEST) {
        !          43258:                        await_bus = 0;
        !          43259:                }
        !          43260:        }
        !          43261:        if (await_bus) {
        !          43262:                printf("Error - ST0x didn't REQ after Identify msg\n");
        !          43263:                return;
        !          43264:        }
        !          43265: #endif 
        !          43266: SSTATUS;
        !          43267: printf("i=%d\n", i);
        !          43268:        
        !          43269: d347 2
        !          43270: a348 2
        !          43271:        clrivec(SS_INT); 
        !          43272:         
        !          43273: d352 1
        !          43274: a352 1
        !          43275:        vrelse(ss_fp); 
        !          43276: d478 32
        !          43277: @
        !          43278: 
        !          43279: 
        !          43280: 1.4
        !          43281: log
        !          43282: @tried to send Identify message - get status 0x40 & fail
        !          43283: @
        !          43284: text
        !          43285: @d5 3
        !          43286: d45 1
        !          43287: d49 1
        !          43288: d52 1
        !          43289: d186 1
        !          43290: a186 1
        !          43291:        for (x=0; x<1000000L; x++);
        !          43292: d188 3
        !          43293: a190 3
        !          43294:        for (x=0; x<1000000L; x++);
        !          43295: }
        !          43296: #endif 
        !          43297: d195 1
        !          43298: a195 1
        !          43299:        sfbyte(ss_csr, WC_ENABLE_PRTY); /* De-assert SCSI enable bit */
        !          43300: d197 1
        !          43301: a197 1
        !          43302:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ARBITRATE);  /* Start arbitration */
        !          43303: d199 1
        !          43304: a199 1
        !          43305:        for ( i = 0, await_bus = 1; i < BUS_RETRIES; i++) {
        !          43306: a208 1
        !          43307: SSTELL("Arbitration complete\n");
        !          43308: d214 1
        !          43309: a214 1
        !          43310:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SELECT | WC_ENABLE_PRTY);
        !          43311: d216 1
        !          43312: a216 1
        !          43313:        for ( i = 0, await_bus = 1; i < BUS_RETRIES; i++) {
        !          43314: d230 2
        !          43315: a231 2
        !          43316:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          43317:        for ( i = 0, await_bus = 1; i < BUS_RETRIES; i++) {
        !          43318: d233 1
        !          43319: a233 1
        !          43320:                if (status & (RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) ==
        !          43321: a236 2
        !          43322:                if (status & (RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE))
        !          43323:                        break;
        !          43324: a237 1
        !          43325: SSTELL("status=%x\n"); 
        !          43326: a241 1
        !          43327: SSTELL("MSG out phase entered.\n");
        !          43328: d243 1
        !          43329: a243 1
        !          43330:        sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
        !          43331: d245 17
        !          43332: a261 1
        !          43333: SSTELL("Identify MSG sent\n");
        !          43334: d263 1
        !          43335: a263 1
        !          43336:        for ( i = 0, await_bus = 1; i < BUS_RETRIES; i++) {
        !          43337: d265 11
        !          43338: a279 1
        !          43339: SSTELL("status=%x\n"); 
        !          43340: d284 3
        !          43341: a286 1
        !          43342: SSTELL("REQ hanging\n");
        !          43343: @
        !          43344: 
        !          43345: 
        !          43346: 1.3
        !          43347: log
        !          43348: @Goes thru arbitration (sans IRQ) successfully
        !          43349: @
        !          43350: text
        !          43351: @d4 4
        !          43352: a7 1
        !          43353:  * $Log$
        !          43354: d40 2
        !          43355: a41 1
        !          43356: #define BUS_RETRIES    100
        !          43357: d43 6
        !          43358: d173 3
        !          43359: d177 11
        !          43360: a187 3
        !          43361:         * Check out Bus Stuff.
        !          43362:         *
        !          43363:         * First, do ST0x arbitration.
        !          43364: d189 1
        !          43365: a189 1
        !          43366:        sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          43367: d191 1
        !          43368: a191 1
        !          43369:        sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          43370: d203 7
        !          43371: a210 3
        !          43372:        sfbyte(ss_dat, HOST_ID | 1);    /* Write two SCSI id's to port */
        !          43373:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SELECT);
        !          43374:        
        !          43375: d220 1
        !          43376: a220 2
        !          43377:        } else
        !          43378:                printf("Arbitration phase succeeded.\n");
        !          43379: d223 37
        !          43380: @
        !          43381: 
        !          43382: 
        !          43383: 1.2
        !          43384: log
        !          43385: @Loads ok, tests Parameter RAM ok.
        !          43386: @
        !          43387: text
        !          43388: @d4 1
        !          43389: d17 9
        !          43390: d27 12
        !          43391: d55 1
        !          43392: d129 4
        !          43393: d163 8
        !          43394: d172 26
        !          43395: d342 1
        !          43396: @
        !          43397: 
        !          43398: 
        !          43399: 1.1
        !          43400: log
        !          43401: @Skeleton - just allocates selector and grabs IRQ
        !          43402: @
        !          43403: text
        !          43404: @d21 4
        !          43405: a24 3
        !          43406: #include       <sys/fdisk.h>
        !          43407: #include       <sys/hdioctl.h>
        !          43408: #include       <sys/buf.h>
        !          43409: d27 1
        !          43410: a27 1
        !          43411: #include       <sys/uproc.h>
        !          43412: a28 1
        !          43413: #include       <devices.h>             /* SCSI_MAJOR */
        !          43414: d30 4
        !          43415: d42 1
        !          43416: a42 1
        !          43417: int    SS_BASE_SEG = 0xDC00    /* Start of memory-mapped communication area */
        !          43418: d91 2
        !          43419: a92 1
        !          43420:        ssunload                        /* Unload */
        !          43421: d114 1
        !          43422: a114 1
        !          43423:        ss_base = (paddr_t)SS_BASE_SEG << 4;
        !          43424: d122 16
        !          43425: d282 4
        !          43426: @
        !          43427: 0707070064030104141004440000030000030000011777770507310660100006100000205103/newbits/kernel/USRSRC/i8086/drv/RCS/ss21_35.c,vhead     1.35;
        !          43428: access   ;
        !          43429: symbols  ;
        !          43430: locks    ;
        !          43431: comment  @ * @;
        !          43432: 
        !          43433: 
        !          43434: 1.35
        !          43435: date     91.04.20.01.35.52;  author root;  state Exp;
        !          43436: branches ;
        !          43437: next   1.34;
        !          43438: 
        !          43439: 1.34
        !          43440: date     91.04.19.09.41.40;  author root;  state Exp;
        !          43441: branches ;
        !          43442: next   1.33;
        !          43443: 
        !          43444: 1.33
        !          43445: date     91.04.17.14.15.48;  author root;  state Exp;
        !          43446: branches ;
        !          43447: next   1.32;
        !          43448: 
        !          43449: 1.32
        !          43450: date     91.04.17.04.07.21;  author root;  state Exp;
        !          43451: branches ;
        !          43452: next   1.31;
        !          43453: 
        !          43454: 1.31
        !          43455: date     91.04.17.03.16.33;  author root;  state Exp;
        !          43456: branches ;
        !          43457: next   1.30;
        !          43458: 
        !          43459: 1.30
        !          43460: date     91.04.17.02.17.43;  author root;  state Exp;
        !          43461: branches ;
        !          43462: next   1.29;
        !          43463: 
        !          43464: 1.29
        !          43465: date     91.04.16.22.40.19;  author root;  state Exp;
        !          43466: branches ;
        !          43467: next   1.28;
        !          43468: 
        !          43469: 1.28
        !          43470: date     91.04.16.20.48.47;  author root;  state Exp;
        !          43471: branches ;
        !          43472: next   1.27;
        !          43473: 
        !          43474: 1.27
        !          43475: date     91.04.16.16.38.47;  author root;  state Exp;
        !          43476: branches ;
        !          43477: next   1.26;
        !          43478: 
        !          43479: 1.26
        !          43480: date     91.04.16.16.13.10;  author root;  state Exp;
        !          43481: branches ;
        !          43482: next   1.25;
        !          43483: 
        !          43484: 1.25
        !          43485: date     91.04.16.01.45.35;  author root;  state Exp;
        !          43486: branches ;
        !          43487: next   1.24;
        !          43488: 
        !          43489: 1.24
        !          43490: date     91.04.12.17.19.25;  author root;  state Exp;
        !          43491: branches ;
        !          43492: next   1.23;
        !          43493: 
        !          43494: 1.23
        !          43495: date     91.04.11.12.51.50;  author root;  state Exp;
        !          43496: branches ;
        !          43497: next   1.22;
        !          43498: 
        !          43499: 1.22
        !          43500: date     91.04.10.16.55.59;  author root;  state Exp;
        !          43501: branches ;
        !          43502: next   1.21;
        !          43503: 
        !          43504: 1.21
        !          43505: date     91.04.10.15.21.41;  author root;  state Exp;
        !          43506: branches ;
        !          43507: next   1.20;
        !          43508: 
        !          43509: 1.20
        !          43510: date     91.04.09.14.23.49;  author root;  state Exp;
        !          43511: branches ;
        !          43512: next   ;
        !          43513: 
        !          43514: 
        !          43515: desc
        !          43516: @Seagate ST01/ST02 hard disk SCSI device driver.
        !          43517: @
        !          43518: 
        !          43519: 
        !          43520: 1.35
        !          43521: log
        !          43522: @ssinit() - improved error recovery.
        !          43523: @
        !          43524: text
        !          43525: @#define MAXSSERR 3
        !          43526: static int sserrct;
        !          43527: /*
        !          43528:  * This is a driver for Seagate ST01/ST02 scsi host adapters.
        !          43529:  *
        !          43530:  * To do:
        !          43531:  * 1.  fix ss_rw() error recovery
        !          43532:  * 2.  reduce number of ss_rw() write errors
        !          43533:  * 3.  figure out what to do about drive parameters (HDGETA)
        !          43534:  * 4.  bootable driver, without/with "at" device(s)
        !          43535:  * 5.  rewrite data_in/data_out transfer phases in assembler
        !          43536:  * 6.  investigate queueing - see if sorting requests will help
        !          43537:  * 7.  use different queues for different SCSI id's
        !          43538:  * 8.  look into kernel for mystery of lost EOI's on IRQ 5.
        !          43539:  *
        !          43540:  * $Log:       /usr/src/sys/i8086/drv/RCS/ss.c,v $
        !          43541:  * Revision 1.34       91/04/19  09:41:40      root
        !          43542:  * Better error recovery, but needs work.
        !          43543:  * 
        !          43544:  * Revision 1.33       91/04/17  14:15:48      root
        !          43545:  * Starting to fix retry mechanism on ss_rw().
        !          43546:  * 
        !          43547:  * Revision 1.32       91/04/17  04:07:21      root
        !          43548:  * Accesses file system but has frequent BFERR 5's.
        !          43549:  * 
        !          43550:  * Revision 1.31       91/04/17  03:16:33      root
        !          43551:  * Now fdisk command works but mkfs fails.
        !          43552:  * 
        !          43553:  * Revision 1.30       91/04/17  02:17:43      root
        !          43554:  * Trying to figure out disconnect after write.
        !          43555:  * 
        !          43556:  * Revision 1.29       91/04/16  22:40:19      root
        !          43557:  * Whole disk devices working - need to implement HDGETA.
        !          43558:  * 
        !          43559:  * Revision 1.28       91/04/16  20:48:47      root
        !          43560:  * Kernel fdisk works, fdisk command gets garbage.
        !          43561:  * 
        !          43562:  * Revision 1.27       91/04/16  16:38:47      root
        !          43563:  * Typos fixed.  Locks up CPU on first open
        !          43564:  * 
        !          43565:  * Revision 1.26       91/04/16  16:13:10      root
        !          43566:  * First clean compile with block routine.
        !          43567:  * 
        !          43568:  * Revision 1.25       91/04/16  01:45:35      root
        !          43569:  * lots of strategy code added - but not ready to compile
        !          43570:  * 
        !          43571:  * Revision 1.24       91/04/12  17:19:25      root
        !          43572:  * Some rearrangements - still working on block & related routines
        !          43573:  * 
        !          43574:  * Revision 1.23       91/04/11  12:51:50      root
        !          43575:  * ssopen compiles - not tested
        !          43576:  * 
        !          43577:  * Revision 1.22       91/04/10  16:55:59      root
        !          43578:  * Starting to get block operations working.
        !          43579:  * 
        !          43580:  * Revision 1.21       91/04/10  15:21:41      root
        !          43581:  * Move define's to ss.h and scsiwork.h.  Other cleanup
        !          43582:  * 
        !          43583:  * Revision 1.20       91/04/09  14:23:49      root
        !          43584:  * Reads boot sector 100 times using IRQ on reconnect
        !          43585:  */
        !          43586: 
        !          43587: /*
        !          43588:  * Includes.
        !          43589:  */
        !          43590: #include       <coherent.h>
        !          43591: #include       <sys/io.h>
        !          43592: #include       <sys/sched.h>
        !          43593: #include       <sys/uproc.h>
        !          43594: #include       <sys/proc.h>
        !          43595: #include       <sys/con.h>
        !          43596: #include       <sys/stat.h>
        !          43597: #include       <sys/devices.h>         /* SCSI_MAJOR */
        !          43598: #include       <errno.h>
        !          43599: 
        !          43600: #include       <sys/fdisk.h>
        !          43601: #include       <sys/hdioctl.h>
        !          43602: #include       <sys/buf.h>
        !          43603: #include       <scsiwork.h>
        !          43604: #include       <ss.h>
        !          43605: 
        !          43606: /*
        !          43607:  * Definitions.
        !          43608:  *     Constants.
        !          43609:  *     Macros with argument lists.
        !          43610:  *     Typedefs.
        !          43611:  *     Enums.
        !          43612:  */
        !          43613: #define DEV_SCSI_ID(dev)       ((dev >> 4) & 0x0007)
        !          43614: #define DEV_LUN(dev)           ((dev >> 2) & 0x0003)
        !          43615: #define DEV_DRIVE(dev)         ((dev >> 2) & 0x001F)
        !          43616: #define DEV_PARTN(dev)         (dev & 0x0003)
        !          43617: #define DEV_SPECIAL(dev)       (dev & 0x0080)
        !          43618: 
        !          43619: #define HOST_ID                0x80    /* Host adapter is SCSI ID #7 */
        !          43620: #define HIPRI_RETRIES  400     /* # of times to retry while hogging CPU */
        !          43621: #define LOPRI_RETRIES  5       /* # of retries with sleep between tries */
        !          43622: #define WHOLE_DRIVE    NPARTN
        !          43623: #define WATCHDOG_SECONDS  4
        !          43624: 
        !          43625: #define IN_BUF_SIZE    512     /* buffer size in "ss" structs */
        !          43626: 
        !          43627: #define DEBUG  1
        !          43628: #if DEBUG
        !          43629: int stats[100], statsptr;
        !          43630: #define PUSHI          { if(statsptr<100)stats[statsptr++] = i; }
        !          43631: #define POPI           { if(sserrct<=MAXSSERR)printf("%d:",statsptr);while(statsptr)\
        !          43632:                                if(sserrct<=MAXSSERR)printf("%d ",stats[--statsptr]);if(sserrct<=MAXSSERR)printf("\n");}
        !          43633: #define SSTELL(foo)    if(sserrct<=MAXSSERR)printf(foo)
        !          43634: #define SSTATUS                {uchar status = ffbyte(ss_csr);if(sserrct<=MAXSSERR)printf("status=%x\n", status);}
        !          43635: #define SSDUMP(ssp, text) {int i;\
        !          43636:        if(sserrct<=MAXSSERR)printf("%s: msg_in=%x cmdstat=%x\n", text, ssp->msg_in,\
        !          43637:        ssp->cmdstat);if(ssp->cmdlen)for(i=0;i<ssp->cmdlen;i++)\
        !          43638:        if(sserrct<=MAXSSERR)printf(" %x", ssp->cmdbuf[i]);if(sserrct<=MAXSSERR)printf(" cmd_bytes_out=%d",\
        !          43639:        ssp->cmd_bytes_out);\
        !          43640:        if(ssp->data_bytes_in)for(i=0;i<ssp->data_bytes_in;i++)\
        !          43641:        if(sserrct<=MAXSSERR)printf(" %x", ffbyte(ssp->in_buf+i));if(sserrct<=MAXSSERR)printf(" data_bytes_in=%d\n",\
        !          43642:        ssp->data_bytes_in);}
        !          43643: #else
        !          43644: #define PUSHI
        !          43645: #define POPI
        !          43646: #define SSTELL(foo)
        !          43647: #define SSTATUS
        !          43648: #define SSDUMP(ssp, text)
        !          43649: #endif
        !          43650: 
        !          43651: typedef unsigned char  uchar;
        !          43652: typedef unsigned long  ulong;
        !          43653: typedef struct ss {
        !          43654:        ulong   capacity;
        !          43655:        ulong   blocklen;
        !          43656:        ulong   bno;
        !          43657:        int     msg_in;
        !          43658:        int     dr_watch;       /* number of seconds for pending timeout */
        !          43659:        uchar   cmdbuf[G1CMDLEN];
        !          43660:        int     cmdlen;
        !          43661:        int     cmd_bytes_out;
        !          43662:        int     cmdstat;
        !          43663:        faddr_t in_buf;
        !          43664:        int     in_buf_len;
        !          43665:        int     data_bytes_in;
        !          43666:        faddr_t out_buf;
        !          43667:        int     out_buf_len;
        !          43668:        int     data_bytes_out;
        !          43669:        BUF     *bp;            /* current I/O request node, or NULL */
        !          43670:        struct  fdisk_s parmp[NPARTN+1];
        !          43671:        unsigned int    ptab_read:1;  /* 1 if partition table has been read */
        !          43672:        unsigned int    id_busy:1;  /* 1 if device with this SCSI id busy */
        !          43673: }      ss_type;
        !          43674: 
        !          43675: /*
        !          43676:  * Functions.
        !          43677:  *     Import Functions.
        !          43678:  *     Export Functions.
        !          43679:  *     Local Functions.
        !          43680:  */
        !          43681: extern int     nulldev();
        !          43682: extern int     nonedev();
        !          43683: extern unsigned char ffbyte();
        !          43684: 
        !          43685: static void    ssopen();               /* CON functions */
        !          43686: static void    ssclose();
        !          43687: static void    ssblock();
        !          43688: static void    ssread();
        !          43689: static void    sswrite();
        !          43690: static int     ssioctl();
        !          43691: static void    sswatch();
        !          43692: static void    ssload();
        !          43693: static void    ssunload();
        !          43694: 
        !          43695: static int     bus_dev_reset();        /* additional support functions */
        !          43696: static int     bus_info_xfer();
        !          43697: static int     bus_pre_xfer();
        !          43698: static int     chk_reconn();
        !          43699: static int     inquiry();
        !          43700: static int     mode_sense();
        !          43701: static int     read_cap();
        !          43702: static void    reconnect();
        !          43703: static int     req_sense();
        !          43704: static int     rezero();
        !          43705: static int     scsicmd();
        !          43706: static void    scsireset();
        !          43707: static void    ss_done();
        !          43708: static int     ss_rw();
        !          43709: static void    ss_start();
        !          43710: static void    ss_start_timing();
        !          43711: static void    ss_stop_timing();
        !          43712: static void    ssdelay();
        !          43713: static int     ssinit();
        !          43714: static void    ssintr();
        !          43715: static int     testready();
        !          43716: 
        !          43717: /*
        !          43718:  * Global Data.
        !          43719:  *     Import Variables.
        !          43720:  *     Export Variables.
        !          43721:  *     Local Variables.
        !          43722:  */
        !          43723: CON    sscon   = {
        !          43724:        DFBLK|DFCHR,                    /* Flags */
        !          43725:        SCSI_MAJOR,                     /* Major index */
        !          43726:        ssopen,                         /* Open */
        !          43727:        ssclose,                        /* Close */
        !          43728:        ssblock,                        /* Block */
        !          43729:        ssread,                         /* Read */
        !          43730:        sswrite,                        /* Write */
        !          43731:        ssioctl,                        /* Ioctl */
        !          43732:        nulldev,                        /* Powerfail */
        !          43733:        sswatch,                        /* Timeout */
        !          43734:        ssload,                         /* Load */
        !          43735:        ssunload,                       /* Unload */
        !          43736:        nulldev                         /* Poll */
        !          43737: };
        !          43738: 
        !          43739:        /* Patch these Export Variables to configure the driver. */
        !          43740: int    NSDRIVE = 1;            /* Bitmap of attached SCSI drives. */
        !          43741: int    SS_INT = 5;             /* ST0[12] use either IRQ3 or IRQ5 */
        !          43742: int    SS_BASE = 0xDE00;       /* Segment addr of ST0x communication area */
        !          43743: 
        !          43744: static int     loading;        /* 1 ssload() is executing */
        !          43745: static BUF     dbuf;           /* For raw I/O */
        !          43746: static paddr_t ss_base;        /* physical address of ST0x comm area */
        !          43747: static faddr_t ss_fp;          /* (far *) to ST0x comm area */
        !          43748: 
        !          43749: static faddr_t ss_ram;         /* (far *) to parameter RAM */
        !          43750: static faddr_t ss_csr;         /* (far *) to control/status */
        !          43751: static faddr_t ss_dat;         /* (far *) to data port */
        !          43752: 
        !          43753: static int     num_drives;     /* number of controller SCSI id's */
        !          43754: static ss_type *ss_tbl;                /* points to block of "ss" structs */
        !          43755: static int     st0x_busy;      /* 1 if SCSI host adapter busy */
        !          43756: 
        !          43757: static TIM     delay_tim;      /* needed for calls to ssdelay() */
        !          43758: static TIM     reset_tim;      /* needed for calls to scsireset() */
        !          43759: static TIM     timeout_tim;    /* needed for calls to timeout() */
        !          43760: static TIM     sst_tim;        /* for timeout() call from ss_start() */
        !          43761: static int     ss_expired;     /* 1 after local timeout */
        !          43762: static ss_type  *ss[MAX_SCSI_ID-1], rqs;
        !          43763: 
        !          43764: /*
        !          43765:  * ssload()    - load routine.
        !          43766:  *
        !          43767:  *     Action: The controller is reset and the interrupt vector is grabbed.
        !          43768:  *             The drive characteristics are set up at this time.
        !          43769:  */
        !          43770: static void ssload()
        !          43771: {
        !          43772:        int erf = 0;  /* 1 if error occurs */
        !          43773:        int i;
        !          43774:        loading = 1;
        !          43775: 
        !          43776:        /*
        !          43777:         * Claim IRQ vector.
        !          43778:         */
        !          43779:        setivec(SS_INT, ssintr);
        !          43780: 
        !          43781:        /*
        !          43782:         * Allocate a selector to map into ST0x memory-mapped comm area.
        !          43783:         */
        !          43784:        ss_base = (paddr_t)((long)(unsigned)SS_BASE << 4);
        !          43785:        ss_fp = ptov(ss_base, (fsize_t)SS_SEL_LEN);
        !          43786: 
        !          43787:        ss_ram = ss_fp + SS_RAM;
        !          43788:        ss_csr = ss_fp + SS_CSR;
        !          43789:        ss_dat = ss_fp + SS_DAT;
        !          43790: 
        !          43791:        /*
        !          43792:         * Primitive test of ST0x RAM.
        !          43793:         */
        !          43794:        sfword(ss_ram, 0xA55A);
        !          43795:        sfword(ss_ram + 2, 0x3CC3);
        !          43796:        sfword(ss_ram + SS_RAM_LEN - 4, 0xA55A);
        !          43797:        sfword(ss_ram + SS_RAM_LEN - 2, 0x3CC3);
        !          43798:        if (ffword(ss_ram) != 0xA55A            /* fetch a "far" word */
        !          43799:        ||  ffword(ss_ram + 2) != 0x3CC3
        !          43800:        ||  ffword(ss_ram + SS_RAM_LEN - 4) != 0xA55A
        !          43801:        ||  ffword(ss_ram + SS_RAM_LEN - 2) != 0x3CC3) {
        !          43802:                printf("Error - ST0x failed memory test\n");
        !          43803:                erf = 1;
        !          43804:        }
        !          43805: 
        !          43806:        /*
        !          43807:         * Allocate drive structs.
        !          43808:         *
        !          43809:         * Do a single call to kalloc() then put allocated pieces into
        !          43810:         * array ss.
        !          43811:         */
        !          43812:        if (!erf) {
        !          43813:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          43814:                        if ((NSDRIVE >> i) & 1)
        !          43815:                                num_drives++;
        !          43816:                if (num_drives == 0) {
        !          43817:                        printf("Error - ss has no valid target id's\n");
        !          43818:                        erf = 1;
        !          43819:                } else if ((ss_tbl = kalloc(num_drives*sizeof(ss_type)))
        !          43820:                == NULL) {
        !          43821:                        printf("Error - ss can't allocate structs\n");
        !          43822:                        erf = 1;
        !          43823:                } else
        !          43824:                        kclear(ss_tbl, num_drives * sizeof(ss_type));
        !          43825:        }
        !          43826:        if (!erf) {
        !          43827:                ss_type *foo = ss_tbl;
        !          43828: 
        !          43829:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          43830:                        if ((NSDRIVE >> i) & 1)
        !          43831:                                ss[i] = foo++;
        !          43832:        }
        !          43833: 
        !          43834:        /*
        !          43835:         * Initialize drives we know about (i.e. in NSDRIVE bitmap).
        !          43836:         */
        !          43837:        st0x_busy++;
        !          43838:        if (!erf) {
        !          43839:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          43840:                        if ((NSDRIVE >> i) & 1)
        !          43841:                                ssinit(i);
        !          43842:        }
        !          43843:        st0x_busy--;
        !          43844:        loading = 0;
        !          43845: }
        !          43846: 
        !          43847: /*
        !          43848:  * ssunload()  - unload routine.
        !          43849:  */
        !          43850: static void ssunload()
        !          43851: {
        !          43852:        /*
        !          43853:         * Deallocate driver heap space.
        !          43854:         */
        !          43855:        if (ss_tbl)
        !          43856:                kfree(ss_tbl);
        !          43857: 
        !          43858:        /*
        !          43859:         * Free the ST0x selector.
        !          43860:         */
        !          43861:        vrelse(ss_fp);
        !          43862: 
        !          43863:        /*
        !          43864:         * Release IRQ vector.
        !          43865:         */
        !          43866:        clrivec(SS_INT);
        !          43867: }
        !          43868: 
        !          43869: /*
        !          43870:  * ssopen()
        !          43871:  *
        !          43872:  *     Input:  dev = disk device to be opened.
        !          43873:  *             mode = access mode [IPR,IPW, IPR+IPW].
        !          43874:  *
        !          43875:  *     Action: Validate the minor device.
        !          43876:  *             Update the paritition table if necessary.
        !          43877:  */
        !          43878: static void ssopen(dev, mode)
        !          43879: register dev_t dev;
        !          43880: {
        !          43881:        int drive, partn;
        !          43882:        int valid_open;
        !          43883:        struct  fdisk_s *fdp;
        !          43884:        ss_type * ssp;
        !          43885:        int s_id;
        !          43886: 
        !          43887:        /*
        !          43888:         * Set up local variables.
        !          43889:         */
        !          43890:        valid_open = 1;
        !          43891:        drive = DEV_SCSI_ID(dev);
        !          43892:        partn = DEV_PARTN(dev);
        !          43893:        s_id = DEV_SCSI_ID(dev);
        !          43894:        ssp = ss[s_id];
        !          43895:        fdp = ssp->parmp;
        !          43896: devmsg(dev, "ssopen");
        !          43897:        /*
        !          43898:         * LUN must be zero.
        !          43899:         * SCSI id must have corresponding 1 in NSDRIVE bitmapped variable.
        !          43900:         */
        !          43901:        if (DEV_LUN(dev) != 0 || ((1 << drive) & NSDRIVE) == 0) {
        !          43902:                u.u_error = ENXIO;
        !          43903:                valid_open = 0;
        !          43904:        }
        !          43905: 
        !          43906:        /*
        !          43907:         * If "special" bit is set, partition field must be zero.
        !          43908:         */
        !          43909:        if (valid_open && DEV_SPECIAL(dev) && partn != 0) {
        !          43910:                u.u_error = ENXIO;
        !          43911:                valid_open = 0;
        !          43912:        }
        !          43913: 
        !          43914:        /*
        !          43915:         * Subscripting gimmick for partition table.
        !          43916:         */
        !          43917:        if (valid_open && dev & SDEV)
        !          43918:                partn = WHOLE_DRIVE;
        !          43919:        /*
        !          43920:         * If not accessing whole drive and the partition table has not
        !          43921:         * been read yet, try to read it now.
        !          43922:         * Do this by calling fdisk() with partition table device on the drive
        !          43923:         * that is being accessed.
        !          43924:         */
        !          43925:        if (valid_open && partn != WHOLE_DRIVE && !(ssp->ptab_read)) {
        !          43926:                int fdisk_dev;
        !          43927: 
        !          43928:                fdisk_dev = (dev | SDEV) & 0xfff0;
        !          43929: devmsg(fdisk_dev, "calling fdisk");
        !          43930:                if (fdisk(fdisk_dev, fdp)) {
        !          43931: int p;
        !          43932:                        fdp[WHOLE_DRIVE].p_size = ssp->capacity;
        !          43933:                        fdp[WHOLE_DRIVE].p_base = 0;
        !          43934: printf("fdisk() succeeded\n");
        !          43935: for (p=0; p<=WHOLE_DRIVE; p++)
        !          43936:        printf("p=%d base=%ld size=%ld\n", p, fdp[p].p_base, fdp[p].p_size);
        !          43937:                        ssp->ptab_read = 1;
        !          43938:                } else {
        !          43939: printf("fdisk() failed\n");
        !          43940:                        u.u_error = ENXIO;
        !          43941:                        valid_open = 0;
        !          43942:                }
        !          43943:        }
        !          43944: 
        !          43945:        /*
        !          43946:         * Ensure partition lies within drive boundaries and is non-zero size.
        !          43947:         */
        !          43948:        if (valid_open && partn != WHOLE_DRIVE
        !          43949:        && (fdp[partn].p_base+fdp[partn].p_size) > fdp[WHOLE_DRIVE].p_size) {
        !          43950:                u.u_error = EBADFMT;
        !          43951:                valid_open = 0;
        !          43952:        }
        !          43953: 
        !          43954:        if (valid_open && partn != WHOLE_DRIVE && fdp[partn].p_size == 0) {
        !          43955:                u.u_error = ENODEV;
        !          43956:                valid_open = 0;
        !          43957:        }
        !          43958: 
        !          43959:        /*
        !          43960:         * OK to open the device.
        !          43961:         * Start watchdog timer (if not already started) for the host adapter.
        !          43962:         */
        !          43963:        if (valid_open) {
        !          43964:                ++drvl[SCSI_MAJOR].d_time;
        !          43965:        }
        !          43966: }
        !          43967: 
        !          43968: /*
        !          43969:  * ssclose()
        !          43970:  */
        !          43971: static void ssclose(dev)
        !          43972: dev_t dev;
        !          43973: {
        !          43974:        /*
        !          43975:         * Decrement the number of watchdog timer requests open for host board.
        !          43976:         */
        !          43977:        --drvl[SCSI_MAJOR].d_time;      
        !          43978: devmsg(dev, "ssclose");
        !          43979: }
        !          43980: 
        !          43981: /*
        !          43982:  * ssread()    - read a block from the raw disk
        !          43983:  *
        !          43984:  *     Input:  dev = disk device to be written to.
        !          43985:  *             iop = pointer to source I/O structure.
        !          43986:  *
        !          43987:  *     Action: Invoke the common raw I/O processing code.
        !          43988:  */
        !          43989: static void ssread(dev, iop)
        !          43990: dev_t  dev;
        !          43991: IO     *iop;
        !          43992: {
        !          43993:        ioreq( &dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC );
        !          43994: }
        !          43995: 
        !          43996: /*
        !          43997:  * sswrite()   - write a block to the raw disk
        !          43998:  *
        !          43999:  *     Input:  dev = disk device to be written to.
        !          44000:  *             iop = pointer to source I/O structure.
        !          44001:  *
        !          44002:  *     Action: Invoke the common raw I/O processing code.
        !          44003:  */
        !          44004: static void sswrite(dev, iop)
        !          44005: dev_t  dev;
        !          44006: IO     *iop;
        !          44007: {
        !          44008:        ioreq( &dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC );
        !          44009: }
        !          44010: 
        !          44011: /*
        !          44012:  * ssioctl()
        !          44013:  *
        !          44014:  *     Input:  dev = disk device to be operated on.
        !          44015:  *             cmd = input/output request to be performed.
        !          44016:  *             vec = (pointer to) optional argument.
        !          44017:  *
        !          44018:  *     Action: Validate the minor device.
        !          44019:  *             Update the paritition table if necessary.
        !          44020:  */
        !          44021: #define NHEAD  4
        !          44022: #define NSEC   52
        !          44023: #define NCYL   1004
        !          44024: 
        !          44025: static int ssioctl(dev, cmd, vec)
        !          44026: register dev_t dev;
        !          44027: int cmd;
        !          44028: char * vec;
        !          44029: {
        !          44030:        int ret = 0;
        !          44031:        hdparm_t hdparm;
        !          44032:        struct  fdisk_s *fdp;
        !          44033:        int s_id;
        !          44034:        ss_type * ssp;
        !          44035: 
        !          44036:        s_id = DEV_SCSI_ID(dev);
        !          44037:        ssp = ss[s_id];
        !          44038:        fdp = ssp->parmp;
        !          44039: 
        !          44040:        switch(cmd) {
        !          44041:        case HDGETA:
        !          44042: printf("HDGETA ");
        !          44043:                fdp = ssp->parmp;
        !          44044:                *(short *)&hdparm.landc[0] =
        !          44045:                *(short *)&hdparm.ncyl[0] = NCYL;
        !          44046:                hdparm.nhead = NHEAD;
        !          44047:                hdparm.nspt = NSEC;
        !          44048: printf("ncyl=%d nhead=%d nspt=%d\n",
        !          44049:   hdparm.ncyl[0]+((int)hdparm.ncyl[1]<<8), (int)hdparm.nhead, (int)hdparm.nspt);
        !          44050:                kucopy( &hdparm, vec, sizeof hdparm );
        !          44051:                ret = 0;
        !          44052:                break;
        !          44053:        default:
        !          44054:                u.u_error = EINVAL;
        !          44055:                ret = -1;
        !          44056:        }
        !          44057: 
        !          44058:        return ret;
        !          44059: }
        !          44060: 
        !          44061: /*
        !          44062:  * ssblock()   - queue a block to the disk
        !          44063:  *
        !          44064:  *     Input:  bp = pointer to block to be queued.
        !          44065:  *
        !          44066:  *     Action: Queue a block to the disk.
        !          44067:  *             Make sure that the transfer is within the disk partition.
        !          44068:  */
        !          44069: static void ssblock(bp)
        !          44070: register BUF   *bp;
        !          44071: {
        !          44072:        register int s;
        !          44073:        struct  fdisk_s *fdp;
        !          44074:        int partition, drive, s_id;
        !          44075:        dev_t dev;
        !          44076:        ss_type * ssp;
        !          44077:        int valid_op = 1;
        !          44078: 
        !          44079:        bp->b_resid = bp->b_count;
        !          44080: 
        !          44081:        /*
        !          44082:         * Set up local variables.
        !          44083:         */
        !          44084:        dev = bp->b_dev;
        !          44085:        partition = DEV_PARTN(dev);
        !          44086:        drive = DEV_DRIVE(dev);
        !          44087:        s_id = DEV_SCSI_ID(dev);
        !          44088:        ssp = ss[s_id];
        !          44089:        if (dev & SDEV)
        !          44090:                partition = WHOLE_DRIVE;
        !          44091:        fdp = ssp->parmp;
        !          44092: 
        !          44093:        /*
        !          44094:         * Range check disk region.
        !          44095:         */
        !          44096:        if (!(ssp->ptab_read)) {
        !          44097:                if ( partition == WHOLE_DRIVE ) {
        !          44098:                        if ((bp->b_bno != 0) || (bp->b_count != BSIZE)) {
        !          44099: {if(sserrct<=MAXSSERR)printf("BF1 ");}
        !          44100:                                bp->b_flag |= BFERR;
        !          44101:                                valid_op = 0;
        !          44102:                        }
        !          44103:                } else {
        !          44104: {if(sserrct<=MAXSSERR)printf("BF2 ");}
        !          44105:                        devmsg(dev, "no partition table");
        !          44106:                        bp->b_flag |= BFERR;
        !          44107:                        valid_op = 0;
        !          44108:                }
        !          44109:        }
        !          44110:        /*
        !          44111:         * Check for read at end of partition.
        !          44112:         * (Need to return with b_resid = BSIZE to signal end of volume.)
        !          44113:         */
        !          44114:        else if ((bp->b_req == BREAD) && (bp->b_bno == fdp[partition].p_size)) {
        !          44115:                valid_op = 0;
        !          44116:        }
        !          44117:        /*
        !          44118:         * Check for read past end of partition.
        !          44119:         */
        !          44120:        else if ( (bp->b_bno + (bp->b_count/BSIZE))
        !          44121:        > fdp[partition].p_size ) {
        !          44122: {if(sserrct<=MAXSSERR)printf("BF3 ");}
        !          44123:                bp->b_flag |= BFERR;
        !          44124:                valid_op = 0;
        !          44125:        }
        !          44126: 
        !          44127:        /*
        !          44128:         * Operation appears valid.
        !          44129:         * Fill fields in the node and queue the request.
        !          44130:         */
        !          44131:        if (valid_op) {
        !          44132: 
        !          44133: /* if(sserrct<=MAXSSERR)printf("ssblock: drv=%x bno=%lx bp=%x flag=%x\n",
        !          44134:        drive, bp->b_bno, bp, bp->b_flag); */
        !          44135: 
        !          44136:                ssq_wr_tail(bp);
        !          44137:                ss_start();
        !          44138:        /*
        !          44139:         * Operation cannot be done.  Release the kernel buffer structure.
        !          44140:         * Value of "bp->b_flag" tells caller if error occurred.
        !          44141:         */
        !          44142:        } else {        /* "valid_op" is FALSE */
        !          44143:                bdone(bp);
        !          44144:        }
        !          44145: }
        !          44146: 
        !          44147: /*
        !          44148:  * ssintr()    - Interrupt routine.
        !          44149:  *
        !          44150:  * If we have been reselected by a recognized target device
        !          44151:  *     let kernel get out of interrupt mode (defer) and do SCSI
        !          44152:  *     reconnect stuff.
        !          44153:  */
        !          44154: static void ssintr()
        !          44155: {
        !          44156:        int s_id;
        !          44157: 
        !          44158:        s_id = chk_reconn();
        !          44159:        if (s_id != -1)
        !          44160:                reconnect(s_id);
        !          44161: /*             defer(reconnect, s_id); */
        !          44162: }
        !          44163: 
        !          44164: /*
        !          44165:  * sswatch()
        !          44166:  *
        !          44167:  * Invoked once per second if any devices going through this driver are open.
        !          44168:  * Poll for any reselect, in case interrupt got lost.
        !          44169:  */
        !          44170: static void sswatch()
        !          44171: {
        !          44172:        int s_id, rs_id;
        !          44173:        ss_type * ssp;
        !          44174: 
        !          44175:        for (s_id = 0; s_id < MAX_SCSI_ID-1; s_id++) {
        !          44176:                ssp = ss[s_id];
        !          44177:                if (ssp && ssp->dr_watch) {
        !          44178:                        ssp->dr_watch--;
        !          44179:                        if (ssp->dr_watch == 0) {
        !          44180: {if(sserrct<=MAXSSERR)printf("BF4 ");}
        !          44181:                                bus_dev_reset(s_id);
        !          44182:                                ssp->bp->b_flag |= BFERR;
        !          44183: {if(sserrct<=MAXSSERR)printf("SCSI id #%d: bno=%lu <Watchdog Timeout>\n", s_id, ss[s_id]->bp->b_bno);}
        !          44184:                                ss_done(s_id);
        !          44185:                        } else {
        !          44186:                                while (1) {
        !          44187:                                        rs_id = chk_reconn();
        !          44188:                                        if (rs_id == -1)
        !          44189:                                                break;
        !          44190:                                        else
        !          44191:                                                reconnect(rs_id);
        !          44192:                                } /* endwhile */
        !          44193:                        }
        !          44194:                }
        !          44195:        } /* endfor */
        !          44196: }
        !          44197: 
        !          44198: /*
        !          44199:  * bus_wait()
        !          44200:  *
        !          44201:  * Wait for specified bit values to appear in Status Register.
        !          44202:  * This uses a tight loop and does not expect to be interrupted.
        !          44203:  *
        !          44204:  * Argument "flags" is a double-byte value;  the high byte is ANDed with
        !          44205:  * status register contents, and the result is tested for equality with
        !          44206:  * the low byte.
        !          44207:  *
        !          44208:  * Return 1 if values wanted appeared, 0 if timeout occurred.
        !          44209:  */
        !          44210: static int bus_wait(flags)
        !          44211: unsigned short flags;
        !          44212: {
        !          44213:        int found, i;
        !          44214:        unsigned char status;
        !          44215: 
        !          44216:        found = 0;
        !          44217:        for ( i = 0; i < HIPRI_RETRIES; i++) {
        !          44218:                status = ffbyte(ss_csr);
        !          44219:                if ((status & (flags >> 8)) == (flags & 0xff)) {
        !          44220:                        found = 1;
        !          44221:                        break;
        !          44222:                }
        !          44223:        }
        !          44224: 
        !          44225:        if (!found)
        !          44226:                {if(sserrct<=MAXSSERR)printf("TO:f=%x s=%x ", flags, status);}
        !          44227: 
        !          44228:        return found;
        !          44229: }
        !          44230: 
        !          44231: /*
        !          44232:  * ssinit()
        !          44233:  *
        !          44234:  * Attempt to initialize the (unique) drive with a given SCSI id.
        !          44235:  * Assume only one drive per SCSI id, having LUN = 0.
        !          44236:  * 
        !          44237:  * Return 1 if success, 0 if failure.
        !          44238:  */
        !          44239: static int ssinit(s_id)
        !          44240: int s_id;
        !          44241: {
        !          44242:        int try;
        !          44243:        int retval = 0;
        !          44244:        uchar query_buf[MODESENSELEN];
        !          44245:        ss_type * ssp = ss[s_id];
        !          44246:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          44247: 
        !          44248: /*FOO*/
        !          44249: bus_dev_reset(s_id);
        !          44250:        /*
        !          44251:         * Try Test Unit Ready command.
        !          44252:         * If it fails, reset SCSI bus and target device, and try again.
        !          44253:         */
        !          44254: printf("T");
        !          44255:        for (try = 0; !retval && try < LOPRI_RETRIES; try++) {
        !          44256:                if (testready(s_id))
        !          44257:                        retval = 1;
        !          44258:                else {
        !          44259: printf("X");
        !          44260:                        if (ssp->cmdstat == CS_BUSY)
        !          44261:                                ssdelay(50);
        !          44262:                        else if (ssp->cmdstat == CS_CHECK)
        !          44263:                                req_sense(s_id);
        !          44264:                        else if (s_id == chk_reconn())
        !          44265:                        {
        !          44266: printf("-r-");
        !          44267:                                ssdelay(50);
        !          44268:                        }
        !          44269:                        else
        !          44270:                                scsireset();
        !          44271:                }
        !          44272: #if 0
        !          44273:                scsireset();
        !          44274:                bus_dev_reset(s_id);
        !          44275: #endif
        !          44276:        } /* endfor */
        !          44277:        if (!retval)
        !          44278:                devmsg(dev, "Test Unit Ready Failed");
        !          44279: 
        !          44280: printf("R");
        !          44281:        if (retval)
        !          44282:                if (req_sense(s_id)) {
        !          44283:                        retval = 1;
        !          44284:                } else
        !          44285:                        devmsg(dev, "Request Sense Failed");
        !          44286: 
        !          44287:        if (retval)
        !          44288:                if (inquiry(s_id, query_buf)) {
        !          44289:                        query_buf[INQUIRYLEN] = 0;
        !          44290:                        devmsg(dev, query_buf + 8);
        !          44291:                        if (query_buf[0] == 0) {
        !          44292:                                retval = 1;
        !          44293:                        } else
        !          44294:                                devmsg(dev, "Not Direct Access Device");
        !          44295:                } else
        !          44296:                        devmsg(dev, "Inquiry Failed");
        !          44297: 
        !          44298:        if (retval)
        !          44299:                if (read_cap(s_id, query_buf)) {
        !          44300:                        retval = 1;
        !          44301:                        ssp->capacity = query_buf[3] | (query_buf[2] << 8)
        !          44302:                        | (((long)(query_buf[1])) << 16)
        !          44303:                        | (((long)(query_buf[0])) << 24);
        !          44304:                        ssp->blocklen = query_buf[7] | (query_buf[6] << 8)
        !          44305:                        | (((long)(query_buf[5])) << 16)
        !          44306:                        | (((long)(query_buf[4])) << 24);
        !          44307: printf("capacity=%ld   block length=%ld\n", ssp->capacity, ssp->blocklen);
        !          44308:                } else
        !          44309:                        devmsg(dev, "Read Capacity Failed");
        !          44310: 
        !          44311:        if (retval)
        !          44312:                if (mode_sense(s_id, query_buf)) {
        !          44313: #define FMT_PG (4+8+8+12)
        !          44314: #define DDG_PG (4+8+8+12+24)
        !          44315:                        uchar heads;
        !          44316:                        unsigned short spt;
        !          44317:                        ulong cyls;
        !          44318: spt=((int)query_buf[FMT_PG+10]<<8) + query_buf[FMT_PG+11];
        !          44319: cyls=((int)query_buf[DDG_PG+2]<<16) + ((int)query_buf[DDG_PG+3]<<8) + query_buf[DDG_PG+4];
        !          44320: heads=query_buf[DDG_PG+5];
        !          44321: printf("%d sectors per track\n", spt);
        !          44322: printf("%ld cylinders\n", cyls);
        !          44323: printf("%d heads\n", heads);
        !          44324:                } else
        !          44325:                        devmsg(dev, "Mode Sense Failed");
        !          44326: 
        !          44327: ssp->id_busy=0;
        !          44328:        return retval;
        !          44329: }
        !          44330: 
        !          44331: /*
        !          44332:  * testready()
        !          44333:  *
        !          44334:  * Send Test Unit Ready command.
        !          44335:  * Retry after bus reset if necessary.
        !          44336:  *
        !          44337:  * Return 1 if unit is ready, 0 if not.
        !          44338:  */
        !          44339: static int testready(s_id)
        !          44340: int s_id;
        !          44341: {
        !          44342:        int retval;
        !          44343:        ss_type * ssp = ss[s_id];
        !          44344: 
        !          44345:        ssp->cmdstat = -1;
        !          44346:        ssp->data_bytes_in = 0;
        !          44347:        ssp->data_bytes_out = 0;
        !          44348:        ssp->cmdbuf[0] = ScmdTESTREADY;
        !          44349:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] =
        !          44350:                ssp->cmdbuf[5] = 0;
        !          44351:        ssp->cmdlen = G0CMDLEN;
        !          44352:        retval = scsicmd(s_id);
        !          44353: 
        !          44354:        return retval;
        !          44355: }
        !          44356: 
        !          44357: /*
        !          44358:  * scsicmd()
        !          44359:  *
        !          44360:  * Send command packet to target device.
        !          44361:  * Start a new SCSI bus cycle when this routine is called.
        !          44362:  * If command status after sending is Device Check (CS_CHECK), do a
        !          44363:  * Request Sense to find out what happened and clear check status.
        !          44364:  *
        !          44365:  * Return 1 if command was send and status was good, else 0.
        !          44366:  */
        !          44367: static int scsicmd(s_id)
        !          44368: int s_id;
        !          44369: {
        !          44370:        int retval;
        !          44371:        ss_type *ssp = ss[s_id];
        !          44372: 
        !          44373:        if (retval = bus_pre_xfer(s_id)) {
        !          44374:                bus_info_xfer(ssp);
        !          44375:                retval = (ssp->cmdlen == ssp->cmd_bytes_out
        !          44376:                        && ssp->cmdstat == CS_GOOD);
        !          44377:        }
        !          44378: 
        !          44379:        if (ssp->cmdstat == CS_CHECK) {
        !          44380:                if (req_sense(s_id))
        !          44381:                        retval = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          44382:        }
        !          44383: 
        !          44384:        return retval;
        !          44385: }
        !          44386: 
        !          44387: /*
        !          44388:  * scsireset()
        !          44389:  *
        !          44390:  * Reset the SCSI bus.
        !          44391:  *
        !          44392:  * Allow settling time when turning reset on/off.
        !          44393:  * Settling times were determined empirically.
        !          44394:  * Each tick is 10 msec.
        !          44395:  *
        !          44396:  * If called while ssload() is running, don't return until reset is complete.
        !          44397:  * If called after ssload(), start up state machine and return.
        !          44398:  *
        !          44399:  * Either way, mark host adapter busy until reset completes.
        !          44400:  */
        !          44401: #define RESET_TICKS    40
        !          44402: static void scsireset()
        !          44403: {
        !          44404:        static int reset_state;
        !          44405: 
        !          44406: printf("!");
        !          44407:        /*
        !          44408:         * During load, it's ok to do sleep() calls for reset settling.
        !          44409:         * After load is finished, use timeout() to accomplish this.
        !          44410:         */
        !          44411:        if (loading) {
        !          44412:                st0x_busy++;
        !          44413:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          44414:                ssdelay(RESET_TICKS);
        !          44415:                sfbyte(ss_csr, 0);
        !          44416:                ssdelay(RESET_TICKS);
        !          44417:                st0x_busy--;
        !          44418:        } else {
        !          44419:                switch(reset_state) {
        !          44420:                case 0:
        !          44421:                        st0x_busy++;
        !          44422:                        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          44423:                        timeout(&reset_tim, RESET_TICKS, scsireset, 0);
        !          44424:                        reset_state = 1;
        !          44425:                        break;
        !          44426:                case 1:
        !          44427:                        sfbyte(ss_csr, 0);
        !          44428:                        timeout(&reset_tim, RESET_TICKS, scsireset, 0);
        !          44429:                        reset_state = 2;
        !          44430:                        break;
        !          44431:                case 2:
        !          44432:                        st0x_busy--;
        !          44433:                        reset_state = 0;
        !          44434:                        break;
        !          44435:                }
        !          44436:        }
        !          44437: }
        !          44438: 
        !          44439: /*
        !          44440:  * ssdelay()
        !          44441:  *
        !          44442:  * Delay for some number of clock ticks.
        !          44443:  * 286/386 kernel ticks are at 100Hz
        !          44444:  */
        !          44445: static void ssdelay(ticks)
        !          44446: int ticks;
        !          44447: {
        !          44448:        timeout(&delay_tim, ticks, wakeup, (int)&delay_tim);
        !          44449:        sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
        !          44450: }
        !          44451: 
        !          44452: /*
        !          44453:  * ss_start_timing()
        !          44454:  *
        !          44455:  * Start a timeout for some number of ticks.
        !          44456:  * Caller knows timer has expired when "ss_expired" goes to 1.
        !          44457:  *
        !          44458:  * Sample invocation:
        !          44459:  *     ss_start_timing(n);
        !          44460:  *     while (check for desired event fails) {
        !          44461:  *             if (ss_expired) {
        !          44462:  *                     ...failure stuff..
        !          44463:  *                     break;
        !          44464:  *             }
        !          44465:  *             ssdelay(m); <= needed to allow kernel to update timers
        !          44466:  *     }
        !          44467:  */
        !          44468: static void ss_start_timing(ticks)
        !          44469: int ticks;
        !          44470: {
        !          44471:        ss_expired = 0;
        !          44472:        timeout(&timeout_tim, ticks, ss_stop_timing, 1);
        !          44473: }
        !          44474: 
        !          44475: /*
        !          44476:  * ss_stop_timing()
        !          44477:  *
        !          44478:  * Stub function called only by ss_start_timing()
        !          44479:  */
        !          44480: static void ss_stop_timing(flagval)
        !          44481: int flagval;
        !          44482: {
        !          44483:        ss_expired = flagval;
        !          44484: }
        !          44485: 
        !          44486: /*
        !          44487:  * bus_pre_xfer()
        !          44488:  *
        !          44489:  * Do bus cycle phases prior to the information transfer phases.
        !          44490:  * This includes arbitration and selection.
        !          44491:  */
        !          44492: static int bus_pre_xfer(s_id)
        !          44493: int s_id;
        !          44494: {
        !          44495:        int tries;
        !          44496:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          44497:        int ret = 0;
        !          44498: 
        !          44499:        for (tries = 0; !ret && tries < LOPRI_RETRIES; tries++) {
        !          44500: if (tries>0)break;
        !          44501:                /*
        !          44502:                 * Do ST0x arbitration.
        !          44503:                 */
        !          44504:                sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          44505:                sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          44506:                sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          44507: 
        !          44508:                /*
        !          44509:                 * SCSI spec says there is "no maximum" to the wait for arbitration
        !          44510:                 * complete.
        !          44511:                 */
        !          44512:                if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
        !          44513:                        if (ffbyte(ss_csr) & (RS_REQUEST|RS_BUSY))
        !          44514:                                ret = 1;
        !          44515:                        continue;
        !          44516:                }
        !          44517: 
        !          44518:                /*
        !          44519:                 * Arbitration complete.  Now select, with ATN to allow messages.
        !          44520:                 */
        !          44521:                sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          44522:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          44523: 
        !          44524:                if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          44525:                        continue;
        !          44526: 
        !          44527:                /*
        !          44528:                 * Send "Identify" Message with Disconnect allowed.
        !          44529:                 */
        !          44530:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          44531: 
        !          44532:                if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          44533:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          44534:                        continue;
        !          44535: 
        !          44536:                /*
        !          44537:                 * During ssload(), diagnostics are running and we don't
        !          44538:                 * want disconnects.  At other times, disconnect is ok.
        !          44539:                 */
        !          44540:                if (loading)
        !          44541:                        sfbyte(ss_dat, MSG_IDENTIFY);
        !          44542:                else
        !          44543:                        sfbyte(ss_dat, MSG_IDENT_DC);
        !          44544:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ENABLE_IRPT);
        !          44545:                ret = 1;
        !          44546:        }
        !          44547: 
        !          44548:        return ret;
        !          44549: }
        !          44550: 
        !          44551: /*
        !          44552:  * bus_info_xfer()
        !          44553:  *
        !          44554:  * Do bus cycle information transfer phases.
        !          44555:  * This includes message in/out, command in/out, and data in/out.
        !          44556:  *
        !          44557:  * If cmdlen is nonzero, cmdbuf is an array of bytes of that length,
        !          44558:  * to be sent to the target.
        !          44559:  *
        !          44560:  * Return 1 if bus timeout did not occur, else 0.
        !          44561:  *
        !          44562:  * pseudocode:
        !          44563:  *
        !          44564:  * while (wait for REQ true or BUSY false on SCSI bus)
        !          44565:  *   if (BUSY false)
        !          44566:  *     break from while loop
        !          44567:  *   else
        !          44568:  *     switch (xfer phase = RS_CTRL_DATA|RS_I_O|RS_MESSAGE)
        !          44569:  *       case XP_MSG_IN/XP_MSG_OUT/...
        !          44570:  *         handle the indicated information transfer phase
        !          44571:  *     endswitch
        !          44572:  *   endif
        !          44573:  * endwhile
        !          44574:  */
        !          44575: static int bus_info_xfer(ssp)
        !          44576: ss_type *ssp;
        !          44577: {
        !          44578:        int bus_timeout;
        !          44579:        uchar phase_type;
        !          44580:        uchar msg_in;
        !          44581:        int no_msg_rcvd = 1;
        !          44582:        int s;
        !          44583:        int bytes_to_send;
        !          44584: int we_wrote=0;
        !          44585: 
        !          44586:        ssp->cmd_bytes_out = 0;
        !          44587:        ssp->msg_in = -1;
        !          44588:        s = sphi();
        !          44589:        while(req_wait(&bus_timeout)) {
        !          44590:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          44591:                switch (phase_type) {
        !          44592:                case XP_MSG_IN:
        !          44593:                        msg_in = ffbyte(ss_dat);
        !          44594:                        switch(msg_in){
        !          44595:                        case MSG_CMD_CMPLT:
        !          44596:                                ssp->msg_in = msg_in;
        !          44597:                                sfbyte(ss_csr, WC_ENABLE_IRPT);
        !          44598:                                break;
        !          44599:                        case MSG_SAVE_DPTR:
        !          44600:                                break;
        !          44601:                        case MSG_RSTOR_DPTR:
        !          44602:                                break;
        !          44603:                        case MSG_DISCONNECT:
        !          44604:                                ssp->msg_in = msg_in;
        !          44605:                                sfbyte(ss_csr, WC_ENABLE_IRPT);
        !          44606:                                break;
        !          44607:                        case MSG_ABORT:
        !          44608:                                break;
        !          44609:                        case MSG_DEV_RESET:
        !          44610:                                break;
        !          44611:                        case MSG_IDENTIFY:
        !          44612:                                break;
        !          44613:                        case MSG_IDENT_DC:
        !          44614:                                break;
        !          44615:                        }
        !          44616:                        break;
        !          44617:                case XP_MSG_OUT:
        !          44618:                        /*
        !          44619:                         * This case shouldn't happen.  We weren't
        !          44620:                         * asserting ATTENTION.  Abort the bus cycle.
        !          44621:                         */
        !          44622:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          44623:                        sfbyte(ss_dat, MSG_ABORT); 
        !          44624:                        break;
        !          44625:                case XP_STAT_IN:
        !          44626:                        ssp->cmdstat = ffbyte(ss_dat);
        !          44627:                        break;
        !          44628:                case XP_CMD_OUT:
        !          44629:                        /*
        !          44630:                         * Ship out command bytes.
        !          44631:                         * Reset SCSI bus if too many command bytes are wanted.
        !          44632:                         */
        !          44633:                        bytes_to_send = ssp->cmdlen - ssp->cmd_bytes_out;
        !          44634:                        if(bytes_to_send > 0) {
        !          44635:                                sfbyte(ss_dat, ssp->cmdbuf[ssp->cmd_bytes_out++]);
        !          44636:                                /*
        !          44637:                                 * If just sent last byte, allow interrupts.
        !          44638:                                 */
        !          44639:                                if (bytes_to_send == 1) {
        !          44640:                                        spl(s);
        !          44641:                                        s = sphi();
        !          44642:                                }
        !          44643:                        } else {        /* This case should not happen. */
        !          44644: SSDUMP(ssp, "Command overrun");
        !          44645:                                scsireset();
        !          44646:                        }
        !          44647:                        break;
        !          44648:                case XP_DATA_IN:
        !          44649:                        /*
        !          44650:                         * If caller's buffer has room, keep incoming
        !          44651:                         * data byte.  Else toss it.
        !          44652:                         */
        !          44653:                        if (ssp->data_bytes_in < ssp->in_buf_len && ssp->in_buf) {
        !          44654:                                uchar dat;
        !          44655: 
        !          44656:                                dat = ffbyte(ss_dat);
        !          44657:                                sfbyte(ssp->in_buf + ssp->data_bytes_in, dat);
        !          44658:                                ssp->data_bytes_in++;
        !          44659:                        } else
        !          44660:                                ffbyte(ss_dat);
        !          44661:                        break;
        !          44662:                case XP_DATA_OUT:
        !          44663: #if 0
        !          44664: if (!we_wrote) {
        !          44665:        we_wrote=1;
        !          44666:        {if(sserrct<=MAXSSERR)printf("W");}
        !          44667: }
        !          44668: #endif
        !          44669:                        /*
        !          44670:                         * Copy output buffer bytes to data register.
        !          44671:                         */
        !          44672:                        if (ssp->data_bytes_out < ssp->out_buf_len && ssp->out_buf) {
        !          44673:                                uchar dat;
        !          44674: 
        !          44675:                                dat = ffbyte(ssp->out_buf + ssp->data_bytes_out);
        !          44676:                                sfbyte(ss_dat, dat);
        !          44677:                                ssp->data_bytes_out++;
        !          44678:                        } else { /* This case should not happen. */
        !          44679: SSDUMP(ssp, "Data out overrun");
        !          44680:                                scsireset();
        !          44681:                        }
        !          44682:                        break;
        !          44683:                default:
        !          44684:                        break;
        !          44685:                } /* endswitch */
        !          44686:        }
        !          44687:        spl(s);
        !          44688: switch(ssp->cmdstat) {
        !          44689: case -1:
        !          44690:        break;
        !          44691: case CS_GOOD:
        !          44692:        break;
        !          44693: case CS_CHECK:
        !          44694:        {if(sserrct<=MAXSSERR)printf("CSK",ssp->cmdstat);}
        !          44695:        break;
        !          44696: case CS_BUSY:
        !          44697:        {if(sserrct<=MAXSSERR)printf("CSY",ssp->cmdstat);}
        !          44698:        break;
        !          44699: case CS_RESERVED:
        !          44700: default:
        !          44701:        {if(sserrct<=MAXSSERR)printf("CS%x",ssp->cmdstat);}
        !          44702: }
        !          44703:        return (bus_timeout) ? 0 : 1 ;
        !          44704: }
        !          44705: /*
        !          44706:  * req_wait()
        !          44707:  *
        !          44708:  * This routine is called at the start of each information transfer
        !          44709:  * phase and after the last such phase.
        !          44710:  *
        !          44711:  * It returns 1 if REQ is asserted on the SCSI bus, meaning another phase
        !          44712:  * may begin, and 0 otherwise.  A REQ signal will not be seen if the function
        !          44713:  * times out or if BUSY drops.  A value of 1 is written to the pointer argument
        !          44714:  * if timeout occurred, else 0 is written.
        !          44715:  */
        !          44716: static int req_wait(to_ptr)
        !          44717: int *to_ptr;
        !          44718: {
        !          44719:        int req_found, i;
        !          44720:        unsigned char status;
        !          44721: 
        !          44722:        *to_ptr = 1;
        !          44723:        req_found = 0;
        !          44724:        for (i = 0; i < HIPRI_RETRIES; i++) {
        !          44725:                status = ffbyte(ss_csr);
        !          44726:                if (status & RS_REQUEST) {
        !          44727:                        req_found = 1;
        !          44728:                        *to_ptr = 0;
        !          44729:                        break;
        !          44730:                } else if ((status & RS_BUSY) == 0) {
        !          44731:                        *to_ptr = 0;
        !          44732:                        break;
        !          44733:                }
        !          44734:        }
        !          44735: 
        !          44736:        if (*to_ptr)
        !          44737:                {if(sserrct<=MAXSSERR)printf("TX: s=%x ", status);}
        !          44738: 
        !          44739:        return req_found;
        !          44740: }
        !          44741: 
        !          44742: /*
        !          44743:  * req_sense()
        !          44744:  *
        !          44745:  * Request Sense for a device.  The main reason for doing this is to
        !          44746:  * clear a standing Command Status of Device Check.
        !          44747:  *
        !          44748:  * Full results are discarded.  Return 1 if Device returns No Sense or
        !          44749:  * or Unit Attention.  Else return 0.
        !          44750:  *
        !          44751:  */
        !          44752: static int req_sense(s_id)
        !          44753: int s_id;
        !          44754: {
        !          44755:        uchar sense_buf[SENSELEN];
        !          44756:        int ret = 0;
        !          44757: 
        !          44758:        rqs.cmdstat = -1;
        !          44759:        rqs.data_bytes_in = 0;
        !          44760:        rqs.data_bytes_out = 0;
        !          44761:        rqs.cmdbuf[0] = ScmdREQUESTSENSE;
        !          44762:        rqs.cmdbuf[1] = rqs.cmdbuf[2] = rqs.cmdbuf[3] =
        !          44763:                rqs.cmdbuf[5] = 0;
        !          44764:                rqs.cmdbuf[4] = SENSELEN;
        !          44765:        rqs.cmdlen = G0CMDLEN;
        !          44766:        rqs.in_buf_len = SENSELEN;
        !          44767:        rqs.out_buf_len = 0;
        !          44768:        FP_OFF(rqs.in_buf) = sense_buf;
        !          44769:        FP_SEL(rqs.in_buf) = sds;
        !          44770: 
        !          44771:        if (bus_pre_xfer(s_id)) {
        !          44772:                bus_info_xfer(&rqs);
        !          44773:                if (rqs.data_bytes_in == SENSELEN) {
        !          44774:                        if (sense_buf[2] == 0x00)       /* No Sense.  AOK */
        !          44775:                                ret = 1;
        !          44776:                        else if (sense_buf[2] == 0x06 && sense_buf[12] == 0x29)
        !          44777:                                ret = 1;
        !          44778:                }
        !          44779:        }
        !          44780: 
        !          44781:        return ret;
        !          44782: }
        !          44783: 
        !          44784: /*
        !          44785:  * inquiry()
        !          44786:  *
        !          44787:  * Inquiry command for a device.
        !          44788:  * Find out if device is direct access, removable, etc.
        !          44789:  *
        !          44790:  * Put result of inquiry into supplied buffer.
        !          44791:  * Return 1 if command succeeds, else 0.
        !          44792:  */
        !          44793: static int inquiry(s_id, buf)
        !          44794: int s_id;
        !          44795: uchar * buf;
        !          44796: {
        !          44797:        int ret = 0;
        !          44798:        ss_type * ssp = ss[s_id];
        !          44799: 
        !          44800:        ssp->cmdstat = -1;
        !          44801:        ssp->data_bytes_in = 0;
        !          44802:        ssp->data_bytes_out = 0;
        !          44803:        ssp->id_busy = 1;
        !          44804:        ssp->cmdbuf[0] = ScmdINQUIRY;
        !          44805:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] =
        !          44806:                ssp->cmdbuf[5] = 0;
        !          44807:                ssp->cmdbuf[4] = INQUIRYLEN;
        !          44808:        ssp->cmdlen = G0CMDLEN;
        !          44809:        FP_OFF(ssp->in_buf) = buf;
        !          44810:        FP_SEL(ssp->in_buf) = sds;
        !          44811:        ssp->in_buf_len = INQUIRYLEN;
        !          44812:        ssp->out_buf_len = 0;
        !          44813: 
        !          44814:        ret = scsicmd(s_id);
        !          44815:        ssp->id_busy = 0;
        !          44816: 
        !          44817:        return ret;
        !          44818: }
        !          44819: 
        !          44820: /*
        !          44821:  * mode_sense()
        !          44822:  *
        !          44823:  * Mode Sense command for a device.
        !          44824:  * Use this to get disk parameters:
        !          44825:  *     number of cylinders
        !          44826:  *     number of heads
        !          44827:  *     number of sectors per track.
        !          44828:  *
        !          44829:  * Put result of mode sense into supplied buffer.
        !          44830:  * Return 1 if command succeeds, else 0.
        !          44831:  */
        !          44832: static int mode_sense(s_id, buf)
        !          44833: int s_id;
        !          44834: uchar * buf;
        !          44835: {
        !          44836:        int ret = 0;
        !          44837:        ss_type * ssp = ss[s_id];
        !          44838: 
        !          44839:        ssp->cmdstat = -1;
        !          44840:        ssp->data_bytes_in = 0;
        !          44841:        ssp->data_bytes_out = 0;
        !          44842:        ssp->id_busy = 1;
        !          44843:        ssp->cmdbuf[0] = ScmdMODESENSE;
        !          44844:        ssp->cmdbuf[1] = 0;
        !          44845:        ssp->cmdbuf[2] = 0x3F;
        !          44846:        ssp->cmdbuf[3] = 0;
        !          44847:        ssp->cmdbuf[4] = MODESENSELEN;
        !          44848:        ssp->cmdbuf[5] = 0;
        !          44849:        ssp->cmdlen = G0CMDLEN;
        !          44850:        FP_OFF(ssp->in_buf) = buf;
        !          44851:        FP_SEL(ssp->in_buf) = sds;
        !          44852:        ssp->in_buf_len = MODESENSELEN;
        !          44853:        ssp->out_buf_len = 0;
        !          44854: 
        !          44855:        ret = scsicmd(s_id);
        !          44856:        ssp->id_busy = 0;
        !          44857: 
        !          44858:        return ret;
        !          44859: }
        !          44860: 
        !          44861: /*
        !          44862:  * read_cap()
        !          44863:  *
        !          44864:  * Read Capacity command for a device.
        !          44865:  *
        !          44866:  * Return 1 if command succeeds, else 0.
        !          44867:  */
        !          44868: static int read_cap(s_id, buf)
        !          44869: int s_id;
        !          44870: uchar * buf;
        !          44871: {
        !          44872:        int ret = 0;
        !          44873:        ss_type * ssp = ss[s_id];
        !          44874: 
        !          44875:        ssp->cmdstat = -1;
        !          44876:        ssp->data_bytes_in = 0;
        !          44877:        ssp->data_bytes_out = 0;
        !          44878:        ssp->id_busy = 1;
        !          44879:        ssp->cmdbuf[0] = ScmdREADCAPACITY;
        !          44880:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] = 0;
        !          44881:        ssp->cmdbuf[5] = ssp->cmdbuf[6] = ssp->cmdbuf[7] = ssp->cmdbuf[8] = 0;
        !          44882:        ssp->cmdbuf[9] = 0;
        !          44883:        ssp->cmdlen = G1CMDLEN;
        !          44884:        FP_OFF(ssp->in_buf) = buf;
        !          44885:        FP_SEL(ssp->in_buf) = sds;
        !          44886:        ssp->in_buf_len = 8;
        !          44887:        ssp->out_buf_len = 0;
        !          44888: 
        !          44889:        ret = scsicmd(s_id);
        !          44890:        ssp->id_busy = 0;
        !          44891: 
        !          44892:        return ret;
        !          44893: }
        !          44894: 
        !          44895: /*
        !          44896:  * ss_start()
        !          44897:  *
        !          44898:  * Invoked whenever there might be I/O to do.
        !          44899:  *
        !          44900:  * Disallow re-entrancy in this routine (variable "locked").
        !          44901:  * If there is a next I/O request queued (peek at head of queue)
        !          44902:  *   get the target SCSI ID.
        !          44903:  *   If target is not busy
        !          44904:  *     remove request from queue
        !          44905:  *     mark target device busy
        !          44906:  *     start watchdog timer
        !          44907:  *     send command to host adapter
        !          44908:  *     if command succeeded
        !          44909:  *       cleanup after command
        !          44910:  *       adjust b_resid field
        !          44911:  *     else if command failed
        !          44912:  *       set error flag
        !          44913:  *       cleanup after command
        !          44914:  *     else (disconnected)
        !          44915:  *       do nothing
        !          44916:  */
        !          44917: static void ss_start()
        !          44918: {
        !          44919: #define RW_TRIES       5
        !          44920:        int s;
        !          44921:        BUF * bp;
        !          44922:        static char locked;
        !          44923:        int s_id;
        !          44924:        ss_type * ssp;
        !          44925:        struct  fdisk_s *fdp;
        !          44926:        int partition;
        !          44927:        dev_t dev;
        !          44928:        static int retry[MAX_SCSI_ID-1];
        !          44929: 
        !          44930:        s = sphi();
        !          44931:        if(locked) {
        !          44932:                spl(s);
        !          44933:                return;
        !          44934:        }
        !          44935:        ++locked;
        !          44936:        spl(s);
        !          44937: 
        !          44938:        if (st0x_busy) {
        !          44939:                timeout(&sst_tim, 50, ss_start, 0);
        !          44940:                return;
        !          44941:        }
        !          44942: 
        !          44943:        if((bp = ssq_rd_head()) != NULL) {
        !          44944:                s_id = DEV_SCSI_ID(bp->b_dev);
        !          44945:                ssp = ss[s_id];
        !          44946:                dev = bp->b_dev;
        !          44947:                partition = DEV_PARTN(dev);
        !          44948:                if (dev & SDEV)
        !          44949:                        partition = WHOLE_DRIVE;
        !          44950:                fdp = ssp->parmp;
        !          44951:                if (!(ssp->id_busy)) {
        !          44952:                        if (partition != WHOLE_DRIVE)
        !          44953:                                ssp->bno = fdp[partition].p_base + bp->b_bno;
        !          44954:                        else
        !          44955:                                ssp->bno = bp->b_bno;
        !          44956:                        ssp->bp = bp;
        !          44957:                        ssp->id_busy = 1;
        !          44958:                        ssp->dr_watch = WATCHDOG_SECONDS;
        !          44959:                        if (ss_rw(s_id)) {
        !          44960:                                retry[s_id] = 0;
        !          44961:                                ssq_rm_head();
        !          44962:                                if (bp->b_req == BREAD)
        !          44963:                                        bp->b_resid -= ssp->data_bytes_in;
        !          44964:                                else
        !          44965:                                        bp->b_resid -= ssp->data_bytes_out;
        !          44966:                                if (ssp->msg_in != MSG_DISCONNECT)
        !          44967:                                        ss_done(s_id);
        !          44968: /* if(sserrct<=MAXSSERR)printf("%d in  %d out\n",ssp->data_bytes_in,ssp->data_bytes_out); */
        !          44969:                        } else {
        !          44970:                                if (++retry[s_id] > RW_TRIES) {
        !          44971: {if(sserrct<=MAXSSERR)printf("BF5 ");}
        !          44972:                                        retry[s_id] = 0;
        !          44973:                                        ssq_rm_head();
        !          44974:                                        bp->b_flag |= BFERR;
        !          44975:                                        ss_done(s_id);
        !          44976:                                } else {
        !          44977:                                        ssp->id_busy = 0;
        !          44978:                                        timeout(&sst_tim, 10, ss_start, 0);
        !          44979: {if(sserrct<=MAXSSERR)printf("R%d ",retry[s_id]);}
        !          44980:                                }
        !          44981:                        }
        !          44982:                }
        !          44983:        }
        !          44984:        --locked;
        !          44985: }
        !          44986: 
        !          44987: /*
        !          44988:  * ss_done
        !          44989:  *
        !          44990:  * Release current i/o buffer to the O/S.
        !          44991:  */
        !          44992: static void ss_done(s_id)
        !          44993: int s_id;
        !          44994: {
        !          44995:        ss_type * ssp = ss[s_id];
        !          44996:        BUF * bp = ssp->bp;
        !          44997:        int s;
        !          44998: 
        !          44999:        s = sphi();
        !          45000:        ssp->id_busy = 0;
        !          45001:        ssp->dr_watch = 0;
        !          45002:        ssp->in_buf = ssp->out_buf = NULL;
        !          45003:        if (bp) {
        !          45004:                bdone(bp);
        !          45005:                ssp->bp = NULL;
        !          45006:        }
        !          45007:        spl(s);
        !          45008: 
        !          45009:        ss_start();
        !          45010: }
        !          45011: 
        !          45012: /*
        !          45013:  * bus_dev_reset()
        !          45014:  *
        !          45015:  * Send Bus Device Reset message to the given SCSI id.
        !          45016:  * Return 1 if host adapter was not busy and no obvious timeouts occurred,
        !          45017:  * else 0.
        !          45018:  */
        !          45019: static int bus_dev_reset(s_id)
        !          45020: {
        !          45021:        int bdr_ok = 1;
        !          45022:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          45023: 
        !          45024: {if(sserrct<=MAXSSERR)printf("bdr");}
        !          45025: 
        !          45026:        if (!loading && st0x_busy)
        !          45027:                bdr_ok = 0;
        !          45028: 
        !          45029:        if (bdr_ok) {
        !          45030:                /*
        !          45031:                 * Do ST0x arbitration.
        !          45032:                 */
        !          45033:                sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          45034:                sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          45035:                sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          45036: 
        !          45037:                /*
        !          45038:                 * SCSI spec says there is "no maximum" to the wait for
        !          45039:                 * arbitration complete.
        !          45040:                 */
        !          45041:                if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
        !          45042:                        bdr_ok = 0;
        !          45043:                }
        !          45044:        }
        !          45045: 
        !          45046:        /*
        !          45047:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          45048:         */
        !          45049:        if (bdr_ok) {
        !          45050:                sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          45051:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          45052: 
        !          45053:                if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          45054:                        bdr_ok = 0;
        !          45055:        }
        !          45056: 
        !          45057:        if (bdr_ok) {
        !          45058:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          45059: 
        !          45060:                if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          45061:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          45062:                        bdr_ok = 0;
        !          45063:        }
        !          45064: 
        !          45065:        if (bdr_ok) {
        !          45066:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          45067:                sfbyte(ss_dat, MSG_DEV_RESET);
        !          45068:                if (!bus_wait((0xFF << 8) | 0))
        !          45069:                        bdr_ok = 0;
        !          45070:        }
        !          45071: 
        !          45072: {if(sserrct<=MAXSSERR)printf("%d",bdr_ok);}
        !          45073:        return bdr_ok;
        !          45074: }
        !          45075: 
        !          45076: /*
        !          45077:  * chk_reconn()
        !          45078:  *
        !          45079:  * Check SELECT to see if any SCSI device has tried to reconnect to the host
        !          45080:  * adapter.  Called if there is an interrupt, and by the timer in case
        !          45081:  * we somehow lose an interrupt.
        !          45082:  *
        !          45083:  * Return -1 if no reselect detected, or the SCSI ID of the reselecting
        !          45084:  * target if there is one.
        !          45085:  *
        !          45086:  * Call reconnect() after this if reselect has occurred.
        !          45087:  */
        !          45088: static int chk_reconn()
        !          45089: {
        !          45090:        uchar csr, dat;
        !          45091:        int s_id = -1;
        !          45092: 
        !          45093:        csr = ffbyte(ss_csr);
        !          45094:        if (csr & (RS_SELECT | RS_I_O)) {
        !          45095:                dat = ffbyte(ss_dat);
        !          45096:                if ((dat & HOST_ID) && (dat & NSDRIVE)) {
        !          45097:                        dat &= ~HOST_ID;
        !          45098:                        s_id = 0;
        !          45099:                        while (dat >>=1)
        !          45100:                                s_id++;
        !          45101:                }
        !          45102:        }
        !          45103: 
        !          45104:        return s_id;
        !          45105: }
        !          45106: 
        !          45107: /*
        !          45108:  * reconnect()
        !          45109:  *
        !          45110:  * Given SCSI ID of target device that is issuing reselect, do reconnect
        !          45111:  * SCSI bus stuff.
        !          45112:  */
        !          45113: static void reconnect(s_id)
        !          45114: int s_id;
        !          45115: {
        !          45116:        uchar dat;
        !          45117:        int cmd_ok = 0;
        !          45118:        ss_type * ssp = ss[s_id];
        !          45119:        BUF * bp = ssp->bp;
        !          45120: 
        !          45121:        dat = ffbyte(ss_dat);
        !          45122:        if ((dat & HOST_ID) && (dat & (1 << s_id)) && ssp) {
        !          45123:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_BUSY);
        !          45124:                if (bus_wait(RS_SELECT << 8 | 0)) {
        !          45125:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          45126:                        cmd_ok = bus_info_xfer(ssp);
        !          45127:                        if (bp) {
        !          45128:                                if (bp->b_req == BREAD)
        !          45129:                                        bp->b_resid -= ssp->data_bytes_in;
        !          45130:                                else
        !          45131:                                        bp->b_resid -= ssp->data_bytes_out;
        !          45132:                                if (cmd_ok && ssp->cmdstat == CS_GOOD) {
        !          45133:                                        if (ssp->msg_in == MSG_DISCONNECT) {
        !          45134:                                                ssp->dr_watch = WATCHDOG_SECONDS;
        !          45135:                                        } else
        !          45136:                                                ss_done(s_id);
        !          45137:                                } else {
        !          45138: {if(sserrct<=MAXSSERR)printf("BF6 ");}
        !          45139:                                        bp->b_flag |= BFERR;
        !          45140:                                        ss_done(s_id);
        !          45141:                                }
        !          45142:                        }
        !          45143:                }
        !          45144:        }
        !          45145: }
        !          45146: 
        !          45147: /*
        !          45148:  * ss_rw()
        !          45149:  *
        !          45150:  * Send read or write command to the host adapter.
        !          45151:  */
        !          45152: static int ss_rw(s_id)
        !          45153: int s_id;
        !          45154: {
        !          45155:        ss_type * ssp = ss[s_id];
        !          45156:        BUF * bp = ssp->bp;
        !          45157:        int rw_ok = 0;
        !          45158: uchar rwc;
        !          45159: 
        !          45160:        ssp->cmdstat = -1;
        !          45161:        if (bp->b_req == BREAD) {
        !          45162:                ssp->cmdbuf[0] = ScmdREADEXTENDED;
        !          45163:                ssp->in_buf_len = bp->b_count;
        !          45164:                ssp->in_buf = bp->b_faddr;
        !          45165:                ssp->out_buf_len = 0;
        !          45166:                ssp->out_buf = NULL;
        !          45167: rwc='R';
        !          45168:        } else {
        !          45169:                ssp->cmdbuf[0] = ScmdWRITEXTENDED;
        !          45170:                ssp->in_buf_len = 0;
        !          45171:                ssp->in_buf = NULL;
        !          45172:                ssp->out_buf_len = bp->b_count;
        !          45173:                ssp->out_buf = bp->b_faddr;
        !          45174: rwc='W';
        !          45175:        }
        !          45176:        ssp->data_bytes_in = 0;
        !          45177:        ssp->data_bytes_out = 0;
        !          45178:        ssp->cmdbuf[1] = 0;
        !          45179:        ssp->cmdbuf[2] = ssp->bno >> 24;
        !          45180:        ssp->cmdbuf[3] = ssp->bno >> 16;
        !          45181:        ssp->cmdbuf[4] = ssp->bno >>  8;
        !          45182:        ssp->cmdbuf[5] = ssp->bno;
        !          45183:        ssp->cmdbuf[6] = 0;
        !          45184:        ssp->cmdbuf[7] = bp->b_count / (BSIZE * 256L);
        !          45185:        ssp->cmdbuf[8] = bp->b_count / BSIZE;
        !          45186:        ssp->cmdbuf[9] = 0;
        !          45187:        ssp->cmdlen = G1CMDLEN;
        !          45188: 
        !          45189: { int s = sphi();
        !          45190:        rw_ok = bus_pre_xfer(s_id);
        !          45191:        if (rw_ok) {
        !          45192:                bus_info_xfer(ssp);
        !          45193: spl(s);
        !          45194:                rw_ok = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          45195: if(!rw_ok) {
        !          45196:   uchar csr=ffbyte(ss_csr), dat=ffbyte(ss_dat);
        !          45197:   sserrct++; if (sserrct <=MAXSSERR) {
        !          45198:     {if(sserrct<=MAXSSERR)printf("F2 cmdlen=%d cmd_bytes_out=%d cmdstat=%d\n", ssp->cmdlen,
        !          45199:        ssp->cmd_bytes_out, ssp->cmdstat);}
        !          45200:     {if(sserrct<=MAXSSERR)printf("%c msg_in=%x inl=%d ", rwc, ssp->msg_in, ssp->in_buf_len);}
        !          45201:     {if(sserrct<=MAXSSERR)printf("inb=%d otl=%d otb=%d\n", ssp->data_bytes_in, ssp->out_buf_len,
        !          45202:     ssp->data_bytes_out);}
        !          45203:     {if(sserrct<=MAXSSERR)printf("csr=%x dat=%x bno=%ld ",csr,dat,bp->b_bno);}
        !          45204:   }
        !          45205: }
        !          45206:        }
        !          45207: else {{if(sserrct<=MAXSSERR)printf("F1");}spl(s);}
        !          45208: }
        !          45209: 
        !          45210:        if (ssp->cmdstat == CS_CHECK) {
        !          45211: {if(sserrct<=MAXSSERR)printf("ss_rw(): requesting sense\n");}
        !          45212:                if (req_sense(s_id)) {
        !          45213:                        rw_ok = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          45214: if(!rw_ok) {if(sserrct<=MAXSSERR)printf("F3");}
        !          45215:                }
        !          45216:        }
        !          45217: 
        !          45218:        if (rw_ok) {
        !          45219:                rw_ok =
        !          45220:                (ssp->cmdstat == CS_GOOD || ssp->msg_in == MSG_DISCONNECT);
        !          45221: if(!rw_ok) {if(sserrct<=MAXSSERR)printf("F4");}
        !          45222:        }
        !          45223: 
        !          45224:        return rw_ok;
        !          45225: 
        !          45226: }
        !          45227: 
        !          45228: /*
        !          45229:  * rezero()
        !          45230:  *
        !          45231:  * Send Rezero Unit command.
        !          45232:  *
        !          45233:  * Return 1 if no timeouts occurred, 0 if not.
        !          45234:  */
        !          45235: static int rezero(s_id)
        !          45236: int s_id;
        !          45237: {
        !          45238:        int retval;
        !          45239:        ss_type * ssp = ss[s_id];
        !          45240: 
        !          45241:        ssp->cmdstat = -1;
        !          45242:        ssp->data_bytes_in = 0;
        !          45243:        ssp->data_bytes_out = 0;
        !          45244:        ssp->cmdbuf[0] = ScmdREZERO;
        !          45245:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] =
        !          45246:                ssp->cmdbuf[5] = 0;
        !          45247:        ssp->cmdlen = G0CMDLEN;
        !          45248:        retval = scsicmd(s_id);
        !          45249: 
        !          45250:        return retval;
        !          45251: }
        !          45252: @
        !          45253: 
        !          45254: 
        !          45255: 1.34
        !          45256: log
        !          45257: @Better error recovery, but needs work.
        !          45258: @
        !          45259: text
        !          45260: @d1 1
        !          45261: d17 3
        !          45262: d96 1
        !          45263: a96 1
        !          45264: #define HIPRI_RETRIES  800     /* # of times to retry while hogging CPU */
        !          45265: d107 4
        !          45266: a110 4
        !          45267: #define POPI           { printf("%d:",statsptr);while(statsptr)\
        !          45268:                                printf("%d ",stats[--statsptr]);printf("\n");}
        !          45269: #define SSTELL(foo)    printf(foo)
        !          45270: #define SSTATUS                {uchar status = ffbyte(ss_csr);printf("status=%x\n", status);}
        !          45271: d112 1
        !          45272: a112 1
        !          45273:        printf("%s: msg_in=%x cmdstat=%x\n", text, ssp->msg_in,\
        !          45274: d114 1
        !          45275: a114 1
        !          45276:        printf(" %x", ssp->cmdbuf[i]);printf(" cmd_bytes_out=%d",\
        !          45277: d117 1
        !          45278: a117 1
        !          45279:        printf(" %x", ffbyte(ssp->in_buf+i));printf(" data_bytes_in=%d\n",\
        !          45280: d180 1
        !          45281: d191 1
        !          45282: d220 1
        !          45283: a220 1
        !          45284: static int     allow_dc;       /* 1 if we allow SCSI targets to disconnect */
        !          45285: d234 1
        !          45286: d250 1
        !          45287: d313 1
        !          45288: d319 2
        !          45289: a320 1
        !          45290:        allow_dc = 1;
        !          45291: d518 1
        !          45292: a518 1
        !          45293: printf("HDGETA\n");
        !          45294: d575 1
        !          45295: a575 1
        !          45296: printf("BFERR 1\n");
        !          45297: d580 1
        !          45298: a580 1
        !          45299: printf("BFERR 2\n");
        !          45300: d598 1
        !          45301: a598 1
        !          45302: printf("BFERR 3\n");
        !          45303: d609 1
        !          45304: a609 1
        !          45305: /* printf("ssblock: drv=%x bno=%lx bp=%x flag=%x\n",
        !          45306: d636 2
        !          45307: a637 1
        !          45308:                defer(reconnect, s_id);
        !          45309: d656 1
        !          45310: a656 1
        !          45311: printf("BFERR 4\n");
        !          45312: d659 1
        !          45313: a659 1
        !          45314: printf("SCSI id #%d: bno=%lu <Watchdog Timeout>\n", s_id, ss[s_id]->bp->b_bno);
        !          45315: d702 1
        !          45316: a702 1
        !          45317:                printf("ST0x timeout;  flags=%x status=%x\n", flags, status);
        !          45318: d736 11
        !          45319: a746 2
        !          45320:                        if (ssp->cmdstat != CS_BUSY)
        !          45321:                                ;
        !          45322: a747 1
        !          45323:                ssdelay(100);
        !          45324: a750 2
        !          45325:                if (testready(s_id))
        !          45326:                        retval = 1;
        !          45327: d821 1
        !          45328: d867 1
        !          45329: d871 5
        !          45330: d880 33
        !          45331: a912 5
        !          45332: printf("scsireset\n");
        !          45333:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          45334:        ssdelay(RESET_TICKS);
        !          45335:        sfbyte(ss_csr, 0);
        !          45336:        ssdelay(RESET_TICKS);
        !          45337: d1012 7
        !          45338: a1018 1
        !          45339:                if (allow_dc)
        !          45340: a1019 2
        !          45341:                else
        !          45342:                        sfbyte(ss_dat, MSG_IDENTIFY);
        !          45343: a1061 1
        !          45344:        ssp->cmdstat = -1;
        !          45345: d1142 1
        !          45346: a1142 1
        !          45347:        printf("W");
        !          45348: d1170 1
        !          45349: a1170 1
        !          45350:        printf("CSK",ssp->cmdstat);
        !          45351: d1173 1
        !          45352: a1173 1
        !          45353:        printf("CSY",ssp->cmdstat);
        !          45354: d1177 1
        !          45355: a1177 1
        !          45356:        printf("CS%x",ssp->cmdstat);
        !          45357: d1213 1
        !          45358: a1213 1
        !          45359:                printf("ST0x info xfer timeout;  status=%x\n", status);
        !          45360: d1234 1
        !          45361: d1276 1
        !          45362: d1315 1
        !          45363: d1351 1
        !          45364: d1444 1
        !          45365: a1444 1
        !          45366: /* printf("%d in  %d out\n",ssp->data_bytes_in,ssp->data_bytes_out); */
        !          45367: d1447 1
        !          45368: a1447 1
        !          45369: printf("BFERR 5\n");
        !          45370: d1455 1
        !          45371: a1455 2
        !          45372: if(sserrct<=5)printf("R%d\n",retry[s_id]);
        !          45373: else printf("%d",retry[s_id]);
        !          45374: d1500 1
        !          45375: a1500 1
        !          45376: printf("bdr");
        !          45377: d1502 1
        !          45378: a1502 1
        !          45379:        if (st0x_busy)
        !          45380: d1548 1
        !          45381: a1548 1
        !          45382: printf("%d",bdr_ok);
        !          45383: d1570 1
        !          45384: a1570 1
        !          45385:        if (csr & RS_SELECT) {
        !          45386: d1598 1
        !          45387: a1598 1
        !          45388:        if ((dat & HOST_ID) && (dat & (1 << s_id)) && ssp && ssp->id_busy) {
        !          45389: d1614 1
        !          45390: a1614 1
        !          45391: printf("BFERR 6\n");
        !          45392: d1636 1
        !          45393: d1673 7
        !          45394: a1679 7
        !          45395:   sserrct++; if (sserrct <=5) {
        !          45396:     printf("F2 cmdlen=%d cmd_bytes_out=%d cmdstat=%d\n", ssp->cmdlen,
        !          45397:        ssp->cmd_bytes_out, ssp->cmdstat);
        !          45398:     printf("%c msg_in=%x inl=%d ", rwc, ssp->msg_in, ssp->in_buf_len);
        !          45399:     printf("inb=%d otl=%d otb=%d\n", ssp->data_bytes_in, ssp->out_buf_len,
        !          45400:     ssp->data_bytes_out);
        !          45401:     printf("csr=%x dat=%x bno=%ld ",csr,dat,bp->b_bno);
        !          45402: d1683 1
        !          45403: a1683 1
        !          45404: else {printf("F1");spl(s);}
        !          45405: d1687 1
        !          45406: a1687 1
        !          45407: printf("ss_rw(): requesting sense\n");
        !          45408: d1690 1
        !          45409: a1690 1
        !          45410: if(!rw_ok) printf("F3");
        !          45411: d1697 1
        !          45412: a1697 1
        !          45413: if(!rw_ok) printf("F4");
        !          45414: d1703 25
        !          45415: @
        !          45416: 
        !          45417: 
        !          45418: 1.33
        !          45419: log
        !          45420: @Starting to fix retry mechanism on ss_rw().
        !          45421: @
        !          45422: text
        !          45423: @d1 1
        !          45424: d6 8
        !          45425: a13 2
        !          45426:  *     figure out a better storage class for rqs
        !          45427:  *      make input buffer for commands dynamic (?)
        !          45428: d16 3
        !          45429: d167 1
        !          45430: a167 1
        !          45431: static void    bus_dev_reset();        /* additional support functions */
        !          45432: d214 1
        !          45433: d229 1
        !          45434: d310 1
        !          45435: a623 1
        !          45436: printf("@@");
        !          45437: d707 1
        !          45438: d713 2
        !          45439: d719 11
        !          45440: a729 3
        !          45441:        if (testready(s_id))
        !          45442:                retval = 1;
        !          45443:        else {
        !          45444: d734 4
        !          45445: a737 3
        !          45446:                else
        !          45447:                        devmsg(dev, "Test Unit Ready Failed");
        !          45448:        }
        !          45449: d739 1
        !          45450: d786 1
        !          45451: d921 1
        !          45452: a921 1
        !          45453:        int ret;
        !          45454: d923 2
        !          45455: a924 1
        !          45456:        for (ret = 0, tries = 0; !ret && tries < LOPRI_RETRIES; tries++) {
        !          45457: d937 2
        !          45458: a938 1
        !          45459:                        scsireset();
        !          45460: d960 4
        !          45461: a963 1
        !          45462:                sfbyte(ss_dat, MSG_IDENT_DC);
        !          45463: d1018 1
        !          45464: d1026 1
        !          45465: a1026 1
        !          45466: sfbyte(ss_csr, WC_ENABLE_IRPT); /* FOO */
        !          45467: d1032 2
        !          45468: d1109 15
        !          45469: d1145 1
        !          45470: a1145 1
        !          45471:        for ( i = 0; i < HIPRI_RETRIES; i++) {
        !          45472: d1187 1
        !          45473: d1231 1
        !          45474: d1271 1
        !          45475: d1304 1
        !          45476: d1355 5
        !          45477: d1393 6
        !          45478: a1398 2
        !          45479:                                } else
        !          45480: printf("R%d\n",retry[s_id]);
        !          45481: a1430 9
        !          45482:  * BDR_CHECK_INTERVAL is the number of ticks to wait between checks for
        !          45483:  * SCSI Bus Free after sending Bus Device Reset.
        !          45484:  * BDR_CHECK_COUNT is the number of times to check for SCSI Bus Free
        !          45485:  * before giving up.
        !          45486:  */
        !          45487: #define BDR_CHECK_INTERVAL     10
        !          45488: #define BDR_CHECK_COUNT                100
        !          45489: 
        !          45490: /*
        !          45491: d1434 2
        !          45492: d1437 1
        !          45493: a1437 1
        !          45494: static void    bus_dev_reset(s_id)
        !          45495: d1439 1
        !          45496: a1439 1
        !          45497:        int tries;
        !          45498: d1441 7
        !          45499: a1447 2
        !          45500: printf("bus_dev_reset\n");
        !          45501:        for (tries = 0; tries < LOPRI_RETRIES; tries++) {
        !          45502: d1456 2
        !          45503: a1457 2
        !          45504:                 * SCSI spec says there is "no maximum" to the wait for arbitration
        !          45505:                 * complete.
        !          45506: d1460 1
        !          45507: a1460 2
        !          45508:                        scsireset();
        !          45509:                        continue;
        !          45510: d1462 1
        !          45511: d1464 4
        !          45512: a1467 3
        !          45513:                /*
        !          45514:                 * Arbitration complete.  Now select, with ATN to allow messages.
        !          45515:                 */
        !          45516: d1472 2
        !          45517: a1473 1
        !          45518:                        continue;
        !          45519: d1475 1
        !          45520: d1480 2
        !          45521: a1481 1
        !          45522:                        continue;
        !          45523: d1483 1
        !          45524: d1486 2
        !          45525: a1487 1
        !          45526:                break;
        !          45527: d1489 3
        !          45528: a1491 7
        !          45529:        for (tries = 0; tries < BDR_CHECK_COUNT; tries++) {
        !          45530:                if (ffbyte(ss_csr) == 0) {
        !          45531:        printf("bus device reset done\n");
        !          45532:                        break;
        !          45533:                }
        !          45534:                ssdelay(BDR_CHECK_INTERVAL);
        !          45535:        }
        !          45536: d1545 13
        !          45537: a1557 8
        !          45538:                        if (bp->b_req == BREAD)
        !          45539:                                bp->b_resid -= ssp->data_bytes_in;
        !          45540:                        else
        !          45541:                                bp->b_resid -= ssp->data_bytes_out;
        !          45542:                        if (cmd_ok && ssp->cmdstat == CS_GOOD) {
        !          45543:                                if (ssp->msg_in == MSG_DISCONNECT) {
        !          45544:                                        ssp->dr_watch = WATCHDOG_SECONDS;
        !          45545:                                } else
        !          45546: d1559 1
        !          45547: a1559 4
        !          45548:                        } else {
        !          45549: printf("BFERR 6\n");
        !          45550:                                bp->b_flag |= BFERR;
        !          45551:                                ss_done(s_id);
        !          45552: d1575 2
        !          45553: a1576 1
        !          45554:        int retval;
        !          45555: d1582 3
        !          45556: d1587 2
        !          45557: d1591 1
        !          45558: d1605 4
        !          45559: a1608 1
        !          45560:        if (retval = bus_pre_xfer(s_id)) {
        !          45561: d1610 13
        !          45562: a1622 3
        !          45563: /* printf("cmdlen=%d cmd_bytes_out=%d cmdstat=%d\n", ssp->cmdlen,
        !          45564:        ssp->cmd_bytes_out, ssp->cmdstat); */
        !          45565:                retval = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          45566: d1624 2
        !          45567: d1629 4
        !          45568: a1632 2
        !          45569:                if (req_sense(s_id))
        !          45570:                        retval = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          45571: d1635 8
        !          45572: a1642 3
        !          45573:        retval = (retval &&
        !          45574:                (ssp->cmdstat == CS_GOOD || ssp->msg_in == MSG_DISCONNECT));
        !          45575:        return retval;
        !          45576: @
        !          45577: 
        !          45578: 
        !          45579: 1.32
        !          45580: log
        !          45581: @Accesses file system but has frequent BFERR 5's.
        !          45582: @
        !          45583: text
        !          45584: @d9 3
        !          45585: d1050 1
        !          45586: d1055 1
        !          45587: d1283 1
        !          45588: d1292 1
        !          45589: a1315 1
        !          45590:                        ssq_rm_head();
        !          45591: d1319 2
        !          45592: a1326 2
        !          45593:                                else
        !          45594:                                        printf("D");
        !          45595: d1329 1
        !          45596: d1331 6
        !          45597: a1336 2
        !          45598:                                bp->b_flag |= BFERR;
        !          45599:                                ss_done(s_id);
        !          45600: a1456 2
        !          45601: printf("R%d", s_id);
        !          45602: if(s_id!=0)s_id=-1;
        !          45603: @
        !          45604: 
        !          45605: 
        !          45606: 1.31
        !          45607: log
        !          45608: @Now fdisk command works but mkfs fails.
        !          45609: @
        !          45610: text
        !          45611: @d9 3
        !          45612: d79 1
        !          45613: a79 1
        !          45614: #define HIPRI_RETRIES  400     /* # of times to retry while hogging CPU */
        !          45615: d583 2
        !          45616: a584 2
        !          45617: printf("ssblock: drv=%x bno=%lx bp=%x flag=%x\n",
        !          45618:        drive, bp->b_bno, bp, bp->b_flag);
        !          45619: a624 1
        !          45620: printf("*");
        !          45621: d1321 1
        !          45622: a1321 1
        !          45623: printf("%d in  %d out\n",ssp->data_bytes_in,ssp->data_bytes_out);
        !          45624: d1503 1
        !          45625: a1503 1
        !          45626: printf("ss_rw(%d)\n", s_id);
        !          45627: d1527 2
        !          45628: a1528 2
        !          45629: printf("cmdlen=%d cmd_bytes_out=%d cmdstat=%d\n", ssp->cmdlen,
        !          45630:        ssp->cmd_bytes_out, ssp->cmdstat);
        !          45631: @
        !          45632: 
        !          45633: 
        !          45634: 1.30
        !          45635: log
        !          45636: @Trying to figure out disconnect after write.
        !          45637: @
        !          45638: text
        !          45639: @d9 3
        !          45640: a398 1
        !          45641: printf("BARF\n");
        !          45642: d619 1
        !          45643: a619 1
        !          45644:        int s_id;
        !          45645: a626 1
        !          45646: printf("1 s_id=%d dr_w=%d\n",s_id,ssp->dr_watch);
        !          45647: d635 2
        !          45648: a636 2
        !          45649:                                        s_id = chk_reconn();
        !          45650:                                        if (s_id == -1)
        !          45651: d639 1
        !          45652: a639 1
        !          45653:                                                reconnect(s_id);
        !          45654: d989 1
        !          45655: a1309 1
        !          45656: printf("2 s_id=%d dr_w=%d\n",s_id,ssp->dr_watch);
        !          45657: d1340 1
        !          45658: d1342 1
        !          45659: a1344 1
        !          45660: printf("3 s_id=%d dr_w=%d\n",s_id,ssp->dr_watch);
        !          45661: d1350 2
        !          45662: a1438 1
        !          45663: printf("chk_reconn: csr=%x dat=%x\n",csr,dat);
        !          45664: a1478 1
        !          45665: printf("4 s_id=%d dr_w=%d\n",s_id,ssp->dr_watch);
        !          45666: a1523 1
        !          45667: printf("ss_rw(): bus_pre_xfer ok\n");
        !          45668: d1528 1
        !          45669: a1528 2
        !          45670:        } else
        !          45671: printf("ss_rw(): bus_pre_xfer not ok\n");
        !          45672: a1537 1
        !          45673: printf("ss_rw(): retval=%d\n", retval);
        !          45674: @
        !          45675: 
        !          45676: 
        !          45677: 1.29
        !          45678: log
        !          45679: @Whole disk devices working - need to implement HDGETA.
        !          45680: @
        !          45681: text
        !          45682: @d9 3
        !          45683: d153 1
        !          45684: a210 1
        !          45685: static int     dr_watch[MAX_SCSI_ID-1];
        !          45686: a362 1
        !          45687: printf("adj partn=%d\n", partn);
        !          45688: d466 3
        !          45689: a468 3
        !          45690: #define NHEAD  7
        !          45691: #define NSEC   28
        !          45692: #define NCYL   1066
        !          45693: d494 1
        !          45694: a494 1
        !          45695:   hdparm.ncyl[0] + hdparm.ncyl[1]<<8, (int)hdparm.nhead, (int)hdparm.nspt);
        !          45696: d625 1
        !          45697: d630 1
        !          45698: a631 1
        !          45699: printf("SCSI id #%d: bno=%lu <Watchdog Timeout>\n", s_id, ss[s_id]->bp->b_bno);
        !          45700: d690 1
        !          45701: a690 1
        !          45702:        uchar query_buf[INQUIRYLEN + 1];
        !          45703: d739 16
        !          45704: d772 2
        !          45705: d967 1
        !          45706: a969 2
        !          45707:        ssp->data_bytes_in = 0;
        !          45708:        ssp->data_bytes_out = 0;
        !          45709: d1043 4
        !          45710: d1121 2
        !          45711: d1161 2
        !          45712: d1180 39
        !          45713: d1232 2
        !          45714: a1293 1
        !          45715:                ssp->bp = bp;
        !          45716: a1298 4
        !          45717:                if (partition != WHOLE_DRIVE)
        !          45718:                        ssp->bno = fdp[partition].p_base + bp->b_bno;
        !          45719:                else
        !          45720:                        ssp->bno = bp->b_bno;
        !          45721: d1300 5
        !          45722: d1308 1
        !          45723: d1316 3
        !          45724: d1342 1
        !          45725: a1344 2
        !          45726: if (bp->b_flag & BFERR)
        !          45727:   printf("BFERR\n");
        !          45728: d1429 1
        !          45729: a1429 1
        !          45730:        uchar dat;
        !          45731: d1432 2
        !          45732: a1433 1
        !          45733:        if (ffbyte(ss_csr) && RS_SELECT) {
        !          45734: d1435 1
        !          45735: d1442 1
        !          45736: d1464 1
        !          45737: a1464 1
        !          45738:        if ((dat & HOST_ID) && (dat & (1 << s_id))) {
        !          45739: d1474 1
        !          45740: a1474 1
        !          45741:                                if (ssp->msg_in == MSG_DISCONNECT)
        !          45742: d1476 2
        !          45743: a1477 1
        !          45744:                                else
        !          45745: d1509 2
        !          45746: @
        !          45747: 
        !          45748: 
        !          45749: 1.28
        !          45750: log
        !          45751: @Kernel fdisk works, fdisk command gets garbage.
        !          45752: @
        !          45753: text
        !          45754: @d9 3
        !          45755: d91 1
        !          45756: a91 1
        !          45757:        printf(" %x", ssp->in_buf[i]);printf(" data_bytes_in=%d\n",\
        !          45758: d113 1
        !          45759: a113 1
        !          45760:        uchar   *in_buf;
        !          45761: d116 1
        !          45762: a116 1
        !          45763:        uchar   *out_buf;
        !          45764: d375 1
        !          45765: d1014 4
        !          45766: a1017 2
        !          45767:                                ssp->in_buf[ssp->data_bytes_in]
        !          45768:                                = ffbyte(ss_dat);
        !          45769: d1027 4
        !          45770: a1030 1
        !          45771:                                sfbyte(ss_dat, ssp->out_buf[ssp->data_bytes_out]);
        !          45772: d1103 2
        !          45773: a1104 1
        !          45774:        rqs.in_buf = sense_buf;
        !          45775: d1109 1
        !          45776: a1109 1
        !          45777:                        if (rqs.in_buf[2] == 0x00)      /* No Sense.  AOK */
        !          45778: d1111 1
        !          45779: a1111 1
        !          45780:                        else if (rqs.in_buf[2] == 0x06 && rqs.in_buf[12] == 0x29)
        !          45781: d1141 2
        !          45782: a1142 1
        !          45783:        ssp->in_buf = buf;
        !          45784: d1171 2
        !          45785: a1172 1
        !          45786:        ssp->in_buf = buf;
        !          45787: d1228 2
        !          45788: d1427 1
        !          45789: a1427 1
        !          45790:                ssp->in_buf = FP_OFF(bp->b_faddr);
        !          45791: d1431 1
        !          45792: a1431 1
        !          45793:                ssp->out_buf = FP_OFF(bp->b_faddr);
        !          45794: @
        !          45795: 
        !          45796: 
        !          45797: 1.27
        !          45798: log
        !          45799: @Typos fixed.  Locks up CPU on first open
        !          45800: @
        !          45801: text
        !          45802: @d9 3
        !          45803: d334 1
        !          45804: a334 1
        !          45805: 
        !          45806: d357 1
        !          45807: a357 1
        !          45808: 
        !          45809: d361 2
        !          45810: d364 6
        !          45811: a369 2
        !          45812:        if (valid_open && partn != WHOLE_DRIVE && !(ssp->ptab_read))
        !          45813:                if (fdisk(dev, fdp)) {
        !          45814: d371 1
        !          45815: d373 1
        !          45816: a373 1
        !          45817: for (p=0; p<WHOLE_DRIVE; p++)
        !          45818: d381 1
        !          45819: d386 1
        !          45820: a386 1
        !          45821:        if (valid_open
        !          45822: d390 1
        !          45823: d393 1
        !          45824: a393 1
        !          45825:        if (valid_open && fdp[partn].p_size == 0) {
        !          45826: d417 1
        !          45827: d460 4
        !          45828: d470 4
        !          45829: d475 4
        !          45830: d480 12
        !          45831: a510 1
        !          45832:        register scsi_work_t *sw;
        !          45833: d538 1
        !          45834: d543 1
        !          45835: d561 1
        !          45836: d572 2
        !          45837: a573 2
        !          45838: printf("ssblock: drv %x bno %x:%x  bp=%x, flag = %o\n",
        !          45839:        drive, (long)sw->sw_bno, bp, bp->b_flag);
        !          45840: d575 1
        !          45841: a575 1
        !          45842:                ssq_wr_tail(sw);
        !          45843: d620 1
        !          45844: d1233 1
        !          45845: d1257 2
        !          45846: d1390 1
        !          45847: d1409 1
        !          45848: a1409 1
        !          45849: 
        !          45850: d1430 1
        !          45851: d1432 5
        !          45852: a1436 3
        !          45853:                retval = (ssp->cmdlen == ssp->cmd_bytes_out
        !          45854:                        && ssp->cmdstat == CS_GOOD);
        !          45855:        }
        !          45856: d1439 1
        !          45857: d1444 3
        !          45858: @
        !          45859: 
        !          45860: 
        !          45861: 1.26
        !          45862: log
        !          45863: @First clean compile with block routine.
        !          45864: @
        !          45865: text
        !          45866: @d9 3
        !          45867: d194 1
        !          45868: a194 1
        !          45869: static ss_type *ss_block;      /* points to block of "ss" structs */
        !          45870: d257 1
        !          45871: a257 1
        !          45872:                } else if ((ss_block = kalloc(num_drives*sizeof(ss_type)))
        !          45873: d262 1
        !          45874: a262 1
        !          45875:                        kclear(ss_block, num_drives * sizeof(ss_type));
        !          45876: d265 1
        !          45877: a265 1
        !          45878:                ss_type *foo = ss_block;
        !          45879: d290 2
        !          45880: a291 2
        !          45881:        if (ss_block)
        !          45882:                kfree(ss_block);
        !          45883: d669 1
        !          45884: a669 1
        !          45885:                if (inquiry(s_id), query_buf) {
        !          45886: d680 1
        !          45887: a680 1
        !          45888:                if (read_cap(s_id), query_buf) {
        !          45889: d1045 1
        !          45890: d1054 1
        !          45891: @
        !          45892: 
        !          45893: 
        !          45894: 1.25
        !          45895: log
        !          45896: @lots of strategy code added - but not ready to compile
        !          45897: @
        !          45898: text
        !          45899: @d9 3
        !          45900: d97 1
        !          45901: a528 6
        !          45902: #ifdef BNO_CALC
        !          45903:                if (partition != WHOLE_DRIVE)
        !          45904:                        sw->sw_bno = fdp[partition].p_base + bp->b_bno;
        !          45905:                else
        !          45906:                        sw->sw_bno = bp->b_bno;
        !          45907: #endif
        !          45908: d555 1
        !          45909: a558 1
        !          45910: printf("@@");
        !          45911: d563 3
        !          45912: d579 2
        !          45913: d583 7
        !          45914: a589 3
        !          45915:                                s_id = chk_reconn();
        !          45916:                                if (s_id != -1)
        !          45917:                                        reconnect(s_id);
        !          45918: d640 2
        !          45919: d666 4
        !          45920: a669 4
        !          45921:                if (inquiry(s_id)) {
        !          45922:                        ss[s_id]->in_buf[INQUIRYLEN] = 0;
        !          45923:                        devmsg(dev, ss[s_id]->in_buf + 8);
        !          45924:                        if (ss[s_id]->in_buf[0] == 0) {
        !          45925: d677 1
        !          45926: a677 1
        !          45927:                if (read_cap(s_id)) {
        !          45928: d679 7
        !          45929: a688 29
        !          45930: #if 0
        !          45931:        /*
        !          45932:         * For test purposes only, try to read the partition table.
        !          45933:         */
        !          45934:        if (retval) {
        !          45935: #define READ_PTS       1
        !          45936: int foo,fof;
        !          45937: for (foo=0,fof=0;foo<READ_PTS;){
        !          45938:        busted=0;
        !          45939:        drvl[SCSI_MAJOR].d_time++;
        !          45940:                if (read_pt(s_id)) {
        !          45941:                        retval = 1;
        !          45942:                } else {
        !          45943:                        devmsg(dev, "Read Partition Table Failed");
        !          45944:                        break;
        !          45945:                }
        !          45946: foo++;
        !          45947:        if (!rpt_irpt){
        !          45948:                fof++;
        !          45949:                if (fof>=3) {
        !          45950:                        printf("3 irq's lost\n");
        !          45951:                        break;
        !          45952:                }
        !          45953:        }
        !          45954: } /*endfor*/
        !          45955: printf("%d read_pt's\n",foo);
        !          45956:        }
        !          45957: #endif
        !          45958: 
        !          45959: a729 1
        !          45960:        int tries;
        !          45961: d731 5
        !          45962: a735 4
        !          45963:        tries = 0;
        !          45964:        do {
        !          45965:                if (tries > 0)
        !          45966:                        ssdelay(100);
        !          45967: d737 4
        !          45968: a740 5
        !          45969:                if (retval = bus_pre_xfer(s_id)) {
        !          45970:                        bus_info_xfer(ssp);
        !          45971:                        retval = (ssp->cmdlen == ssp->cmd_bytes_out
        !          45972:                                && ssp->cmdstat == CS_GOOD);
        !          45973:                }
        !          45974: a741 52
        !          45975:                if (ssp->cmdstat == CS_CHECK) {
        !          45976:                        if (req_sense(s_id))
        !          45977:                                retval = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          45978:                }
        !          45979: 
        !          45980:                tries++;
        !          45981:        } while (ssp->cmdstat == CS_BUSY && tries < LOPRI_RETRIES);
        !          45982: 
        !          45983:        if (ssp->msg_in == MSG_DISCONNECT) {
        !          45984:                int connected = 0;
        !          45985:                uchar dat, csr;
        !          45986: 
        !          45987: printf("Disconnected ");
        !          45988: {
        !          45989:        int s;
        !          45990:        s=sphi();
        !          45991:        while(!rpt_irpt && !busted)
        !          45992:                sleep(&rpt_irpt, CVBLKIO,IVBLKIO,SVBLKIO);
        !          45993:        spl(s);
        !          45994: }
        !          45995:                for (tries = 0; tries < 10; tries++) {
        !          45996:                        csr = ffbyte(ss_csr);
        !          45997:                        if (csr & RS_SELECT) {
        !          45998:                                dat = ffbyte(ss_dat);
        !          45999:                                if (dat & HOST_ID) {
        !          46000: printf("%d tries Reconnected\n",tries);
        !          46001:                                        connected = 1;
        !          46002:                                        break;
        !          46003:                                } else {
        !          46004:                                        int t;
        !          46005: printf("Host not selected\n");
        !          46006:                                        for (t = 0; t < 10; t++) {
        !          46007:                                                if (ffbyte(ss_csr) & RS_SELECT == 0) {
        !          46008: printf("Select dropped by target\n");
        !          46009:                                                        break;
        !          46010:                                                }
        !          46011:                                                ssdelay(10);
        !          46012:                                        }
        !          46013:                                }
        !          46014:                        }
        !          46015:                        ssdelay(10);
        !          46016:                }
        !          46017:                if (connected) {
        !          46018:                        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_BUSY);
        !          46019:                        if (bus_wait(RS_SELECT << 8 | 0)) {
        !          46020:                                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          46021:                                bus_info_xfer(ssp);
        !          46022:                                retval = (ssp->cmdstat == CS_GOOD);
        !          46023:                        }
        !          46024:                }
        !          46025:        }
        !          46026: 
        !          46027: d977 1
        !          46028: a977 1
        !          46029:                        if (ssp->data_bytes_out < ssp->out_buf_len && ssp->out_buf)
        !          46030: d980 1
        !          46031: a980 1
        !          46032:                        else {  /* This case should not happen. */
        !          46033: d1070 1
        !          46034: d1073 1
        !          46035: a1073 1
        !          46036: static int inquiry(s_id)
        !          46037: d1075 1
        !          46038: d1080 1
        !          46039: d1086 1
        !          46040: d1090 1
        !          46041: d1102 1
        !          46042: a1102 1
        !          46043: static int read_cap(s_id)
        !          46044: d1104 1
        !          46045: d1109 1
        !          46046: d1115 1
        !          46047: d1119 1
        !          46048: a1119 9
        !          46049:        if (ret) {
        !          46050:                ssp->capacity = ssp->in_buf[3] | (ssp->in_buf[2] << 8)
        !          46051:                | (((long)(ssp->in_buf[1])) << 16)
        !          46052:                | (((long)(ssp->in_buf[0])) << 24);
        !          46053:                ssp->blocklen = ssp->in_buf[7] | (ssp->in_buf[6] << 8)
        !          46054:                | (((long)(ssp->in_buf[5])) << 16)
        !          46055:                | (((long)(ssp->in_buf[4])) << 24);
        !          46056: printf("capacity=%ld   block length=%ld\n", ssp->capacity, ssp->blocklen);
        !          46057:        }
        !          46058: d1153 3
        !          46059: d1169 7
        !          46060: a1217 28
        !          46061:  * read_pt()
        !          46062:  *
        !          46063:  * Read partition table for a device.
        !          46064:  *
        !          46065:  * Return 1 if command succeeds, else 0.
        !          46066:  */
        !          46067: static int read_pt(s_id)
        !          46068: int s_id;
        !          46069: {
        !          46070:        int ret = 0;
        !          46071:        ss_type * ssp = ss[s_id];
        !          46072: 
        !          46073:        ssp->cmdbuf[0] = ScmdREADEXTENDED;
        !          46074:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] = 0;
        !          46075:        ssp->cmdbuf[5] = ssp->cmdbuf[6] = ssp->cmdbuf[7] = ssp->cmdbuf[9] = 0;
        !          46076:        ssp->cmdbuf[8] = 1;     /* transfer 1 block */
        !          46077:        ssp->cmdlen = G1CMDLEN;
        !          46078:        ssp->in_buf_len = BSIZE;
        !          46079: 
        !          46080:        ret = scsicmd(s_id);
        !          46081:        if (ret) {
        !          46082: printf("signature low:%x high:%x\n", ssp->in_buf[510], ssp->in_buf[511]);
        !          46083:        }
        !          46084: 
        !          46085:        return ret;
        !          46086: }
        !          46087: 
        !          46088: /*
        !          46089: d1321 1
        !          46090: d1324 1
        !          46091: d1326 20
        !          46092: a1345 5
        !          46093:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_BUSY);
        !          46094:        if (bus_wait(RS_SELECT << 8 | 0)) {
        !          46095:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          46096:                if (bus_info_xfer(ssp) && ssp->cmdstat == CS_GOOD)
        !          46097:                        cmd_ok = 1;
        !          46098: d1347 1
        !          46099: a1347 7
        !          46100: /* This is not finished: dr_watch, bdone, id_busy, etc. 
        !          46101: and what of another disconnect??? */
        !          46102: /* no disconnect allowed for inquiry, test ready, read capacity, etc. */
        !          46103:                bp->b_resid -= BSIZE;
        !          46104:        if (cmd_ok)
        !          46105:        if (ssp->msg_in != MSG_DISCONNECT)
        !          46106:                ssp->dr_watch = WATCHDOG_SECONDS;
        !          46107: a1348 2
        !          46108: }
        !          46109: 
        !          46110: d1370 6
        !          46111: a1375 2
        !          46112:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] = 0;
        !          46113:        ssp->cmdbuf[5] = ssp->cmdbuf[6] = ssp->cmdbuf[9] = 0;
        !          46114: d1378 1
        !          46115: @
        !          46116: 
        !          46117: 
        !          46118: 1.24
        !          46119: log
        !          46120: @Some rearrangements - still working on block & related routines
        !          46121: @
        !          46122: text
        !          46123: @a0 2
        !          46124: int rpt_irpt;
        !          46125: int busted;
        !          46126: d2 1
        !          46127: a2 1
        !          46128:  * This is a driver for Seagate ST01/ST02 scsi hard disk controllers.
        !          46129: d9 3
        !          46130: d61 1
        !          46131: a64 6
        !          46132:                                /* Device States */
        !          46133: #define        SIDLE           0       /* controller idle */
        !          46134: #define        SRETRY          1       /* seeking */
        !          46135: #define        SREAD           2       /* reading */
        !          46136: #define        SWRITE          3       /* writing */
        !          46137: 
        !          46138: d90 1
        !          46139: d92 2
        !          46140: a93 2
        !          46141:        long    capacity;
        !          46142:        long    blocklen;
        !          46143: d95 1
        !          46144: d100 1
        !          46145: a100 1
        !          46146:        uchar   in_buf[IN_BUF_SIZE];
        !          46147: d103 4
        !          46148: a106 1
        !          46149:        BUF     *bp;
        !          46150: d135 1
        !          46151: a135 2
        !          46152: static void    chk_reconn();
        !          46153: static void    do_ss();
        !          46154: d138 1
        !          46155: d143 1
        !          46156: a192 1
        !          46157: static int     ss_state;       /* starts at SIDLE */
        !          46158: d380 2
        !          46159: a381 1
        !          46160:         * OK - open the device.
        !          46161: d394 3
        !          46162: d521 2
        !          46163: a522 1
        !          46164:         * See if we can allocate a request node for this operation.
        !          46165: d525 1
        !          46166: a525 16
        !          46167:                bp->b_actf = NULL;
        !          46168:                sw = (scsi_work_t *)kalloc( sizeof(*sw) );
        !          46169:                if (sw == NULL) {
        !          46170:                        devmsg(dev, "out of kernel memory");
        !          46171:                        bp->b_flag |= BFERR;
        !          46172:                        valid_op = 0;
        !          46173:                }
        !          46174:        }
        !          46175: 
        !          46176:        /*
        !          46177:         * Operation appears valid and we have a node for it.
        !          46178:         * Fill fields in the node and queue the request.
        !          46179:         */
        !          46180:        if (valid_op) {
        !          46181:                sw->sw_bp = bp;
        !          46182:                sw->sw_drv = drive;
        !          46183: d530 1
        !          46184: a530 1
        !          46185:                sw->sw_retry = 1;
        !          46186: d536 1
        !          46187: a536 2
        !          46188:                if (ss_state == SIDLE)
        !          46189:                        ss_start();
        !          46190: d548 4
        !          46191: d555 6
        !          46192: a560 3
        !          46193:        printf("@@");
        !          46194:        rpt_irpt=1;
        !          46195:        wakeup(&rpt_irpt);
        !          46196: d568 2
        !          46197: a569 1
        !          46198:        int     s_id;
        !          46199: d571 6
        !          46200: a576 5
        !          46201:        for (s_id = 0; s_id < MAX_SCSI_ID-1; s_id++)
        !          46202:                if (dr_watch[s_id]) {
        !          46203:                        dr_watch[s_id]--;
        !          46204:                        chk_reconn();
        !          46205:                        if (dr_watch[s_id] == 0) {
        !          46206: d579 4
        !          46207: d585 1
        !          46208: a585 4
        !          46209:        printf("*");
        !          46210:        busted = 1;
        !          46211:        drvl[SCSI_MAJOR].d_time--;
        !          46212:        wakeup(&rpt_irpt);
        !          46213: d673 1
        !          46214: a673 1
        !          46215: #if 1
        !          46216: a680 1
        !          46217:        rpt_irpt=0;
        !          46218: d968 1
        !          46219: d1032 1
        !          46220: a1032 1
        !          46221:                        if (ssp->data_bytes_in < ssp->in_buf_len)
        !          46222: d1035 2
        !          46223: a1036 1
        !          46224:                        else
        !          46225: a1037 1
        !          46226:                        ssp->data_bytes_in++;
        !          46227: d1041 1
        !          46228: a1041 1
        !          46229:                         * Temporary filler.
        !          46230: d1043 7
        !          46231: a1049 1
        !          46232:                        sfbyte(ss_dat, 0xAA);
        !          46233: d1193 1
        !          46234: a1193 2
        !          46235:  * Invoked whenever there is I/O to do.  Pull first request, if any,
        !          46236:  * off the queue, send it to the drive, and delete it from the queue.
        !          46237: d1196 15
        !          46238: d1215 1
        !          46239: a1215 1
        !          46240:        scsi_work_t *sw;
        !          46241: d1217 2
        !          46242: d1228 20
        !          46243: a1247 8
        !          46244:        if((sw = ssq_rm_head()) != NULL) {
        !          46245:                if (sw->sw_bp->b_req == BWRITE)
        !          46246:                        ss_state = SWRITE;
        !          46247:                else if (sw->sw_bp->b_req == BREAD)
        !          46248:                        ss_state = SREAD;
        !          46249:                else
        !          46250:                        printf("Error:  b_req=%d\n", sw->sw_bp->b_req);
        !          46251:                do_ss(sw);
        !          46252: d1253 1
        !          46253: a1253 1
        !          46254:  * do_ss()
        !          46255: a1254 24
        !          46256:  * Begin a block read or write command as found in an "sw" queue entry.
        !          46257:  */
        !          46258: static void do_ss(sw)
        !          46259: struct scsi_work_t * sw;
        !          46260: {
        !          46261:        BUF * bp;
        !          46262: 
        !          46263: printf("do_ss\n");
        !          46264:        bp = sw->sw_bp;
        !          46265:        switch(ss_state) {
        !          46266:        case SREAD:
        !          46267:                bp->b_resid -= BSIZE;
        !          46268:                ss_done(sw);
        !          46269:                break;
        !          46270:        case SWRITE:
        !          46271:                bp->b_resid -= BSIZE;
        !          46272:                ss_done(sw);
        !          46273:                break;
        !          46274:        }
        !          46275: }
        !          46276: 
        !          46277: /*
        !          46278:  * ss_done
        !          46279:  *
        !          46280: d1257 2
        !          46281: a1258 2
        !          46282: static void ss_done(sw)
        !          46283: struct scsi_work_t * sw;
        !          46284: d1260 2
        !          46285: a1261 1
        !          46286:        BUF * bp;
        !          46287: d1263 4
        !          46288: a1266 5
        !          46289: printf("ss_done\n");
        !          46290:        if (sw) {
        !          46291:                bp = sw->sw_bp;
        !          46292: 
        !          46293:                ss_state = SIDLE;
        !          46294: d1268 1
        !          46295: a1268 1
        !          46296:                kfree(sw);
        !          46297: d1270 2
        !          46298: a1272 4
        !          46299:        if (ssq_rd_head())
        !          46300:                ss_start();
        !          46301: }
        !          46302: 
        !          46303: d1358 1
        !          46304: a1358 1
        !          46305:                        printf("bus device reset done\n");
        !          46306: d1368 1
        !          46307: a1368 1
        !          46308:  * Poll to see if any SCSI device has tried to reconnect to the host
        !          46309: d1371 5
        !          46310: d1377 1
        !          46311: a1377 1
        !          46312: static void chk_reconn()
        !          46313: d1379 15
        !          46314: d1395 68
        !          46315: @
        !          46316: 
        !          46317: 
        !          46318: 1.23
        !          46319: log
        !          46320: @ssopen compiles - not tested
        !          46321: @
        !          46322: text
        !          46323: @d11 3
        !          46324: d25 19
        !          46325: d45 4
        !          46326: d61 2
        !          46327: d93 18
        !          46328: d112 4
        !          46329: a115 1
        !          46330:  * Includes.
        !          46331: a116 30
        !          46332: #include       <coherent.h>
        !          46333: #include       <sys/io.h>
        !          46334: #include       <sys/sched.h>
        !          46335: #include       <sys/uproc.h>
        !          46336: #include       <sys/proc.h>
        !          46337: #include       <sys/con.h>
        !          46338: #include       <sys/stat.h>
        !          46339: #include       <sys/devices.h>         /* SCSI_MAJOR */
        !          46340: #include       <errno.h>
        !          46341: 
        !          46342: #include       <sys/fdisk.h>
        !          46343: #include       <sys/hdioctl.h>
        !          46344: #include       <sys/buf.h>
        !          46345: #include       <scsiwork.h>
        !          46346: #include       <ss.h>
        !          46347: 
        !          46348: /*
        !          46349:  * Export Functions.
        !          46350:  */
        !          46351: 
        !          46352: /*
        !          46353:  * Export Variables - patch these to configure the driver.
        !          46354:  */
        !          46355: int    NSDRIVE = 1;            /* Bitmap of attached SCSI drives. */
        !          46356: int    SS_INT = 5;             /* ST0[12] use either IRQ3 or IRQ5 */
        !          46357: int    SS_BASE = 0xDE00;       /* Segment addr of ST0x communication area */
        !          46358: 
        !          46359: /*
        !          46360:  * Import Functions.
        !          46361:  */
        !          46362: a120 3
        !          46363: /*
        !          46364:  * Local Functions.
        !          46365:  */
        !          46366: d134 1
        !          46367: d150 4
        !          46368: a153 1
        !          46369:  * Local Variables.
        !          46370: a154 20
        !          46371: static BUF     dbuf;           /* For raw I/O */
        !          46372: static paddr_t ss_base;        /* physical address of ST0x comm area */
        !          46373: static faddr_t ss_fp;          /* (far *) to ST0x comm area */
        !          46374: 
        !          46375: static faddr_t ss_ram;         /* (far *) to parameter RAM */
        !          46376: static faddr_t ss_csr;         /* (far *) to control/status */
        !          46377: static faddr_t ss_dat;         /* (far *) to data port */
        !          46378: 
        !          46379: static int     num_drives;     /* number of controller SCSI id's */
        !          46380: static struct ss *ss_block;    /* points to block of "ss" structs */
        !          46381: static int     st0x_busy;      /* 1 if SCSI host adapter busy */
        !          46382: 
        !          46383: static TIM     delay_tim;      /* needed for calls to ssdelay() */
        !          46384: static TIM     timeout_tim;    /* needed for calls to timeout() */
        !          46385: static int     ss_expired;     /* 1 after local timeout */
        !          46386: static int     ss_state;       /* starts at SIDLE */
        !          46387: 
        !          46388: /*
        !          46389:  * Driver CON entry - an export variable.
        !          46390:  */
        !          46391: d171 4
        !          46392: a174 5
        !          46393: /*
        !          46394:  * A per-drive structure - ss
        !          46395:  */
        !          46396: #define IN_BUF_SIZE    512
        !          46397: typedef unsigned char  uchar;
        !          46398: d176 3
        !          46399: a178 15
        !          46400: static struct ss       {
        !          46401:        long    capacity;
        !          46402:        long    blocklen;
        !          46403:        int     msg_in;
        !          46404:        uchar   cmdbuf[G1CMDLEN];
        !          46405:        int     cmdlen;
        !          46406:        int     cmd_bytes_out;
        !          46407:        int     cmdstat;
        !          46408:        uchar   in_buf[IN_BUF_SIZE];
        !          46409:        int     in_buf_len;
        !          46410:        int     data_bytes_in;
        !          46411:        struct  fdisk_s parmp[NPARTN+1];
        !          46412:        unsigned int    ptab_read:1;  /* 1 if partition table has been read */
        !          46413:        unsigned int    id_busy:1;  /* 1 if device with this SCSI id busy */
        !          46414: } *ss[MAX_SCSI_ID-1], rqs;
        !          46415: d180 15
        !          46416: d249 1
        !          46417: a249 1
        !          46418:                } else if ((ss_block = kalloc(num_drives*sizeof(struct ss)))
        !          46419: d254 1
        !          46420: a254 1
        !          46421:                        kclear(ss_block, num_drives * sizeof(struct ss));
        !          46422: d257 1
        !          46423: a257 1
        !          46424:                struct ss *foo = ss_block;
        !          46425: d311 1
        !          46426: a311 1
        !          46427:        struct ss * ssp;
        !          46428: d467 1
        !          46429: a467 1
        !          46430:        struct ss * ssp;
        !          46431: d571 11
        !          46432: d584 1
        !          46433: a584 1
        !          46434:        drvl[SCSI_MAJOR].d_time=0;
        !          46435: d683 1
        !          46436: a683 1
        !          46437:        drvl[SCSI_MAJOR].d_time=1;
        !          46438: d718 1
        !          46439: a718 1
        !          46440:        struct ss * ssp = ss[s_id];
        !          46441: d743 1
        !          46442: a743 1
        !          46443:        struct ss *ssp = ss[s_id];
        !          46444: d958 1
        !          46445: a958 1
        !          46446: struct ss *ssp;
        !          46447: d1136 1
        !          46448: a1136 1
        !          46449:        struct ss * ssp = ss[s_id];
        !          46450: d1161 1
        !          46451: a1161 1
        !          46452:        struct ss * ssp = ss[s_id];
        !          46453: d1253 2
        !          46454: a1254 1
        !          46455:        bp = sw->sw_bp;
        !          46456: d1256 4
        !          46457: a1259 3
        !          46458:        ss_state = SIDLE;
        !          46459:        bdone(bp);
        !          46460:        kfree(sw);
        !          46461: d1276 1
        !          46462: a1276 1
        !          46463:        struct ss * ssp = ss[s_id];
        !          46464: d1356 11
        !          46465: @
        !          46466: 
        !          46467: 
        !          46468: 1.22
        !          46469: log
        !          46470: @Starting to get block operations working.
        !          46471: @
        !          46472: text
        !          46473: @d11 3
        !          46474: a76 1
        !          46475: #include       <ss.h>
        !          46476: d82 1
        !          46477: a101 4
        !          46478: extern void ssq_wr_tail();
        !          46479: extern scsi_work_t * ssq_rd_head();
        !          46480: extern scsi_work_t * ssq_rm_head();
        !          46481: 
        !          46482: d303 1
        !          46483: a303 1
        !          46484: static void ssopen( dev, mode )
        !          46485: d307 4
        !          46486: a310 1
        !          46487:        int erf = 0;
        !          46488: d312 4
        !          46489: d318 3
        !          46490: d328 1
        !          46491: a328 1
        !          46492:                erf = 1;
        !          46493: d332 1
        !          46494: a332 1
        !          46495:         * If "special" bit is set, partition must be zero.
        !          46496: d334 1
        !          46497: a334 1
        !          46498:        if (!erf && DEV_SPECIAL(dev) && partn != 0) {
        !          46499: d336 1
        !          46500: a336 1
        !          46501:                erf = 1;
        !          46502: d340 1
        !          46503: a340 1
        !          46504:         * If "special" bit is NOT set, error return for now.
        !          46505: d342 2
        !          46506: a343 4
        !          46507:        if (!erf && !DEV_SPECIAL(dev)) {
        !          46508:                u.u_error = ENXIO;
        !          46509:                erf = 1;
        !          46510:        }
        !          46511: d346 2
        !          46512: a347 1
        !          46513:         * OK - open the device.
        !          46514: d349 13
        !          46515: a361 4
        !          46516:        if (!erf) {
        !          46517:                ++drvl[SCSI_MAJOR].d_time;
        !          46518:        }
        !          46519: #if 0
        !          46520: d365 2
        !          46521: a366 1
        !          46522:        if ((pparm[p].p_base+pparm[p].p_size) > pparm[d+NDRIVE*NPARTN].p_size)
        !          46523: d368 4
        !          46524: a371 1
        !          46525:        else if ( pparm[p].p_size == 0 )
        !          46526: d373 9
        !          46527: a381 1
        !          46528: #endif
        !          46529: d387 1
        !          46530: a387 1
        !          46531: static void ssclose( dev )
        !          46532: d394 1
        !          46533: a394 1
        !          46534:  * ssread()    - write a block to the raw disk
        !          46535: d401 1
        !          46536: a401 1
        !          46537: static void ssread( dev, iop )
        !          46538: d416 1
        !          46539: a416 1
        !          46540: static void sswrite( dev, iop )
        !          46541: d433 1
        !          46542: a433 1
        !          46543: static int ssioctl( dev, cmd, vec )
        !          46544: d660 1
        !          46545: a660 10
        !          46546: #if 0
        !          46547:        if (retval) {
        !          46548:                retval = fdisk(dev, ss[s_id]->parmp);
        !          46549:                if (retval) {
        !          46550:                        printf("fdisk scsi id #%d succeeded\n", s_id);
        !          46551:                        ss[s_id]->ptab_read = 1;
        !          46552:                } else
        !          46553:                        printf("fdisk scsi id #%d failed\n", s_id);
        !          46554:        }
        !          46555: #else
        !          46556: a788 1
        !          46557: printf("Select deasserted by target\n");
        !          46558: @
        !          46559: 
        !          46560: 
        !          46561: 1.21
        !          46562: log
        !          46563: @Move define's to ss.h and scsiwork.h.  Other cleanup
        !          46564: @
        !          46565: text
        !          46566: @a6 1
        !          46567:  *     turn on interrupts
        !          46568: d11 3
        !          46569: d645 1
        !          46570: d647 1
        !          46571: a647 1
        !          46572: for (foo=0,fof=0;foo<100;){
        !          46573: @
        !          46574: 
        !          46575: 
        !          46576: 1.20
        !          46577: log
        !          46578: @Reads boot sector 100 times using IRQ on reconnect
        !          46579: @
        !          46580: text
        !          46581: @d12 2
        !          46582: a13 51
        !          46583:  * Revision 1.19       91/03/26  23:15:47      root
        !          46584:  * Reads partition table in prototype code
        !          46585:  * 
        !          46586:  * Revision 1.18       91/03/25  20:11:30      root
        !          46587:  * first raw read - disconnects
        !          46588:  * 
        !          46589:  * Revision 1.17       91/03/25  19:06:36      root
        !          46590:  * calls ssqueue functions - need real i/o
        !          46591:  * 
        !          46592:  * Revision 1.16       91/03/22  17:40:03      root
        !          46593:  * Need to do more with ss_start()
        !          46594:  * 
        !          46595:  * Revision 1.15       91/03/21  16:44:03      root
        !          46596:  * getting ready to call fdisk - finish ss_start next
        !          46597:  * 
        !          46598:  * Revision 1.14       91/03/20  17:25:14      root
        !          46599:  * Inquiry and Read Capacity working
        !          46600:  * 
        !          46601:  * Revision 1.13       91/03/18  17:43:18      root
        !          46602:  * add retry logic to scsicmd(); general cleanup
        !          46603:  * 
        !          46604:  * Revision 1.12       91/03/14  17:22:28      root
        !          46605:  * Test Ready now works, including Req Sense
        !          46606:  * 
        !          46607:  * Revision 1.11       91/03/14  15:45:12      root
        !          46608:  * has trouble with Test Ready using bus_info_xfer fsa
        !          46609:  * 
        !          46610:  * Revision 1.10       91/03/13  17:08:03      root
        !          46611:  * still more to do on bus_info_xfer
        !          46612:  * 
        !          46613:  * Revision 1.9        91/03/12  16:08:23      root
        !          46614:  * need to finish bus_info_xfer()
        !          46615:  * 
        !          46616:  * Revision 1.8        91/03/11  17:41:10      root
        !          46617:  * started ssopen()/wrote stub for ssinit()
        !          46618:  * 
        !          46619:  * Revision 1.7        91/03/08  17:07:28      root
        !          46620:  * Does Test Read and Request Sense properly.
        !          46621:  * 
        !          46622:  * Revision 1.6        91/03/07  16:41:31      root
        !          46623:  * sends Test Ready, Starts to Request Sense
        !          46624:  * 
        !          46625:  * Revision 1.5        91/03/07  11:48:39      root
        !          46626:  * Now sends Identify and Abort messages & completes a SCSI bus cycle
        !          46627:  *
        !          46628:  * Revision 1.4        91/03/06  16:31:45      root
        !          46629:  * tried to send Identify message - get status 0x40 & fail
        !          46630:  *
        !          46631:  * Revision 1.3        91/03/05  17:03:43      root
        !          46632:  * Goes thru arbitration (sans IRQ) successfully
        !          46633:  *
        !          46634: a24 26
        !          46635: #define SS_RAM         0x1800  /* Offset of parameter RAM */
        !          46636: #define SS_CSR         0x1A00  /* Offset of control/status register */
        !          46637: #define SS_DAT         0x1C00  /* Offset of data port */
        !          46638: 
        !          46639: #define SS_RAM_LEN     128     /* ST0x has 128 bytes of RAM */
        !          46640: #define SS_DAT_LEN     0x400   /* Byte range mapped to data port */
        !          46641: #define SS_SEL_LEN     0x2000  /* Total size of memory-mapped area */
        !          46642: 
        !          46643: #define WC_ENABLE_SCSI 0x80    /* Write Control (WC) register bits */
        !          46644: #define WC_ENABLE_IRPT 0x40
        !          46645: #define WC_ENABLE_PRTY 0x20
        !          46646: #define WC_ARBITRATE   0x10
        !          46647: #define WC_ATTENTION   0x08
        !          46648: #define WC_BUSY        0x04
        !          46649: #define WC_SELECT      0x02
        !          46650: #define WC_SCSI_RESET          0x01
        !          46651: 
        !          46652: #define RS_ARBIT_COMPL 0x80    /* Read STATUS (RS) register bits */
        !          46653: #define RS_PRTY_ERROR  0x40
        !          46654: #define RS_SELECT      0x20
        !          46655: #define RS_REQUEST     0x10
        !          46656: #define RS_CTRL_DATA   0x08
        !          46657: #define RS_I_O         0x04
        !          46658: #define RS_MESSAGE     0x02
        !          46659: #define RS_BUSY        0x01
        !          46660: 
        !          46661: a29 19
        !          46662: #define G0CMDLEN       6       /* Group 0 commands are 6 bytes long  */
        !          46663: #define G1CMDLEN       10      /* Group 1 commands are 10 bytes long */
        !          46664: #define SENSELEN       22      /* number of bytes returned w/ req sense */
        !          46665: #define INQUIRYLEN     54      /* number of bytes returned w/ inquiry */
        !          46666: 
        !          46667:                                /* Message types */
        !          46668: #define MSG_CMD_CMPLT  0x00    /* Command Complete */
        !          46669: #define MSG_SAVE_DPTR  0x02    /* Save SCSI data pointer */
        !          46670: #define MSG_RSTOR_DPTR 0x03    /* Restore SCSI pointers */
        !          46671: #define MSG_DISCONNECT 0x04    /* Target is about to disconnect */
        !          46672: #define MSG_ABORT      0x06    /* End the current SCSI bus cycle */
        !          46673: #define MSG_DEV_RESET  0x0C    /* Bus Device Reset */
        !          46674: #define MSG_IDENT_DC   0xC0    /* Identify, with Disconnect allowed */
        !          46675: 
        !          46676: #define CS_GOOD                0x00    /* Command Status from the drive */
        !          46677: #define CS_CHECK       0x02
        !          46678: #define CS_BUSY                0x08
        !          46679: #define CS_RESERVED    0x18
        !          46680: 
        !          46681: a35 12
        !          46682: /*
        !          46683:  * Information Transfer Phase masks -
        !          46684:  * setting of RS_MESSAGE, RS_I_O, and RS_CTRL_DATA determines which of six
        !          46685:  * possible info transfer phases is occurring.
        !          46686:  */
        !          46687: #define XP_MSG_IN      (RS_MESSAGE | RS_I_O | RS_CTRL_DATA)
        !          46688: #define XP_MSG_OUT     (RS_MESSAGE          | RS_CTRL_DATA)
        !          46689: #define XP_STAT_IN     (             RS_I_O | RS_CTRL_DATA)
        !          46690: #define XP_CMD_OUT     (                      RS_CTRL_DATA)
        !          46691: #define XP_DATA_IN     (             RS_I_O               )
        !          46692: #define XP_DATA_OUT    (                                 0)
        !          46693: 
        !          46694: d70 1
        !          46695: a70 1
        !          46696: #include       <devices.h>             /* SCSI_MAJOR */
        !          46697: d72 1
        !          46698: d104 1
        !          46699: a104 3
        !          46700: static void    ssload();
        !          46701: static void    ssunload();
        !          46702: static void    ssopen();
        !          46703: d106 1
        !          46704: d111 10
        !          46705: a120 2
        !          46706: static void    ssblock();
        !          46707: static int     ssinit();
        !          46708: d123 2
        !          46709: a124 3
        !          46710: static void    ssdelay();
        !          46711: static int     bus_pre_xfer();
        !          46712: static int     bus_info_xfer();
        !          46713: d127 2
        !          46714: a128 3
        !          46715: static int     req_sense();
        !          46716: static int     inquiry();
        !          46717: static int     read_cap();
        !          46718: a129 4
        !          46719: static void    ss_start();
        !          46720: static void    ss_done();
        !          46721: static void    do_ss();
        !          46722: static void    bus_dev_reset();
        !          46723: d435 1
        !          46724: d437 2
        !          46725: a446 1
        !          46726: 
        !          46727: a448 2
        !          46728:        bp->b_resid = bp->b_count;
        !          46729:        
        !          46730: d458 1
        !          46731: a458 2
        !          46732:                                bdone(bp);
        !          46733:                                return;
        !          46734: d463 1
        !          46735: a463 2
        !          46736:                        bdone(bp);
        !          46737:                        return;
        !          46738: d471 1
        !          46739: a471 2
        !          46740:                bdone(bp);
        !          46741:                return;
        !          46742: d479 1
        !          46743: a479 2
        !          46744:                bdone(bp);
        !          46745:                return;
        !          46746: d482 11
        !          46747: a492 7
        !          46748:        bp->b_actf = NULL;
        !          46749:        sw = (scsi_work_t *)kalloc( sizeof(*sw) );
        !          46750:        if (sw == NULL) {
        !          46751:                devmsg(dev, "out of kernel memory");
        !          46752:                bp->b_flag |= BFERR;
        !          46753:                bdone(bp);
        !          46754:                return;
        !          46755: a493 7
        !          46756:        sw->sw_bp = bp;
        !          46757:        sw->sw_drv = drive;
        !          46758:        if (partition != WHOLE_DRIVE)
        !          46759:                sw->sw_bno = fdp[partition].p_base + bp->b_bno;
        !          46760:        else
        !          46761:                sw->sw_bno = bp->b_bno;
        !          46762:        sw->sw_retry = 1;
        !          46763: d495 13
        !          46764: d511 10
        !          46765: a520 3
        !          46766:        ssq_wr_tail(sw);
        !          46767:        if (ss_state == SIDLE)
        !          46768:                ss_start();
        !          46769: a525 6
        !          46770: #if 0
        !          46771: static int irpted;
        !          46772: static long x;
        !          46773: for (x = 0, irpted = 0; x < 100000L; x++)  if (irpted) break;
        !          46774: #endif
        !          46775: 
        !          46776: a583 16
        !          46777:  *
        !          46778:  * Pseudocode:
        !          46779:  *
        !          46780:  * retval = 0
        !          46781:  * if Test Unit Ready command fails, even after SCSI reset and retry
        !          46782:  *   print "Test Unit Ready fails"
        !          46783:  * else if Request Sense command fails
        !          46784:  *   print "Request Sense fails"
        !          46785:  * else if Read Capacity command succeeds
        !          46786:  *   print "Read Capacity fails"
        !          46787:  * else if partition table can't be read
        !          46788:  *   print "can't get partition table"
        !          46789:  * else
        !          46790:  *   print "SCSI id #n initialized"
        !          46791:  *   retval = 1
        !          46792:  * return retval
        !          46793: d591 4
        !          46794: d671 2
        !          46795: a785 2
        !          46796: int RESET_ON_TICKS = 40;
        !          46797: int RESET_OFF_TICKS = 40;
        !          46798: d790 1
        !          46799: a790 1
        !          46800:        ssdelay(RESET_ON_TICKS);
        !          46801: d792 1
        !          46802: a792 1
        !          46803:        ssdelay(RESET_OFF_TICKS);
        !          46804: a940 4
        !          46805:                        /*
        !          46806:                         * Only pay attention to first msg byte in.
        !          46807:                         * Don't care about extended messages.
        !          46808:                         */
        !          46809: a941 1
        !          46810: printf("msg_in = %x\n", msg_in);
        !          46811: @
        !          46812: 0707070064030104131004440000030000030000011777770507310661700006100000210603/newbits/kernel/USRSRC/i8086/drv/RCS/ss36_46.c,vhead     1.46;
        !          46813: access   ;
        !          46814: symbols  ;
        !          46815: locks    ;
        !          46816: comment  @ * @;
        !          46817: 
        !          46818: 
        !          46819: 1.46
        !          46820: date     91.05.16.21.54.10;  author root;  state Exp;
        !          46821: branches ;
        !          46822: next   1.45;
        !          46823: 
        !          46824: 1.45
        !          46825: date     91.05.16.17.47.26;  author root;  state Exp;
        !          46826: branches ;
        !          46827: next   1.44;
        !          46828: 
        !          46829: 1.44
        !          46830: date     91.05.16.14.17.20;  author root;  state Exp;
        !          46831: branches ;
        !          46832: next   1.43;
        !          46833: 
        !          46834: 1.43
        !          46835: date     91.05.16.01.08.22;  author root;  state Exp;
        !          46836: branches ;
        !          46837: next   1.42;
        !          46838: 
        !          46839: 1.42
        !          46840: date     91.05.15.23.58.22;  author root;  state Exp;
        !          46841: branches ;
        !          46842: next   1.41;
        !          46843: 
        !          46844: 1.41
        !          46845: date     91.05.15.21.57.55;  author root;  state Exp;
        !          46846: branches 1.41.1.1;
        !          46847: next   1.40;
        !          46848: 
        !          46849: 1.40
        !          46850: date     91.05.15.15.19.52;  author root;  state Exp;
        !          46851: branches 1.40.1.1;
        !          46852: next   1.39;
        !          46853: 
        !          46854: 1.39
        !          46855: date     91.05.15.09.35.58;  author root;  state Exp;
        !          46856: branches ;
        !          46857: next   1.38;
        !          46858: 
        !          46859: 1.38
        !          46860: date     91.05.14.10.05.37;  author root;  state Exp;
        !          46861: branches ;
        !          46862: next   1.37;
        !          46863: 
        !          46864: 1.37
        !          46865: date     91.05.13.15.02.21;  author root;  state Exp;
        !          46866: branches ;
        !          46867: next   1.36;
        !          46868: 
        !          46869: 1.36
        !          46870: date     91.05.13.11.08.25;  author root;  state Exp;
        !          46871: branches ;
        !          46872: next   ;
        !          46873: 
        !          46874: 1.40.1.1
        !          46875: date     91.05.15.23.21.27;  author root;  state Exp;
        !          46876: branches ;
        !          46877: next   ;
        !          46878: 
        !          46879: 1.41.1.1
        !          46880: date     91.05.15.23.47.43;  author root;  state Exp;
        !          46881: branches ;
        !          46882: next   ;
        !          46883: 
        !          46884: 
        !          46885: desc
        !          46886: @Seagate ST01/ST02 device driver - state machine version.
        !          46887: @
        !          46888: 
        !          46889: 
        !          46890: 1.46
        !          46891: log
        !          46892: @Hang bug fixed.  Raw i/o > 1 block reads 0.
        !          46893: @
        !          46894: text
        !          46895: @/*
        !          46896:  * Device driver for Seagate ST01/ST02 scsi host adapters.
        !          46897:  *
        !          46898:  * To do:
        !          46899:  *     set host_claimed conscientiously
        !          46900:  *     works but hogs CPU during big dd to /dev/null
        !          46901:  *
        !          46902:  *     bufq_rd_head()
        !          46903:  *     bufq_rm_head()
        !          46904:  *     bufq_wr_tail()
        !          46905:  *
        !          46906:  *     backoff & retry when bdr or req sense needed
        !          46907:  *     nonzero LUN's
        !          46908:  *     assembler I/O
        !          46909:  *
        !          46910:  * $Log:       /usr/src/sys/i8086/drv/RCS/ss.c,v $
        !          46911:  * Revision 1.45       91/05/16  17:47:26      root
        !          46912:  * Still trying to test ss_get.  Always hangs.
        !          46913:  * 
        !          46914:  * Revision 1.44       91/05/16  14:17:20      root
        !          46915:  * Drop unneeded fields from ss struct.  Try ss_get().
        !          46916:  * 
        !          46917:  * Revision 1.43       91/05/16  01:08:22      root
        !          46918:  * Needs assembler I/O most.
        !          46919:  * 
        !          46920:  * Revision 1.42       91/05/15  23:58:22      root
        !          46921:  * COH fdisk command gives junk when DEBUG=1, ok if DEBUG=3
        !          46922:  * 
        !          46923:  * Revision 1.41       91/05/15  21:57:55      root
        !          46924:  * First working version.
        !          46925:  * 
        !          46926:  * Revision 1.40       91/05/15  15:19:52      root
        !          46927:  * First clean compile of state machine version.
        !          46928:  * 
        !          46929:  * Revision 1.39       91/05/15  09:35:58      root
        !          46930:  * Code recover, do_connect, etc..
        !          46931:  * 
        !          46932:  * Revision 1.38       91/05/14  10:05:37      root
        !          46933:  * Code ss_mach().
        !          46934:  * 
        !          46935:  * Revision 1.37       91/05/13  15:02:21      root
        !          46936:  * Initial state machine hacks.
        !          46937:  * 
        !          46938:  * Revision 1.36       91/05/13  11:08:25      root
        !          46939:  * Last version before using state machine logic.
        !          46940:  * 
        !          46941:  */
        !          46942: 
        !          46943: /*
        !          46944:  * Debug levels.
        !          46945:  * DEBUG = 0   No debug output.
        !          46946:  * DEBUG = 1   Debug output on error only.
        !          46947:  * DEBUG = 2   Debug output on error only and at other selected places.
        !          46948:  * DEBUG = 3   Maximum debug output.
        !          46949:  */
        !          46950: #if (DEBUG >= 1)
        !          46951: #define PR1(str)               printf(str)
        !          46952: #else
        !          46953: #define PR1(str)
        !          46954: #endif
        !          46955: #if (DEBUG >= 2)
        !          46956: #define PR2(str)               printf(str)
        !          46957: #else
        !          46958: #define PR2(str)
        !          46959: #endif
        !          46960: #if (DEBUG >= 3)
        !          46961: #define PR3(str)               printf(str)
        !          46962: #else
        !          46963: #define PR3(str)
        !          46964: #endif
        !          46965: 
        !          46966: /* TEMPORARY S**T */
        !          46967: #define bufq_rd_head(s_id)     ssq_rd_head()
        !          46968: #define bufq_rm_head(s_id)     ssq_rm_head()
        !          46969: #define bufq_wr_tail(s_id, foo)        ssq_wr_tail(foo)
        !          46970: 
        !          46971: /*
        !          46972:  * Includes.
        !          46973:  */
        !          46974: #include       <coherent.h>
        !          46975: #include       <sys/io.h>
        !          46976: #include       <sys/sched.h>
        !          46977: #include       <sys/uproc.h>
        !          46978: #include       <sys/proc.h>
        !          46979: #include       <sys/con.h>
        !          46980: #include       <sys/stat.h>
        !          46981: #include       <sys/devices.h>         /* SCSI_MAJOR */
        !          46982: #include       <errno.h>
        !          46983: 
        !          46984: #include       <sys/fdisk.h>
        !          46985: #include       <sys/hdioctl.h>
        !          46986: #include       <sys/buf.h>
        !          46987: #include       <scsiwork.h>
        !          46988: #include       <ss.h>
        !          46989: 
        !          46990: /*
        !          46991:  * Definitions.
        !          46992:  *     Constants.
        !          46993:  *     Macros with argument lists.
        !          46994:  *     Typedefs.
        !          46995:  *     Enums.
        !          46996:  */
        !          46997: #define DEV_SCSI_ID(dev)       ((dev >> 4) & 0x0007)
        !          46998: #define DEV_LUN(dev)           ((dev >> 2) & 0x0003)
        !          46999: #define DEV_DRIVE(dev)         ((dev >> 2) & 0x001F)
        !          47000: #define DEV_PARTN(dev)         (dev & 0x0003)
        !          47001: #define DEV_SPECIAL(dev)       (dev & 0x0080)
        !          47002: 
        !          47003: #define HOST_ID                0x80    /* Host adapter is SCSI ID #7 */
        !          47004: #define HIPRI_RETRIES  400     /* # of times to retry while hogging CPU */
        !          47005: #define LOPRI_RETRIES  5       /* # of retries with sleep between tries */
        !          47006: #define WHOLE_DRIVE    NPARTN
        !          47007: 
        !          47008: #define BUS_FREE       ((ffbyte(ss_csr) & (RS_BUSY | RS_SELECT)) == 0)
        !          47009: #define TGT_RSEL       \
        !          47010:        (  (ffbyte(ss_csr) & (RS_SELECT |  RS_I_O   )) \
        !          47011:        && (ffbyte(ss_dat) & (HOST_ID   | (1<<s_id) )) )
        !          47012: 
        !          47013: #define DELAY_ARB      10      /* delays units are 10 msec (clock ticks) */
        !          47014: #define DELAY_BDR      30
        !          47015: #define DELAY_BSY      10
        !          47016: #define DELAY_RES      40
        !          47017: #define DELAY_RST      40
        !          47018: 
        !          47019: #define MAX_AVL_COUNT  10
        !          47020: #define MAX_BDR_COUNT  2
        !          47021: #define MAX_BSY_COUNT  2
        !          47022: #define MAX_TRY_COUNT  7
        !          47023: 
        !          47024: typedef unsigned char  uchar;
        !          47025: typedef unsigned int   uint;
        !          47026: typedef unsigned long  ulong;
        !          47027: 
        !          47028: typedef enum {                 /* values for current driver state */
        !          47029:        SST_DEQUEUE =0,
        !          47030:        SST_BUS_DEV_RESET,
        !          47031:        SST_HIPRI_RESET,
        !          47032:        SST_LOPRI_RESET,
        !          47033:        SST_POLL_ARBITN,
        !          47034:        SST_POLL_BEGIN_IO,
        !          47035:        SST_POLL_RESELECT,
        !          47036:        SST_REQ_SENSE,
        !          47037:        SST_RESET_DONE,
        !          47038:        SST_RESET_OFF
        !          47039: } SST_TYPE;
        !          47040: 
        !          47041: typedef enum {                 /* values for input to recovery routine */
        !          47042:        RV_A_TIMEOUT,
        !          47043:        RV_P_TIMEOUT,
        !          47044:        RV_R_TIMEOUT,
        !          47045:        RV_BF_TIMEOUT,
        !          47046:        RV_CS_BUSY,
        !          47047:        RV_CS_CHECK
        !          47048: } RV_TYPE;
        !          47049: 
        !          47050: typedef struct ss {
        !          47051:        ulong   capacity;
        !          47052:        ulong   blocklen;
        !          47053:        ulong   bno;
        !          47054:        int     msg_in;
        !          47055:        int     dr_watch;
        !          47056:        uchar   cmdbuf[G1CMDLEN];
        !          47057:        int     cmdlen;
        !          47058:        int     cmd_bytes_out;
        !          47059:        int     cmdstat;
        !          47060:        BUF     *bp;            /* current I/O request node, or NULL */
        !          47061:        struct  fdisk_s parmp[NPARTN+1];
        !          47062:        SST_TYPE state;
        !          47063:        TIM     tim;            /* for target-specific timers */
        !          47064:        uchar   avl_count;
        !          47065:        uchar   bdr_count;
        !          47066:        uchar   bsy_count;
        !          47067:        uchar   try_count;
        !          47068:        uint    busy:1;         /* 1 if command uses local buffer */
        !          47069:        uint    expired:1;      /* 1 if target's timer has expired */
        !          47070:        uint    ptab_read:1;    /* 1 if partition table has been read */
        !          47071:        uint    waiting:1;      /* 1 if target timer is running */
        !          47072: }      ss_type;
        !          47073: 
        !          47074: typedef struct {
        !          47075:        uint    ncyl;
        !          47076:        uchar   nhead;
        !          47077:        uchar   nspt;
        !          47078: }      drv_parm_type;
        !          47079: 
        !          47080: /*
        !          47081:  * Functions.
        !          47082:  *     Import Functions.
        !          47083:  *     Export Functions.
        !          47084:  *     Local Functions.
        !          47085:  */
        !          47086: extern int     nulldev();
        !          47087: extern int     nonedev();
        !          47088: extern unsigned char ffbyte();
        !          47089: 
        !          47090: static void    ssopen();               /* CON functions */
        !          47091: static void    ssclose();
        !          47092: static void    ssblock();
        !          47093: static void    ssread();
        !          47094: static void    sswrite();
        !          47095: static int     ssioctl();
        !          47096: static void    sswatch();
        !          47097: static void    ssload();
        !          47098: static void    ssunload();
        !          47099: 
        !          47100: static int     bus_dev_reset();        /* additional support functions */
        !          47101: static int     chk_reconn();
        !          47102: static void    do_connect();
        !          47103: static int     far_info_xfer();
        !          47104: static int     host_ident();
        !          47105: static void    init_pointers();
        !          47106: static int     inquiry();
        !          47107: static int     local_info_xfer();
        !          47108: static int     mode_sense();
        !          47109: static void    nonpolled();
        !          47110: static int     read_cap();
        !          47111: static void    recover();
        !          47112: static int     req_sense();
        !          47113: static int     rsel_handshake();
        !          47114: static void    ss_finished();
        !          47115: static void    ss_mach();
        !          47116: static void    set_timeout();
        !          47117: static int     ssinit();
        !          47118: static void    ssintr();
        !          47119: static int     start_arb();
        !          47120: static void    stop_timeout();
        !          47121: 
        !          47122: /*
        !          47123:  * Global Data.
        !          47124:  *     Import Variables.
        !          47125:  *     Export Variables.
        !          47126:  *     Local Variables.
        !          47127:  */
        !          47128: CON    sscon   = {
        !          47129:        DFBLK|DFCHR,                    /* Flags */
        !          47130:        SCSI_MAJOR,                     /* Major index */
        !          47131:        ssopen,                         /* Open */
        !          47132:        ssclose,                        /* Close */
        !          47133:        ssblock,                        /* Block */
        !          47134:        ssread,                         /* Read */
        !          47135:        sswrite,                        /* Write */
        !          47136:        ssioctl,                        /* Ioctl */
        !          47137:        nulldev,                        /* Powerfail */
        !          47138:        sswatch,                        /* Timeout */
        !          47139:        ssload,                         /* Load */
        !          47140:        ssunload,                       /* Unload */
        !          47141:        nulldev                         /* Poll */
        !          47142: };
        !          47143: 
        !          47144:        /* Patch these Export Variables to configure the driver. */
        !          47145: int    NSDRIVE = 1;            /* Bitmap of attached SCSI drives. */
        !          47146: int    SS_INT = 5;             /* ST0[12] use either IRQ3 or IRQ5 */
        !          47147: int    SS_BASE = 0xDE00;       /* Segment addr of ST0x communication area */
        !          47148: 
        !          47149: #define NCYL   1004
        !          47150: #define NHEAD  4
        !          47151: #define NSPT   52
        !          47152: 
        !          47153: drv_parm_type drv_parm[MAX_SCSI_ID-1] = {
        !          47154:        { NCYL, NHEAD, NSPT},
        !          47155:        { 0, 0, 0},
        !          47156:        { 0, 0, 0},
        !          47157:        { 0, 0, 0},
        !          47158:        { 0, 0, 0},
        !          47159:        { 0, 0, 0},
        !          47160:        { 0, 0, 0}
        !          47161: };
        !          47162: 
        !          47163: static BUF     dbuf;           /* For raw I/O */
        !          47164: static paddr_t ss_base;        /* physical address of ST0x comm area */
        !          47165: static faddr_t ss_fp;          /* (far *) to ST0x comm area */
        !          47166: 
        !          47167: static faddr_t ss_ram;         /* (far *) to parameter RAM */
        !          47168: static faddr_t ss_csr;         /* (far *) to control/status */
        !          47169: static faddr_t ss_dat;         /* (far *) to data port */
        !          47170: 
        !          47171: static int     num_drives;     /* number of controller SCSI id's */
        !          47172: 
        !          47173: static int     do_sst_op;      /* 1 when state machine iteration continues */
        !          47174: static int     host_claimed;   /* -1 or SCSI id of target using the host */
        !          47175: static int     ss_expired;     /* 1 after local timeout */
        !          47176: 
        !          47177: static ss_type *ss_tbl;        /* points to block of "ss" structs */
        !          47178: static ss_type  *ss[MAX_SCSI_ID-1];
        !          47179: 
        !          47180: /*
        !          47181:  * ssload()    - load routine.
        !          47182:  *
        !          47183:  *     Action: The controller is reset and the interrupt vector is grabbed.
        !          47184:  *             The drive characteristics are set up at this time.
        !          47185:  */
        !          47186: static void ssload()
        !          47187: {
        !          47188:        int erf = 0;  /* 1 if error occurs */
        !          47189:        int i;
        !          47190: 
        !          47191:        /*
        !          47192:         * Claim IRQ vector.
        !          47193:         */
        !          47194:        setivec(SS_INT, ssintr);
        !          47195: 
        !          47196:        /*
        !          47197:         * Allocate a selector to map into ST0x memory-mapped comm area.
        !          47198:         */
        !          47199:        ss_base = (paddr_t)((long)(unsigned)SS_BASE << 4);
        !          47200:        ss_fp = ptov(ss_base, (fsize_t)SS_SEL_LEN);
        !          47201: 
        !          47202:        ss_ram = ss_fp + SS_RAM;
        !          47203:        ss_csr = ss_fp + SS_CSR;
        !          47204:        ss_dat = ss_fp + SS_DAT;
        !          47205: printf("ss_dat=%lx ", ss_dat);
        !          47206:        /*
        !          47207:         * Primitive test of ST0x RAM.
        !          47208:         */
        !          47209:        sfword(ss_ram, 0xA55A);
        !          47210:        sfword(ss_ram + 2, 0x3CC3);
        !          47211:        sfword(ss_ram + SS_RAM_LEN - 4, 0xA55A);
        !          47212:        sfword(ss_ram + SS_RAM_LEN - 2, 0x3CC3);
        !          47213:        if (ffword(ss_ram) != 0xA55A            /* fetch a "far" word */
        !          47214:        ||  ffword(ss_ram + 2) != 0x3CC3
        !          47215:        ||  ffword(ss_ram + SS_RAM_LEN - 4) != 0xA55A
        !          47216:        ||  ffword(ss_ram + SS_RAM_LEN - 2) != 0x3CC3) {
        !          47217:                printf("Error - ST0x failed memory test\n");
        !          47218:                erf = 1;
        !          47219:        }
        !          47220: 
        !          47221:        /*
        !          47222:         * Allocate drive structs.
        !          47223:         *
        !          47224:         * Do a single call to kalloc() then put allocated pieces into
        !          47225:         * array ss.
        !          47226:         *
        !          47227:         * First allocate and clear storage.  Then hook up the pointers.
        !          47228:         */
        !          47229:        if (!erf) {
        !          47230:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          47231:                        if ((NSDRIVE >> i) & 1)
        !          47232:                                num_drives++;
        !          47233:                if (num_drives == 0) {
        !          47234:                        printf("Error - ss has no valid target id's\n");
        !          47235:                        erf = 1;
        !          47236:                } else if ((ss_tbl = kalloc(num_drives*sizeof(ss_type)))
        !          47237:                == NULL) {
        !          47238:                        printf("Error - ss can't allocate structs\n");
        !          47239:                        erf = 1;
        !          47240:                } else
        !          47241:                        kclear(ss_tbl, num_drives * sizeof(ss_type));
        !          47242:        }
        !          47243:        if (!erf) {
        !          47244:                ss_type *foo = ss_tbl;
        !          47245: 
        !          47246:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          47247:                        if ((NSDRIVE >> i) & 1)
        !          47248:                                ss[i] = foo++;
        !          47249:        }
        !          47250: 
        !          47251:        /*
        !          47252:         * Initialize drives we know about (i.e. in NSDRIVE bitmap).
        !          47253:         */
        !          47254:        host_claimed = -1;
        !          47255:        if (!erf) {
        !          47256:                for (i = 0; i < MAX_SCSI_ID -1; i++)
        !          47257:                        if ((NSDRIVE >> i) & 1)
        !          47258:                                ssinit(i);
        !          47259:        }
        !          47260: }
        !          47261: 
        !          47262: /*
        !          47263:  * ssunload()  - unload routine.
        !          47264:  */
        !          47265: static void ssunload()
        !          47266: {
        !          47267:        /*
        !          47268:         * Deallocate driver heap space.
        !          47269:         */
        !          47270:        if (ss_tbl)
        !          47271:                kfree(ss_tbl);
        !          47272: 
        !          47273:        /*
        !          47274:         * Free the ST0x selector.
        !          47275:         */
        !          47276:        vrelse(ss_fp);
        !          47277: 
        !          47278:        /*
        !          47279:         * Release IRQ vector.
        !          47280:         */
        !          47281:        clrivec(SS_INT);
        !          47282: }
        !          47283: 
        !          47284: /*
        !          47285:  * ssopen()
        !          47286:  *
        !          47287:  *     Input:  dev = disk device to be opened.
        !          47288:  *             mode = access mode [IPR,IPW, IPR+IPW].
        !          47289:  *
        !          47290:  *     Action: Validate the minor device.
        !          47291:  *             Update the paritition table if necessary.
        !          47292:  */
        !          47293: static void ssopen(dev, mode)
        !          47294: register dev_t dev;
        !          47295: {
        !          47296:        int drive, partn;
        !          47297:        int valid_open;
        !          47298:        struct  fdisk_s *fdp;
        !          47299:        ss_type * ssp;
        !          47300:        int s_id;
        !          47301: 
        !          47302:        /*
        !          47303:         * Set up local variables.
        !          47304:         */
        !          47305:        valid_open = 1;
        !          47306:        drive = DEV_SCSI_ID(dev);
        !          47307:        partn = DEV_PARTN(dev);
        !          47308:        s_id = DEV_SCSI_ID(dev);
        !          47309:        ssp = ss[s_id];
        !          47310:        fdp = ssp->parmp;
        !          47311: 
        !          47312: #if (DEBUG >= 3)
        !          47313: devmsg(dev, "ssopen");
        !          47314: #endif
        !          47315: 
        !          47316:        /*
        !          47317:         * LUN must be zero.
        !          47318:         * SCSI id must have corresponding 1 in NSDRIVE bitmapped variable.
        !          47319:         */
        !          47320:        if (DEV_LUN(dev) != 0 || ((1 << drive) & NSDRIVE) == 0) {
        !          47321:                u.u_error = ENXIO;
        !          47322:                valid_open = 0;
        !          47323:        }
        !          47324: 
        !          47325:        /*
        !          47326:         * If "special" bit is set, partition field must be zero.
        !          47327:         */
        !          47328:        if (valid_open && DEV_SPECIAL(dev) && partn != 0) {
        !          47329:                u.u_error = ENXIO;
        !          47330:                valid_open = 0;
        !          47331:        }
        !          47332: 
        !          47333:        /*
        !          47334:         * Subscripting gimmick for partition table.
        !          47335:         */
        !          47336:        if (valid_open && dev & SDEV)
        !          47337:                partn = WHOLE_DRIVE;
        !          47338:        /*
        !          47339:         * If not accessing whole drive and the partition table has not
        !          47340:         * been read yet, try to read it now.
        !          47341:         * Do this by calling fdisk() with partition table device on the drive
        !          47342:         * that is being accessed.
        !          47343:         */
        !          47344:        if (valid_open && partn != WHOLE_DRIVE && !(ssp->ptab_read)) {
        !          47345:                int fdisk_dev;
        !          47346: 
        !          47347:                fdisk_dev = (dev | SDEV) & 0xfff0;
        !          47348: 
        !          47349: #if (DEBUG >=3)
        !          47350:                devmsg(fdisk_dev, "calling fdisk");
        !          47351:                if (fdisk(fdisk_dev, fdp)) {
        !          47352:                        int p;
        !          47353: 
        !          47354:                        fdp[WHOLE_DRIVE].p_size = ssp->capacity;
        !          47355:                        fdp[WHOLE_DRIVE].p_base = 0;
        !          47356:                        printf("fdisk() succeeded\n");
        !          47357:                        for (p=0; p<=WHOLE_DRIVE; p++)
        !          47358:        printf("p=%d base=%ld size=%ld\n", p, fdp[p].p_base, fdp[p].p_size);
        !          47359:                        ssp->ptab_read = 1;
        !          47360:                } else {
        !          47361:                        printf("fdisk() failed\n");
        !          47362:                        u.u_error = ENXIO;
        !          47363:                        valid_open = 0;
        !          47364:                }
        !          47365: #else
        !          47366:                if (fdisk(fdisk_dev, fdp)) {
        !          47367:                        fdp[WHOLE_DRIVE].p_size = ssp->capacity;
        !          47368:                        fdp[WHOLE_DRIVE].p_base = 0;
        !          47369:                        ssp->ptab_read = 1;
        !          47370:                } else {
        !          47371:                        u.u_error = ENXIO;
        !          47372:                        valid_open = 0;
        !          47373:                }
        !          47374: #endif
        !          47375: 
        !          47376:        }
        !          47377: 
        !          47378:        /*
        !          47379:         * Ensure partition lies within drive boundaries and is non-zero size.
        !          47380:         */
        !          47381:        if (valid_open && partn != WHOLE_DRIVE
        !          47382:        && (fdp[partn].p_base+fdp[partn].p_size) > fdp[WHOLE_DRIVE].p_size) {
        !          47383:                u.u_error = EBADFMT;
        !          47384:                valid_open = 0;
        !          47385:        }
        !          47386: 
        !          47387:        if (valid_open && partn != WHOLE_DRIVE && fdp[partn].p_size == 0) {
        !          47388:                u.u_error = ENODEV;
        !          47389:                valid_open = 0;
        !          47390:        }
        !          47391: 
        !          47392:        /*
        !          47393:         * OK to open the device.
        !          47394:         * Start watchdog timer (if not already started) for the host adapter.
        !          47395:         */
        !          47396:        if (valid_open) {
        !          47397:                ++drvl[SCSI_MAJOR].d_time;
        !          47398:                ++ssp->dr_watch;
        !          47399:        }
        !          47400: }
        !          47401: 
        !          47402: /*
        !          47403:  * ssclose()
        !          47404:  */
        !          47405: static void ssclose(dev)
        !          47406: dev_t dev;
        !          47407: {
        !          47408:        ss_type * ssp;
        !          47409:        int s_id;
        !          47410: 
        !          47411:        s_id = DEV_SCSI_ID(dev);
        !          47412:        ssp = ss[s_id];
        !          47413: 
        !          47414:        /*
        !          47415:         * Decrement the number of watchdog timer requests open for host
        !          47416:         * adapter and for target.
        !          47417:         */
        !          47418:        --drvl[SCSI_MAJOR].d_time;      
        !          47419:        --ssp->dr_watch;
        !          47420: 
        !          47421: #if (DEBUG >= 3)
        !          47422: devmsg(dev, "ssclose");
        !          47423: #endif
        !          47424: 
        !          47425: }
        !          47426: 
        !          47427: /*
        !          47428:  * ssread()    - read a block from the raw disk
        !          47429:  *
        !          47430:  *     Input:  dev = disk device to be written to.
        !          47431:  *             iop = pointer to source I/O structure.
        !          47432:  *
        !          47433:  *     Action: Invoke the common raw I/O processing code.
        !          47434:  */
        !          47435: static void ssread(dev, iop)
        !          47436: dev_t  dev;
        !          47437: IO     *iop;
        !          47438: {
        !          47439:        ioreq( &dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC );
        !          47440: }
        !          47441: 
        !          47442: /*
        !          47443:  * sswrite()   - write a block to the raw disk
        !          47444:  *
        !          47445:  *     Input:  dev = disk device to be written to.
        !          47446:  *             iop = pointer to source I/O structure.
        !          47447:  *
        !          47448:  *     Action: Invoke the common raw I/O processing code.
        !          47449:  */
        !          47450: static void sswrite(dev, iop)
        !          47451: dev_t  dev;
        !          47452: IO     *iop;
        !          47453: {
        !          47454:        ioreq( &dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC );
        !          47455: }
        !          47456: 
        !          47457: /*
        !          47458:  * ssioctl()
        !          47459:  *
        !          47460:  *     Input:  dev = disk device to be operated on.
        !          47461:  *             cmd = input/output request to be performed.
        !          47462:  *             vec = (pointer to) optional argument.
        !          47463:  *
        !          47464:  *     Action: Validate the minor device.
        !          47465:  *             Update the paritition table if necessary.
        !          47466:  */
        !          47467: 
        !          47468: static int ssioctl(dev, cmd, vec)
        !          47469: register dev_t dev;
        !          47470: int cmd;
        !          47471: char * vec;
        !          47472: {
        !          47473:        int ret = 0;
        !          47474:        hdparm_t hdparm;
        !          47475:        struct  fdisk_s *fdp;
        !          47476:        int s_id;
        !          47477:        ss_type * ssp;
        !          47478: 
        !          47479:        s_id = DEV_SCSI_ID(dev);
        !          47480:        ssp = ss[s_id];
        !          47481:        fdp = ssp->parmp;
        !          47482: 
        !          47483:        switch(cmd) {
        !          47484:        case HDGETA:
        !          47485: PR3("HDGETA ");
        !          47486:                fdp = ssp->parmp;
        !          47487:                *(short *)&hdparm.landc[0] =
        !          47488:                *(short *)&hdparm.ncyl[0] = drv_parm[s_id].ncyl;
        !          47489:                hdparm.nhead = drv_parm[s_id].nhead;
        !          47490:                hdparm.nspt = drv_parm[s_id].nspt;
        !          47491: #if (DEBUG >= 3)
        !          47492: printf("ncyl=%d nhead=%d nspt=%d\n",
        !          47493:   hdparm.ncyl[0]+((int)hdparm.ncyl[1]<<8), (int)hdparm.nhead, (int)hdparm.nspt);
        !          47494: #endif
        !          47495:                kucopy( &hdparm, vec, sizeof hdparm );
        !          47496:                ret = 0;
        !          47497:                break;
        !          47498:        default:
        !          47499:                u.u_error = EINVAL;
        !          47500:                ret = -1;
        !          47501:        }
        !          47502: 
        !          47503:        return ret;
        !          47504: }
        !          47505: 
        !          47506: /*
        !          47507:  * ssblock()   - queue a block to the disk
        !          47508:  *
        !          47509:  *     Input:  bp = pointer to block to be queued.
        !          47510:  *
        !          47511:  *     Action: Queue a block to the disk.
        !          47512:  *             Make sure that the transfer is within the disk partition.
        !          47513:  */
        !          47514: static void ssblock(bp)
        !          47515: register BUF   *bp;
        !          47516: {
        !          47517:        struct  fdisk_s *fdp;
        !          47518:        int partition, drive, s_id;
        !          47519:        dev_t dev;
        !          47520:        ss_type * ssp;
        !          47521: 
        !          47522:        /*
        !          47523:         * Set up local variables.
        !          47524:         */
        !          47525:        dev = bp->b_dev;
        !          47526:        partition = DEV_PARTN(dev);
        !          47527:        drive = DEV_DRIVE(dev);
        !          47528:        s_id = DEV_SCSI_ID(dev);
        !          47529:        ssp = ss[s_id];
        !          47530:        if (dev & SDEV)
        !          47531:                partition = WHOLE_DRIVE;
        !          47532:        fdp = ssp->parmp;
        !          47533: 
        !          47534:        bp->b_resid = bp->b_count;
        !          47535: 
        !          47536:        /*
        !          47537:         * Range check disk region.
        !          47538:         */
        !          47539:        if (!(ssp->ptab_read)) {
        !          47540:                if ( partition == WHOLE_DRIVE ) {
        !          47541:                        if ((bp->b_bno != 0) || (bp->b_count != BSIZE)) {
        !          47542: PR1("BF1 ");
        !          47543:                                bp->b_flag |= BFERR;
        !          47544:                                goto bad_open;
        !          47545:                        }
        !          47546:                } else {
        !          47547: PR2("BF2 ");
        !          47548:                        devmsg(dev, "no partition table");
        !          47549:                        bp->b_flag |= BFERR;
        !          47550:                        goto bad_open;
        !          47551:                }
        !          47552:        }
        !          47553: 
        !          47554:        /*
        !          47555:         * Check for read at end of partition.
        !          47556:         * (Need to return with b_resid = BSIZE to signal end of volume.)
        !          47557:         */
        !          47558:        else if ((bp->b_req == BREAD) && (bp->b_bno == fdp[partition].p_size)) {
        !          47559:                goto bad_open;
        !          47560:        }
        !          47561: 
        !          47562:        /*
        !          47563:         * Check for read past end of partition.
        !          47564:         */
        !          47565:        else if ( (bp->b_bno + (bp->b_count/BSIZE))
        !          47566:        > fdp[partition].p_size ) {
        !          47567: PR3("BF3 ");
        !          47568:                bp->b_flag |= BFERR;
        !          47569:                goto bad_open;
        !          47570:        }
        !          47571: 
        !          47572:        /*
        !          47573:         * Fail if request is for zero bytes or is not even # of blocks.
        !          47574:         */
        !          47575:        if ((bp->b_count % BSIZE) || bp->b_count == 0) {
        !          47576:                bp->b_flag |= BFERR;
        !          47577:                goto bad_open;
        !          47578:        }
        !          47579: 
        !          47580:        /*
        !          47581:         * Operation appears valid.
        !          47582:         * Fill fields in the node and queue the request.
        !          47583:         */
        !          47584:        bufq_wr_tail(s_id, bp);
        !          47585:        ss_mach(s_id);
        !          47586:        goto end_open;
        !          47587: 
        !          47588:        /*
        !          47589:         * Operation cannot be done.  Release the kernel buffer structure.
        !          47590:         * Value of "bp->b_flag" tells caller if error occurred.
        !          47591:         */
        !          47592: bad_open:
        !          47593:                bdone(bp);
        !          47594: 
        !          47595: end_open:
        !          47596:        return;
        !          47597: }
        !          47598: 
        !          47599: /*
        !          47600:  * ssintr()    - Interrupt routine.
        !          47601:  *
        !          47602:  * If we have been reselected by a recognized target device
        !          47603:  *     let kernel get out of interrupt mode (defer) and do SCSI
        !          47604:  *     reconnect stuff.
        !          47605:  */
        !          47606: static void ssintr()
        !          47607: {
        !          47608:        int s_id;
        !          47609: 
        !          47610:        s_id = chk_reconn();
        !          47611:        if (s_id != -1) {
        !          47612:                defer(ss_mach, s_id);
        !          47613: PR3("!");
        !          47614:        }
        !          47615: }
        !          47616: 
        !          47617: /*
        !          47618:  * sswatch()
        !          47619:  *
        !          47620:  * Invoked once per second if any devices going through this driver are open.
        !          47621:  * Poll for any reselect, in case interrupt got lost.
        !          47622:  */
        !          47623: static void sswatch()
        !          47624: {
        !          47625:        int s_id;
        !          47626:        ss_type * ssp;
        !          47627: 
        !          47628:        for (s_id = 0; s_id < MAX_SCSI_ID-1; s_id++) {
        !          47629:                ssp = ss[s_id];
        !          47630:                if (ssp && ssp->dr_watch)
        !          47631:                        defer(ss_mach, s_id);
        !          47632:        } /* endfor */
        !          47633: }
        !          47634: 
        !          47635: /*
        !          47636:  * bus_wait()
        !          47637:  *
        !          47638:  * Wait for specified bit values to appear in Status Register.
        !          47639:  * This uses a tight loop and does not expect to be interrupted.
        !          47640:  *
        !          47641:  * Argument "flags" is a double-byte value;  the high byte is ANDed with
        !          47642:  * status register contents, and the result is tested for equality with
        !          47643:  * the low byte.
        !          47644:  *
        !          47645:  * Return 1 if values wanted appeared, 0 if timeout occurred.
        !          47646:  */
        !          47647: static int bus_wait(flags)
        !          47648: unsigned short flags;
        !          47649: {
        !          47650:        int found, i;
        !          47651:        unsigned char status;
        !          47652: 
        !          47653:        found = 0;
        !          47654:        for ( i = 0; i < HIPRI_RETRIES; i++) {
        !          47655:                status = ffbyte(ss_csr);
        !          47656:                if ((status & (flags >> 8)) == (flags & 0xff)) {
        !          47657:                        found = 1;
        !          47658:                        break;
        !          47659:                }
        !          47660:        }
        !          47661: 
        !          47662: #if (DEBUG >= 1)
        !          47663:        if (!found)
        !          47664:                printf("TO:f=%x s=%x ", flags, status);
        !          47665: #endif
        !          47666: 
        !          47667:        return found;
        !          47668: }
        !          47669: 
        !          47670: /*
        !          47671:  * ssinit()
        !          47672:  *
        !          47673:  * Attempt to initialize the (unique) drive with a given SCSI id.
        !          47674:  * Assume only one drive per SCSI id, having LUN = 0.
        !          47675:  * 
        !          47676:  * Return 1 if success, 0 if failure.
        !          47677:  */
        !          47678: static int ssinit(s_id)
        !          47679: int s_id;
        !          47680: {
        !          47681:        int retval = 1;
        !          47682:        uchar query_buf[MODESENSELEN];
        !          47683:        ss_type * ssp = ss[s_id];
        !          47684:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          47685: 
        !          47686:        if (retval)
        !          47687:                if (inquiry(s_id, query_buf)) {
        !          47688:                        query_buf[INQUIRYLEN] = 0;
        !          47689: #if (debug >= 2)
        !          47690:                        devmsg(dev, query_buf + 8);
        !          47691: #endif
        !          47692:                        if (query_buf[0] == 0) {
        !          47693:                                retval = 1;
        !          47694:                        } else
        !          47695:                                devmsg(dev, "Not Direct Access Device");
        !          47696:                } else
        !          47697:                        devmsg(dev, "Inquiry Failed");
        !          47698: 
        !          47699:        if (retval)
        !          47700:                if (read_cap(s_id, query_buf)) {
        !          47701:                        retval = 1;
        !          47702:                        ssp->capacity = query_buf[3] | (query_buf[2] << 8)
        !          47703:                        | (((long)(query_buf[1])) << 16)
        !          47704:                        | (((long)(query_buf[0])) << 24);
        !          47705:                        ssp->blocklen = query_buf[7] | (query_buf[6] << 8)
        !          47706:                        | (((long)(query_buf[5])) << 16)
        !          47707:                        | (((long)(query_buf[4])) << 24);
        !          47708: #if (DEBUG >= 3)
        !          47709: printf("capacity=%ld   block length=%ld\n", ssp->capacity, ssp->blocklen);
        !          47710: #endif
        !          47711:                } else
        !          47712:                        devmsg(dev, "Read Capacity Failed");
        !          47713: 
        !          47714:        if (retval)
        !          47715:                if (mode_sense(s_id, query_buf)) {
        !          47716: #if (DEBUG >= 3)
        !          47717: #define FMT_PG (4+8+8+12)
        !          47718: #define DDG_PG (4+8+8+12+24)
        !          47719: 
        !          47720: uchar heads;
        !          47721: unsigned short spt;
        !          47722: ulong cyls;
        !          47723: 
        !          47724: spt=((int)query_buf[FMT_PG+10]<<8) + query_buf[FMT_PG+11];
        !          47725: cyls=((int)query_buf[DDG_PG+2]<<16) + ((int)query_buf[DDG_PG+3]<<8) + query_buf[DDG_PG+4];
        !          47726: heads=query_buf[DDG_PG+5];
        !          47727: printf("%d sectors per track\n", spt);
        !          47728: printf("%ld cylinders\n", cyls);
        !          47729: printf("%d heads\n", heads);
        !          47730: #endif
        !          47731:                } else
        !          47732:                        devmsg(dev, "Mode Sense Failed");
        !          47733: 
        !          47734:        return retval;
        !          47735: }
        !          47736: 
        !          47737: /*
        !          47738:  * far_info_xfer()
        !          47739:  *
        !          47740:  * Do bus cycle information transfer phases.
        !          47741:  * This includes message in/out, command in/out, and data in/out.
        !          47742:  *
        !          47743:  * If cmdlen is nonzero, cmdbuf is an array of bytes of that length,
        !          47744:  * to be sent to the target.
        !          47745:  *
        !          47746:  * Return 1 if bus timeout did not occur, else 0.
        !          47747:  *
        !          47748:  * pseudocode:
        !          47749:  *
        !          47750:  * while (wait for REQ true or BUSY false on SCSI bus)
        !          47751:  *   if (BUSY false)
        !          47752:  *     break from while loop
        !          47753:  *   else
        !          47754:  *     switch (xfer phase = RS_CTRL_DATA|RS_I_O|RS_MESSAGE)
        !          47755:  *       case XP_MSG_IN/XP_MSG_OUT/...
        !          47756:  *         handle the indicated information transfer phase
        !          47757:  *     endswitch
        !          47758:  *   endif
        !          47759:  * endwhile
        !          47760:  */
        !          47761: static int far_info_xfer(s_id)
        !          47762: int s_id;
        !          47763: {
        !          47764:        int bus_timeout;
        !          47765:        uchar phase_type;
        !          47766:        uchar msg_in;
        !          47767:        int s;
        !          47768:        int bytes_to_send;
        !          47769:        ss_type * ssp = ss[s_id];
        !          47770:        BUF * bp = ssp->bp;
        !          47771:        int xfer_good = 1;
        !          47772:        int xfer_count = bp->b_count - bp->b_resid;
        !          47773:        int i = 0;
        !          47774: 
        !          47775:        ssp->cmd_bytes_out = 0;
        !          47776:        ssp->msg_in = -1;
        !          47777:        s = sphi();
        !          47778:        while (req_wait(&bus_timeout) && xfer_good) {
        !          47779:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          47780:                switch (phase_type) {
        !          47781:                case XP_MSG_IN:
        !          47782:                        msg_in = ffbyte(ss_dat);
        !          47783:                        switch(msg_in){
        !          47784:                        case MSG_CMD_CMPLT:
        !          47785:                                ssp->msg_in = msg_in;
        !          47786:                                sfbyte(ss_csr, WC_ENABLE_IRPT);
        !          47787:                                break;
        !          47788:                        case MSG_SAVE_DPTR:
        !          47789:                                break;
        !          47790:                        case MSG_RSTOR_DPTR:
        !          47791:                                break;
        !          47792:                        case MSG_DISCONNECT:
        !          47793:                                ssp->msg_in = msg_in;
        !          47794:                                sfbyte(ss_csr, WC_ENABLE_IRPT);
        !          47795:                                break;
        !          47796:                        case MSG_ABORT:
        !          47797:                                break;
        !          47798:                        case MSG_DEV_RESET:
        !          47799:                                break;
        !          47800:                        case MSG_IDENTIFY:
        !          47801:                                break;
        !          47802:                        case MSG_IDENT_DC:
        !          47803:                                break;
        !          47804:                        }
        !          47805:                        break;
        !          47806:                case XP_MSG_OUT:
        !          47807:                        /*
        !          47808:                         * This case shouldn't happen.  We weren't
        !          47809:                         * asserting ATTENTION.  Abort the bus cycle.
        !          47810:                         */
        !          47811:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          47812:                        sfbyte(ss_dat, MSG_ABORT); 
        !          47813:                        break;
        !          47814:                case XP_STAT_IN:
        !          47815:                        ssp->cmdstat = ffbyte(ss_dat);
        !          47816:                        break;
        !          47817:                case XP_CMD_OUT:
        !          47818:                        /*
        !          47819:                         * Ship out command bytes.
        !          47820:                         * Reset SCSI bus if too many command bytes are wanted.
        !          47821:                         */
        !          47822:                        bytes_to_send = ssp->cmdlen - ssp->cmd_bytes_out;
        !          47823:                        if(bytes_to_send > 0) {
        !          47824:                                sfbyte(ss_dat, ssp->cmdbuf[ssp->cmd_bytes_out++]);
        !          47825:                                /*
        !          47826:                                 * If just sent last byte, allow interrupts.
        !          47827:                                 */
        !          47828:                                if (bytes_to_send == 1) {
        !          47829:                                        spl(s);
        !          47830:                                        s = sphi();
        !          47831:                                }
        !          47832:                        } else {        /* This case should not happen. */
        !          47833:                                xfer_good = 0;
        !          47834:                        }
        !          47835:                        break;
        !          47836:                case XP_DATA_IN:
        !          47837:                        /*
        !          47838:                         * If caller's buffer has room, keep incoming
        !          47839:                         * data byte.  Else toss it.
        !          47840:                         */
        !          47841:                        if (bp->b_req == BREAD)
        !          47842:                                ss_get(ss_fp, bp->b_faddr + xfer_count, BSIZE);
        !          47843:                        else
        !          47844:                                xfer_good = 0;
        !          47845:                        break;
        !          47846:                case XP_DATA_OUT:
        !          47847:                        /*
        !          47848:                         * Copy output buffer bytes to data register.
        !          47849:                         */
        !          47850:                        if (bp->b_req == BWRITE) {
        !          47851:                                uchar dat;
        !          47852: 
        !          47853:                                dat = ffbyte(bp->b_faddr + xfer_count + i);
        !          47854:                                sfbyte(ss_dat, dat);
        !          47855:                                i++;
        !          47856:                        } else /* This case should not happen. */
        !          47857:                                xfer_good = 0;
        !          47858:                        break;
        !          47859:                default:
        !          47860:                        break;
        !          47861:                } /* endswitch */
        !          47862:        }
        !          47863:        spl(s);
        !          47864: #if (DEBUG >= 1)
        !          47865: switch(ssp->cmdstat) {
        !          47866: case -1:
        !          47867:        if (msg_in != MSG_DISCONNECT)
        !          47868:                printf("CS-",ssp->cmdstat);
        !          47869:        break;
        !          47870: case CS_GOOD:
        !          47871:        break;
        !          47872: case CS_CHECK:
        !          47873:        printf("CSK",ssp->cmdstat);
        !          47874:        break;
        !          47875: case CS_BUSY:
        !          47876:        printf("CSY",ssp->cmdstat);
        !          47877:        break;
        !          47878: case CS_RESERVED:
        !          47879: default:
        !          47880:        printf("CS%x",ssp->cmdstat);
        !          47881: #endif
        !          47882: }
        !          47883:        return (bus_timeout) ? 0 : 1 ;
        !          47884: }
        !          47885: 
        !          47886: /*
        !          47887:  * req_wait()
        !          47888:  *
        !          47889:  * This routine is called at the start of each information transfer
        !          47890:  * phase and after the last such phase.
        !          47891:  *
        !          47892:  * It returns 1 if REQ is asserted on the SCSI bus, meaning another phase
        !          47893:  * may begin, and 0 otherwise.  A REQ signal will not be seen if the function
        !          47894:  * times out or if BUSY drops.  A value of 1 is written to the pointer argument
        !          47895:  * if timeout occurred, else 0 is written.
        !          47896:  */
        !          47897: static int req_wait(to_ptr)
        !          47898: int *to_ptr;
        !          47899: {
        !          47900:        int req_found, i;
        !          47901:        unsigned char status;
        !          47902: 
        !          47903:        *to_ptr = 1;
        !          47904:        req_found = 0;
        !          47905:        for (i = 0; i < HIPRI_RETRIES; i++) {
        !          47906:                status = ffbyte(ss_csr);
        !          47907:                if (status & RS_REQUEST) {
        !          47908:                        req_found = 1;
        !          47909:                        *to_ptr = 0;
        !          47910:                        break;
        !          47911:                } else if ((status & RS_BUSY) == 0) {
        !          47912:                        *to_ptr = 0;
        !          47913:                        break;
        !          47914:                }
        !          47915:        }
        !          47916: 
        !          47917: #if (DEBUG >= 1)
        !          47918:        if (*to_ptr) {
        !          47919:                printf("TX: s=%x ", status);
        !          47920:        }
        !          47921: #endif
        !          47922: 
        !          47923:        return req_found;
        !          47924: }
        !          47925: 
        !          47926: /*
        !          47927:  * req_sense()
        !          47928:  *
        !          47929:  * Request Sense for a device.  The main reason for doing this is to
        !          47930:  * clear a standing Command Status of Device Check.
        !          47931:  *
        !          47932:  * Full results are discarded.  Return 1 if Device returns No Sense or
        !          47933:  * or Unit Attention.  Else return 0.
        !          47934:  *
        !          47935:  */
        !          47936: static int req_sense(s_id)
        !          47937: int s_id;
        !          47938: {
        !          47939:        uchar sense_buf[SENSELEN];
        !          47940:        uchar cmdbuf[G0CMDLEN];
        !          47941:        int ret = 0;
        !          47942: 
        !          47943:        cmdbuf[0] = ScmdREQUESTSENSE;
        !          47944:        cmdbuf[1] = 0;
        !          47945:        cmdbuf[2] = 0;
        !          47946:        cmdbuf[3] = 0;
        !          47947:        cmdbuf[4] = SENSELEN;
        !          47948:        cmdbuf[5] = 0;
        !          47949: 
        !          47950:        if (start_arb() && host_ident(s_id, 0) &&
        !          47951:        local_info_xfer(cmdbuf, G0CMDLEN, sense_buf, SENSELEN, NULL, 0)) {
        !          47952:                if (sense_buf[2] == 0x00)       /* No Sense.  AOK */
        !          47953:                        ret = 1;
        !          47954:                else if (sense_buf[2] == 0x06 && sense_buf[12] == 0x29)
        !          47955:                        ret = 1;
        !          47956:        }
        !          47957: 
        !          47958:        return ret;
        !          47959: }
        !          47960: 
        !          47961: /*
        !          47962:  * inquiry()
        !          47963:  *
        !          47964:  * Inquiry command for a device.
        !          47965:  * Find out if device is direct access, removable, etc.
        !          47966:  *
        !          47967:  * Put result of inquiry into supplied buffer.
        !          47968:  * Return 1 if command succeeds, else 0.
        !          47969:  */
        !          47970: static int inquiry(s_id, buf)
        !          47971: int s_id;
        !          47972: uchar * buf;
        !          47973: {
        !          47974:        int ret = 0;
        !          47975:        uchar cmdbuf[G0CMDLEN];
        !          47976: 
        !          47977:        cmdbuf[0] = ScmdINQUIRY;
        !          47978:        cmdbuf[1] = 0;
        !          47979:        cmdbuf[2] = 0;
        !          47980:        cmdbuf[3] = 0;
        !          47981:        cmdbuf[4] = INQUIRYLEN;
        !          47982:        cmdbuf[5] = 0;
        !          47983: 
        !          47984:        if (start_arb() && host_ident(s_id, 0) &&
        !          47985:        local_info_xfer(cmdbuf, G0CMDLEN, buf, INQUIRYLEN, NULL, 0))
        !          47986:                ret = 1;
        !          47987: 
        !          47988:        return ret;
        !          47989: }
        !          47990: 
        !          47991: /*
        !          47992:  * mode_sense()
        !          47993:  *
        !          47994:  * Mode Sense command for a device.
        !          47995:  * Use this to get disk parameters:
        !          47996:  *     number of cylinders
        !          47997:  *     number of heads
        !          47998:  *     number of sectors per track.
        !          47999:  *
        !          48000:  * Put result of mode sense into supplied buffer.
        !          48001:  * Return 1 if command succeeds, else 0.
        !          48002:  */
        !          48003: static int mode_sense(s_id, buf)
        !          48004: int s_id;
        !          48005: uchar * buf;
        !          48006: {
        !          48007:        int ret = 0;
        !          48008:        uchar cmdbuf[G0CMDLEN];
        !          48009: 
        !          48010:        cmdbuf[0] = ScmdMODESENSE;
        !          48011:        cmdbuf[1] = 0;
        !          48012:        cmdbuf[2] = 0x3F;
        !          48013:        cmdbuf[3] = 0;
        !          48014:        cmdbuf[4] = MODESENSELEN;
        !          48015:        cmdbuf[5] = 0;
        !          48016: 
        !          48017:        if (start_arb() && host_ident(s_id, 0) &&
        !          48018:        local_info_xfer(cmdbuf, G0CMDLEN, buf, MODESENSELEN, NULL, 0))
        !          48019:                ret = 1;
        !          48020: 
        !          48021:        return ret;
        !          48022: }
        !          48023: 
        !          48024: /*
        !          48025:  * read_cap()
        !          48026:  *
        !          48027:  * Read Capacity command for a device.
        !          48028:  *
        !          48029:  * Return 1 if command succeeds, else 0.
        !          48030:  */
        !          48031: static int read_cap(s_id, buf)
        !          48032: int s_id;
        !          48033: uchar * buf;
        !          48034: {
        !          48035:        int ret = 0;
        !          48036:        uchar cmdbuf[G1CMDLEN];
        !          48037: 
        !          48038:        cmdbuf[0] = ScmdREADCAPACITY;
        !          48039:        cmdbuf[1] = 0;
        !          48040:        cmdbuf[2] = 0;
        !          48041:        cmdbuf[3] = 0;
        !          48042:        cmdbuf[4] = 0;
        !          48043:        cmdbuf[5] = 0;
        !          48044:        cmdbuf[6] = 0;
        !          48045:        cmdbuf[7] = 0;
        !          48046:        cmdbuf[8] = 0;
        !          48047:        cmdbuf[9] = 0;
        !          48048: 
        !          48049:        if (start_arb() && host_ident(s_id, 0) &&
        !          48050:        local_info_xfer(cmdbuf, G1CMDLEN, buf, READCAPLEN, NULL, 0))
        !          48051:                ret = 1;
        !          48052: 
        !          48053:        return ret;
        !          48054: }
        !          48055: 
        !          48056: /*
        !          48057:  * bus_dev_reset()
        !          48058:  *
        !          48059:  * Send Bus Device Reset message to the given SCSI id.
        !          48060:  * Return 1 if host adapter was not busy and no obvious timeouts occurred,
        !          48061:  * else 0.
        !          48062:  */
        !          48063: static int bus_dev_reset(s_id)
        !          48064: {
        !          48065:        int bdr_ok = 1;
        !          48066:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          48067: 
        !          48068: PR1("bdr");
        !          48069: 
        !          48070:        if (bdr_ok) {
        !          48071:                /*
        !          48072:                 * Do ST0x arbitration.
        !          48073:                 */
        !          48074:                sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          48075:                sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          48076:                sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          48077: 
        !          48078:                /*
        !          48079:                 * SCSI spec says there is "no maximum" to the wait for
        !          48080:                 * arbitration complete.
        !          48081:                 */
        !          48082:                if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
        !          48083:                        bdr_ok = 0;
        !          48084:                }
        !          48085:        }
        !          48086: 
        !          48087:        /*
        !          48088:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          48089:         */
        !          48090:        if (bdr_ok) {
        !          48091:                sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          48092:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          48093: 
        !          48094:                if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          48095:                        bdr_ok = 0;
        !          48096:        }
        !          48097: 
        !          48098:        if (bdr_ok) {
        !          48099:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          48100: 
        !          48101:                if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          48102:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          48103:                        bdr_ok = 0;
        !          48104:        }
        !          48105: 
        !          48106:        if (bdr_ok) {
        !          48107:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          48108:                sfbyte(ss_dat, MSG_DEV_RESET);
        !          48109:                if (!bus_wait((0xFF << 8) | 0))
        !          48110:                        bdr_ok = 0;
        !          48111:        }
        !          48112: 
        !          48113:        return bdr_ok;
        !          48114: }
        !          48115: 
        !          48116: /*
        !          48117:  * chk_reconn()
        !          48118:  *
        !          48119:  * Check SELECT to see if any SCSI device has tried to reconnect to the host
        !          48120:  * adapter.  Called if there is an interrupt, and by the timer in case
        !          48121:  * we somehow lose an interrupt.
        !          48122:  *
        !          48123:  * Return -1 if no reselect detected, or the SCSI ID of the reselecting
        !          48124:  * target if there is one.
        !          48125:  */
        !          48126: static int chk_reconn()
        !          48127: {
        !          48128:        uchar csr, dat;
        !          48129:        int s_id = -1;
        !          48130: 
        !          48131:        csr = ffbyte(ss_csr);
        !          48132:        if (csr & (RS_SELECT | RS_I_O)) {
        !          48133:                dat = ffbyte(ss_dat);
        !          48134:                if ((dat & HOST_ID) && (dat & NSDRIVE)) {
        !          48135:                        dat &= ~HOST_ID;
        !          48136:                        s_id = 0;
        !          48137:                        while (dat >>=1)
        !          48138:                                s_id++;
        !          48139:                }
        !          48140:        }
        !          48141: 
        !          48142:        return s_id;
        !          48143: }
        !          48144: 
        !          48145: /*
        !          48146:  * ss_mach()
        !          48147:  *
        !          48148:  *     Gives a distinct state machine for each target device.
        !          48149:  */
        !          48150: void   ss_mach(s_id)
        !          48151: int s_id;
        !          48152: {
        !          48153:        ss_type * ssp = ss[s_id];
        !          48154:        BUF * bp;
        !          48155:        int s;
        !          48156: 
        !          48157:        do_sst_op = 1; /* plan to run this routine again in most cases */
        !          48158:        while (do_sst_op) {
        !          48159:                bp = ssp->bp;  /* nonpolled() below can change ssp->bp */
        !          48160:                switch (ssp->state) {
        !          48161:                /*
        !          48162:                 * Polling states execute whether ssp->waiting or not.
        !          48163:                 */
        !          48164:                case SST_POLL_ARBITN:
        !          48165: PR3("PA ");
        !          48166:                        if (ffbyte(ss_csr) & RS_ARBIT_COMPL) {
        !          48167:                                ssp->waiting = 0;
        !          48168:                                if (host_ident(s_id, 1))
        !          48169:                                        do_connect(s_id);
        !          48170:                                else
        !          48171:                                        recover(s_id, RV_P_TIMEOUT);
        !          48172:                        } else {
        !          48173:                                if (ssp->expired) {
        !          48174:                                        ssp->expired = 0;
        !          48175:                                        recover(s_id, RV_A_TIMEOUT);
        !          48176:                                } else
        !          48177:                                        do_sst_op = 0;
        !          48178:                        }
        !          48179:                        break;
        !          48180:                case SST_POLL_BEGIN_IO:
        !          48181: PR3("PBI ");
        !          48182:                        if (bp == NULL)
        !          48183:                                ssp->state = SST_DEQUEUE;
        !          48184:                        else {
        !          48185:                                /*
        !          48186:                                 * At this point a SCSI command is about to
        !          48187:                                 * be initiated.  It may be a retry.
        !          48188:                                 */
        !          48189:                                if (host_claimed == -1 && BUS_FREE && BUS_FREE) {
        !          48190:                                        host_claimed = s_id;
        !          48191:                                        ssp->waiting = 0;
        !          48192:                                        init_pointers(s_id);
        !          48193:                                        s=sphi();
        !          48194:                                        if (start_arb()) {
        !          48195:                                                if (host_ident(s_id, 1)) {
        !          48196:                                                        do_connect(s_id);
        !          48197:                                                        spl(s);
        !          48198:                                                } else {
        !          48199:                                                        spl(s);
        !          48200:                                                        recover(s_id, RV_P_TIMEOUT);
        !          48201:                                                }
        !          48202:                                        } else {
        !          48203:                                                spl(s);
        !          48204:                                                ssp->state = SST_POLL_ARBITN;
        !          48205:                                                set_timeout(s_id, DELAY_ARB);
        !          48206:                                        }
        !          48207:                                } else { /* host busy or bus not free */
        !          48208:                                        ++ssp->avl_count;
        !          48209:                                        if (ssp->avl_count >= MAX_AVL_COUNT)
        !          48210:                                                recover(s_id, RV_BF_TIMEOUT);
        !          48211:                                        else
        !          48212:                                                set_timeout(s_id, DELAY_BSY);
        !          48213:                                }
        !          48214:                        }
        !          48215:                        break;
        !          48216:                case SST_POLL_RESELECT:
        !          48217: PR3("PR ");
        !          48218:                        if (TGT_RSEL) {
        !          48219:                                ssp->waiting = 0;
        !          48220:                                s=sphi();
        !          48221:                                if (rsel_handshake()) {
        !          48222:                                        do_connect(s_id);
        !          48223:                                        spl(s);
        !          48224:                                } else {
        !          48225:                                        spl(s);
        !          48226:                                        recover(s_id, RV_P_TIMEOUT);
        !          48227:                                }
        !          48228:                        } else  { /* Reselect poll is negative */
        !          48229:                                if (ssp->expired) {
        !          48230:                                        ssp->expired = 0;
        !          48231:                                        recover(s_id, RV_R_TIMEOUT);
        !          48232:                                } else
        !          48233:                                        do_sst_op = 0;
        !          48234:                        }
        !          48235:                        break;
        !          48236:                default:
        !          48237:                        if (ssp->waiting)
        !          48238:                                do_sst_op = 0;
        !          48239:                        else {
        !          48240:                                /*
        !          48241:                                 * Nonpolling states execute only if no
        !          48242:                                 * target timer is running.
        !          48243:                                 */
        !          48244:                                nonpolled(s_id);
        !          48245:                        }
        !          48246:                } /* endswitch */
        !          48247:        } /* endwhile */
        !          48248: }
        !          48249: 
        !          48250: /*
        !          48251:  * nonpolled()
        !          48252:  *
        !          48253:  * Part of ss_mach() - handling of nonpolling states is taken out simply
        !          48254:  * for readability.
        !          48255:  */
        !          48256: static void nonpolled(s_id)
        !          48257: int s_id;
        !          48258: {
        !          48259:        ss_type * ssp = ss[s_id];
        !          48260:        BUF * bp = ssp->bp;
        !          48261:        struct  fdisk_s *fdp;
        !          48262:        int partition;
        !          48263:        dev_t dev;
        !          48264: 
        !          48265:        switch (ssp->state) {
        !          48266:        case SST_BUS_DEV_RESET:
        !          48267: PR3("BDR ");
        !          48268:                if (bus_dev_reset(s_id)) {
        !          48269:                        do_sst_op = 0;
        !          48270:                        set_timeout(s_id, DELAY_BDR);
        !          48271:                        ssp->state = SST_REQ_SENSE;
        !          48272:                } else
        !          48273:                        recover(s_id, RV_P_TIMEOUT);
        !          48274:                break;
        !          48275:        case SST_DEQUEUE:
        !          48276:                if(bufq_rd_head(s_id) != NULL && !ssp->busy) {
        !          48277: PR3("DQ ");
        !          48278:                        ssp->busy = 1;
        !          48279:                        bp = bufq_rm_head(s_id);
        !          48280:                        ssp->bp = bp;
        !          48281:                        dev = bp->b_dev;
        !          48282:                        partition = DEV_PARTN(dev);
        !          48283:                        if (dev & SDEV)
        !          48284:                                partition = WHOLE_DRIVE;
        !          48285:                        fdp = ssp->parmp;
        !          48286:                        if (partition != WHOLE_DRIVE)
        !          48287:                                ssp->bno = fdp[partition].p_base + bp->b_bno;
        !          48288:                        else
        !          48289:                                ssp->bno = bp->b_bno;
        !          48290:                        if (bp->b_req == BREAD)
        !          48291:                                ssp->cmdbuf[0] = ScmdREADEXTENDED;
        !          48292:                        else
        !          48293:                                ssp->cmdbuf[0] = ScmdWRITEXTENDED;
        !          48294:                        ssp->cmdbuf[1] = 0;
        !          48295:                        ssp->cmdbuf[2] = ssp->bno >> 24;
        !          48296:                        ssp->cmdbuf[3] = ssp->bno >> 16;
        !          48297:                        ssp->cmdbuf[4] = ssp->bno >>  8;
        !          48298:                        ssp->cmdbuf[5] = ssp->bno;
        !          48299:                        ssp->cmdbuf[6] = 0;
        !          48300:                        ssp->cmdbuf[7] = 0;
        !          48301:                        ssp->cmdbuf[8] = 1;
        !          48302:                        ssp->cmdbuf[9] = 0;
        !          48303:                        ssp->cmdlen = G1CMDLEN;
        !          48304:                        init_pointers(s_id);
        !          48305:                        ssp->bdr_count = 0;
        !          48306:                        ssp->bsy_count = 0;
        !          48307:                        ssp->try_count = 0;
        !          48308:                        ssp->state = SST_POLL_BEGIN_IO;
        !          48309:                } else /* queue is empty or ssp->busy */
        !          48310:                        do_sst_op = 0;
        !          48311:                break;
        !          48312:        case SST_HIPRI_RESET:
        !          48313:        case SST_LOPRI_RESET:
        !          48314: PR1("rst");
        !          48315: if ((ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA)) == XP_MSG_OUT) {
        !          48316:        printf("honk");
        !          48317:        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          48318:        sfbyte(ss_dat, MSG_ABORT); 
        !          48319: }
        !          48320:                /*
        !          48321:                 * SST_LOPRI_RESET is same as SST_HIPRI_RESET for now.
        !          48322:                 * Later, can implement a delay to allow other targets to
        !          48323:                 * finish pending operations.
        !          48324:                 */
        !          48325:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET); /* reset ON */
        !          48326:                ssp->state = SST_RESET_OFF;
        !          48327:                set_timeout(s_id, DELAY_RST);
        !          48328:                break;
        !          48329:        case SST_REQ_SENSE:
        !          48330: PR1("RQS ");
        !          48331:                if (req_sense(s_id))
        !          48332:                        ssp->state = SST_POLL_BEGIN_IO;
        !          48333:                else
        !          48334:                        recover(s_id, RV_P_TIMEOUT);
        !          48335:                break;
        !          48336:        case SST_RESET_DONE:
        !          48337: PR3("RDN ");
        !          48338:                ssp->state = SST_POLL_BEGIN_IO;
        !          48339:                break;
        !          48340:        case SST_RESET_OFF:
        !          48341: PR3("RFF ");
        !          48342:                sfbyte(ss_csr, 0); /* reset OFF */
        !          48343:                ssp->state = SST_RESET_DONE;
        !          48344:                set_timeout(s_id, DELAY_RST);
        !          48345:        } /* endswitch */
        !          48346: }
        !          48347: 
        !          48348: /*
        !          48349:  * start_arb()
        !          48350:  *
        !          48351:  * return 1 if host adapter returned Arbitration Complete within allotted
        !          48352:  * number of tries, else 0
        !          48353:  */
        !          48354: static int start_arb()
        !          48355: {
        !          48356:        sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          48357:        sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          48358:        sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          48359: 
        !          48360:        /*
        !          48361:         * SCSI spec says there is "no maximum" to the wait for arbitration
        !          48362:         * complete.
        !          48363:         */
        !          48364:        return bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL);
        !          48365: }
        !          48366: 
        !          48367: /*
        !          48368:  * host_ident()
        !          48369:  *
        !          48370:  * This routine is the bridge in a SCSI bus cycle between Abitration
        !          48371:  * Complete and the Information Transfer phases.
        !          48372:  *
        !          48373:  * return 1 if everything went ok, 0 in case of timeout
        !          48374:  */
        !          48375: static int host_ident(s_id, disconnect)
        !          48376: int s_id;
        !          48377: int disconnect;
        !          48378: {
        !          48379:        int ret = 0;
        !          48380: 
        !          48381:        /*
        !          48382:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          48383:         */
        !          48384:        sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          48385:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          48386: 
        !          48387:        if (bus_wait(RS_BUSY << 8 | RS_BUSY)) {
        !          48388:                /*
        !          48389:                 * Assert ATTN so target expects incoming message byte.
        !          48390:                 */
        !          48391:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          48392: 
        !          48393:                if (bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          48394:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE))) {
        !          48395:                        if (disconnect)
        !          48396:                                sfbyte(ss_dat, MSG_IDENT_DC);
        !          48397:                        else
        !          48398:                                sfbyte(ss_dat, MSG_IDENTIFY);
        !          48399:                        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ENABLE_IRPT);
        !          48400:                        ret = 1;
        !          48401:                }
        !          48402:        }
        !          48403:        return ret;
        !          48404: }
        !          48405: 
        !          48406: /*
        !          48407:  * rsel_handshake()
        !          48408:  *
        !          48409:  * After Reselect is detected, a couple steps are needed before entering
        !          48410:  * Information Transfer phases.  This routine does those steps.
        !          48411:  *
        !          48412:  * return 1 if ok, 0 in case of timeout.
        !          48413:  */
        !          48414: static int rsel_handshake()
        !          48415: {
        !          48416:        int ret = 0;
        !          48417: 
        !          48418:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_BUSY);
        !          48419:        if (bus_wait(RS_SELECT << 8 | 0)) {
        !          48420:                sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          48421:                ret = 1;
        !          48422:        }
        !          48423:        return ret;
        !          48424: }
        !          48425: 
        !          48426: /*
        !          48427:  * set_timeout()
        !          48428:  *
        !          48429:  * Start a timer so as not to wait forever in case something goes wrong while
        !          48430:  * waiting for an event.  Available delays are:
        !          48431:  *
        !          48432:  *     DELAY_ARB -     wait for arbitration complete
        !          48433:  *     DELAY_BDR -     allow settling time after Bus Device Reset
        !          48434:  *     DELAY_BSY -     wait for not HOST_BUSY and bus free
        !          48435:  *     DELAY_RES -     wait for reselect by target
        !          48436:  *     DELAY_RST -     allow settling times when doing SCSI Bus Reset
        !          48437:  *
        !          48438:  * Second argument is number of clock ticks to wait until timer expiration.
        !          48439:  */
        !          48440: static void set_timeout(s_id, delay)
        !          48441: int s_id, delay;
        !          48442: {
        !          48443:        ss_type * ssp = ss[s_id];
        !          48444: 
        !          48445:        ssp->expired = 0;
        !          48446:        ssp->waiting = 1;
        !          48447:        do_sst_op =  0;
        !          48448:        timeout(&(ssp->tim), delay, stop_timeout, s_id);
        !          48449: }
        !          48450: 
        !          48451: /*
        !          48452:  * stop_timeout()
        !          48453:  *
        !          48454:  * Called on expiration of the timer for a given target.
        !          48455:  * Don't expire a timer if it's no longer active.
        !          48456:  */
        !          48457: static void stop_timeout(s_id)
        !          48458: int s_id;
        !          48459: {
        !          48460:        ss_type * ssp = ss[s_id];
        !          48461: 
        !          48462:        if (ssp->waiting) {
        !          48463:                ssp->expired = 1;
        !          48464:                ssp->waiting = 0;
        !          48465:        }
        !          48466:        ss_mach(s_id);
        !          48467: }
        !          48468: 
        !          48469: /*
        !          48470:  * init_pointers()
        !          48471:  *
        !          48472:  * Initialize command and data pointers when starting (or restarting)
        !          48473:  * a block i/o command.
        !          48474:  */
        !          48475: static void init_pointers(s_id)
        !          48476: int s_id;
        !          48477: {
        !          48478:        ss_type * ssp = ss[s_id];
        !          48479:        BUF * bp = ssp->bp;
        !          48480: 
        !          48481:        ssp->cmdstat = -1;
        !          48482:        ssp->cmd_bytes_out = 0;
        !          48483:        ssp->avl_count = 0;
        !          48484: }
        !          48485: 
        !          48486: /*
        !          48487:  * recover()
        !          48488:  *
        !          48489:  * This routine is called directly or indirectly from ss_mach().  It
        !          48490:  * determines what to do when the interface fails to behave as desired.
        !          48491:  *
        !          48492:  * Arguments are the SCSI id of the target HDC and an error type.
        !          48493:  * Error types are:
        !          48494:  *
        !          48495:  * RV_A_TIMEOUT (arbitration timeout)
        !          48496:  * Host adapter takes too long to respond with arbitration complete.
        !          48497:  * 
        !          48498:  * RV_P_TIMEOUT (protocol timeout)
        !          48499:  * Timeout waiting for desired SCSI bus status while connected to a target.
        !          48500:  * 
        !          48501:  * RV_R_TIMEOUT (reconnect timeout)
        !          48502:  * Timeout after target disconnects, waiting for reconnect.
        !          48503:  * 
        !          48504:  * RV_BF_TIMEOUT (bus free timeout)
        !          48505:  * Waited too long for host not busy and BUS_FREE.
        !          48506:  * 
        !          48507:  * RV_CS_BUSY (target device busy)
        !          48508:  * Command status returned was Busy.
        !          48509:  * 
        !          48510:  * RV_CS_CHECK (target device check)
        !          48511:  * Command status returned was CHECK.
        !          48512:  * 
        !          48513:  * Whenever an error occurs, one of the above inputs, together with the SCSI id
        !          48514:  * of the target, is sent to the recovery process.  The recovery process in turn
        !          48515:  * programs the next state for the machine.
        !          48516:  */
        !          48517: static void recover(s_id, errtype)
        !          48518: int s_id;
        !          48519: RV_TYPE errtype;
        !          48520: {
        !          48521:        ss_type * ssp = ss[s_id];
        !          48522:        BUF * bp = ssp->bp;
        !          48523: 
        !          48524:        ++ssp->try_count;
        !          48525:        if (ssp->try_count < MAX_TRY_COUNT) {
        !          48526: 
        !          48527:                switch (errtype) {
        !          48528: 
        !          48529:                case RV_CS_BUSY:
        !          48530:                        ++ssp->bsy_count;
        !          48531:                        if (ssp->bsy_count < MAX_BSY_COUNT) {
        !          48532:                                ssp->state = SST_POLL_BEGIN_IO;
        !          48533:                                set_timeout(s_id, DELAY_BSY);
        !          48534:                        } else
        !          48535:                                ssp->state = SST_BUS_DEV_RESET;
        !          48536:                        break;
        !          48537: 
        !          48538:                case RV_CS_CHECK:
        !          48539:                        ssp->state = SST_REQ_SENSE;
        !          48540:                        break;
        !          48541: 
        !          48542:                case RV_P_TIMEOUT:
        !          48543:                        /* fall thru */
        !          48544:                case RV_R_TIMEOUT:
        !          48545:                        ++ssp->bdr_count;
        !          48546:                        if (ssp->bdr_count < MAX_BDR_COUNT)
        !          48547:                                ssp->state = SST_BUS_DEV_RESET;
        !          48548:                        else
        !          48549:                                ssp->state = SST_LOPRI_RESET;
        !          48550:                        break;
        !          48551: 
        !          48552:                case RV_BF_TIMEOUT:
        !          48553:                        host_claimed = -1;
        !          48554:                        /* fall thru */
        !          48555:                case RV_A_TIMEOUT:
        !          48556:                        ssp->state = SST_HIPRI_RESET;
        !          48557:                }
        !          48558:        } else { /* try_count >= MAX_TRY_COUNT */
        !          48559:                if (bp) {
        !          48560:                        bp->b_flag |= BFERR;
        !          48561: PR3("BF4 ");
        !          48562:                }
        !          48563:                ss_finished(s_id);
        !          48564:        }
        !          48565: }
        !          48566: 
        !          48567: /*
        !          48568:  * ss_finished
        !          48569:  *
        !          48570:  * Release current i/o buffer to the O/S.
        !          48571:  */
        !          48572: static void ss_finished(s_id)
        !          48573: int s_id;
        !          48574: {
        !          48575:        ss_type * ssp = ss[s_id];
        !          48576:        BUF * bp = ssp->bp;
        !          48577:        int go_again = 1;
        !          48578: 
        !          48579:        if (host_claimed == s_id)
        !          48580:                host_claimed = -1;
        !          48581:        ssp->busy = 0;
        !          48582:        if (bp) {
        !          48583:                if (!(bp->b_flag & BFERR))
        !          48584:                        bp->b_resid -= BSIZE;
        !          48585:                if ((bp->b_flag & BFERR) || bp->b_resid == 0) {
        !          48586:                        ssp->bp = NULL;
        !          48587:                        bdone(bp);
        !          48588:                        go_again = 0;
        !          48589:                }
        !          48590:        }
        !          48591:        if (go_again) {
        !          48592:                ssp->state = SST_POLL_BEGIN_IO;
        !          48593:                ssp->bdr_count = 0;
        !          48594:                ssp->bsy_count = 0;
        !          48595:                ssp->try_count = 0;
        !          48596:        } else
        !          48597:                ssp->state = SST_DEQUEUE;
        !          48598: }
        !          48599: 
        !          48600: /*
        !          48601:  * do_connect()
        !          48602:  *
        !          48603:  * This function is called when the host is successfully connected to
        !          48604:  * the target.
        !          48605:  */
        !          48606: static void do_connect(s_id)
        !          48607: int s_id;
        !          48608: {
        !          48609:        int result;
        !          48610:        ss_type * ssp = ss[s_id];
        !          48611: 
        !          48612:        result = far_info_xfer(s_id);
        !          48613:        if (host_claimed == s_id)
        !          48614:                host_claimed = -1;
        !          48615:        if (!result)
        !          48616:                recover(s_id, RV_P_TIMEOUT);
        !          48617:        else if (ssp->msg_in == MSG_DISCONNECT) {
        !          48618:                ssp->state = SST_POLL_RESELECT;
        !          48619:                set_timeout(s_id, DELAY_RES);
        !          48620:        } else if (ssp->msg_in == MSG_CMD_CMPLT && ssp->cmdstat == CS_GOOD)
        !          48621:                ss_finished(s_id);
        !          48622:        else if (ssp->cmdstat == CS_BUSY)
        !          48623:                recover(s_id, RV_CS_BUSY);
        !          48624:        else if (ssp->cmdstat == CS_CHECK)
        !          48625:                recover(s_id, RV_CS_CHECK);
        !          48626:        else  /* something else went wrong */
        !          48627:                recover(s_id, RV_P_TIMEOUT);
        !          48628: }
        !          48629: 
        !          48630: /*
        !          48631:  * local_info_xfer()
        !          48632:  *
        !          48633:  * Do bus cycle information transfer phases.
        !          48634:  * Transfer is for a command which will produce local results in the driver.
        !          48635:  * Other ...info_xfer routine handles kernel block i/o commands.
        !          48636:  *
        !          48637:  * Return 1 if transfer succeeded, else 0.
        !          48638:  *
        !          48639:  */
        !          48640: static int local_info_xfer(cmdbuf, cmdlen, inbuf, inlen, outbuf, outlen)
        !          48641: uchar * cmdbuf, * inbuf, * outbuf;
        !          48642: uint cmdlen, inlen, outlen;
        !          48643: {
        !          48644:        int bus_timeout;
        !          48645:        uchar phase_type;
        !          48646:        int s;
        !          48647:        int cmd_bytes_out = 0;
        !          48648:        int data_bytes_in = 0;
        !          48649:        int data_bytes_out = 0;
        !          48650:        int ret = 0;
        !          48651:        int xfer_good = 1;
        !          48652:        int cmdstat = -1;
        !          48653:        int msg_in = -1;
        !          48654: 
        !          48655:        s = sphi();
        !          48656:        while (req_wait(&bus_timeout) && xfer_good) {
        !          48657:                phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
        !          48658:                switch (phase_type) {
        !          48659:                case XP_MSG_IN:
        !          48660:                        msg_in = ffbyte(ss_dat);
        !          48661:                        switch(msg_in){
        !          48662:                        case MSG_CMD_CMPLT:
        !          48663:                        case MSG_DISCONNECT:
        !          48664:                                sfbyte(ss_csr, WC_ENABLE_IRPT);
        !          48665:                                break;
        !          48666:                        }
        !          48667:                        break;
        !          48668:                case XP_MSG_OUT:
        !          48669:                        /*
        !          48670:                         * This case shouldn't happen.  We weren't
        !          48671:                         * asserting ATTENTION.  Abort the bus cycle.
        !          48672:                         */
        !          48673:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          48674:                        sfbyte(ss_dat, MSG_ABORT); 
        !          48675:                        break;
        !          48676:                case XP_STAT_IN:
        !          48677:                        cmdstat = ffbyte(ss_dat);
        !          48678:                        break;
        !          48679:                case XP_CMD_OUT:
        !          48680:                        /*
        !          48681:                         * Ship out command bytes.
        !          48682:                         */
        !          48683:                        if (cmd_bytes_out < cmdlen) {
        !          48684:                                sfbyte(ss_dat, cmdbuf[cmd_bytes_out++]);
        !          48685:                                /*
        !          48686:                                 * If just sent last byte, allow interrupts.
        !          48687:                                 */
        !          48688:                                if (cmd_bytes_out == cmdlen) {
        !          48689:                                        spl(s);
        !          48690:                                        s = sphi();
        !          48691:                                }
        !          48692:                        } else {        /* This case should not happen. */
        !          48693:                                xfer_good = 0;
        !          48694:                        }
        !          48695:                        break;
        !          48696:                case XP_DATA_IN:
        !          48697:                        /*
        !          48698:                         * If caller's buffer has room, keep incoming
        !          48699:                         * data byte.  Else toss it.
        !          48700:                         */
        !          48701:                        if (data_bytes_in < inlen) {
        !          48702:                                inbuf[data_bytes_in++] = ffbyte(ss_dat);
        !          48703:                        } else
        !          48704:                                ffbyte(ss_dat);
        !          48705:                        break;
        !          48706:                case XP_DATA_OUT:
        !          48707:                        /*
        !          48708:                         * Copy output buffer bytes to data register.
        !          48709:                         */
        !          48710:                        if (data_bytes_out < outlen) {
        !          48711:                                sfbyte(outbuf[data_bytes_out++], ss_dat);
        !          48712:                        } else { /* This case should not happen. */
        !          48713:                                xfer_good = 0;
        !          48714:                        }
        !          48715:                        break;
        !          48716:                default:
        !          48717:                        break;
        !          48718:                } /* endswitch */
        !          48719:        }
        !          48720:        spl(s);
        !          48721: 
        !          48722:        if (!bus_timeout && xfer_good && cmdstat == CS_GOOD)
        !          48723:                ret = 1;
        !          48724: 
        !          48725:        host_claimed = -1;
        !          48726:        return ret;
        !          48727: }
        !          48728: @
        !          48729: 
        !          48730: 
        !          48731: 1.45
        !          48732: log
        !          48733: @Still trying to test ss_get.  Always hangs.
        !          48734: @
        !          48735: text
        !          48736: @a11 1
        !          48737:  *     mask interrupts on finishing arbitration, etc.
        !          48738: d17 3
        !          48739: a165 2
        !          48740:        int     data_bytes_in;
        !          48741:        int     data_bytes_out;
        !          48742: a626 1
        !          48743:        int valid_op = 1;
        !          48744: d640 2
        !          48745: d650 1
        !          48746: a650 1
        !          48747:                                valid_op = 0;
        !          48748: d656 1
        !          48749: a656 1
        !          48750:                        valid_op = 0;
        !          48751: d659 1
        !          48752: d665 1
        !          48753: a665 1
        !          48754:                valid_op = 0;
        !          48755: d667 1
        !          48756: d675 1
        !          48757: a675 1
        !          48758:                valid_op = 0;
        !          48759: d679 8
        !          48760: d690 4
        !          48761: a693 4
        !          48762:        if (valid_op) {
        !          48763:                bufq_wr_tail(s_id, bp);
        !          48764:                ss_mach(s_id);
        !          48765:        }
        !          48766: d698 1
        !          48767: a698 1
        !          48768:        else {  /* "valid_op" is FALSE */
        !          48769: d700 3
        !          48770: a702 1
        !          48771:        }
        !          48772: d878 2
        !          48773: a879 1
        !          48774: int first=1;
        !          48775: d947 4
        !          48776: a950 23
        !          48777: if (bp->b_req == BREAD) {
        !          48778:        if (first) {
        !          48779:                first=0;
        !          48780:                printf("ss_fp=%lx ", ss_fp);
        !          48781:                printf("buf_f=%lx resid=%d ", bp->b_faddr, bp->b_resid);
        !          48782:        }
        !          48783: #if 0
        !          48784:        if (bp->b_resid <= SS_DAT_LEN) {
        !          48785:                ss_get(ss_fp, bp->b_faddr, (uint)bp->b_resid);
        !          48786: printf("word 1FC = %x\n", ffword(bp->b_faddr+0x1fc));
        !          48787: ssp->data_bytes_in += bp->b_resid;
        !          48788:        } else
        !          48789: #endif
        !          48790:                        if (ssp->data_bytes_in < bp->b_count) {
        !          48791:                                uchar dat;
        !          48792: 
        !          48793:                                dat = ffbyte(ss_dat);
        !          48794:                                sfbyte(bp->b_faddr + ssp->data_bytes_in, dat);
        !          48795:                                ssp->data_bytes_in++;
        !          48796:                        } else
        !          48797:                                ffbyte(ss_dat);
        !          48798: } else
        !          48799:        xfer_good = 0;
        !          48800: d956 1
        !          48801: a956 2
        !          48802: if (bp->b_req == BWRITE) {
        !          48803:                        if (ssp->data_bytes_out < bp->b_count) {
        !          48804: d959 1
        !          48805: a959 1
        !          48806:                                dat = ffbyte(bp->b_faddr + ssp->data_bytes_out);
        !          48807: d961 2
        !          48808: a962 2
        !          48809:                                ssp->data_bytes_out++;
        !          48810:                        } else { /* This case should not happen. */
        !          48811: a963 3
        !          48812:                        }
        !          48813: } else
        !          48814:        xfer_good = 0;
        !          48815: d1406 2
        !          48816: a1407 2
        !          48817:                        ssp->cmdbuf[7] = bp->b_count / (BSIZE * 256L);
        !          48818:                        ssp->cmdbuf[8] = bp->b_count / BSIZE;
        !          48819: a1587 2
        !          48820:        ssp->data_bytes_in = 0;
        !          48821:        ssp->data_bytes_out = 0;
        !          48822: a1589 3
        !          48823:        if (bp) {
        !          48824:                bp->b_resid = bp->b_count;
        !          48825:        }
        !          48826: d1683 1
        !          48827: d1689 7
        !          48828: a1695 6
        !          48829:                ssp->bp = NULL;
        !          48830:                if (bp->b_req == BREAD)
        !          48831:                        bp->b_resid -= ssp->data_bytes_in;
        !          48832:                else
        !          48833:                        bp->b_resid -= ssp->data_bytes_out;
        !          48834:                bdone(bp);
        !          48835: d1697 7
        !          48836: a1703 3
        !          48837:        ssp->state = SST_DEQUEUE;
        !          48838:        do_sst_op = 0;
        !          48839:        set_timeout(2);
        !          48840: @
        !          48841: 
        !          48842: 
        !          48843: 1.44
        !          48844: log
        !          48845: @Drop unneeded fields from ss struct.  Try ss_get().
        !          48846: @
        !          48847: text
        !          48848: @d18 3
        !          48849: d311 1
        !          48850: a311 1
        !          48851: 
        !          48852: d865 1
        !          48853: d934 7
        !          48854: a940 1
        !          48855:        if (bp->b_resid <= SS_DAT_LEN)
        !          48856: d942 4
        !          48857: a945 1
        !          48858:        else {
        !          48859: a953 1
        !          48860:        }
        !          48861: d1430 5
        !          48862: d1679 1
        !          48863: a1679 1
        !          48864:                if (bp)
        !          48865: d1681 2
        !          48866: @
        !          48867: 
        !          48868: 
        !          48869: 1.43
        !          48870: log
        !          48871: @Needs assembler I/O most.
        !          48872: @
        !          48873: text
        !          48874: @d18 3
        !          48875: a160 2
        !          48876:        faddr_t in_buf;
        !          48877:        int     in_buf_len;
        !          48878: a161 2
        !          48879:        faddr_t out_buf;
        !          48880:        int     out_buf_len;
        !          48881: d860 1
        !          48882: d929 5
        !          48883: a933 1
        !          48884:                        if (ssp->data_bytes_in < ssp->in_buf_len && ssp->in_buf) {
        !          48885: d937 1
        !          48886: a937 1
        !          48887:                                sfbyte(ssp->in_buf + ssp->data_bytes_in, dat);
        !          48888: d941 3
        !          48889: d949 2
        !          48890: a950 1
        !          48891:                        if (ssp->data_bytes_out < ssp->out_buf_len && ssp->out_buf) {
        !          48892: d953 1
        !          48893: a953 1
        !          48894:                                dat = ffbyte(ssp->out_buf + ssp->data_bytes_out);
        !          48895: d959 2
        !          48896: a1585 11
        !          48897:                if (bp->b_req == BREAD) {
        !          48898:                        ssp->in_buf_len = bp->b_count;
        !          48899:                        ssp->in_buf = bp->b_faddr;
        !          48900:                        ssp->out_buf_len = 0;
        !          48901:                        ssp->out_buf = NULL;
        !          48902:                } else {
        !          48903:                        ssp->in_buf_len = 0;
        !          48904:                        ssp->in_buf = NULL;
        !          48905:                        ssp->out_buf_len = bp->b_count;
        !          48906:                        ssp->out_buf = bp->b_faddr;
        !          48907:                }
        !          48908: a1681 1
        !          48909:        ssp->in_buf = ssp->out_buf = NULL;
        !          48910: d1691 2
        !          48911: @
        !          48912: 
        !          48913: 
        !          48914: 1.42
        !          48915: log
        !          48916: @COH fdisk command gives junk when DEBUG=1, ok if DEBUG=3
        !          48917: @
        !          48918: text
        !          48919: @d18 3
        !          48920: d598 1
        !          48921: a599 1
        !          48922: #endif
        !          48923: d1608 1
        !          48924: a1608 1
        !          48925:  * RV_BF_TIMEOUT (reconnect timeout)
        !          48926: a1685 1
        !          48927:                ssp->state = SST_DEQUEUE;
        !          48928: d1692 1
        !          48929: @
        !          48930: 
        !          48931: 
        !          48932: 1.41
        !          48933: log
        !          48934: @First working version.
        !          48935: @
        !          48936: text
        !          48937: @a11 1
        !          48938:  *     bus_pre_xfer() -> start_arb() + host_ident()
        !          48939: d18 3
        !          48940: a201 1
        !          48941: static int     bus_pre_xfer();
        !          48942: d826 1
        !          48943: a826 1
        !          48944:  * bus_pre_xfer()
        !          48945: a827 55
        !          48946:  * Do bus cycle phases prior to the information transfer phases.
        !          48947:  * This includes arbitration and selection.
        !          48948:  */
        !          48949: static int bus_pre_xfer(s_id)
        !          48950: int s_id;
        !          48951: {
        !          48952:        int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
        !          48953:        int ret = 0;
        !          48954: 
        !          48955:        /*
        !          48956:         * Do ST0x arbitration.
        !          48957:         */
        !          48958:        sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          48959:        sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          48960:        sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          48961: 
        !          48962:        /*
        !          48963:         * SCSI spec says there is "no maximum" to the wait for arbitration
        !          48964:         * complete.
        !          48965:         */
        !          48966:        if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
        !          48967:                if (ffbyte(ss_csr) & (RS_REQUEST|RS_BUSY))
        !          48968:                        ret = 1;
        !          48969:                goto frotz;
        !          48970:        }
        !          48971: 
        !          48972:        /*
        !          48973:         * Arbitration complete.  Now select, with ATN to allow messages.
        !          48974:         */
        !          48975:        sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          48976:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          48977: 
        !          48978:        if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          48979:                goto frotz;
        !          48980: 
        !          48981:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          48982: 
        !          48983:        if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          48984:        | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          48985:                goto frotz;
        !          48986: 
        !          48987:        /*
        !          48988:         * Disallow Disconnect.
        !          48989:         */
        !          48990:        sfbyte(ss_dat, MSG_IDENTIFY);
        !          48991:        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ENABLE_IRPT);
        !          48992:        ret = 1;
        !          48993: 
        !          48994: frotz:
        !          48995:        return ret;
        !          48996: }
        !          48997: 
        !          48998: /*
        !          48999:  * far_info_xfer()
        !          49000:  *
        !          49001: d863 1
        !          49002: a863 1
        !          49003:        while(req_wait(&bus_timeout) && xfer_good) {
        !          49004: d1040 1
        !          49005: a1040 1
        !          49006:        if (bus_pre_xfer(s_id) &&
        !          49007: d1074 1
        !          49008: a1074 1
        !          49009:        if (bus_pre_xfer(s_id) &&
        !          49010: d1107 1
        !          49011: a1107 1
        !          49012:        if (bus_pre_xfer(s_id) &&
        !          49013: d1139 1
        !          49014: a1139 1
        !          49015:        if (bus_pre_xfer(s_id) &&
        !          49016: d1258 1
        !          49017: a1258 1
        !          49018:                                if (host_ident(s_id))
        !          49019: d1285 1
        !          49020: a1285 1
        !          49021:                                                if (host_ident(s_id)) {
        !          49022: d1453 1
        !          49023: a1453 1
        !          49024:  * host_ident(s_id)
        !          49025: d1460 1
        !          49026: a1460 1
        !          49027: static int host_ident(s_id)
        !          49028: d1462 1
        !          49029: d1480 4
        !          49030: a1483 1
        !          49031:                        sfbyte(ss_dat, MSG_IDENT_DC); /* allow Disconnect */
        !          49032: d1748 1
        !          49033: a1748 1
        !          49034:        while(req_wait(&bus_timeout) && xfer_good) {
        !          49035: @
        !          49036: 
        !          49037: 
        !          49038: 1.41.1.1
        !          49039: log
        !          49040: @Comment out spl stuff in ss_mach().
        !          49041: @
        !          49042: text
        !          49043: @a18 3
        !          49044:  * Revision 1.41       91/05/15  21:57:55      root
        !          49045:  * First working version.
        !          49046:  * 
        !          49047: d1337 1
        !          49048: a1337 1
        !          49049: /* ZZ                                  s=sphi(); */
        !          49050: d1341 1
        !          49051: a1341 1
        !          49052: /* ZZ                                                  spl(s); */
        !          49053: d1343 1
        !          49054: a1343 1
        !          49055: /* ZZ                                                  spl(s); */
        !          49056: d1347 1
        !          49057: a1347 1
        !          49058: /* ZZ                                          spl(s); */
        !          49059: d1364 1
        !          49060: a1364 1
        !          49061: /* ZZ                          s=sphi(); */
        !          49062: d1367 1
        !          49063: a1367 1
        !          49064: /* ZZ                                  spl(s); */
        !          49065: d1369 1
        !          49066: a1369 1
        !          49067: /* ZZ                                  spl(s); */
        !          49068: @
        !          49069: 
        !          49070: 
        !          49071: 1.40
        !          49072: log
        !          49073: @First clean compile of state machine version.
        !          49074: @
        !          49075: text
        !          49076: @d5 2
        !          49077: a6 4
        !          49078:  *     local commands: (right now there aren't any!)
        !          49079:  *             local_buf = 0
        !          49080:  *             local_done = 0
        !          49081:  *             local_failed = 0
        !          49082: a7 5
        !          49083:  * Cleanup:
        !          49084:  *     set host_claimed conscientiously
        !          49085:  *     get rid of declarations for deleted functions
        !          49086:  *
        !          49087:  * To try after initial working version:
        !          49088: d15 2
        !          49089: d19 3
        !          49090: d36 23
        !          49091: d62 1
        !          49092: a62 1
        !          49093: #define bufq_wr_tail(s_id, foo)        ssq_wr_head(foo)
        !          49094: a99 1
        !          49095: #define WATCHDOG_SECONDS  4
        !          49096: a100 2
        !          49097: #define IN_BUF_SIZE    512     /* buffer size in "ss" structs */
        !          49098: 
        !          49099: d120 1
        !          49100: a168 3
        !          49101:        uint    local_buf:1;    /* 1 if command uses local buffer */
        !          49102:        uint    local_done:1;   /* 1 if local command is finished */
        !          49103:        uint    local_fail:1;   /* 1 if local command ended in error */
        !          49104: a212 1
        !          49105: static int     rezero();
        !          49106: a213 3
        !          49107: static int     scsicmd();
        !          49108: static void    scsireset();
        !          49109: static void    ss_done();
        !          49110: a272 3
        !          49111: static TIM     reset_tim;      /* needed for calls to scsireset() */
        !          49112: static TIM     timeout_tim;    /* needed for calls to timeout() */
        !          49113: 
        !          49114: d411 2
        !          49115: d414 2
        !          49116: d448 3
        !          49117: a450 1
        !          49118: devmsg(fdisk_dev, "calling fdisk");
        !          49119: d452 2
        !          49120: a453 1
        !          49121: int p;
        !          49122: d456 2
        !          49123: a457 2
        !          49124: printf("fdisk() succeeded\n");
        !          49125: for (p=0; p<=WHOLE_DRIVE; p++)
        !          49126: d461 1
        !          49127: a461 1
        !          49128: printf("fdisk() failed\n");
        !          49129: d465 11
        !          49130: d520 2
        !          49131: d523 2
        !          49132: d585 1
        !          49133: a585 1
        !          49134: printf("HDGETA ");
        !          49135: d591 1
        !          49136: d595 1
        !          49137: d641 1
        !          49138: a641 1
        !          49139: printf("BF1 ");
        !          49140: d646 1
        !          49141: a646 1
        !          49142: printf("BF2 ");
        !          49143: d664 1
        !          49144: a664 1
        !          49145: printf("BF3 ");
        !          49146: d698 1
        !          49147: a698 1
        !          49148:        if (s_id != -1)
        !          49149: d700 2
        !          49150: d749 1
        !          49151: d752 1
        !          49152: d776 1
        !          49153: d778 1
        !          49154: d795 1
        !          49155: d797 1
        !          49156: d803 1
        !          49157: d806 5
        !          49158: a810 3
        !          49159:                        uchar heads;
        !          49160:                        unsigned short spt;
        !          49161:                        ulong cyls;
        !          49162: d817 1
        !          49163: d1008 1
        !          49164: d1025 1
        !          49165: d1029 1
        !          49166: d1061 2
        !          49167: a1062 1
        !          49168:        if (*to_ptr)
        !          49169: d1064 2
        !          49170: d1212 1
        !          49171: a1212 1
        !          49172: printf("bdr");
        !          49173: d1298 2
        !          49174: a1299 1
        !          49175:        BUF * bp = ssp->bp;
        !          49176: d1303 1
        !          49177: d1309 1
        !          49178: d1325 2
        !          49179: a1326 1
        !          49180:                        if (bp == NULL && ssp->local_buf == 0)
        !          49181: d1337 1
        !          49182: d1339 1
        !          49183: a1339 1
        !          49184:                                                if (host_ident(s_id))
        !          49185: d1341 3
        !          49186: a1343 1
        !          49187:                                                else
        !          49188: d1345 1
        !          49189: d1347 1
        !          49190: d1361 1
        !          49191: d1364 2
        !          49192: a1365 1
        !          49193:                                if (rsel_handshake())
        !          49194: d1367 3
        !          49195: a1369 1
        !          49196:                                else
        !          49197: d1371 1
        !          49198: d1411 1
        !          49199: d1421 1
        !          49200: d1458 1
        !          49201: d1469 1
        !          49202: d1476 1
        !          49203: d1480 1
        !          49204: d1533 1
        !          49205: a1533 8
        !          49206:                        /*
        !          49207:                         * If using a local buffer rather than doing a kernel
        !          49208:                         * block i/o request, inhibit Disconnect.
        !          49209:                         */
        !          49210:                        if (ss[s_id]->local_buf)
        !          49211:                                sfbyte(ss_dat, MSG_IDENTIFY);
        !          49212:                        else
        !          49213:                                sfbyte(ss_dat, MSG_IDENT_DC);
        !          49214: a1711 3
        !          49215:                if (ssp->local_buf) {
        !          49216:                        ssp->local_fail = 1;
        !          49217:                }
        !          49218: a1739 5
        !          49219:        if (ssp->local_buf) {
        !          49220:                ssp->local_buf = 0;
        !          49221:                ssp->local_done = 1;
        !          49222:                ssp->state = SST_POLL_BEGIN_IO;
        !          49223:        }
        !          49224: @
        !          49225: 
        !          49226: 
        !          49227: 1.40.1.1
        !          49228: log
        !          49229: @Fix 2 bugs in version 1.40
        !          49230: @
        !          49231: text
        !          49232: @a23 3
        !          49233:  * Revision 1.40       91/05/15  15:19:52      root
        !          49234:  * First clean compile of state machine version.
        !          49235:  * 
        !          49236: d41 1
        !          49237: a41 1
        !          49238: #define bufq_wr_tail(s_id, foo)        ssq_wr_tail(foo)
        !          49239: d1247 1
        !          49240: a1247 1
        !          49241:        BUF * bp;
        !          49242: a1250 1
        !          49243:                bp = ssp->bp;
        !          49244: @
        !          49245: 
        !          49246: 
        !          49247: 1.39
        !          49248: log
        !          49249: @Code recover, do_connect, etc..
        !          49250: @
        !          49251: text
        !          49252: @d2 1
        !          49253: a2 1
        !          49254:  * This is a driver for Seagate ST01/ST02 scsi host adapters.
        !          49255: d5 7
        !          49256: a12 8
        !          49257:  *     if (bp->b_req == BREAD) {...
        !          49258:  *     set host_claimed conscientiously
        !          49259:  *     ss_start() code moved elsewhere
        !          49260:  *     initialize and maintain retry counters
        !          49261:  *     inquiry()
        !          49262:  *     read_cap()
        !          49263:  *     mode_sense()
        !          49264:  *     req_sense() <- called from dblock!!!
        !          49265: d21 1
        !          49266: d24 3
        !          49267: d38 5
        !          49268: a183 1
        !          49269: static int     bus_info_xfer();
        !          49270: d187 1
        !          49271: d191 1
        !          49272: d202 1
        !          49273: a203 3
        !          49274: static void    ss_start();
        !          49275: static void    ss_start_timing();
        !          49276: static void    ss_stop_timing();
        !          49277: a204 1
        !          49278: static void    ssdelay();
        !          49279: a260 1
        !          49280: static TIM     delay_tim;      /* needed for calls to ssdelay() */
        !          49281: a261 1
        !          49282: static TIM     sst_tim;        /* for timeout() call from ss_start() */
        !          49283: a583 1
        !          49284:        register int s;
        !          49285: d641 1
        !          49286: a641 1
        !          49287:                bufq_wr_tail(bp, s_id);
        !          49288: d643 1
        !          49289: d648 1
        !          49290: a648 1
        !          49291:        } else {        /* "valid_op" is FALSE */
        !          49292: a730 1
        !          49293:        int try;
        !          49294: d780 1
        !          49295: a780 1
        !          49296:  * ssdelay()
        !          49297: a781 16
        !          49298:  * Delay for some number of clock ticks.
        !          49299:  * 286/386 kernel ticks are at 100Hz
        !          49300:  *
        !          49301:  * This routine is of limited use as it can only be called via
        !          49302:  * ssload()/ssunload()/ssopen()/ssclose().
        !          49303:  */
        !          49304: static void ssdelay(ticks)
        !          49305: int ticks;
        !          49306: {
        !          49307:        timeout(&delay_tim, ticks, wakeup, (int)&delay_tim);
        !          49308:        sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
        !          49309: }
        !          49310: 
        !          49311: /*
        !          49312:  * bus_pre_xfer()
        !          49313:  *
        !          49314: a787 1
        !          49315:        int tries;
        !          49316: d791 6
        !          49317: a796 8
        !          49318:        for (tries = 0; !ret && tries < LOPRI_RETRIES; tries++) {
        !          49319: if (tries>0)break;
        !          49320:                /*
        !          49321:                 * Do ST0x arbitration.
        !          49322:                 */
        !          49323:                sfbyte(ss_csr, 0);              /* De-assert SCSI enable bit */
        !          49324:                sfbyte(ss_dat, HOST_ID);        /* Write my SCSI id to port */
        !          49325:                sfbyte(ss_csr, WC_ARBITRATE);   /* Start arbitration */
        !          49326: d798 9
        !          49327: a806 9
        !          49328:                /*
        !          49329:                 * SCSI spec says there is "no maximum" to the wait for arbitration
        !          49330:                 * complete.
        !          49331:                 */
        !          49332:                if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
        !          49333:                        if (ffbyte(ss_csr) & (RS_REQUEST|RS_BUSY))
        !          49334:                                ret = 1;
        !          49335:                        continue;
        !          49336:                }
        !          49337: d808 5
        !          49338: a812 5
        !          49339:                /*
        !          49340:                 * Arbitration complete.  Now select, with ATN to allow messages.
        !          49341:                 */
        !          49342:                sfbyte(ss_dat, HOST_ID | (1 << s_id));  /* Write both SCSI id's */
        !          49343:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
        !          49344: d814 2
        !          49345: a815 2
        !          49346:                if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
        !          49347:                        continue;
        !          49348: d817 1
        !          49349: a817 4
        !          49350:                /*
        !          49351:                 * Send "Identify" Message with Disconnect allowed.
        !          49352:                 */
        !          49353:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ATTENTION);
        !          49354: d819 3
        !          49355: a821 3
        !          49356:                if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
        !          49357:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          49358:                        continue;
        !          49359: d823 6
        !          49360: a828 11
        !          49361:                /*
        !          49362:                 * During ssload(), diagnostics are running and we don't
        !          49363:                 * want disconnects.  At other times, disconnect is ok.
        !          49364:                 */
        !          49365:                if (loading)
        !          49366:                        sfbyte(ss_dat, MSG_IDENTIFY);
        !          49367:                else
        !          49368:                        sfbyte(ss_dat, MSG_IDENT_DC);
        !          49369:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_ENABLE_IRPT);
        !          49370:                ret = 1;
        !          49371:        }
        !          49372: d830 1
        !          49373: d835 1
        !          49374: a835 1
        !          49375:  * bus_info_xfer()
        !          49376: d858 2
        !          49377: a859 2
        !          49378: static int bus_info_xfer(ssp)
        !          49379: ss_type *ssp;
        !          49380: a863 1
        !          49381:        int no_msg_rcvd = 1;
        !          49382: d866 2
        !          49383: a867 1
        !          49384: int we_wrote=0;
        !          49385: d872 1
        !          49386: a872 1
        !          49387:        while(req_wait(&bus_timeout)) {
        !          49388: d927 1
        !          49389: a927 1
        !          49390:                                scsireset();
        !          49391: a944 6
        !          49392: #if 0
        !          49393: if (!we_wrote) {
        !          49394:        we_wrote=1;
        !          49395:        printf("W");
        !          49396: }
        !          49397: #endif
        !          49398: d955 1
        !          49399: a955 1
        !          49400:                                scsireset();
        !          49401: d965 2
        !          49402: d1033 1
        !          49403: d1036 6
        !          49404: a1041 12
        !          49405:        rqs.cmdstat = -1;
        !          49406:        rqs.data_bytes_in = 0;
        !          49407:        rqs.data_bytes_out = 0;
        !          49408:        rqs.cmdbuf[0] = ScmdREQUESTSENSE;
        !          49409:        rqs.cmdbuf[1] = rqs.cmdbuf[2] = rqs.cmdbuf[3] =
        !          49410:                rqs.cmdbuf[5] = 0;
        !          49411:                rqs.cmdbuf[4] = SENSELEN;
        !          49412:        rqs.cmdlen = G0CMDLEN;
        !          49413:        rqs.in_buf_len = SENSELEN;
        !          49414:        rqs.out_buf_len = 0;
        !          49415:        FP_OFF(rqs.in_buf) = sense_buf;
        !          49416:        FP_SEL(rqs.in_buf) = sds;
        !          49417: d1043 6
        !          49418: a1048 8
        !          49419:        if (bus_pre_xfer(s_id)) {
        !          49420:                bus_info_xfer(&rqs);
        !          49421:                if (rqs.data_bytes_in == SENSELEN) {
        !          49422:                        if (sense_buf[2] == 0x00)       /* No Sense.  AOK */
        !          49423:                                ret = 1;
        !          49424:                        else if (sense_buf[2] == 0x06 && sense_buf[12] == 0x29)
        !          49425:                                ret = 1;
        !          49426:                }
        !          49427: d1068 1
        !          49428: a1068 1
        !          49429:        ss_type * ssp = ss[s_id];
        !          49430: d1070 6
        !          49431: a1075 13
        !          49432:        ssp->cmdstat = -1;
        !          49433:        ssp->data_bytes_in = 0;
        !          49434:        ssp->data_bytes_out = 0;
        !          49435:        ssp->id_busy = 1;
        !          49436:        ssp->cmdbuf[0] = ScmdINQUIRY;
        !          49437:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] =
        !          49438:                ssp->cmdbuf[5] = 0;
        !          49439:                ssp->cmdbuf[4] = INQUIRYLEN;
        !          49440:        ssp->cmdlen = G0CMDLEN;
        !          49441:        FP_OFF(ssp->in_buf) = buf;
        !          49442:        FP_SEL(ssp->in_buf) = sds;
        !          49443:        ssp->in_buf_len = INQUIRYLEN;
        !          49444:        ssp->out_buf_len = 0;
        !          49445: d1077 3
        !          49446: a1079 2
        !          49447:        ret = scsicmd(s_id);
        !          49448:        ssp->id_busy = 0;
        !          49449: d1101 1
        !          49450: a1101 1
        !          49451:        ss_type * ssp = ss[s_id];
        !          49452: d1103 6
        !          49453: a1108 15
        !          49454:        ssp->cmdstat = -1;
        !          49455:        ssp->data_bytes_in = 0;
        !          49456:        ssp->data_bytes_out = 0;
        !          49457:        ssp->id_busy = 1;
        !          49458:        ssp->cmdbuf[0] = ScmdMODESENSE;
        !          49459:        ssp->cmdbuf[1] = 0;
        !          49460:        ssp->cmdbuf[2] = 0x3F;
        !          49461:        ssp->cmdbuf[3] = 0;
        !          49462:        ssp->cmdbuf[4] = MODESENSELEN;
        !          49463:        ssp->cmdbuf[5] = 0;
        !          49464:        ssp->cmdlen = G0CMDLEN;
        !          49465:        FP_OFF(ssp->in_buf) = buf;
        !          49466:        FP_SEL(ssp->in_buf) = sds;
        !          49467:        ssp->in_buf_len = MODESENSELEN;
        !          49468:        ssp->out_buf_len = 0;
        !          49469: d1110 3
        !          49470: a1112 2
        !          49471:        ret = scsicmd(s_id);
        !          49472:        ssp->id_busy = 0;
        !          49473: d1129 1
        !          49474: a1129 1
        !          49475:        ss_type * ssp = ss[s_id];
        !          49476: d1131 10
        !          49477: a1140 13
        !          49478:        ssp->cmdstat = -1;
        !          49479:        ssp->data_bytes_in = 0;
        !          49480:        ssp->data_bytes_out = 0;
        !          49481:        ssp->id_busy = 1;
        !          49482:        ssp->cmdbuf[0] = ScmdREADCAPACITY;
        !          49483:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] = 0;
        !          49484:        ssp->cmdbuf[5] = ssp->cmdbuf[6] = ssp->cmdbuf[7] = ssp->cmdbuf[8] = 0;
        !          49485:        ssp->cmdbuf[9] = 0;
        !          49486:        ssp->cmdlen = G1CMDLEN;
        !          49487:        FP_OFF(ssp->in_buf) = buf;
        !          49488:        FP_SEL(ssp->in_buf) = sds;
        !          49489:        ssp->in_buf_len = 8;
        !          49490:        ssp->out_buf_len = 0;
        !          49491: d1142 3
        !          49492: a1144 2
        !          49493:        ret = scsicmd(s_id);
        !          49494:        ssp->id_busy = 0;
        !          49495: d1150 1
        !          49496: a1150 1
        !          49497:  * ss_start()
        !          49498: a1151 91
        !          49499:  * Invoked whenever there might be I/O to do.
        !          49500:  *
        !          49501:  * Disallow re-entrancy in this routine (variable "locked").
        !          49502:  * If there is a next I/O request queued (peek at head of queue)
        !          49503:  *   get the target SCSI ID.
        !          49504:  *   If target is not busy
        !          49505:  *     remove request from queue
        !          49506:  *     mark target device busy
        !          49507:  *     start watchdog timer
        !          49508:  *     send command to host adapter
        !          49509:  *     if command succeeded
        !          49510:  *       cleanup after command
        !          49511:  *       adjust b_resid field
        !          49512:  *     else if command failed
        !          49513:  *       set error flag
        !          49514:  *       cleanup after command
        !          49515:  *     else (disconnected)
        !          49516:  *       do nothing
        !          49517:  */
        !          49518: static void ss_start()
        !          49519: {
        !          49520: #define RW_TRIES       5
        !          49521:        int s;
        !          49522:        BUF * bp;
        !          49523:        static char locked;
        !          49524:        int s_id;
        !          49525:        ss_type * ssp;
        !          49526:        struct  fdisk_s *fdp;
        !          49527:        int partition;
        !          49528:        dev_t dev;
        !          49529:        static int retry[MAX_SCSI_ID-1];
        !          49530: 
        !          49531:        s = sphi();
        !          49532:        if(locked) {
        !          49533:                spl(s);
        !          49534:                return;
        !          49535:        }
        !          49536:        ++locked;
        !          49537:        spl(s);
        !          49538: 
        !          49539:        if (st0x_busy) {
        !          49540:                timeout(&sst_tim, 50, ss_start, 0);
        !          49541:                return;
        !          49542:        }
        !          49543: 
        !          49544:        if((bp = ssq_rd_head()) != NULL) {
        !          49545:                s_id = DEV_SCSI_ID(bp->b_dev);
        !          49546:                ssp = ss[s_id];
        !          49547:                dev = bp->b_dev;
        !          49548:                partition = DEV_PARTN(dev);
        !          49549:                if (dev & SDEV)
        !          49550:                        partition = WHOLE_DRIVE;
        !          49551:                fdp = ssp->parmp;
        !          49552:                if (!(ssp->id_busy)) {
        !          49553:                        if (partition != WHOLE_DRIVE)
        !          49554:                                ssp->bno = fdp[partition].p_base + bp->b_bno;
        !          49555:                        else
        !          49556:                                ssp->bno = bp->b_bno;
        !          49557:                        ssp->bp = bp;
        !          49558:                        ssp->id_busy = 1;
        !          49559:                        ssp->dr_watch = WATCHDOG_SECONDS;
        !          49560:                        if (ss_rw(s_id)) {
        !          49561:                                retry[s_id] = 0;
        !          49562:                                ssq_rm_head();
        !          49563:                                if (bp->b_req == BREAD)
        !          49564:                                        bp->b_resid -= ssp->data_bytes_in;
        !          49565:                                else
        !          49566:                                        bp->b_resid -= ssp->data_bytes_out;
        !          49567:                                if (ssp->msg_in != MSG_DISCONNECT)
        !          49568:                                        ss_done(s_id);
        !          49569:                        } else {
        !          49570:                                if (++retry[s_id] > RW_TRIES) {
        !          49571: printf("BF5 ");
        !          49572:                                        retry[s_id] = 0;
        !          49573:                                        ssq_rm_head();
        !          49574:                                        bp->b_flag |= BFERR;
        !          49575:                                        ss_done(s_id);
        !          49576:                                } else {
        !          49577:                                        ssp->id_busy = 0;
        !          49578:                                        timeout(&sst_tim, 10, ss_start, 0);
        !          49579: printf("R%d ",retry[s_id]);
        !          49580:                                }
        !          49581:                        }
        !          49582:                }
        !          49583:        }
        !          49584:        --locked;
        !          49585: }
        !          49586: 
        !          49587: /*
        !          49588:  * bus_dev_reset()
        !          49589:  *
        !          49590: a1267 1
        !          49591:                                endif
        !          49592: d1278 1
        !          49593: a1278 1
        !          49594:                                if (host_claimed == -1 && BUS_FREE) {
        !          49595: d1291 1
        !          49596: a1291 1
        !          49597:                                } else  /* host busy or bus not free */
        !          49598: d1340 3
        !          49599: d1357 14
        !          49600: a1370 1
        !          49601:                        init_pointers(s_id);
        !          49602: d1381 4
        !          49603: d1461 1
        !          49604: a1461 1
        !          49605:                | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
        !          49606: d1466 1
        !          49607: a1466 1
        !          49608:                        if (ss[s_id]->local_buf))
        !          49609: d1517 1
        !          49610: a1517 1
        !          49611:        ssp->timing = 1;
        !          49612: d1528 1
        !          49613: a1528 1
        !          49614: static void stop_timeout(s_id);
        !          49615: a1559 1
        !          49616:                        ssp->cmdbuf[0] = ScmdREADEXTENDED;
        !          49617: a1564 1
        !          49618:                        ssp->cmdbuf[0] = ScmdWRITEXTENDED;
        !          49619: d1622 1
        !          49620: a1622 2
        !          49621:                                ssp->state = SST_BUS_DEV_RST;
        !          49622:                        }
        !          49623: d1634 1
        !          49624: a1634 1
        !          49625:                                ssp->state = SST_BUS_DEV_RST;
        !          49626: a1636 1
        !          49627:                        }
        !          49628: d1642 1
        !          49629: a1642 1
        !          49630:                case RV_A_TIMEOUT
        !          49631: d1645 1
        !          49632: a1645 1
        !          49633:        else { /* try_count >= MAX_TRY_COUNT */
        !          49634: a1670 1
        !          49635:                bdone(bp);
        !          49636: d1673 5
        !          49637: d1682 1
        !          49638: d1696 1
        !          49639: d1698 1
        !          49640: a1698 1
        !          49641:        result = info_xfer(s_id);
        !          49642: d1704 1
        !          49643: a1704 1
        !          49644:                target_state = SST_POLL_RESELECT;
        !          49645: d1708 1
        !          49646: a1708 1
        !          49647:        } else if (ssp->cmdstat == CS_BUSY)
        !          49648: d1710 1
        !          49649: a1710 1
        !          49650:        } else if (ssp->cmdstat == CS_CHECK)
        !          49651: d1715 99
        !          49652: @
        !          49653: 
        !          49654: 
        !          49655: 1.38
        !          49656: log
        !          49657: @Code ss_mach().
        !          49658: @
        !          49659: text
        !          49660: @d5 16
        !          49661: a20 4
        !          49662:  *     bufq_wr_tail
        !          49663:  *     recover()
        !          49664:  *     do_connect()
        !          49665:  *     set_timeout()
        !          49666: d24 3
        !          49667: d80 11
        !          49668: d94 1
        !          49669: a94 1
        !          49670: typedef enum {
        !          49671: d106 10
        !          49672: d121 1
        !          49673: a121 1
        !          49674:        int     dr_watch;       /* number of seconds for pending timeout */
        !          49675: d136 11
        !          49676: a146 5
        !          49677:        unsigned int    busy:1;         /* 1 if command uses local buffer */
        !          49678:        unsigned int    expired:1;      /* 1 if target's timer has expired */
        !          49679:        unsigned int    local_buf:1;    /* 1 if command uses local buffer */
        !          49680:        unsigned int    ptab_read:1;    /* 1 if partition table has been read */
        !          49681:        unsigned int    waiting:1;      /* 1 if target timer is running */
        !          49682: d179 1
        !          49683: d181 1
        !          49684: d186 1
        !          49685: a186 1
        !          49686: static void    reconnect();
        !          49687: a193 1
        !          49688: static int     ss_rw();
        !          49689: d197 1
        !          49690: d202 1
        !          49691: d261 1
        !          49692: a261 1
        !          49693: static int     host_busy;      /* 1 when host is arbitrating or connected */
        !          49694: d341 1
        !          49695: d662 1
        !          49696: a662 1
        !          49697:                defer(ss_mach, s_id); */
        !          49698: d679 1
        !          49699: a679 1
        !          49700:                        ss_mach(s_id);
        !          49701: d777 1
        !          49702: a777 1
        !          49703:  * scsireset()
        !          49704: a778 48
        !          49705:  * Reset the SCSI bus.
        !          49706:  *
        !          49707:  * Allow settling time when turning reset on/off.
        !          49708:  * Settling times were determined empirically.
        !          49709:  * Each tick is 10 msec.
        !          49710:  *
        !          49711:  * If called while ssload() is running, don't return until reset is complete.
        !          49712:  * If called after ssload(), start up state machine and return.
        !          49713:  *
        !          49714:  * Either way, mark host adapter busy until reset completes.
        !          49715:  */
        !          49716: #define RESET_TICKS    40
        !          49717: static void scsireset()
        !          49718: {
        !          49719:        static int reset_state;
        !          49720: 
        !          49721: printf("!");
        !          49722:        /*
        !          49723:         * During load, it's ok to do sleep() calls for reset settling.
        !          49724:         * After load is finished, use timeout() to accomplish this.
        !          49725:         */
        !          49726:        if (loading) {
        !          49727:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          49728:                ssdelay(RESET_TICKS);
        !          49729:                sfbyte(ss_csr, 0);
        !          49730:                ssdelay(RESET_TICKS);
        !          49731:        } else {
        !          49732:                switch(reset_state) {
        !          49733:                case 0:
        !          49734:                        sfbyte(ss_csr, WC_ENABLE_SCSI | WC_SCSI_RESET);
        !          49735:                        timeout(&reset_tim, RESET_TICKS, scsireset, 0);
        !          49736:                        reset_state = 1;
        !          49737:                        break;
        !          49738:                case 1:
        !          49739:                        sfbyte(ss_csr, 0);
        !          49740:                        timeout(&reset_tim, RESET_TICKS, scsireset, 0);
        !          49741:                        reset_state = 2;
        !          49742:                        break;
        !          49743:                case 2:
        !          49744:                        reset_state = 0;
        !          49745:                        break;
        !          49746:                }
        !          49747:        }
        !          49748: }
        !          49749: 
        !          49750: /*
        !          49751:  * ssdelay()
        !          49752:  *
        !          49753: d781 3
        !          49754: d793 1
        !          49755: a793 1
        !          49756:  * ss_start_timing()
        !          49757: a794 34
        !          49758:  * Start a timeout for some number of ticks.
        !          49759:  * Caller knows timer has expired when "ss_expired" goes to 1.
        !          49760:  *
        !          49761:  * Sample invocation:
        !          49762:  *     ss_start_timing(n);
        !          49763:  *     while (check for desired event fails) {
        !          49764:  *             if (ss_expired) {
        !          49765:  *                     ...failure stuff..
        !          49766:  *                     break;
        !          49767:  *             }
        !          49768:  *             ssdelay(m); <= needed to allow kernel to update timers
        !          49769:  *     }
        !          49770:  */
        !          49771: static void ss_start_timing(ticks)
        !          49772: int ticks;
        !          49773: {
        !          49774:        ss_expired = 0;
        !          49775:        timeout(&timeout_tim, ticks, ss_stop_timing, 1);
        !          49776: }
        !          49777: 
        !          49778: /*
        !          49779:  * ss_stop_timing()
        !          49780:  *
        !          49781:  * Stub function called only by ss_start_timing()
        !          49782:  */
        !          49783: static void ss_stop_timing(flagval)
        !          49784: int flagval;
        !          49785: {
        !          49786:        ss_expired = flagval;
        !          49787: }
        !          49788: 
        !          49789: /*
        !          49790:  * bus_pre_xfer()
        !          49791:  *
        !          49792: d1291 1
        !          49793: a1291 1
        !          49794:  * ss_done
        !          49795: a1292 25
        !          49796:  * Release current i/o buffer to the O/S.
        !          49797:  */
        !          49798: static void ss_done(s_id)
        !          49799: int s_id;
        !          49800: {
        !          49801:        ss_type * ssp = ss[s_id];
        !          49802:        BUF * bp = ssp->bp;
        !          49803:        int s;
        !          49804: 
        !          49805:        s = sphi();
        !          49806:        ssp->id_busy = 0;
        !          49807:        ssp->dr_watch = 0;
        !          49808:        ssp->in_buf = ssp->out_buf = NULL;
        !          49809:        if (bp) {
        !          49810:                bdone(bp);
        !          49811:                ssp->bp = NULL;
        !          49812:        }
        !          49813:        spl(s);
        !          49814: 
        !          49815:        ss_start();
        !          49816: }
        !          49817: 
        !          49818: /*
        !          49819:  * bus_dev_reset()
        !          49820:  *
        !          49821: a1358 2
        !          49822:  *
        !          49823:  * Call reconnect() after this if reselect has occurred.
        !          49824: d1380 1
        !          49825: a1380 1
        !          49826:  * reconnect()
        !          49827: a1381 135
        !          49828:  * Given SCSI ID of target device that is issuing reselect, do reconnect
        !          49829:  * SCSI bus stuff.
        !          49830:  */
        !          49831: static void reconnect(s_id)
        !          49832: int s_id;
        !          49833: {
        !          49834:        uchar dat;
        !          49835:        int cmd_ok = 0;
        !          49836:        ss_type * ssp = ss[s_id];
        !          49837:        BUF * bp = ssp->bp;
        !          49838: 
        !          49839:        dat = ffbyte(ss_dat);
        !          49840:        if ((dat & HOST_ID) && (dat & (1 << s_id)) && ssp) {
        !          49841:                sfbyte(ss_csr, WC_ENABLE_SCSI | WC_BUSY);
        !          49842:                if (bus_wait(RS_SELECT << 8 | 0)) {
        !          49843:                        sfbyte(ss_csr, WC_ENABLE_SCSI);
        !          49844:                        cmd_ok = bus_info_xfer(ssp);
        !          49845:                        if (bp) {
        !          49846:                                if (bp->b_req == BREAD)
        !          49847:                                        bp->b_resid -= ssp->data_bytes_in;
        !          49848:                                else
        !          49849:                                        bp->b_resid -= ssp->data_bytes_out;
        !          49850:                                if (cmd_ok && ssp->cmdstat == CS_GOOD) {
        !          49851:                                        if (ssp->msg_in == MSG_DISCONNECT) {
        !          49852:                                                ssp->dr_watch = WATCHDOG_SECONDS;
        !          49853:                                        } else
        !          49854:                                                ss_done(s_id);
        !          49855:                                } else {
        !          49856: printf("BF6 ");
        !          49857:                                        bp->b_flag |= BFERR;
        !          49858:                                        ss_done(s_id);
        !          49859:                                }
        !          49860:                        }
        !          49861:                }
        !          49862:        }
        !          49863: }
        !          49864: 
        !          49865: /*
        !          49866:  * ss_rw()
        !          49867:  *
        !          49868:  * Send read or write command to the host adapter.
        !          49869:  */
        !          49870: static int ss_rw(s_id)
        !          49871: int s_id;
        !          49872: {
        !          49873:        ss_type * ssp = ss[s_id];
        !          49874:        BUF * bp = ssp->bp;
        !          49875:        int rw_ok = 0;
        !          49876: uchar rwc;
        !          49877: 
        !          49878:        ssp->cmdstat = -1;
        !          49879:        if (bp->b_req == BREAD) {
        !          49880:                ssp->cmdbuf[0] = ScmdREADEXTENDED;
        !          49881:                ssp->in_buf_len = bp->b_count;
        !          49882:                ssp->in_buf = bp->b_faddr;
        !          49883:                ssp->out_buf_len = 0;
        !          49884:                ssp->out_buf = NULL;
        !          49885: rwc='R';
        !          49886:        } else {
        !          49887:                ssp->cmdbuf[0] = ScmdWRITEXTENDED;
        !          49888:                ssp->in_buf_len = 0;
        !          49889:                ssp->in_buf = NULL;
        !          49890:                ssp->out_buf_len = bp->b_count;
        !          49891:                ssp->out_buf = bp->b_faddr;
        !          49892: rwc='W';
        !          49893:        }
        !          49894:        ssp->data_bytes_in = 0;
        !          49895:        ssp->data_bytes_out = 0;
        !          49896:        ssp->cmdbuf[1] = 0;
        !          49897:        ssp->cmdbuf[2] = ssp->bno >> 24;
        !          49898:        ssp->cmdbuf[3] = ssp->bno >> 16;
        !          49899:        ssp->cmdbuf[4] = ssp->bno >>  8;
        !          49900:        ssp->cmdbuf[5] = ssp->bno;
        !          49901:        ssp->cmdbuf[6] = 0;
        !          49902:        ssp->cmdbuf[7] = bp->b_count / (BSIZE * 256L);
        !          49903:        ssp->cmdbuf[8] = bp->b_count / BSIZE;
        !          49904:        ssp->cmdbuf[9] = 0;
        !          49905:        ssp->cmdlen = G1CMDLEN;
        !          49906: 
        !          49907: { int s = sphi();
        !          49908:        rw_ok = bus_pre_xfer(s_id);
        !          49909:        if (rw_ok) {
        !          49910:                bus_info_xfer(ssp);
        !          49911: spl(s);
        !          49912:                rw_ok = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          49913:        }
        !          49914: else {{if(sserrct<=MAXSSERR)printf("F1");}spl(s);}
        !          49915: }
        !          49916: 
        !          49917:        if (ssp->cmdstat == CS_CHECK) {
        !          49918: {if(sserrct<=MAXSSERR)printf("ss_rw(): requesting sense\n");}
        !          49919:                if (req_sense(s_id)) {
        !          49920:                        rw_ok = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          49921: if(!rw_ok) {if(sserrct<=MAXSSERR)printf("F3");}
        !          49922:                }
        !          49923:        }
        !          49924: 
        !          49925:        if (rw_ok) {
        !          49926:                rw_ok =
        !          49927:                (ssp->cmdstat == CS_GOOD || ssp->msg_in == MSG_DISCONNECT);
        !          49928: if(!rw_ok) {if(sserrct<=MAXSSERR)printf("F4");}
        !          49929:        }
        !          49930: 
        !          49931:        return rw_ok;
        !          49932: 
        !          49933: }
        !          49934: 
        !          49935: /*
        !          49936:  * rezero()
        !          49937:  *
        !          49938:  * Send Rezero Unit command.
        !          49939:  *
        !          49940:  * Return 1 if no timeouts occurred, 0 if not.
        !          49941:  */
        !          49942: static int rezero(s_id)
        !          49943: int s_id;
        !          49944: {
        !          49945:        int retval;
        !          49946:        ss_type * ssp = ss[s_id];
        !          49947: 
        !          49948:        ssp->cmdstat = -1;
        !          49949:        ssp->data_bytes_in = 0;
        !          49950:        ssp->data_bytes_out = 0;
        !          49951:        ssp->cmdbuf[0] = ScmdREZERO;
        !          49952:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] =
        !          49953:                ssp->cmdbuf[5] = 0;
        !          49954:        ssp->cmdlen = G0CMDLEN;
        !          49955:        retval = scsicmd(s_id);
        !          49956: 
        !          49957:        return retval;
        !          49958: }
        !          49959: 
        !          49960: /*
        !          49961:  * ss_mach()
        !          49962:  *
        !          49963: d1404 2
        !          49964: a1405 1
        !          49965:                                if (ssp->expired)
        !          49966: d1407 1
        !          49967: a1407 1
        !          49968:                                else
        !          49969: d1412 1
        !          49970: a1412 1
        !          49971:                case SST_POLL_BEGIN_IO
        !          49972: d1420 2
        !          49973: a1421 2
        !          49974:                                if (!host_busy && BUS_FREE) {
        !          49975:                                        host_busy = 1;
        !          49976: d1423 1
        !          49977: a1423 5
        !          49978:                                        ssp->cmd_bytes_out = 0;
        !          49979:                                        ssp->data_bytes_in = 0;
        !          49980:                                        ssp->data_bytes_out = 0;
        !          49981:                                        if (bp)
        !          49982:                                                bp->b_resid = bp->b_count;
        !          49983: d1431 1
        !          49984: a1431 1
        !          49985:                                                set_timeout(DELAY_ARB);
        !          49986: d1433 6
        !          49987: a1438 2
        !          49988:                                } else  /* host_busy or bus not free */
        !          49989:                                        set_timeout(DELAY_BSY);
        !          49990: a1444 1
        !          49991:                                if reconnect handshake succeeds
        !          49992: d1450 2
        !          49993: a1451 1
        !          49994:                                if (ssp->expired)
        !          49995: d1453 1
        !          49996: a1453 1
        !          49997:                                else
        !          49998: d1487 1
        !          49999: a1487 1
        !          50000:                        set_timeout(DELAY_BDR);
        !          50001: d1493 1
        !          50002: a1493 1
        !          50003:                if(ssq_rd_head() != NULL && !ssp->busy) {
        !          50004: d1495 12
        !          50005: a1506 2
        !          50006:                        bp = ssq_rm_head();
        !          50007:                        form current block request - initialize try counts, etc.
        !          50008: d1520 1
        !          50009: a1520 1
        !          50010:                set_timeout(DELAY_RST);
        !          50011: d1534 1
        !          50012: a1534 1
        !          50013:                set_timeout(DELAY_RST);
        !          50014: d1618 217
        !          50015: @
        !          50016: 
        !          50017: 
        !          50018: 1.37
        !          50019: log
        !          50020: @Initial state machine hacks.
        !          50021: @
        !          50022: text
        !          50023: @d5 5
        !          50024: d12 3
        !          50025: d60 4
        !          50026: a63 23
        !          50027: #define DEBUG  1
        !          50028: #if DEBUG
        !          50029: int stats[100], statsptr;
        !          50030: #define PUSHI          { if(statsptr<100)stats[statsptr++] = i; }
        !          50031: #define POPI           { if(sserrct<=MAXSSERR)printf("%d:",statsptr);while(statsptr)\
        !          50032:                                if(sserrct<=MAXSSERR)printf("%d ",stats[--statsptr]);if(sserrct<=MAXSSERR)printf("\n");}
        !          50033: #define SSTELL(foo)    if(sserrct<=MAXSSERR)printf(foo)
        !          50034: #define SSTATUS                {uchar status = ffbyte(ss_csr);if(sserrct<=MAXSSERR)printf("status=%x\n", status);}
        !          50035: #define SSDUMP(ssp, text) {int i;\
        !          50036:        if(sserrct<=MAXSSERR)printf("%s: msg_in=%x cmdstat=%x\n", text, ssp->msg_in,\
        !          50037:        ssp->cmdstat);if(ssp->cmdlen)for(i=0;i<ssp->cmdlen;i++)\
        !          50038:        if(sserrct<=MAXSSERR)printf(" %x", ssp->cmdbuf[i]);if(sserrct<=MAXSSERR)printf(" cmd_bytes_out=%d",\
        !          50039:        ssp->cmd_bytes_out);\
        !          50040:        if(ssp->data_bytes_in)for(i=0;i<ssp->data_bytes_in;i++)\
        !          50041:        if(sserrct<=MAXSSERR)printf(" %x", ffbyte(ssp->in_buf+i));if(sserrct<=MAXSSERR)printf(" data_bytes_in=%d\n",\
        !          50042:        ssp->data_bytes_in);}
        !          50043: #else
        !          50044: #define PUSHI
        !          50045: #define POPI
        !          50046: #define SSTELL(foo)
        !          50047: #define SSTATUS
        !          50048: #define SSDUMP(ssp, text)
        !          50049: #endif
        !          50050: d68 12
        !          50051: d98 7
        !          50052: a104 1
        !          50053:        unsigned int    ptab_read:1;  /* 1 if partition table has been read */
        !          50054: a121 1
        !          50055: extern void    ss_mach();
        !          50056: d137 1
        !          50057: d140 1
        !          50058: d145 1
        !          50059: d149 1
        !          50060: d157 1
        !          50061: a157 1
        !          50062: static int     testready();
        !          50063: a208 1
        !          50064: static ss_type *ss_tbl;                /* points to block of "ss" structs */
        !          50065: d212 1
        !          50066: d214 3
        !          50067: a216 1
        !          50068: static TIM     sst_tim;        /* for timeout() call from ss_start() */
        !          50069: d218 2
        !          50070: a540 2
        !          50071:        bp->b_resid = bp->b_count;
        !          50072: 
        !          50073: d731 1
        !          50074: a731 1
        !          50075:  * testready()
        !          50076: a732 56
        !          50077:  * Send Test Unit Ready command.
        !          50078:  * Retry after bus reset if necessary.
        !          50079:  *
        !          50080:  * Return 1 if unit is ready, 0 if not.
        !          50081:  */
        !          50082: static int testready(s_id)
        !          50083: int s_id;
        !          50084: {
        !          50085:        int retval;
        !          50086:        ss_type * ssp = ss[s_id];
        !          50087: 
        !          50088:        ssp->cmdstat = -1;
        !          50089:        ssp->data_bytes_in = 0;
        !          50090:        ssp->data_bytes_out = 0;
        !          50091:        ssp->cmdbuf[0] = ScmdTESTREADY;
        !          50092:        ssp->cmdbuf[1] = ssp->cmdbuf[2] = ssp->cmdbuf[3] = ssp->cmdbuf[4] =
        !          50093:                ssp->cmdbuf[5] = 0;
        !          50094:        ssp->cmdlen = G0CMDLEN;
        !          50095:        retval = scsicmd(s_id);
        !          50096: 
        !          50097:        return retval;
        !          50098: }
        !          50099: 
        !          50100: /*
        !          50101:  * scsicmd()
        !          50102:  *
        !          50103:  * Send command packet to target device.
        !          50104:  * Start a new SCSI bus cycle when this routine is called.
        !          50105:  * If command status after sending is Device Check (CS_CHECK), do a
        !          50106:  * Request Sense to find out what happened and clear check status.
        !          50107:  *
        !          50108:  * Return 1 if command was send and status was good, else 0.
        !          50109:  */
        !          50110: static int scsicmd(s_id)
        !          50111: int s_id;
        !          50112: {
        !          50113:        int retval;
        !          50114:        ss_type *ssp = ss[s_id];
        !          50115: 
        !          50116:        if (retval = bus_pre_xfer(s_id)) {
        !          50117:                bus_info_xfer(ssp);
        !          50118:                retval = (ssp->cmdlen == ssp->cmd_bytes_out
        !          50119:                        && ssp->cmdstat == CS_GOOD);
        !          50120:        }
        !          50121: 
        !          50122:        if (ssp->cmdstat == CS_CHECK) {
        !          50123:                if (req_sense(s_id))
        !          50124:                        retval = (ssp->cmdlen == ssp->cmd_bytes_out);
        !          50125:        }
        !          50126: 
        !          50127:        return retval;
        !          50128: }
        !          50129: 
        !          50130: /*
        !          50131:  * scsireset()
        !          50132:  *
        !          50133: a982 1
        !          50134: SSDUMP(ssp, "Command overrun");
        !          50135: a1016 1
        !          50136: SSDUMP(ssp, "Data out overrun");
        !          50137: a1361 3
        !          50138:        if (!loading && st0x_busy)
        !          50139:                bdr_ok = 0;
        !          50140: 
        !          50141: a1404 1
        !          50142: printf("%d",bdr_ok);
        !          50143: d1573 229
        !          50144: @
        !          50145: 
        !          50146: 
        !          50147: 1.36
        !          50148: log
        !          50149: @Last version before using state machine logic.
        !          50150: @
        !          50151: text
        !          50152: @d7 3
        !          50153: d77 1
        !          50154: a97 1
        !          50155:        unsigned int    id_busy:1;  /* 1 if device with this SCSI id busy */
        !          50156: d100 6
        !          50157: d115 1
        !          50158: d176 14
        !          50159: a189 1
        !          50160: static int     loading;        /* 1 ssload() is executing */
        !          50161: a199 1
        !          50162: static int     st0x_busy;      /* 1 if SCSI host adapter busy */
        !          50163: d206 1
        !          50164: a206 1
        !          50165: static ss_type  *ss[MAX_SCSI_ID-1], rqs;
        !          50166: a217 1
        !          50167:        loading = 1;
        !          50168: d254 2
        !          50169: a281 1
        !          50170:        st0x_busy++;
        !          50171: a286 2
        !          50172:        st0x_busy--;
        !          50173:        loading = 0;
        !          50174: d407 1
        !          50175: d417 6
        !          50176: d424 2
        !          50177: a425 1
        !          50178:         * Decrement the number of watchdog timer requests open for host board.
        !          50179: d428 1
        !          50180: a471 3
        !          50181: #define NHEAD  4
        !          50182: #define NSEC   52
        !          50183: #define NCYL   1004
        !          50184: d493 3
        !          50185: a495 3
        !          50186:                *(short *)&hdparm.ncyl[0] = NCYL;
        !          50187:                hdparm.nhead = NHEAD;
        !          50188:                hdparm.nspt = NSEC;
        !          50189: d547 1
        !          50190: a547 1
        !          50191: {if(sserrct<=MAXSSERR)printf("BF1 ");}
        !          50192: d552 1
        !          50193: a552 1
        !          50194: {if(sserrct<=MAXSSERR)printf("BF2 ");}
        !          50195: d570 1
        !          50196: a570 1
        !          50197: {if(sserrct<=MAXSSERR)printf("BF3 ");}
        !          50198: d580 2
        !          50199: a581 6
        !          50200: 
        !          50201: /* if(sserrct<=MAXSSERR)printf("ssblock: drv=%x bno=%lx bp=%x flag=%x\n",
        !          50202:        drive, bp->b_bno, bp, bp->b_flag); */
        !          50203: 
        !          50204:                ssq_wr_tail(bp);
        !          50205:                ss_start();
        !          50206: d604 1
        !          50207: a604 2
        !          50208:                reconnect(s_id);
        !          50209: /*             defer(reconnect, s_id); */
        !          50210: d615 1
        !          50211: a615 1
        !          50212:        int s_id, rs_id;
        !          50213: d620 2
        !          50214: a621 18
        !          50215:                if (ssp && ssp->dr_watch) {
        !          50216:                        ssp->dr_watch--;
        !          50217:                        if (ssp->dr_watch == 0) {
        !          50218: {if(sserrct<=MAXSSERR)printf("BF4 ");}
        !          50219:                                bus_dev_reset(s_id);
        !          50220:                                ssp->bp->b_flag |= BFERR;
        !          50221: {if(sserrct<=MAXSSERR)printf("SCSI id #%d: bno=%lu <Watchdog Timeout>\n", s_id, ss[s_id]->bp->b_bno);}
        !          50222:                                ss_done(s_id);
        !          50223:                        } else {
        !          50224:                                while (1) {
        !          50225:                                        rs_id = chk_reconn();
        !          50226:                                        if (rs_id == -1)
        !          50227:                                                break;
        !          50228:                                        else
        !          50229:                                                reconnect(rs_id);
        !          50230:                                } /* endwhile */
        !          50231:                        }
        !          50232:                }
        !          50233: d653 1
        !          50234: a653 1
        !          50235:                {if(sserrct<=MAXSSERR)printf("TO:f=%x s=%x ", flags, status);}
        !          50236: d670 1
        !          50237: a670 1
        !          50238:        int retval = 0;
        !          50239: a674 33
        !          50240: /*FOO*/
        !          50241: bus_dev_reset(s_id);
        !          50242:        /*
        !          50243:         * Try Test Unit Ready command.
        !          50244:         * If it fails, reset SCSI bus and target device, and try again.
        !          50245:         */
        !          50246: printf("T");
        !          50247:        for (try = 0; !retval && try < LOPRI_RETRIES; try++) {
        !          50248:                if (testready(s_id))
        !          50249:                        retval = 1;
        !          50250:                else {
        !          50251: printf("X");
        !          50252:                        if (ssp->cmdstat == CS_BUSY)
        !          50253:                                ssdelay(50);
        !          50254:                        else if (ssp->cmdstat == CS_CHECK)
        !          50255:                                req_sense(s_id);
        !          50256:                        else if (s_id == chk_reconn())
        !          50257:                        {
        !          50258: printf("-r-");
        !          50259:                                ssdelay(50);
        !          50260:                        }
        !          50261:                        else
        !          50262:                                scsireset();
        !          50263:                }
        !          50264: #if 0
        !          50265:                scsireset();
        !          50266:                bus_dev_reset(s_id);
        !          50267: #endif
        !          50268:        } /* endfor */
        !          50269:        if (!retval)
        !          50270:                devmsg(dev, "Test Unit Ready Failed");
        !          50271: 
        !          50272: printf("R");
        !          50273: a675 6
        !          50274:                if (req_sense(s_id)) {
        !          50275:                        retval = 1;
        !          50276:                } else
        !          50277:                        devmsg(dev, "Request Sense Failed");
        !          50278: 
        !          50279:        if (retval)
        !          50280: a714 1
        !          50281: ssp->id_busy=0;
        !          50282: a798 1
        !          50283:                st0x_busy++;
        !          50284: a802 1
        !          50285:                st0x_busy--;
        !          50286: a805 1
        !          50287:                        st0x_busy++;
        !          50288: a815 1
        !          50289:                        st0x_busy--;
        !          50290: d1049 1
        !          50291: a1049 1
        !          50292:        {if(sserrct<=MAXSSERR)printf("W");}
        !          50293: d1077 1
        !          50294: a1077 1
        !          50295:        {if(sserrct<=MAXSSERR)printf("CSK",ssp->cmdstat);}
        !          50296: d1080 1
        !          50297: a1080 1
        !          50298:        {if(sserrct<=MAXSSERR)printf("CSY",ssp->cmdstat);}
        !          50299: d1084 1
        !          50300: a1084 1
        !          50301:        {if(sserrct<=MAXSSERR)printf("CS%x",ssp->cmdstat);}
        !          50302: d1120 1
        !          50303: a1120 1
        !          50304:                {if(sserrct<=MAXSSERR)printf("TX: s=%x ", status);}
        !          50305: a1350 1
        !          50306: /* if(sserrct<=MAXSSERR)printf("%d in  %d out\n",ssp->data_bytes_in,ssp->data_bytes_out); */
        !          50307: d1353 1
        !          50308: a1353 1
        !          50309: {if(sserrct<=MAXSSERR)printf("BF5 ");}
        !          50310: d1361 1
        !          50311: a1361 1
        !          50312: {if(sserrct<=MAXSSERR)printf("R%d ",retry[s_id]);}
        !          50313: d1406 1
        !          50314: a1406 1
        !          50315: {if(sserrct<=MAXSSERR)printf("bdr");}
        !          50316: d1454 1
        !          50317: a1454 1
        !          50318: {if(sserrct<=MAXSSERR)printf("%d",bdr_ok);}
        !          50319: d1520 1
        !          50320: a1520 1
        !          50321: {if(sserrct<=MAXSSERR)printf("BF6 ");}
        !          50322: a1576 11
        !          50323: if(!rw_ok) {
        !          50324:   uchar csr=ffbyte(ss_csr), dat=ffbyte(ss_dat);
        !          50325:   sserrct++; if (sserrct <=MAXSSERR) {
        !          50326:     {if(sserrct<=MAXSSERR)printf("F2 cmdlen=%d cmd_bytes_out=%d cmdstat=%d\n", ssp->cmdlen,
        !          50327:        ssp->cmd_bytes_out, ssp->cmdstat);}
        !          50328:     {if(sserrct<=MAXSSERR)printf("%c msg_in=%x inl=%d ", rwc, ssp->msg_in, ssp->in_buf_len);}
        !          50329:     {if(sserrct<=MAXSSERR)printf("inb=%d otl=%d otb=%d\n", ssp->data_bytes_in, ssp->out_buf_len,
        !          50330:     ssp->data_bytes_out);}
        !          50331:     {if(sserrct<=MAXSSERR)printf("csr=%x dat=%x bno=%ld ",csr,dat,bp->b_bno);}
        !          50332:   }
        !          50333: }
        !          50334: @
        !          50335: 0707070064030104121004440000030000030000011777770507310663600005600000022502/newbits/kernel/USRSRC/i8086/drv/RCS/ssas.s,vhead     1.7;
        !          50336: branch   ;
        !          50337: access   ;
        !          50338: symbols  ;
        !          50339: locks    ;
        !          50340: comment  @/ @;
        !          50341: 
        !          50342: 
        !          50343: 1.7
        !          50344: date     91.06.01.10.51.00;  author hal;  state Exp;
        !          50345: branches ;
        !          50346: next     1.6;
        !          50347: 
        !          50348: 1.6
        !          50349: date     91.06.01.10.32.51;  author hal;  state Exp;
        !          50350: branches ;
        !          50351: next     1.5;
        !          50352: 
        !          50353: 1.5
        !          50354: date     91.05.20.17.22.03;  author root;  state Exp;
        !          50355: branches ;
        !          50356: next     1.4;
        !          50357: 
        !          50358: 1.4
        !          50359: date     91.05.20.16.21.35;  author root;  state Exp;
        !          50360: branches ;
        !          50361: next     1.3;
        !          50362: 
        !          50363: 1.3
        !          50364: date     91.05.20.10.23.13;  author root;  state Exp;
        !          50365: branches ;
        !          50366: next     1.2;
        !          50367: 
        !          50368: 1.2
        !          50369: date     91.05.17.00.24.17;  author root;  state Exp;
        !          50370: branches ;
        !          50371: next     1.1;
        !          50372: 
        !          50373: 1.1
        !          50374: date     91.05.16.14.16.21;  author root;  state Exp;
        !          50375: branches ;
        !          50376: next     ;
        !          50377: 
        !          50378: 
        !          50379: desc
        !          50380: @Assembler I/O for Seagate SCSI.
        !          50381: @
        !          50382: 
        !          50383: 
        !          50384: 1.7
        !          50385: log
        !          50386: @Add ffcopy().
        !          50387: @
        !          50388: text
        !          50389: @////////
        !          50390: /
        !          50391: / I/O for Seagate ST01/ST02 SCSI Host Adapters.
        !          50392: /
        !          50393: / $Log:        ssas.s,v $
        !          50394: / Revision 1.6  91/06/01  10:32:51  hal
        !          50395: / Do handshaking both ways.  Now names are ss_getb()/ss_putb().
        !          50396: / 
        !          50397: / Revision 1.5 91/05/20  17:22:03      root
        !          50398: / Not using ss_put() any more.
        !          50399: / 
        !          50400: / Revision 1.4 91/05/20  16:21:35      root
        !          50401: / Call to ss_putc() now works.
        !          50402: / 
        !          50403: / Revision 1.3 91/05/20  10:23:13      root
        !          50404: / Drop 3rd arg.  Same code for Seagate & Future Domain.
        !          50405: / 
        !          50406: / Revision 1.2 91/05/17  00:24:17      root
        !          50407: / Code ss_put - use REQ handshake.
        !          50408: / 
        !          50409: / Revision 1.1 91/05/16  14:16:21      root
        !          50410: / Initial version - no code yet for ss_put().
        !          50411: / 
        !          50412: /
        !          50413: /      Since these functions are called from the midst of C code in
        !          50414: /      the "ss" driver, they need to preserve the following registers:
        !          50415: /              SI  DI  SP  BP    SS  DS  ES
        !          50416: /      Additionally, surrounding C code is expected to leave the "D"
        !          50417: /      CPU flag clear (string op's increment index registers).
        !          50418: /
        !          50419: ////////
        !          50420: 
        !          50421: ////////
        !          50422: /
        !          50423: /      Export functions.
        !          50424: /
        !          50425: ////////
        !          50426:        .globl  ss_getb_
        !          50427:        .globl  ss_putb_
        !          50428:        .globl  ffcopy_
        !          50429: 
        !          50430: ////////
        !          50431: /
        !          50432: / Constants
        !          50433: /
        !          50434: /      Relative to the RAM base address of the host adapter, offsets
        !          50435: /      for Control/Status Register (CSR) and Data Port (DAT) differ
        !          50436: /      between Seagate and Future Domain as follows:
        !          50437: /                      Seagate         Future Domain
        !          50438: /              SS_CSR  0x1A00          0x1C00
        !          50439: /              SS_DAT  0x1C00          0x1E00
        !          50440: /      The difference between these (CSR_OFF) is 0x200 in either case.
        !          50441: /
        !          50442: ////////
        !          50443: 
        !          50444:        BSIZE   = 0x200         / Disk block size in bytes
        !          50445:        CSR_OFF = 0x200
        !          50446: 
        !          50447:        REQ_LIM = 500
        !          50448:        RS_REQUEST = 0x10
        !          50449: 
        !          50450: ////////
        !          50451: /
        !          50452: / ss_getb(ss_dat_fp, buf_fp)
        !          50453: / faddr_t ss_dat_fp, buf_fp;
        !          50454: /
        !          50455: / Fetch input bytes from host adapter and store at buffer address.
        !          50456: /
        !          50457: / Do REQ handshaking and return the number of bytes remaining to transfer.
        !          50458: / (So return value of 0 means no error.)
        !          50459: /
        !          50460: / Here is the stack after initial "push bp":
        !          50461: /
        !          50462: /      10(bp)  FP_SEL(buf_fp)
        !          50463: /      8(bp)   FP_OFF(buf_fp)
        !          50464: /      6(bp)   FP_SEL(ss_dat_fp)
        !          50465: /      4(bp)   FP_OFF(ss_dat_fp)
        !          50466: /      2(bp)   return IP
        !          50467: /      0(bp)   old bp
        !          50468: /
        !          50469: ////////
        !          50470: 
        !          50471: ss_getb_:
        !          50472:        push    bp
        !          50473:        mov     bp, sp
        !          50474:        push    es
        !          50475:        push    di
        !          50476:        push    ds
        !          50477:        push    si
        !          50478: 
        !          50479:        lds     si, 4(bp)       / ss_dat_fp to DS:SI
        !          50480:        mov     bx, si          / .. and to DS:BX
        !          50481:        sub     bx, $CSR_OFF    / ss_csr to DS:BX
        !          50482:        les     di, 8(bp)       / buf_fp to ES:DI
        !          50483:        mov     cx, $BSIZE      / rep count to CX
        !          50484: 
        !          50485: G01:                           / start outer loop - reading bytes from SCSI
        !          50486:        mov     ax, $REQ_LIM    / max # of times to look for REQ
        !          50487: G02:                           / start inner loop - polling for REQ
        !          50488:        movb    dl, (bx)
        !          50489:        testb   dl, $RS_REQUEST
        !          50490:        jne     G03             / got REQ
        !          50491:        dec     ax
        !          50492:        jnz     G02             / no REQ - look again
        !          50493:        jmp     G04             / no REQ - give up
        !          50494: 
        !          50495: G03:                           / got REQ - ok to read a byte
        !          50496:        movsb
        !          50497:        loop    G01
        !          50498: G04:                           / all done
        !          50499:        mov     ax, cx          / normal exit returns 0
        !          50500: 
        !          50501:        pop     si
        !          50502:        pop     ds
        !          50503:        pop     di
        !          50504:        pop     es
        !          50505:        pop     bp
        !          50506:        ret
        !          50507: 
        !          50508: ////////
        !          50509: /
        !          50510: / int ss_putb(ss_dat_fp, buf_fp)
        !          50511: / faddr_t ss_dat_fp, buf_fp;
        !          50512: /
        !          50513: / Write output bytes to host adapter from buffer address.
        !          50514: /
        !          50515: / Return the number of bytes remaining to be sent (should be 0).
        !          50516: /
        !          50517: / Here is the stack after initial "push bp":
        !          50518: /
        !          50519: /      10(bp)  FP_SEL(buf_fp)
        !          50520: /      8(bp)   FP_OFF(buf_fp)
        !          50521: /      6(bp)   FP_SEL(ss_dat_fp)
        !          50522: /      4(bp)   FP_OFF(ss_dat_fp)
        !          50523: /      2(bp)   return IP
        !          50524: /      0(bp)   old bp
        !          50525: /
        !          50526: ////////
        !          50527: 
        !          50528: ss_putb_:
        !          50529:        push    bp
        !          50530:        mov     bp, sp
        !          50531:        push    es
        !          50532:        push    di
        !          50533:        push    ds
        !          50534:        push    si 
        !          50535:        lds     si, 8(bp)       / buf_fp to DS:SI
        !          50536:        les     di, 4(bp)       / ss_dat_fp  to ES:DI
        !          50537:        mov     bx, di          / .. and to ES:BX
        !          50538:        sub     bx, $CSR_OFF    / ss_csr to ES:BX
        !          50539:        mov     cx, $BSIZE      / count to CX
        !          50540: 
        !          50541: P01:                           / start outer loop - writing bytes to SCSI
        !          50542:        mov     ax, $REQ_LIM    / max # of times to look for REQ
        !          50543: P02:                           / start inner loop - polling for REQ
        !          50544:        movb    dl, es:(bx)
        !          50545:        testb   dl, $RS_REQUEST
        !          50546:        jne     P03             / got REQ
        !          50547:        dec     ax
        !          50548:        jnz     P02             / no REQ - look again
        !          50549:        jmp     P04             / no REQ - give up
        !          50550: 
        !          50551: P03:                           / got REQ - ok to write a byte
        !          50552:        movsb
        !          50553:        loop    P01
        !          50554: P04:                           / all done - now restore registers
        !          50555:        mov     ax, cx
        !          50556:        pop     si
        !          50557:        pop     ds
        !          50558:        pop     di
        !          50559:        pop     es
        !          50560:        pop     bp
        !          50561:        ret
        !          50562: 
        !          50563: ////////
        !          50564: /
        !          50565: / void ffcopy(from_fp, to_fp, count)
        !          50566: / faddr_t from_fp, to_fp;
        !          50567: / int count;
        !          50568: /
        !          50569: / Copy count bytes from from_fp to to_fp.
        !          50570: /
        !          50571: / Here is the stack after initial "push bp":
        !          50572: /
        !          50573: /      12(bp)  count
        !          50574: /      10(bp)  FP_SEL(to_fp)
        !          50575: /      8(bp)   FP_OFF(to_fp)
        !          50576: /      6(bp)   FP_SEL(from_fp)
        !          50577: /      4(bp)   FP_OFF(from_fp)
        !          50578: /      2(bp)   return IP
        !          50579: /      0(bp)   old bp
        !          50580: /
        !          50581: ////////
        !          50582: 
        !          50583: ffcopy_:
        !          50584:        push    bp
        !          50585:        mov     bp, sp
        !          50586:        push    es
        !          50587:        push    di
        !          50588:        push    ds
        !          50589:        push    si
        !          50590: 
        !          50591:        lds     si, 4(bp)       / from_fp  to DS:SI
        !          50592:        les     di, 8(bp)       / to_fp to ES:DI
        !          50593:        mov     cx, 12(bp)      / rep count to CX
        !          50594:        rep
        !          50595:        movsb
        !          50596: 
        !          50597:        pop     si
        !          50598:        pop     ds
        !          50599:        pop     di
        !          50600:        pop     es
        !          50601:        pop     bp
        !          50602:        ret
        !          50603: @
        !          50604: 
        !          50605: 
        !          50606: 1.6
        !          50607: log
        !          50608: @Do handshaking both ways.  Now names are ss_getb()/ss_putb().
        !          50609: @
        !          50610: text
        !          50611: @d5 4
        !          50612: a8 1
        !          50613: / $Log:        /usr/src/sys/i8086/drv/RCS/ssas.s,v $
        !          50614: d40 1
        !          50615: d174 41
        !          50616: @
        !          50617: 
        !          50618: 
        !          50619: 1.5
        !          50620: log
        !          50621: @Not using ss_put() any more.
        !          50622: @
        !          50623: text
        !          50624: @d6 3
        !          50625: d35 2
        !          50626: a36 2
        !          50627:        .globl  ss_get_
        !          50628: /      .globl  ss_put_
        !          50629: d60 1
        !          50630: a60 1
        !          50631: / ss_get(ss_dat_fp, buf_fp)
        !          50632: a63 2
        !          50633: / (Also used conversely - this routine should be called "ff_bcopy()"
        !          50634: / for "far-to-far block copy".)
        !          50635: d65 3
        !          50636: d79 1
        !          50637: a79 1
        !          50638: ss_get_:
        !          50639: d87 3
        !          50640: a89 1
        !          50641:        lds     si, 4(bp)       / ss_dat_fp  to DS:SI
        !          50642: d92 12
        !          50643: a103 1
        !          50644:        rep
        !          50645: d105 3
        !          50646: a115 2
        !          50647: / THE FOLLOWING ROUTINE APPEARS TO BE UNNECESSARY, SO IS COMMENTED OUT.
        !          50648: 
        !          50649: d118 1
        !          50650: a118 1
        !          50651: / int ss_put(ss_dat_fp, buf_fp)
        !          50652: d136 34
        !          50653: a169 34
        !          50654: /ss_put_:
        !          50655: /      push    bp
        !          50656: /      mov     bp, sp
        !          50657: /      push    es
        !          50658: /      push    di
        !          50659: /      push    ds
        !          50660: /      push    si 
        !          50661: /      lds     si, 8(bp)       / buf_fp to DS:SI
        !          50662: /      les     di, 4(bp)       / ss_dat_fp  to ES:DI
        !          50663: /      mov     bx, di          / .. and to ES:BX
        !          50664: /      sub     bx, $CSR_OFF    / ss_csr to ES:BX
        !          50665: /      mov     cx, $BSIZE      / count to CX
        !          50666: /
        !          50667: /P01:                          / start outer loop - writing bytes to SCSI
        !          50668: /      mov     ax, $REQ_LIM    / max # of times to look for REQ
        !          50669: /P02:                          / start inner loop - polling for REQ
        !          50670: /      movb    dl, es:(bx)
        !          50671: /      testb   dl, $RS_REQUEST
        !          50672: /      jne     P03
        !          50673: /      dec     ax
        !          50674: /      jnz     P02
        !          50675: /      jmp     P04
        !          50676: /
        !          50677: /P03:                          / got REQ - ok to write a byte
        !          50678: /      movsb
        !          50679: /      loop    P01
        !          50680: /P04:                          / all done - now restore registers
        !          50681: /      mov     ax, cx
        !          50682: /      pop     si
        !          50683: /      pop     ds
        !          50684: /      pop     di
        !          50685: /      pop     es
        !          50686: /      pop     bp
        !          50687: /      ret
        !          50688: @
        !          50689: 
        !          50690: 
        !          50691: 1.4
        !          50692: log
        !          50693: @Call to ss_putc() now works.
        !          50694: @
        !          50695: text
        !          50696: @d6 3
        !          50697: d33 1
        !          50698: a33 2
        !          50699:        .globl  ss_put_
        !          50700:        .globl  req_waitA_      / temporary!
        !          50701: d61 2
        !          50702: d96 2
        !          50703: d118 12
        !          50704: a129 36
        !          50705: ss_put_:
        !          50706:        push    bp
        !          50707:        mov     bp, sp
        !          50708:        push    es
        !          50709:        push    di
        !          50710:        push    ds
        !          50711:        push    si 
        !          50712:        lds     si, 8(bp)       / buf_fp to DS:SI
        !          50713:        les     di, 4(bp)       / ss_dat_fp  to ES:DI
        !          50714:        mov     bx, di          / .. and to ES:BX
        !          50715:        sub     bx, $CSR_OFF    / ss_csr to ES:BX
        !          50716:        mov     cx, $BSIZE      / count to CX
        !          50717: 
        !          50718: P01:                           / start outer loop - writing bytes to SCSI
        !          50719:        mov     ax, $REQ_LIM    / max # of times to look for REQ
        !          50720: P02:                           / start inner loop - polling for REQ
        !          50721:        movb    dl, es:(bx)
        !          50722:        testb   dl, $RS_REQUEST
        !          50723:        jne     P03
        !          50724:        dec     ax
        !          50725:        jnz     P02
        !          50726:        jmp     P04
        !          50727: 
        !          50728: P03:                           / got REQ - ok to write a byte
        !          50729:        movsb
        !          50730:        loop    P01
        !          50731: P04:                           / all done - now restore registers
        !          50732:        mov     ax, cx
        !          50733:        pop     si
        !          50734:        pop     ds
        !          50735:        pop     di
        !          50736:        pop     es
        !          50737:        pop     bp
        !          50738:        ret
        !          50739: 
        !          50740: ////////
        !          50741: d131 9
        !          50742: a139 2
        !          50743: / int req_waitA(ss_dat_fp, buf_fp)
        !          50744: / faddr_t ss_dat_fp, buf_fp;
        !          50745: d141 11
        !          50746: a151 49
        !          50747: / Return when REQ is true or timeout.
        !          50748: /
        !          50749: / Return 1 if REQ received, 0 if timeout.
        !          50750: /
        !          50751: / Here is the stack after initial "push bp":
        !          50752: /
        !          50753: /      10(bp)  FP_SEL(buf_fp)
        !          50754: /      8(bp)   FP_OFF(buf_fp)
        !          50755: /      6(bp)   FP_SEL(ss_dat_fp)
        !          50756: /      4(bp)   FP_OFF(ss_dat_fp)
        !          50757: /      2(bp)   return IP
        !          50758: /      0(bp)   old bp
        !          50759: /
        !          50760: ////////
        !          50761: 
        !          50762: req_waitA_:
        !          50763:        push    bp
        !          50764:        mov     bp, sp
        !          50765:        push    es
        !          50766:        push    di
        !          50767:        push    ds
        !          50768:        push    si 
        !          50769:        lds     si, 8(bp)       / buf_fp to DS:SI
        !          50770:        les     di, 4(bp)       / ss_dat_fp  to ES:DI
        !          50771:        mov     bx, di          / .. and to ES:BX
        !          50772:        sub     bx, $CSR_OFF    / ss_csr to ES:BX
        !          50773:        mov     cx, $BSIZE      / count to CX
        !          50774: 
        !          50775: Q01:                           / start outer loop - writing bytes to SCSI
        !          50776:        mov     ax, $REQ_LIM    / max # of times to look for REQ
        !          50777: Q02:                           / start inner loop - polling for REQ
        !          50778:        movb    dl, es:(bx)
        !          50779:        testb   dl, $RS_REQUEST
        !          50780:        jne     Q03
        !          50781:        dec     ax
        !          50782:        jnz     Q02
        !          50783:        xor     ax, ax          / timeout - return 0
        !          50784:        jmp     Q04
        !          50785: 
        !          50786: Q03:                           / got REQ
        !          50787:        mov     ax, $1          / return 1
        !          50788: Q04:                           / all done - now restore registers
        !          50789:        movb    dh, $0xEE
        !          50790:        pop     si
        !          50791:        pop     ds
        !          50792:        pop     di
        !          50793:        pop     es
        !          50794:        pop     bp
        !          50795:        ret
        !          50796: @
        !          50797: 
        !          50798: 
        !          50799: 1.3
        !          50800: log
        !          50801: @Drop 3rd arg.  Same code for Seagate & Future Domain.
        !          50802: @
        !          50803: text
        !          50804: @d6 3
        !          50805: d31 1
        !          50806: d50 1
        !          50807: a50 1
        !          50808:        REQ_LIM = 200
        !          50809: d122 1
        !          50810: a122 1
        !          50811:        sub     bx, CSR_OFF     / ss_csr to ES:BX
        !          50812: d146 55
        !          50813: @
        !          50814: 
        !          50815: 
        !          50816: 1.2
        !          50817: log
        !          50818: @Code ss_put - use REQ handshake.
        !          50819: @
        !          50820: text
        !          50821: @d6 3
        !          50822: a31 2
        !          50823: /      Also defined in /usr/src/sys/i8086/sys/ss.h:
        !          50824: /              SS_CSR  SS_DAT  RS_REQUEST
        !          50825: d33 8
        !          50826: d43 2
        !          50827: a44 2
        !          50828:        SS_CSR  = 0x1A00
        !          50829:        SS_DAT  = 0x1C00
        !          50830: d51 2
        !          50831: a52 3
        !          50832: / ss_get(ss_fp, buf_fp, count)
        !          50833: / faddr_t ss_fp, buf_fp;
        !          50834: / int count;
        !          50835: a54 1
        !          50836: / Count must be <= SS_RAM_LEN (0x400).
        !          50837: a57 1
        !          50838: /      12(bp)  count
        !          50839: d60 2
        !          50840: a61 2
        !          50841: /      6(bp)   FP_SEL(ss_fp)
        !          50842: /      4(bp)   FP_OFF(ss_fp)
        !          50843: d75 1
        !          50844: a75 2
        !          50845:        lds     si, 4(bp)       / ss_fp  to DS:SI
        !          50846:        add     si, $SS_DAT     / ss_dat to DS:SI
        !          50847: d77 1
        !          50848: a77 1
        !          50849:        mov     cx, 12(bp)      / count to CX
        !          50850: d90 2
        !          50851: a91 3
        !          50852: / int ss_put(ss_fp, buf_fp, count)
        !          50853: / faddr_t ss_fp, buf_fp;
        !          50854: / int count;
        !          50855: a93 1
        !          50856: / Count must be <= SS_RAM_LEN (0x400).
        !          50857: d95 1
        !          50858: a95 1
        !          50859: / Return 0 if timeout occurred, otherwise nonzero.
        !          50860: a98 1
        !          50861: /      12(bp)  count
        !          50862: d101 2
        !          50863: a102 2
        !          50864: /      6(bp)   FP_SEL(ss_fp)
        !          50865: /      4(bp)   FP_OFF(ss_fp)
        !          50866: d116 1
        !          50867: a116 1
        !          50868:        les     di, 4(bp)       / ss_fp  to ES:DI
        !          50869: d118 2
        !          50870: a119 3
        !          50871:        add     di, $SS_DAT     / ss_dat to ES:DI
        !          50872:        add     bx, $SS_CSR     / ss_csr to ES:BX
        !          50873:        mov     cx, 12(bp)      / count to CX
        !          50874: d121 1
        !          50875: a121 1
        !          50876: P01:                           / start of 2 loops
        !          50877: d123 4
        !          50878: a126 2
        !          50879:        testb   es:(bx), $RS_REQUEST
        !          50880:        jne     P02
        !          50881: d128 2
        !          50882: a129 2
        !          50883:        jnz     P01
        !          50884:        jmp     P03
        !          50885: d131 1
        !          50886: a131 1
        !          50887: P02:                           / got REQ - ok to write a byte
        !          50888: d134 2
        !          50889: a135 1
        !          50890: P03:                           / all done - now restore registers
        !          50891: @
        !          50892: 
        !          50893: 
        !          50894: 1.1
        !          50895: log
        !          50896: @Initial version - no code yet for ss_put().
        !          50897: @
        !          50898: text
        !          50899: @d5 4
        !          50900: a8 1
        !          50901: / $Log$
        !          50902: d24 1
        !          50903: a24 1
        !          50904: /      .globl  ss_put_
        !          50905: d29 2
        !          50906: a30 1
        !          50907: /      These are also defined in /usr/src/sys/i8086/sys/ss.h
        !          50908: d37 3
        !          50909: d82 56
        !          50910: @
        !          50911: 0707070064030104111004440000030000030000011777770507310664000006100000010712/newbits/kernel/USRSRC/i8086/drv/RCS/ssqueue.c,vhead     1.5;
        !          50912: access   ;
        !          50913: symbols  ;
        !          50914: locks    ;
        !          50915: comment  @ * @;
        !          50916: 
        !          50917: 
        !          50918: 1.5
        !          50919: date     91.04.17.03.49.56;  author root;  state Exp;
        !          50920: branches ;
        !          50921: next   1.4;
        !          50922: 
        !          50923: 1.4
        !          50924: date     91.04.16.01.47.29;  author root;  state Exp;
        !          50925: branches ;
        !          50926: next   1.3;
        !          50927: 
        !          50928: 1.3
        !          50929: date     91.03.25.19.05.25;  author root;  state Exp;
        !          50930: branches 1.3.1.1;
        !          50931: next   1.2;
        !          50932: 
        !          50933: 1.2
        !          50934: date     91.03.25.13.04.04;  author root;  state Exp;
        !          50935: branches ;
        !          50936: next   1.1;
        !          50937: 
        !          50938: 1.1
        !          50939: date     91.03.22.17.39.06;  author root;  state Exp;
        !          50940: branches ;
        !          50941: next   ;
        !          50942: 
        !          50943: 1.3.1.1
        !          50944: date     91.04.11.15.59.53;  author root;  state Exp;
        !          50945: branches ;
        !          50946: next   ;
        !          50947: 
        !          50948: 
        !          50949: desc
        !          50950: @Queueing routines for HD device driver.
        !          50951: @
        !          50952: 
        !          50953: 
        !          50954: 1.5
        !          50955: log
        !          50956: @Turn off debug printing.
        !          50957: @
        !          50958: text
        !          50959: @/*
        !          50960:  * File:       ssqueue.c
        !          50961:  *
        !          50962:  * Purpose:
        !          50963:  *     Queueing routines for Seagate SCSI driver.
        !          50964:  *     Should be generalizable for other hard drives.
        !          50965:  *
        !          50966:  * $Log:       /usr/src/sys/i8086/drv/RCS/ssqueue.c,v $
        !          50967:  * Revision 1.4        91/04/16  01:47:29      root
        !          50968:  * Use BUF rather than scsi_work_t as queue element type.
        !          50969:  * 
        !          50970:  * Revision 1.3.1.1    91/04/11  15:59:53      root
        !          50971:  * debug printing added
        !          50972:  * 
        !          50973:  * Revision 1.3        91/03/25  19:05:25      root
        !          50974:  * run at high priority
        !          50975:  * 
        !          50976:  * Revision 1.2        91/03/25  13:04:04      root
        !          50977:  * Minor code fixes.  Now passes unit test.
        !          50978:  * 
        !          50979:  * Revision 1.1        91/03/22  17:39:06      root
        !          50980:  * Initial code - not tested yet
        !          50981:  * 
        !          50982:  */
        !          50983: 
        !          50984: /*
        !          50985:  * Includes.
        !          50986:  */
        !          50987: #include <coherent.h>
        !          50988: #include <sys/buf.h>
        !          50989: 
        !          50990: /*
        !          50991:  * Definitions.
        !          50992:  *     Constants.
        !          50993:  *     Macros with argument lists.
        !          50994:  *     Typedefs.
        !          50995:  *     Enums.
        !          50996:  */
        !          50997: 
        !          50998: /*
        !          50999:  * Global Data.
        !          51000:  *     Import Variables.
        !          51001:  *     Export Variables.
        !          51002:  *     Local Variables.
        !          51003:  */
        !          51004: static BUF     * ssq_head;     /* point to first node */
        !          51005: static BUF     * ssq_tail;     /* point to last node */
        !          51006: static int             ssq_count;      /* number of nodes in the queue */
        !          51007: 
        !          51008: /*
        !          51009:  * Functions.
        !          51010:  *     Import Functions.
        !          51011:  *     Export Functions.
        !          51012:  *     Local Functions.
        !          51013:  */
        !          51014: void ssq_wr_tail();
        !          51015: BUF * ssq_rd_head();
        !          51016: BUF * ssq_rm_head();
        !          51017: 
        !          51018: /*
        !          51019:  * Debug macros.
        !          51020:  */
        !          51021: #if 0
        !          51022: #define QSIZE  printf("Q%d:", ssq_count)
        !          51023: #else
        !          51024: #define QSIZE
        !          51025: #endif
        !          51026: 
        !          51027: /*
        !          51028:  * ssq_wr_tail()
        !          51029:  *
        !          51030:  * Append a BUF object to the doubly-linked queue.
        !          51031:  * Object to be inserted has been allocated by the caller.
        !          51032:  * Run at high priority.
        !          51033:  */
        !          51034: void ssq_wr_tail(bp)
        !          51035: BUF * bp;
        !          51036: {
        !          51037:        int s;
        !          51038: 
        !          51039:        s = sphi();
        !          51040:        if (ssq_count == 0) {
        !          51041:                ssq_head = ssq_tail = bp;
        !          51042:                bp->b_actf = bp->b_actl = NULL;
        !          51043:        } else {
        !          51044:                ssq_tail->b_actf = bp;
        !          51045:                bp->b_actf = NULL;
        !          51046:                bp->b_actl = ssq_tail;
        !          51047:                ssq_tail = bp;
        !          51048:        }
        !          51049:        ssq_count++;
        !          51050: QSIZE;
        !          51051:        spl(s);
        !          51052: }
        !          51053: 
        !          51054: /*
        !          51055:  * ssq_rd_head()
        !          51056:  *
        !          51057:  * Nondestructively fetch the head entry in the queue - i.e., this routine
        !          51058:  * does not remove an entry from the queue (see ss_rm_head() for that).
        !          51059:  * Return NULL if queue is empty, else return pointer to head item.
        !          51060:  */
        !          51061: BUF * ssq_rd_head()
        !          51062: {
        !          51063:        return ssq_head;
        !          51064: }
        !          51065: 
        !          51066: /*
        !          51067:  * ssq_rm_head()
        !          51068:  *
        !          51069:  * Delete head item from the queue.  Return a pointer to the node deleted,
        !          51070:  * or NULL if the queue was already empty.
        !          51071:  * Run at high priority.
        !          51072:  *
        !          51073:  * This routine does NOT deallocate the node.  That must be done by the
        !          51074:  * calling function after this routine runs.
        !          51075:  */
        !          51076: BUF * ssq_rm_head()
        !          51077: {
        !          51078:        BUF * ret;
        !          51079:        int s;
        !          51080: 
        !          51081:        s = sphi();
        !          51082:        if (ssq_count > 0) {
        !          51083:                ret = ssq_head;
        !          51084:                if (ssq_count == 1) {
        !          51085:                        ssq_head = ssq_tail = NULL;
        !          51086:                } else {
        !          51087:                        ssq_head = ssq_head->b_actf;
        !          51088:                        ssq_head->b_actl = NULL;
        !          51089:                }
        !          51090:                ssq_count--;
        !          51091: QSIZE;
        !          51092:        } else
        !          51093:                ret = NULL;
        !          51094:        spl(s);
        !          51095: 
        !          51096:        return ret;
        !          51097: }
        !          51098: @
        !          51099: 
        !          51100: 
        !          51101: 1.4
        !          51102: log
        !          51103: @Use BUF rather than scsi_work_t as queue element type.
        !          51104: @
        !          51105: text
        !          51106: @d9 3
        !          51107: d63 1
        !          51108: a63 1
        !          51109: #if 1
        !          51110: @
        !          51111: 
        !          51112: 
        !          51113: 1.3
        !          51114: log
        !          51115: @run at high priority
        !          51116: @
        !          51117: text
        !          51118: @d9 6
        !          51119: a27 1
        !          51120: #include <scsiwork.h>
        !          51121: d43 2
        !          51122: a44 2
        !          51123: static scsi_work_t     * ssq_head;     /* point to first node */
        !          51124: static scsi_work_t     * ssq_tail;     /* point to last node */
        !          51125: d54 2
        !          51126: a55 2
        !          51127: scsi_work_t * ssq_rd_head();
        !          51128: scsi_work_t * ssq_rm_head();
        !          51129: d58 9
        !          51130: d69 1
        !          51131: a69 1
        !          51132:  * Append a scsi_work_t object to the doubly-linked queue.
        !          51133: d73 2
        !          51134: a74 2
        !          51135: void ssq_wr_tail(sw)
        !          51136: scsi_work_t * sw;
        !          51137: d80 2
        !          51138: a81 2
        !          51139:                ssq_head = ssq_tail = sw;
        !          51140:                sw->sw_actf = sw->sw_actl = NULL;
        !          51141: d83 4
        !          51142: a86 4
        !          51143:                ssq_tail->sw_actf = sw;
        !          51144:                sw->sw_actf = NULL;
        !          51145:                sw->sw_actl = ssq_tail;
        !          51146:                ssq_tail = sw;
        !          51147: d89 1
        !          51148: d100 1
        !          51149: a100 1
        !          51150: scsi_work_t * ssq_rd_head()
        !          51151: d115 1
        !          51152: a115 1
        !          51153: scsi_work_t * ssq_rm_head()
        !          51154: d117 1
        !          51155: a117 1
        !          51156:        scsi_work_t * ret;
        !          51157: d126 2
        !          51158: a127 2
        !          51159:                        ssq_head = ssq_head->sw_actf;
        !          51160:                        ssq_head->sw_actl = NULL;
        !          51161: d130 1
        !          51162: @
        !          51163: 
        !          51164: 
        !          51165: 1.3.1.1
        !          51166: log
        !          51167: @debug printing added
        !          51168: @
        !          51169: text
        !          51170: @a8 3
        !          51171:  * Revision 1.3        91/03/25  19:05:25      root
        !          51172:  * run at high priority
        !          51173:  * 
        !          51174: a52 9
        !          51175:  * Debug macros.
        !          51176:  */
        !          51177: #if 1
        !          51178: #define QSIZE  printf("Q%d:", ssq_count)
        !          51179: #else
        !          51180: #define QSIZE
        !          51181: #endif
        !          51182: 
        !          51183: /*
        !          51184: a74 1
        !          51185: QSIZE;
        !          51186: a114 1
        !          51187: QSIZE;
        !          51188: @
        !          51189: 
        !          51190: 
        !          51191: 1.2
        !          51192: log
        !          51193: @Minor code fixes.  Now passes unit test.
        !          51194: @
        !          51195: text
        !          51196: @d9 3
        !          51197: d57 1
        !          51198: d62 3
        !          51199: d75 1
        !          51200: d95 1
        !          51201: d103 1
        !          51202: d105 1
        !          51203: d117 1
        !          51204: @
        !          51205: 
        !          51206: 
        !          51207: 1.1
        !          51208: log
        !          51209: @Initial code - not tested yet
        !          51210: @
        !          51211: text
        !          51212: @d8 4
        !          51213: a11 1
        !          51214:  * $Log$
        !          51215: d18 1
        !          51216: d101 1
        !          51217: a101 1
        !          51218:                        ssq_head->sw_actl = NULL
        !          51219: @
        !          51220: 0707070064030104101005550000030000030000011777770507310664100006000000010616/newbits/kernel/USRSRC/i8086/drv/RCS/310.diff,vhead     1.1;
        !          51221: access   ;
        !          51222: symbols  ;
        !          51223: locks    bin:1.1;
        !          51224: comment  @ * @;
        !          51225: 
        !          51226: 
        !          51227: 1.1
        !          51228: date     91.06.10.14.42.07;  author bin;  state Exp;
        !          51229: branches ;
        !          51230: next   ;
        !          51231: 
        !          51232: 
        !          51233: desc
        !          51234: @initial version prov by hal
        !          51235: @
        !          51236: 
        !          51237: 
        !          51238: 
        !          51239: 1.1
        !          51240: log
        !          51241: @Initial revision
        !          51242: @
        !          51243: text
        !          51244: @*** alx310.c  Sat Feb  2 16:44:45 1991
        !          51245: --- alx.c      Sat Feb 16 01:27:53 1991
        !          51246: ***************
        !          51247: *** 25,34 ****
        !          51248: --- 25,42 ----
        !          51249:   
        !          51250:   #define DTRTMOUT  3  /* DTR timeout interval in seconds for close */
        !          51251:   #define      IENABLE (IE_RxI+IE_TxI+IE_LSI)
        !          51252: + #define IE_ALL       (IE_RxI|IE_TxI|IE_LSI|IE_MSI)
        !          51253:   
        !          51254: + #define RTS_ON()     { outb(ALPORT+MCR, inb(ALPORT+MCR) | MC_RTS); }
        !          51255: + #define RTS_OFF()    { outb(ALPORT+MCR, inb(ALPORT+MCR) & ~MC_RTS); }
        !          51256: + 
        !          51257:   int  al_sg_set = 0;
        !          51258:   int  al_sg_clr = 0;
        !          51259:   static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          51260: + static int drlsd;    /* delta carrier detect - set by alxintr(), read
        !          51261: +                         by alxcycle() */
        !          51262: + static int rawin_ct; /* number of characters in input silo */                           
        !          51263: + static int want_rts;
        !          51264:   
        !          51265:   /*
        !          51266:    * functions herein
        !          51267: ***************
        !          51268: *** 135,141 ****
        !          51269:   
        !          51270:        b = ALPORT;
        !          51271:   
        !          51272: !      if ( inb(b+IER) & ~IENABLE ) { /* chip not found */
        !          51273:                u.u_error = ENXIO;
        !          51274:                return;
        !          51275:        }
        !          51276: --- 143,149 ----
        !          51277:   
        !          51278:        b = ALPORT;
        !          51279:   
        !          51280: !      if ( inb(b+IER) & ~IE_ALL ) { /* chip not found */
        !          51281:                u.u_error = ENXIO;
        !          51282:                return;
        !          51283:        }
        !          51284: ***************
        !          51285: *** 190,195 ****
        !          51286: --- 198,205 ----
        !          51287:                        *irqtty = tp_table[AL_NUM];
        !          51288:                        outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          51289:                }
        !          51290: +              RTS_ON();
        !          51291: +              want_rts = 0;
        !          51292:        
        !          51293:                outb(b+IER, IENABLE);        /* enable interrupts */
        !          51294:        
        !          51295: ***************
        !          51296: *** 316,322 ****
        !          51297:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          51298:                        state--;
        !          51299:        }
        !          51300: !      outb(b+MCR, 0);
        !          51301:        com_usage[AL_NUM] = COM_UNUSED;
        !          51302:        set_poll_rate();
        !          51303:        CDUMP("closed")
        !          51304: --- 326,335 ----
        !          51305:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          51306:                        state--;
        !          51307:        }
        !          51308: !      /*
        !          51309: !       * Turn off MC_OUT2 so IRQ can be used by other port.
        !          51310: !       */
        !          51311: !      outb(b+MCR, inb(b+MCR)&(~MC_OUT2));
        !          51312:        com_usage[AL_NUM] = COM_UNUSED;
        !          51313:        set_poll_rate();
        !          51314:        CDUMP("closed")
        !          51315: ***************
        !          51316: *** 343,350 ****
        !          51317: --- 356,365 ----
        !          51318:   {
        !          51319:        register int    s, b;
        !          51320:        int stat1, stat2;
        !          51321: +      char ier_save;
        !          51322:   
        !          51323:        s = sphi();
        !          51324: +      ier_save=inb(b+IER);    /* some chips need this */
        !          51325:        b = ALPORT;
        !          51326:        stat1 = inb(b+MCR);             /* get current MCR register status */
        !          51327:        stat2 = inb(b+LCR);             /* get current LCR register status */
        !          51328: ***************
        !          51329: *** 384,389 ****
        !          51330: --- 399,405 ----
        !          51331:        default:
        !          51332:                ttioctl(tp, com, vec);
        !          51333:        }
        !          51334: +      outb(b+IER, ier_save);
        !          51335:        spl(s);
        !          51336:   }
        !          51337:   
        !          51338: ***************
        !          51339: *** 466,472 ****
        !          51340:                /*
        !          51341:                 * Carrier changed.
        !          51342:                 */
        !          51343: !              if ( b & MS_DRLSD ) {
        !          51344:                        /*
        !          51345:                         * wakeup open
        !          51346:                         */
        !          51347: --- 482,489 ----
        !          51348:                /*
        !          51349:                 * Carrier changed.
        !          51350:                 */
        !          51351: !              if ((b & MS_DRLSD) || drlsd) {
        !          51352: !                      drlsd = 0;
        !          51353:                        /*
        !          51354:                         * wakeup open
        !          51355:                         */
        !          51356: ***************
        !          51357: *** 482,487 ****
        !          51358: --- 499,505 ----
        !          51359:                                 * clear carrier flag; send hangup signal
        !          51360:                                 */
        !          51361:                                tp->t_rawin.si_ox = tp->t_rawin.si_ix;
        !          51362: +                              rawin_ct = 0;
        !          51363:                                tthup( tp );
        !          51364:                        }
        !          51365:                }
        !          51366: ***************
        !          51367: *** 497,502 ****
        !          51368: --- 515,521 ----
        !          51369:                else
        !          51370:                        tp->t_rawin.si_ox++;
        !          51371:        }
        !          51372: +      rawin_ct = 0;
        !          51373:   
        !          51374:        /*
        !          51375:         * Calculate free output slot count.
        !          51376: ***************
        !          51377: *** 520,530 ****
        !          51378:         * (Re)start output, wake sleeping processes, etc.
        !          51379:         */
        !          51380:        ttstart( tp );
        !          51381:   
        !          51382:        /*
        !          51383:         * Schedule next cycle.
        !          51384:         */
        !          51385: !      timeout( &tp->t_rawtim, HZ/10, alxcycle, tp );
        !          51386:   }
        !          51387:   
        !          51388:   /*
        !          51389: --- 539,554 ----
        !          51390:         * (Re)start output, wake sleeping processes, etc.
        !          51391:         */
        !          51392:        ttstart( tp );
        !          51393: +      
        !          51394: +      if (want_rts) {
        !          51395: +              RTS_ON();
        !          51396: +              want_rts = 0;
        !          51397: +      }
        !          51398:   
        !          51399:        /*
        !          51400:         * Schedule next cycle.
        !          51401:         */
        !          51402: !      timeout( &tp->t_rawtim, HZ/20, alxcycle, tp );
        !          51403:   }
        !          51404:   
        !          51405:   /*
        !          51406: ***************
        !          51407: *** 619,624 ****
        !          51408: --- 643,659 ----
        !          51409:                tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          51410:                if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          51411:                        tp->t_rawin.si_ix = 0;
        !          51412: +                      
        !          51413: +              /*
        !          51414: +               * Preliminary code!
        !          51415: +               * De-assert RTS if we are close to filling the input silo.
        !          51416: +               */     
        !          51417: +              rawin_ct++;
        !          51418: +              if (!want_rts && rawin_ct > SI_BUFSIZ / 4) {
        !          51419: +                      RTS_OFF();
        !          51420: +                      want_rts = 1;
        !          51421: +              }
        !          51422: +              
        !          51423:                goto rescan;
        !          51424:   
        !          51425:        case Tx_INTR:
        !          51426: ***************
        !          51427: *** 650,655 ****
        !          51428: --- 685,707 ----
        !          51429:                        defer( alxcycle, tp );
        !          51430:                }
        !          51431:                goto rescan;
        !          51432: +              
        !          51433: +      case MS_INTR:
        !          51434: +              /*
        !          51435: +               * This is preliminary code - use delta of CTS from
        !          51436: +               * modem to implement flow control.
        !          51437: +               *
        !          51438: +               * Sense delta of RLSD for use by alxcycle().
        !          51439: +               */
        !          51440: +              b = inb(ALPORT+MSR);
        !          51441: +              if (b & MS_DCTS)
        !          51442: +                      if (b & MS_CTS)
        !          51443: +                              tp->t_flags &= ~T_STOP;
        !          51444: +                      else
        !          51445: +                              tp->t_flags |= T_STOP;
        !          51446: +              if (b & MS_DRLSD)
        !          51447: +                      drlsd = 1;              
        !          51448: +              goto rescan;
        !          51449:        }
        !          51450:   }
        !          51451:   
        !          51452: @
        !          51453: 0707070064030104071005550000030000030000011777770507310664200006000000006664/newbits/kernel/USRSRC/i8086/drv/RCS/311.diff,vhead     1.1;
        !          51454: access   ;
        !          51455: symbols  ;
        !          51456: locks    bin:1.1;
        !          51457: comment  @ * @;
        !          51458: 
        !          51459: 
        !          51460: 1.1
        !          51461: date     91.06.10.14.42.15;  author bin;  state Exp;
        !          51462: branches ;
        !          51463: next   ;
        !          51464: 
        !          51465: 
        !          51466: desc
        !          51467: @initial version prov by hal
        !          51468: @
        !          51469: 
        !          51470: 
        !          51471: 
        !          51472: 1.1
        !          51473: log
        !          51474: @Initial revision
        !          51475: @
        !          51476: text
        !          51477: @*** alx311.c  Sat Feb  2 16:45:12 1991
        !          51478: --- alx.c      Sat Feb 16 01:27:53 1991
        !          51479: ***************
        !          51480: *** 27,32 ****
        !          51481: --- 27,35 ----
        !          51482:   #define      IENABLE (IE_RxI+IE_TxI+IE_LSI)
        !          51483:   #define IE_ALL       (IE_RxI|IE_TxI|IE_LSI|IE_MSI)
        !          51484:   
        !          51485: + #define RTS_ON()     { outb(ALPORT+MCR, inb(ALPORT+MCR) | MC_RTS); }
        !          51486: + #define RTS_OFF()    { outb(ALPORT+MCR, inb(ALPORT+MCR) & ~MC_RTS); }
        !          51487: + 
        !          51488:   int  al_sg_set = 0;
        !          51489:   int  al_sg_clr = 0;
        !          51490:   static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          51491: ***************
        !          51492: *** 195,201 ****
        !          51493:                        *irqtty = tp_table[AL_NUM];
        !          51494:                        outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          51495:                }
        !          51496: !              want_rts = 1;
        !          51497:        
        !          51498:                outb(b+IER, IENABLE);        /* enable interrupts */
        !          51499:        
        !          51500: --- 198,205 ----
        !          51501:                        *irqtty = tp_table[AL_NUM];
        !          51502:                        outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          51503:                }
        !          51504: !              RTS_ON();
        !          51505: !              want_rts = 0;
        !          51506:        
        !          51507:                outb(b+IER, IENABLE);        /* enable interrupts */
        !          51508:        
        !          51509: ***************
        !          51510: *** 206,212 ****
        !          51511:                                        SVTTOUT);       /* wait for carrier */
        !          51512:                                if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          51513:                                        outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          51514: -                                      want_rts = 0;
        !          51515:                                        /*
        !          51516:                                         * make sure port is hungup
        !          51517:                                         * disable all ints except for TxI
        !          51518: --- 210,215 ----
        !          51519: ***************
        !          51520: *** 300,306 ****
        !          51521:                 * Hangup port
        !          51522:                 */
        !          51523:                outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          51524: -              want_rts = 0;
        !          51525:                /*
        !          51526:                 * Hold dtr low for timeout
        !          51527:                 */
        !          51528: --- 303,308 ----
        !          51529: ***************
        !          51530: *** 422,428 ****
        !          51531:                if (tp->t_flags & T_MODC) {  /* modem control? */
        !          51532:                        tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          51533:                        outb(b+MCR, inb(b+MCR) & MC_OUT2); /* hangup */
        !          51534: -                      want_rts = 0;
        !          51535:                }
        !          51536:        }
        !          51537:   
        !          51538: --- 424,429 ----
        !          51539: ***************
        !          51540: *** 515,522 ****
        !          51541:                        tp->t_rawin.si_ox++;
        !          51542:        }
        !          51543:        rawin_ct = 0;
        !          51544: -      if (want_rts)
        !          51545: -              outb(b+MCR, inb(b+MCR) | MC_RTS);
        !          51546:   
        !          51547:        /*
        !          51548:         * Calculate free output slot count.
        !          51549: --- 516,521 ----
        !          51550: ***************
        !          51551: *** 540,550 ****
        !          51552:         * (Re)start output, wake sleeping processes, etc.
        !          51553:         */
        !          51554:        ttstart( tp );
        !          51555:   
        !          51556:        /*
        !          51557:         * Schedule next cycle.
        !          51558:         */
        !          51559: !      timeout( &tp->t_rawtim, HZ/10, alxcycle, tp );
        !          51560:   }
        !          51561:   
        !          51562:   /*
        !          51563: --- 539,554 ----
        !          51564:         * (Re)start output, wake sleeping processes, etc.
        !          51565:         */
        !          51566:        ttstart( tp );
        !          51567: +      
        !          51568: +      if (want_rts) {
        !          51569: +              RTS_ON();
        !          51570: +              want_rts = 0;
        !          51571: +      }
        !          51572:   
        !          51573:        /*
        !          51574:         * Schedule next cycle.
        !          51575:         */
        !          51576: !      timeout( &tp->t_rawtim, HZ/20, alxcycle, tp );
        !          51577:   }
        !          51578:   
        !          51579:   /*
        !          51580: ***************
        !          51581: *** 639,652 ****
        !          51582:                tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          51583:                if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          51584:                        tp->t_rawin.si_ix = 0;
        !          51585: !                      rawin_ct++;
        !          51586:                /*
        !          51587:                 * Preliminary code!
        !          51588:                 * De-assert RTS if we are close to filling the input silo.
        !          51589:                 */     
        !          51590: !              if (want_rts && (sizeof(tp->t_rawin.si_buf) - rawin_ct < 4))
        !          51591: !                      outb(b+MCR, inb(b+MCR) & ~MC_RTS);
        !          51592: !                      goto rescan;
        !          51593:   
        !          51594:        case Tx_INTR:
        !          51595:                /*
        !          51596: --- 643,660 ----
        !          51597:                tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          51598:                if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          51599:                        tp->t_rawin.si_ix = 0;
        !          51600: !                      
        !          51601:                /*
        !          51602:                 * Preliminary code!
        !          51603:                 * De-assert RTS if we are close to filling the input silo.
        !          51604:                 */     
        !          51605: !              rawin_ct++;
        !          51606: !              if (!want_rts && rawin_ct > SI_BUFSIZ / 4) {
        !          51607: !                      RTS_OFF();
        !          51608: !                      want_rts = 1;
        !          51609: !              }
        !          51610: !              
        !          51611: !              goto rescan;
        !          51612:   
        !          51613:        case Tx_INTR:
        !          51614:                /*
        !          51615: ***************
        !          51616: *** 693,698 ****
        !          51617: --- 701,707 ----
        !          51618:                                tp->t_flags |= T_STOP;
        !          51619:                if (b & MS_DRLSD)
        !          51620:                        drlsd = 1;              
        !          51621: +              goto rescan;
        !          51622:        }
        !          51623:   }
        !          51624:   
        !          51625: @
        !          51626: 0707070064030104061004440000030000030000011777770507310664300005700000041621/newbits/kernel/USRSRC/i8086/drv/RCS/Mf.norm,vhead     1.1;
        !          51627: access   ;
        !          51628: symbols  ;
        !          51629: locks    bin:1.1;
        !          51630: comment  @ * @;
        !          51631: 
        !          51632: 
        !          51633: 1.1
        !          51634: date     91.06.10.14.42.19;  author bin;  state Exp;
        !          51635: branches ;
        !          51636: next   ;
        !          51637: 
        !          51638: 
        !          51639: desc
        !          51640: @initial version prov by hal
        !          51641: @
        !          51642: 
        !          51643: 
        !          51644: 
        !          51645: 1.1
        !          51646: log
        !          51647: @Initial revision
        !          51648: @
        !          51649: text
        !          51650: @# $Header: /usr/src/sys/i8086/drv/RCS/Makefile,v 2.2 89/01/06 15:42:27 src Exp $
        !          51651: #
        !          51652: # Makefile for ibm specific coherent sources and coherent images.
        !          51653: #
        !          51654: # Revision 2.1 88/09/03  13:02:03      src
        !          51655: # *** empty log message ***
        !          51656: # 
        !          51657: # Revision 1.1 88/03/24  16:50:12      src
        !          51658: # Initial revision
        !          51659: # 
        !          51660: 
        !          51661: AS=exec /bin/as
        !          51662: CC=exec /bin/cc
        !          51663: CPP=exec /lib/cpp
        !          51664: #CFLAGS=       -VCNEST -VSINU -I.. -I../sys -I../.. -I../../sys 
        !          51665: CFLAGS=-I.. -I../sys -I../.. -I../../sys \
        !          51666:        -I/usr/include/sys
        !          51667: AFLAGS=-gx
        !          51668: 
        !          51669: # Include directories
        !          51670: USRINC=/usr/include
        !          51671: SYSINC=/usr/include/sys
        !          51672: KERINC=/usr/src/sys/sys
        !          51673: DRVINC=/usr/src/sys/i8086/sys
        !          51674: USRSYS=/usr/sys
        !          51675: 
        !          51676: HERE=  objects/pccon.o \
        !          51677:        objects/console.o \
        !          51678:        objects/dmareq.o
        !          51679: 
        !          51680: # The following don't compile due to missing header files
        !          51681: #      objects/jr.o objects/jras.o
        !          51682: DRVOBJ=        objects/alx.o \
        !          51683:        objects/ms.o \
        !          51684:        objects/ati.o \
        !          51685:        objects/com1.o objects/com2.o \
        !          51686:        objects/eye.o objects/eyeas.o \
        !          51687:        objects/fdisk.o \
        !          51688:        objects/fl.o \
        !          51689:        objects/fontw.o \
        !          51690:        objects/gr.o objects/gras.o objects/gmas.o objects/hgas.o \
        !          51691:        objects/hs.o objects/clocked.o \
        !          51692:        objects/ipc.o objects/ipcas.o \
        !          51693:        objects/kb.o objects/mm.o \
        !          51694:        objects/lp.o \
        !          51695:        objects/me.o objects/meas.o \
        !          51696:        objects/mmas.o \
        !          51697:        objects/msg.o objects/msgcon.o objects/msgstub.o \
        !          51698:        objects/rm.o \
        !          51699:        objects/rp.o objects/rpas.o \
        !          51700:        objects/rs0.o objects/rs1.o objects/rsas.o \
        !          51701:        objects/sem.o objects/semcon.o objects/semstub.o \
        !          51702:        objects/shm.o objects/shmcon.o objects/shmstub.o \
        !          51703:         objects/sham.o \
        !          51704:        objects/sl.o \
        !          51705:        objects/st.o \
        !          51706:        objects/tn.o objects/tnas.o \
        !          51707:        objects/tty.o \
        !          51708: 
        !          51709: all: $(HERE) $(DRVOBJ)
        !          51710:        @@exec /bin/sync
        !          51711: 
        !          51712: shrink:
        !          51713:        exec /bin/rm -f objects/*
        !          51714: 
        !          51715: #      rm -f $(USRSYS)/lib/jr.a
        !          51716: #      ar rc $(USRSYS)/lib/jr.a objects/jr.o objects/jras.o
        !          51717: install: all
        !          51718:        rm -f $(USRSYS)/lib/eye.a
        !          51719:        ar rc $(USRSYS)/lib/eye.a objects/eye.o objects/eyeas.o
        !          51720:        rm -f $(USRSYS)/lib/ms.a
        !          51721:        ar rc $(USRSYS)/lib/ms.a objects/ms.o
        !          51722:        rm -f $(USRSYS)/lib/al.a
        !          51723:        ar rc $(USRSYS)/lib/al.a objects/com1.o objects/com2.o objects/alx.o \
        !          51724:                                objects/tty.o objects/clocked.o
        !          51725:        rm -f $(USRSYS)/lib/ati.a
        !          51726:        ar rc $(USRSYS)/lib/ati.a objects/mm.o objects/ati.o objects/kb.o \
        !          51727:                                objects/tty.o
        !          51728:        rm -f $(USRSYS)/lib/fl.a
        !          51729:        ar rc $(USRSYS)/lib/fl.a objects/fl.o
        !          51730:        rm -f $(USRSYS)/lib/gm.a
        !          51731:        ar rc $(USRSYS)/lib/gm.a objects/mm.o objects/gr.o objects/gmas.o \
        !          51732:                                objects/fontw.o objects/kb.o objects/tty.o
        !          51733:        ranlib $(USRSYS)/lib/gm.a
        !          51734:        rm -f $(USRSYS)/lib/gr.a
        !          51735:        ar rc $(USRSYS)/lib/gr.a objects/mm.o objects/gr.o objects/gras.o \
        !          51736:                                objects/fontw.o objects/kb.o objects/tty.o
        !          51737:        ranlib $(USRSYS)/lib/gr.a
        !          51738:        rm -f $(USRSYS)/lib/hs.a
        !          51739:        ar rc $(USRSYS)/lib/hs.a objects/hs.o objects/clocked.o
        !          51740:        rm -f $(USRSYS)/lib/lp.a
        !          51741:        ar rc $(USRSYS)/lib/lp.a objects/lp.o
        !          51742:        rm -f $(USRSYS)/lib/mm.a
        !          51743:        ar rc $(USRSYS)/lib/mm.a objects/mm.o objects/mmas.o objects/kb.o \
        !          51744:                                objects/tty.o
        !          51745:        rm -f $(USRSYS)/lib/me.a
        !          51746:        ar rc $(USRSYS)/lib/me.a objects/me.o objects/meas.o objects/fdisk.o
        !          51747:        rm -f $(USRSYS)/lib/msg.a
        !          51748:        ar rc $(USRSYS)/lib/msg.a objects/msgcon.o objects/msg.o \
        !          51749:                                objects/ipc.o objects/ipcas.o
        !          51750:        rm -f $(USRSYS)/lib/rm.a
        !          51751:        ar rc $(USRSYS)/lib/rm.a objects/rm.o
        !          51752:        rm -f $(USRSYS)/lib/rp.a
        !          51753:        ar rc $(USRSYS)/lib/rp.a objects/rp.o objects/rpas.o
        !          51754:        rm -f $(USRSYS)/lib/rs.a
        !          51755:        ar rc $(USRSYS)/lib/rs.a objects/rs0.o objects/rs1.o objects/rsas.o
        !          51756:        rm -f $(USRSYS)/lib/sem.a
        !          51757:        ar rc $(USRSYS)/lib/sem.a objects/semcon.o objects/sem.o \
        !          51758:                                objects/ipc.o objects/ipcas.o
        !          51759:        rm -f $(USRSYS)/lib/sham.a
        !          51760:        ar rc $(USRSYS)/lib/sham.a objects/shmcon.o objects/sham.o \
        !          51761:                                objects/ipc.o objects/ipcas.o
        !          51762:        rm -f $(USRSYS)/lib/shm.a
        !          51763:        ar rc $(USRSYS)/lib/shm.a objects/shmcon.o objects/shm.o \
        !          51764:                                objects/ipc.o objects/ipcas.o
        !          51765:        rm -f $(USRSYS)/lib/sl.a
        !          51766:        ar rc $(USRSYS)/lib/sl.a objects/sl.o objects/tty.o
        !          51767:        rm -f $(USRSYS)/lib/st.a
        !          51768:        ar rc $(USRSYS)/lib/st.a objects/st.o
        !          51769:        rm -f $(USRSYS)/lib/stubs.a
        !          51770:        ar rc $(USRSYS)/lib/stubs.a objects/*stub.o
        !          51771:        rm -f $(USRSYS)/lib/tn.a
        !          51772:        ar rc $(USRSYS)/lib/tn.a objects/tn.o objects/tnas.o
        !          51773: 
        !          51774: objects/alx.o:                         \
        !          51775:                $(KERINC)/clist.h       \
        !          51776:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51777:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51778:                                        $(SYSINC)/fun.h \
        !          51779:                $(SYSINC)/con.h         \
        !          51780:                $(USRINC)/errno.h       \
        !          51781:                $(DRVINC)/i8086.h       \
        !          51782:                $(DRVINC)/ins8250.h     \
        !          51783:                $(SYSINC)/sched.h       \
        !          51784:                $(SYSINC)/stat.h        \
        !          51785:                $(SYSINC)/timeout.h     \
        !          51786:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          51787:                $(SYSINC)/uproc.h       \
        !          51788:                alx.c
        !          51789:        $(CC) $(CFLAGS) -c -o $@@ alx.c
        !          51790: 
        !          51791: objects/ati.o: ati.s
        !          51792:        exec /lib/cpp -E -DATI_132=1 ati.s > ati.i
        !          51793:        exec /bin/as -gxo $@@ ati.i
        !          51794:        exec /bin/rm -f ati.i
        !          51795: 
        !          51796: objects/clocked.o: clocked.c
        !          51797:        $(CC) $(CFLAGS) -c -o $@@ clocked.c
        !          51798: 
        !          51799: objects/com1.o:                        \
        !          51800:                $(KERINC)/clist.h       \
        !          51801:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51802:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51803:                                        $(SYSINC)/fun.h \
        !          51804:                $(SYSINC)/con.h         \
        !          51805:                $(USRINC)/errno.h       \
        !          51806:                $(DRVINC)/i8086.h       \
        !          51807:                $(DRVINC)/ins8250.h     \
        !          51808:                $(SYSINC)/sched.h       \
        !          51809:                $(SYSINC)/stat.h        \
        !          51810:                $(SYSINC)/timeout.h     \
        !          51811:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          51812:                $(SYSINC)/uproc.h       \
        !          51813:                al.c
        !          51814:        $(CC) $(CFLAGS) -DALCOM1=1 -c -o $@@ al.c
        !          51815: 
        !          51816: objects/com2.o:                        \
        !          51817:                $(KERINC)/clist.h       \
        !          51818:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51819:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51820:                                        $(SYSINC)/fun.h \
        !          51821:                $(SYSINC)/con.h         \
        !          51822:                $(USRINC)/errno.h       \
        !          51823:                $(DRVINC)/i8086.h       \
        !          51824:                $(DRVINC)/ins8250.h     \
        !          51825:                $(SYSINC)/sched.h       \
        !          51826:                $(SYSINC)/stat.h        \
        !          51827:                $(SYSINC)/timeout.h     \
        !          51828:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          51829:                $(SYSINC)/uproc.h       \
        !          51830:                al.c
        !          51831:        $(CC) $(CFLAGS) -DALCOM2=1 -c -o $@@ al.c
        !          51832: 
        !          51833: objects/com3.o:                                \
        !          51834:                $(KERINC)/clist.h       \
        !          51835:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51836:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51837:                                        $(SYSINC)/fun.h \
        !          51838:                $(SYSINC)/con.h         \
        !          51839:                $(USRINC)/errno.h       \
        !          51840:                $(DRVINC)/i8086.h       \
        !          51841:                $(DRVINC)/ins8250.h     \
        !          51842:                $(SYSINC)/sched.h       \
        !          51843:                $(SYSINC)/stat.h        \
        !          51844:                $(SYSINC)/timeout.h     \
        !          51845:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          51846:                $(SYSINC)/uproc.h       \
        !          51847:                al.c
        !          51848:        $(CC) $(CFLAGS) -DALCOM3=1 -c -o $@@ al.c
        !          51849: 
        !          51850: objects/console.o:                     \
        !          51851:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51852:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51853:                                        $(SYSINC)/fun.h \
        !          51854:                $(SYSINC)/con.h         \
        !          51855:                $(SYSINC)/inode.h       \
        !          51856:                $(SYSINC)/io.h          \
        !          51857:                $(SYSINC)/stat.h        \
        !          51858:                console.c
        !          51859:        $(CC) $(CFLAGS) -c -o $@@ console.c
        !          51860: 
        !          51861: objects/dmareq.o:                      \
        !          51862:                $(SYSINC)/buf.h         \
        !          51863:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51864:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51865:                                        $(SYSINC)/fun.h \
        !          51866:                $(SYSINC)/con.h         \
        !          51867:                $(DRVINC)/dmac.h        \
        !          51868:                $(USRINC)/errno.h       \
        !          51869:                $(SYSINC)/io.h          \
        !          51870:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          51871:                $(SYSINC)/sched.h       \
        !          51872:                $(SYSINC)/seg.h         \
        !          51873:                $(SYSINC)/stat.h        \
        !          51874:                $(SYSINC)/uproc.h       \
        !          51875:                dmareq.c
        !          51876:        $(CC) $(CFLAGS) -c -o $@@ dmareq.c
        !          51877: 
        !          51878: objects/eye.o:                         \
        !          51879:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51880:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51881:                                        $(SYSINC)/fun.h \
        !          51882:                $(SYSINC)/con.h         \
        !          51883:                $(USRINC)/errno.h       \
        !          51884:                $(SYSINC)/eye.h         \
        !          51885:                $(SYSINC)/inode.h       \
        !          51886:                $(SYSINC)/io.h          \
        !          51887:                $(SYSINC)/stat.h        \
        !          51888:                $(SYSINC)/types.h       \
        !          51889:                $(SYSINC)/uproc.h       \
        !          51890:                eye.c
        !          51891:        $(CC) $(CFLAGS) -c -o $@@ eye.c
        !          51892: 
        !          51893: objects/eyeas.o: eyeas.s               \
        !          51894:                $(SYSINC)/eye.h
        !          51895:        exec /lib/cpp -E eyeas.s > eyeas.i
        !          51896:        exec /bin/as -gxo $@@ eyeas.i
        !          51897:        exec /bin/rm -f eyeas.i
        !          51898: 
        !          51899: objects/fdisk.o:                       \
        !          51900:                $(SYSINC)/buf.h         \
        !          51901:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51902:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51903:                                        $(SYSINC)/fun.h \
        !          51904:                $(SYSINC)/con.h         \
        !          51905:                $(USRINC)/errno.h       \
        !          51906:                $(SYSINC)/fdisk.h       \
        !          51907:                $(SYSINC)/inode.h       \
        !          51908:                $(SYSINC)/uproc.h       \
        !          51909:                fdisk.c
        !          51910:        $(CC) $(CFLAGS) -c -o $@@ fdisk.c
        !          51911: 
        !          51912: objects/fl.o:                          \
        !          51913:                $(SYSINC)/buf.h         \
        !          51914:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51915:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51916:                                        $(SYSINC)/fun.h \
        !          51917:                $(SYSINC)/con.h         \
        !          51918:                $(DRVINC)/dmac.h        \
        !          51919:                $(USRINC)/errno.h       \
        !          51920:                $(SYSINC)/fdioctl.h     \
        !          51921:                $(DRVINC)/i8086.h       \
        !          51922:                $(SYSINC)/sched.h       \
        !          51923:                $(SYSINC)/stat.h        \
        !          51924:                $(SYSINC)/timeout.h     \
        !          51925:                $(SYSINC)/uproc.h       \
        !          51926:                fl.c
        !          51927:        $(CC) $(CFLAGS) -c -o $@@ fl.c
        !          51928: 
        !          51929: objects/fontw.o: fontgen.c
        !          51930:        $(CC) -i fontgen.c
        !          51931:        exec ./l.out > $*.s
        !          51932:        exec /bin/rm l.out
        !          51933:        $(AS) -gxo $@@ $*.s
        !          51934: 
        !          51935: objects/gmas.o: gras.s
        !          51936:        exec /lib/cpp -E -DTECMAR gras.s > gmas.i
        !          51937:        exec /bin/as -gxo $@@ gmas.i
        !          51938:        exec /bin/rm -f gmas.i
        !          51939: 
        !          51940: objects/gr.o:                          \
        !          51941:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51942:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51943:                                        $(SYSINC)/fun.h \
        !          51944:                $(SYSINC)/con.h         \
        !          51945:                $(USRINC)/errno.h       \
        !          51946:                $(SYSINC)/sched.h       \
        !          51947:                $(SYSINC)/timeout.h     \
        !          51948:                $(SYSINC)/types.h       \
        !          51949:                $(SYSINC)/uproc.h       \
        !          51950:                gr.c
        !          51951:        $(CC) $(CFLAGS) -c -o $@@ gr.c
        !          51952: 
        !          51953: objects/gras.o: gras.s
        !          51954:        exec /lib/cpp -E gras.s > gras.i
        !          51955:        exec /bin/as -gxo $@@ gras.i
        !          51956:        exec /bin/rm -f gras.i
        !          51957: 
        !          51958: objects/hgas.o: gras.s
        !          51959:        exec /lib/cpp -E -DHERCULES gras.s > hgas.i
        !          51960:        exec /bin/as -gxo $@@ hgas.i
        !          51961:        exec /bin/rm -f hgas.i
        !          51962: 
        !          51963: objects/hd.o: hd.c
        !          51964:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          51965: 
        !          51966: objects/hs.o:                          \
        !          51967:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51968:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51969:                                        $(SYSINC)/fun.h \
        !          51970:                $(SYSINC)/con.h         \
        !          51971:                $(USRINC)/errno.h       \
        !          51972:                $(DRVINC)/ins8250.h     \
        !          51973:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          51974:                $(SYSINC)/stat.h        \
        !          51975:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          51976:                $(SYSINC)/uproc.h       \
        !          51977:                hs.c
        !          51978:        $(CC) $(CFLAGS) -c -o $@@ hs.c
        !          51979: 
        !          51980: objects/ipc.o:                         \
        !          51981:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51982:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51983:                                        $(SYSINC)/fun.h \
        !          51984:                $(SYSINC)/ipc.h         \
        !          51985:                $(SYSINC)/uproc.h       \
        !          51986:                ipc.c
        !          51987:        $(CC) $(CFLAGS) -c -o $@@ ipc.c
        !          51988: 
        !          51989: objects/ipcas.o: ipcas.s
        !          51990:        $(AS) -gxo $@@ $<
        !          51991: 
        !          51992: objects/jr.o:                          \
        !          51993:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          51994:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          51995:                                        $(SYSINC)/fun.h \
        !          51996:                $(SYSINC)/buf.h         \
        !          51997:                $(SYSINC)/con.h         \
        !          51998:                $(SYSINC)/stat.h        \
        !          51999:                $(SYSINC)/uproc.h       \
        !          52000:                $(USRINC)/errno.h       \
        !          52001:                jr.c
        !          52002:        $(CC) $(CFLAGS) -c -o $@@ jr.c
        !          52003: 
        !          52004: objects/jras.o: jras.s
        !          52005:        $(AS) -gxo $@@ $<
        !          52006: 
        !          52007: objects/kb.o:                          \
        !          52008:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52009:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52010:                                        $(SYSINC)/fun.h \
        !          52011:                $(SYSINC)/con.h         \
        !          52012:                $(USRINC)/errno.h       \
        !          52013:                $(DRVINC)/i8086.h       \
        !          52014:                $(SYSINC)/sched.h       \
        !          52015:                $(USRINC)/signal.h      \
        !          52016:                $(SYSINC)/stat.h        \
        !          52017:                $(SYSINC)/timeout.h     \
        !          52018:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          52019:                $(SYSINC)/uproc.h       \
        !          52020:                kb.c
        !          52021:        $(CC) $(CFLAGS) -c -o $@@ kb.c
        !          52022: 
        !          52023: objects/lp.o:                          \
        !          52024:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52025:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52026:                                        $(SYSINC)/fun.h \
        !          52027:                $(SYSINC)/con.h         \
        !          52028:                $(USRINC)/errno.h       \
        !          52029:                $(DRVINC)/i8086.h       \
        !          52030:                $(SYSINC)/io.h          \
        !          52031:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          52032:                $(SYSINC)/stat.h        \
        !          52033:                $(SYSINC)/timeout.h     \
        !          52034:                $(SYSINC)/uproc.h       \
        !          52035:                lp.c
        !          52036:        $(CC) $(CFLAGS) -c -o $@@ lp.c
        !          52037: 
        !          52038: objects/me.o:                          \
        !          52039:                $(SYSINC)/buf.h         \
        !          52040:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52041:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52042:                                        $(SYSINC)/fun.h \
        !          52043:                $(SYSINC)/con.h         \
        !          52044:                $(DRVINC)/dmac.h        \
        !          52045:                $(USRINC)/errno.h       \
        !          52046:                $(SYSINC)/inode.h       \
        !          52047:                $(DRVINC)/me.h          \
        !          52048:                $(SYSINC)/stat.h        \
        !          52049:                $(SYSINC)/types.h       \
        !          52050:                $(SYSINC)/uproc.h       \
        !          52051:                me.c
        !          52052:        $(CC) $(CFLAGS) -c -o $@@ me.c
        !          52053: 
        !          52054: objects/meas.o: meas.s
        !          52055:        $(AS) -gxo $@@ meas.s
        !          52056: 
        !          52057: objects/mm.o:                          \
        !          52058:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52059:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52060:                                        $(SYSINC)/fun.h \
        !          52061:                $(SYSINC)/sched.h       \
        !          52062:                $(USRINC)/errno.h       \
        !          52063:                $(SYSINC)/stat.h        \
        !          52064:                $(SYSINC)/io.h          \
        !          52065:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          52066:                $(SYSINC)/uproc.h       \
        !          52067:                $(SYSINC)/timeout.h     \
        !          52068:                mm.c
        !          52069:        $(CC) $(CFLAGS) -c -o $@@ mm.c
        !          52070: 
        !          52071: objects/mmas.o: mmas.s
        !          52072:        -/lib/cpp -E mmas.s > mmas.i
        !          52073:        exec /bin/as -gxo $@@ mmas.i
        !          52074:        exec /bin/rm -f mmas.i
        !          52075: 
        !          52076: objects/ms.o:                          \
        !          52077:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52078:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52079:                                        $(SYSINC)/fun.h \
        !          52080:                $(SYSINC)/uproc.h       \
        !          52081:                $(SYSINC)/con.h         \
        !          52082:                $(SYSINC)/ms.h          \
        !          52083:                $(USRINC)/errno.h       \
        !          52084:                ms.c
        !          52085:        $(CC) $(CFLAGS) -c -o $@@ ms.c
        !          52086: 
        !          52087: objects/msg.o:                         \
        !          52088:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52089:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52090:                                        $(SYSINC)/fun.h \
        !          52091:                $(SYSINC)/con.h         \
        !          52092:                $(USRINC)/errno.h       \
        !          52093:                $(SYSINC)/msg.h         \
        !          52094:                $(SYSINC)/sched.h       \
        !          52095:                $(SYSINC)/seg.h         \
        !          52096:                $(SYSINC)/stat.h        \
        !          52097:                $(SYSINC)/types.h       \
        !          52098:                $(SYSINC)/uproc.h       \
        !          52099:                msg.c
        !          52100:        $(CC) $(CFLAGS) -c -o $@@ msg.c
        !          52101: 
        !          52102: objects/msgcon.o:                      \
        !          52103:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52104:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52105:                                        $(SYSINC)/fun.h \
        !          52106:                $(SYSINC)/con.h         \
        !          52107:                $(USRINC)/errno.h       \
        !          52108:                $(SYSINC)/msg.h         \
        !          52109:                $(SYSINC)/types.h       \
        !          52110:                $(SYSINC)/uproc.h       \
        !          52111:                msgcon.c
        !          52112:        $(CC) $(CFLAGS) -c -o $@@ msgcon.c
        !          52113: 
        !          52114: objects/msgstub.o:                     \
        !          52115:                msgstub.c
        !          52116:        $(CC) $(CFLAGS) -c -o $@@ msgstub.c
        !          52117: 
        !          52118: objects/pccon.o:                       \
        !          52119:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52120:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52121:                                        $(SYSINC)/fun.h \
        !          52122:                $(SYSINC)/con.h         \
        !          52123:                $(USRINC)/mtype.h       \
        !          52124:                $(SYSINC)/stat.h        \
        !          52125:                pccon.c
        !          52126:        $(CC) $(CFLAGS) -c -o $@@ pccon.c
        !          52127: 
        !          52128: objects/rm.o: rm.c
        !          52129:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          52130: 
        !          52131: objects/rp.o:                          \
        !          52132:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52133:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52134:                                        $(SYSINC)/fun.h \
        !          52135:                $(SYSINC)/con.h         \
        !          52136:                $(USRINC)/errno.h       \
        !          52137:                $(SYSINC)/seg.h         \
        !          52138:                $(SYSINC)/sched.h       \
        !          52139:                $(SYSINC)/stat.h        \
        !          52140:                $(USRINC)/termio.h      \
        !          52141:                $(SYSINC)/uproc.h       \
        !          52142:                $(USRINC)/v7sgtty.h     \
        !          52143:                rp.c
        !          52144:        $(CC) $(CFLAGS) -c -o $@@ rp.c
        !          52145: 
        !          52146: objects/rpas.o: rpas.s
        !          52147:        $(AS) -gxo $@@ $<
        !          52148: 
        !          52149: objects/rs0.o:                         \
        !          52150:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52151:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52152:                                        $(SYSINC)/fun.h \
        !          52153:                $(SYSINC)/con.h         \
        !          52154:                $(USRINC)/errno.h       \
        !          52155:                $(DRVINC)/ins8250.h     \
        !          52156:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          52157:                $(SYSINC)/sched.h       \
        !          52158:                $(SYSINC)/stat.h        \
        !          52159:                $(USRINC)/termio.h      \
        !          52160:                $(SYSINC)/uproc.h       \
        !          52161:                rs.c
        !          52162:        $(CC) $(CFLAGS) -DRS0 -c -o $@@ rs.c
        !          52163: 
        !          52164: objects/rs1.o:                                 \
        !          52165:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52166:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52167:                                        $(SYSINC)/fun.h \
        !          52168:                $(SYSINC)/con.h         \
        !          52169:                $(USRINC)/errno.h       \
        !          52170:                $(DRVINC)/ins8250.h     \
        !          52171:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          52172:                $(SYSINC)/sched.h       \
        !          52173:                $(SYSINC)/stat.h        \
        !          52174:                $(USRINC)/termio.h      \
        !          52175:                $(SYSINC)/uproc.h       \
        !          52176:                rs.c
        !          52177:        $(CC) $(CFLAGS) -DRS1 -c -o $@@ rs.c
        !          52178: 
        !          52179: objects/rsas.o: rsas.s
        !          52180:        $(AS) -gxo $@@ $<
        !          52181: 
        !          52182: objects/sem.o:                         \
        !          52183:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52184:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52185:                                        $(SYSINC)/fun.h \
        !          52186:                $(SYSINC)/con.h         \
        !          52187:                $(USRINC)/errno.h       \
        !          52188:                $(SYSINC)/sched.h       \
        !          52189:                $(SYSINC)/sem.h         \
        !          52190:                $(SYSINC)/stat.h        \
        !          52191:                $(SYSINC)/types.h       \
        !          52192:                $(SYSINC)/uproc.h       \
        !          52193:                sem.c
        !          52194:        $(CC) $(CFLAGS) -c -o $@@ sem.c
        !          52195: 
        !          52196: objects/semcon.o:                      \
        !          52197:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52198:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52199:                                        $(SYSINC)/fun.h \
        !          52200:                $(SYSINC)/con.h         \
        !          52201:                $(USRINC)/errno.h       \
        !          52202:                $(SYSINC)/sem.h         \
        !          52203:                $(SYSINC)/types.h       \
        !          52204:                $(SYSINC)/uproc.h       \
        !          52205:                semcon.c
        !          52206:        $(CC) $(CFLAGS) -c -o $@@ semcon.c
        !          52207: 
        !          52208: objects/semstub.o:                     \
        !          52209:                semstub.c
        !          52210:        $(CC) $(CFLAGS) -c -o $@@ semstub.c
        !          52211: 
        !          52212: objects/shm.o:                         \
        !          52213:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52214:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52215:                                        $(SYSINC)/fun.h \
        !          52216:                $(SYSINC)/con.h         \
        !          52217:                $(USRINC)/errno.h       \
        !          52218:                $(SYSINC)/sched.h       \
        !          52219:                $(SYSINC)/seg.h         \
        !          52220:                $(SYSINC)/shm.h         \
        !          52221:                $(SYSINC)/stat.h        \
        !          52222:                $(SYSINC)/types.h       \
        !          52223:                $(SYSINC)/uproc.h       \
        !          52224:                shm.c
        !          52225:        $(CC) $(CFLAGS) -c -o $@@ shm.c
        !          52226: 
        !          52227: objects/sham.o:                                \
        !          52228:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52229:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52230:                                        $(SYSINC)/fun.h \
        !          52231:                $(SYSINC)/con.h         \
        !          52232:                $(USRINC)/errno.h       \
        !          52233:                $(SYSINC)/sched.h       \
        !          52234:                $(SYSINC)/seg.h         \
        !          52235:                $(SYSINC)/shm.h         \
        !          52236:                $(SYSINC)/stat.h        \
        !          52237:                $(SYSINC)/types.h       \
        !          52238:                $(SYSINC)/uproc.h       \
        !          52239:                sham.c
        !          52240:        $(CC) $(CFLAGS) -c -o $@@ sham.c
        !          52241: 
        !          52242: objects/shmcon.o:                      \
        !          52243:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52244:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52245:                                        $(SYSINC)/fun.h \
        !          52246:                $(SYSINC)/con.h         \
        !          52247:                $(USRINC)/errno.h       \
        !          52248:                $(SYSINC)/sched.h       \
        !          52249:                $(SYSINC)/seg.h         \
        !          52250:                $(SYSINC)/shm.h         \
        !          52251:                $(SYSINC)/stat.h        \
        !          52252:                $(SYSINC)/types.h       \
        !          52253:                $(SYSINC)/uproc.h       \
        !          52254:                shmcon.c
        !          52255:        $(CC) $(CFLAGS) -c -o $@@ shmcon.c
        !          52256: 
        !          52257: objects/shmstub.o:                     \
        !          52258:                shmstub.c
        !          52259:        $(CC) $(CFLAGS) -c -o $@@ shmstub.c
        !          52260: 
        !          52261: objects/sl.o:                          \
        !          52262:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52263:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52264:                                        $(SYSINC)/fun.h \
        !          52265:                $(SYSINC)/con.h         \
        !          52266:                $(USRINC)/errno.h       \
        !          52267:                $(DRVINC)/ins8250.h     \
        !          52268:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          52269:                $(SYSINC)/stat.h        \
        !          52270:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          52271:                $(SYSINC)/uproc.h       \
        !          52272:                sl.c
        !          52273:        $(CC) $(CFLAGS) -c -o $@@ sl.c
        !          52274: 
        !          52275: objects/st.o:                          \
        !          52276:                $(SYSINC)/buf.h         \
        !          52277:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52278:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52279:                                        $(SYSINC)/fun.h \
        !          52280:                $(SYSINC)/con.h         \
        !          52281:                $(SYSINC)/const.h       \
        !          52282:                $(USRINC)/errno.h       \
        !          52283:                $(SYSINC)/inode.h       \
        !          52284:                $(SYSINC)/mtioctl.h     \
        !          52285:                $(SYSINC)/sched.h       \
        !          52286:                $(SYSINC)/seg.h         \
        !          52287:                $(SYSINC)/stat.h        \
        !          52288:                $(SYSINC)/uproc.h       \
        !          52289:                st.c
        !          52290:        $(CC) $(CFLAGS) -c -o $@@ st.c
        !          52291: 
        !          52292: objects/tn.o:                          \
        !          52293:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52294:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52295:                                        $(SYSINC)/fun.h \
        !          52296:                $(SYSINC)/con.h         \
        !          52297:                $(USRINC)/errno.h       \
        !          52298:                $(SYSINC)/sched.h       \
        !          52299:                $(SYSINC)/timeout.h     \
        !          52300:                $(SYSINC)/types.h       \
        !          52301:                $(SYSINC)/uproc.h       \
        !          52302:                tn.c
        !          52303:        $(CC) $(CFLAGS) -c -o $@@ tn.c
        !          52304: 
        !          52305: objects/tnas.o: tnas.s
        !          52306:        $(AS) -gxo $@@ $<
        !          52307: 
        !          52308: objects/tty.o: ../../ttydrv/tty.c
        !          52309:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          52310: @
        !          52311: 0707070064030104051004440000030000030000011777770507310664700005500000001662/newbits/kernel/USRSRC/i8086/drv/RCS/Mf.qq,vhead     1.1;
        !          52312: access   ;
        !          52313: symbols  ;
        !          52314: locks    bin:1.1;
        !          52315: comment  @ * @;
        !          52316: 
        !          52317: 
        !          52318: 1.1
        !          52319: date     91.06.10.14.42.34;  author bin;  state Exp;
        !          52320: branches ;
        !          52321: next   ;
        !          52322: 
        !          52323: 
        !          52324: desc
        !          52325: @initial version prov by hal
        !          52326: @
        !          52327: 
        !          52328: 
        !          52329: 
        !          52330: 1.1
        !          52331: log
        !          52332: @Initial revision
        !          52333: @
        !          52334: text
        !          52335: @# Make file for a loadable driver
        !          52336: 
        !          52337: AS=exec /bin/as
        !          52338: CC=exec /bin/cc
        !          52339: CPP=exec /lib/cpp
        !          52340: CFLAGS=-I.. -I../sys -I../.. -I../../sys \
        !          52341:        -I/usr/include/sys
        !          52342: AFLAGS=-gx
        !          52343: 
        !          52344: # Include directories
        !          52345: USRINC=/usr/include
        !          52346: SYSINC=/usr/include/sys
        !          52347: KERINC=/usr/src/sys/sys
        !          52348: DRVINC=/usr/src/sys/i8086/sys
        !          52349: USRSYS=/usr/sys
        !          52350: 
        !          52351: DRVOBJ=        objects/qq.o
        !          52352: 
        !          52353: qq: objects/qq.o
        !          52354:        rm -f $(USRSYS)/lib/qq.a
        !          52355:        ar rc $(USRSYS)/lib/qq.a objects/qq.o
        !          52356: 
        !          52357: objects/qq.o:                          \
        !          52358:                $(KERINC)/coherent.h    $(SYSINC)/types.h \
        !          52359:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52360:                                        $(SYSINC)/fun.h \
        !          52361:                $(SYSINC)/con.h         \
        !          52362:                $(USRINC)/errno.h       \
        !          52363:                $(SYSINC)/sched.h       \
        !          52364:                $(SYSINC)/seg.h         \
        !          52365:                $(SYSINC)/stat.h        \
        !          52366:                $(SYSINC)/types.h       \
        !          52367:                $(SYSINC)/uproc.h       \
        !          52368:                qq.c
        !          52369:        $(CC) $(CFLAGS) -c -o $@@ qq.c
        !          52370: @
        !          52371: 0707070064030104041004440000030000030000011777770507310664700006100000001662/newbits/kernel/USRSRC/i8086/drv/RCS/Mf.qq.foo,vhead     1.1;
        !          52372: access   ;
        !          52373: symbols  ;
        !          52374: locks    bin:1.1;
        !          52375: comment  @ * @;
        !          52376: 
        !          52377: 
        !          52378: 1.1
        !          52379: date     91.06.10.14.42.37;  author bin;  state Exp;
        !          52380: branches ;
        !          52381: next   ;
        !          52382: 
        !          52383: 
        !          52384: desc
        !          52385: @initial version prov by hal
        !          52386: @
        !          52387: 
        !          52388: 
        !          52389: 
        !          52390: 1.1
        !          52391: log
        !          52392: @Initial revision
        !          52393: @
        !          52394: text
        !          52395: @# Make file for a loadable driver
        !          52396: 
        !          52397: AS=exec /bin/as
        !          52398: CC=exec /bin/cc
        !          52399: CPP=exec /lib/cpp
        !          52400: CFLAGS=-I.. -I../sys -I../.. -I../../sys \
        !          52401:        -I/usr/include/sys
        !          52402: AFLAGS=-gx
        !          52403: 
        !          52404: # Include directories
        !          52405: USRINC=/usr/include
        !          52406: SYSINC=/usr/include/sys
        !          52407: KERINC=/usr/src/sys/sys
        !          52408: DRVINC=/usr/src/sys/i8086/sys
        !          52409: USRSYS=/usr/sys
        !          52410: 
        !          52411: DRVOBJ=        objects/qq.o
        !          52412: 
        !          52413: qq: objects/qq.o
        !          52414:        rm -f $(USRSYS)/lib/qq.a
        !          52415:        ar rc $(USRSYS)/lib/qq.a objects/qq.o
        !          52416: 
        !          52417: objects/qq.o:                          \
        !          52418:                $(KERINC)/coherent.h    $(SYSINC)/types.h \
        !          52419:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52420:                                        $(SYSINC)/fun.h \
        !          52421:                $(SYSINC)/con.h         \
        !          52422:                $(USRINC)/errno.h       \
        !          52423:                $(SYSINC)/sched.h       \
        !          52424:                $(SYSINC)/seg.h         \
        !          52425:                $(SYSINC)/stat.h        \
        !          52426:                $(SYSINC)/types.h       \
        !          52427:                $(SYSINC)/uproc.h       \
        !          52428:                qq.c
        !          52429:        $(CC) $(CFLAGS) -c -o $@@ qq.c
        !          52430: @
        !          52431: 0707070064030104031004440000030000030000011777770507310665000005500000003661/newbits/kernel/USRSRC/i8086/drv/RCS/Mf.sd,vhead     1.1;
        !          52432: access   ;
        !          52433: symbols  ;
        !          52434: locks    bin:1.1;
        !          52435: comment  @ * @;
        !          52436: 
        !          52437: 
        !          52438: 1.1
        !          52439: date     91.06.10.14.42.39;  author bin;  state Exp;
        !          52440: branches ;
        !          52441: next   ;
        !          52442: 
        !          52443: 
        !          52444: desc
        !          52445: @initial version prov by hal
        !          52446: @
        !          52447: 
        !          52448: 
        !          52449: 
        !          52450: 1.1
        !          52451: log
        !          52452: @Initial revision
        !          52453: @
        !          52454: text
        !          52455: @# (lgl-
        !          52456: #      COHERENT Driver Kit Version 1.1.0
        !          52457: #      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          52458: #      All rights reserved. May not be copied without permisdion.
        !          52459: # -lgl)
        !          52460: #
        !          52461: # Makefile for Adaptec AHA154x SCSI driver "sd"
        !          52462: #
        !          52463: AS=exec /bin/as
        !          52464: CC=exec /bin/cc
        !          52465: CPP=exec /lib/icpp
        !          52466: CFLAGS=-I.. -I../sys -I../.. -I../../sys -I/usr/include/sys
        !          52467: AFLAGS=-gx
        !          52468: OBJECTS=objects/scsi.o objects/aha.o objects/fdisk.o
        !          52469: 
        !          52470: # Include directories
        !          52471: USRINC=/usr/include
        !          52472: SYSINC=/usr/include/sys
        !          52473: KERINC=/usr/src/sys/sys
        !          52474: DRVINC=/usr/src/sys/i8086/sys
        !          52475: USRSYS=/usr/sys
        !          52476: 
        !          52477: sd: $(USRSYS)/lib/aha154x.a
        !          52478:        :
        !          52479: 
        !          52480: $(USRSYS)/lib/aha154x.a: $(OBJECTS)
        !          52481:        rm -f $(USRSYS)/lib/aha154x.a
        !          52482:        ar rc $(USRSYS)/lib/aha154x.a $(OBJECTS)
        !          52483: 
        !          52484: objects/scsi.o:                                \
        !          52485:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52486:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52487:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          52488:                $(SYSINC)/fdisk.h       \
        !          52489:                $(SYSINC)/hdioctl.h     \
        !          52490:                $(SYSINC)/sdioctl.h     \
        !          52491:                $(SYSINC)/buf.h         \
        !          52492:                $(SYSINC)/con.h         \
        !          52493:                $(SYSINC)/stat.h        \
        !          52494:                $(SYSINC)/uproc.h       \
        !          52495:                $(USRINC)/errno.h       \
        !          52496:                $(DRVINC)/scsiwork.h    \
        !          52497:                scsi.c
        !          52498:        $(CC) $(CFLAGS) -c -o objects/scsi.o scsi.c
        !          52499: 
        !          52500: objects/aha.o:                         \
        !          52501:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52502:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52503:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          52504:                $(SYSINC)/buf.h         \
        !          52505:                $(SYSINC)/sched.h               \
        !          52506:                $(DRVINC)/scsiwork.h    \
        !          52507:                $(DRVINC)/aha154x.h     \
        !          52508:                aha.c
        !          52509:        $(CC) $(CFLAGS) -c -o $@@ aha.c
        !          52510: 
        !          52511: objects/fdisk.o:                       \
        !          52512:                $(SYSINC)/buf.h         \
        !          52513:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          52514:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          52515:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          52516:                $(SYSINC)/con.h \
        !          52517:                $(USRINC)/errno.h       \
        !          52518:                $(SYSINC)/fdisk.h       \
        !          52519:                $(SYSINC)/inode.h       \
        !          52520:                $(SYSINC)/uproc.h       \
        !          52521:                fdisk.c
        !          52522:        $(CC) $(CFLAGS) -c -o $@@ fdisk.c
        !          52523: @
        !          52524: 0707070064030104021004440000030000030000011777770507310665000006100000041315/newbits/kernel/USRSRC/i8086/drv/RCS/alx.c.1.6,vhead     1.1;
        !          52525: access   ;
        !          52526: symbols  ;
        !          52527: locks    bin:1.1;
        !          52528: comment  @ * @;
        !          52529: 
        !          52530: 
        !          52531: 1.1
        !          52532: date     91.06.10.14.45.25;  author bin;  state Exp;
        !          52533: branches ;
        !          52534: next   ;
        !          52535: 
        !          52536: 
        !          52537: desc
        !          52538: @initial version prov by hal
        !          52539: @
        !          52540: 
        !          52541: 
        !          52542: 
        !          52543: 1.1
        !          52544: log
        !          52545: @Initial revision
        !          52546: @
        !          52547: text
        !          52548: @/* (-lgl
        !          52549:  *     COHERENT Driver Kit Version 1.1.0
        !          52550:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          52551:  *     All rights reserved. May not be copied without permission.
        !          52552:  *
        !          52553:  * $Log:       /usr/src/sys/i8086/drv/RCS/alx.c,v $
        !          52554:  * Revision 1.6        91/04/03  18:55:07      root
        !          52555:  * alxclose():  do closing state machine BEFORE dropping control lines.
        !          52556:  * alxioctl():  save and restore interrupt enable register.
        !          52557:  * alxopen():   wait for pending last close (fixes SLOW port bug).
        !          52558:  * This version needs al.h 1.3 or later.
        !          52559:  * 
        !          52560:  * Revision 1.5        91/04/02  17:53:37      root
        !          52561:  * save MSR delta status; add MS_INTR handling; use al.h 1.2
        !          52562:  * 
        !          52563:  * Revision 1.4        91/02/22  09:21:17      root
        !          52564:  * alxintr():  replace repeated use of ALPORT macro by local variable
        !          52565:  * 
        !          52566:  * Revision 1.3        91/02/21  14:58:16      root
        !          52567:  * Fix unconditional "hupcl" bug in 3.1.0 version.
        !          52568:  * 
        !          52569:  * Revision 1.2        91/02/21  11:21:40      hal
        !          52570:  * Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          52571:  * 
        !          52572:  * Revision 1.1        91/02/21  11:08:31      hal
        !          52573:  * Used in COH Release 3.0.0 - no COM3/COM4
        !          52574:  *
        !          52575:  -lgl) */
        !          52576: /*
        !          52577:  * Shared parts of IBM async port drivers.
        !          52578:  */
        !          52579: #include <coherent.h>
        !          52580: #include <i8086.h>
        !          52581: #include <al.h>
        !          52582: #include <con.h>
        !          52583: #include <errno.h>
        !          52584: #include <stat.h>
        !          52585: #include <tty.h>
        !          52586: #include <uproc.h>
        !          52587: #include <sys/timeout.h>
        !          52588: #include <clist.h>
        !          52589: #include <ins8250.h>
        !          52590: #include <sched.h>
        !          52591: 
        !          52592: #define ALPORT (((COM_DDP *)(tp->t_ddp))->port)
        !          52593: #define AL_TIM (((COM_DDP *)(tp->t_ddp))->tim)
        !          52594: #define AL_NUM (((COM_DDP *)(tp->t_ddp))->com_num)
        !          52595: #define AL_MSR_DELTAS  (((COM_DDP *)(tp->t_ddp))->msr_deltas)
        !          52596: #define AL_H_CLOSE     (((COM_DDP *)(tp->t_ddp))->h_close)
        !          52597: 
        !          52598: #define DTRTMOUT  3    /* DTR timeout interval in seconds for close */
        !          52599: #define        IENABLE (IE_RxI+IE_TxI+IE_LSI)
        !          52600: 
        !          52601: int    al_sg_set = 0;
        !          52602: int    al_sg_clr = 0;
        !          52603: static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          52604: 
        !          52605: /*
        !          52606:  * functions herein
        !          52607:  */
        !          52608: int    alxopen();
        !          52609: int    alxclose();
        !          52610: int    alxtimer();
        !          52611: int    alxioctl();
        !          52612: int    alxparam();
        !          52613: int    alxcycle();
        !          52614: int    alxstart();
        !          52615: int    alxbreak();
        !          52616: int    alxintr();
        !          52617: static int     alxclk();
        !          52618: static set_poll_rate();
        !          52619: 
        !          52620: /*
        !          52621:  * Baud rate table and polling rate table.
        !          52622:  * Indexed by ioctl bit rates.
        !          52623:  */
        !          52624: int albaud[] ={
        !          52625:        0,                              /* 0 */
        !          52626:        2304,                           /* 50 */
        !          52627:        1536,                           /* 75 */
        !          52628:        1047,                           /* 110 */
        !          52629:        857,                            /* 134.5 */
        !          52630:        768,                            /* 150 */
        !          52631:        576,                            /* 200 */
        !          52632:        384,                            /* 300 */
        !          52633:        192,                            /* 600 */
        !          52634:        96,                             /* 1200 */
        !          52635:        64,                             /* 1800 */
        !          52636:        58,                             /* 2000 */
        !          52637:        48,                             /* 2400 */
        !          52638:        32,                             /* 3600 */
        !          52639:        24,                             /* 4800 */
        !          52640:        16,                             /* 7200 */
        !          52641:        12,                             /* 9600 */
        !          52642:        6,                              /* 19200 */
        !          52643:        0,                              /* EXTA */
        !          52644:        0                               /* EXTB */
        !          52645: };
        !          52646: 
        !          52647: /*
        !          52648:  *     alp_rate[] is tied to albaud[] - it gives the minimum polling
        !          52649:  *     rate for the corresponding port speed; it must be a multiple
        !          52650:  *     of 100 (system clock Hz) and >= baud/6
        !          52651:  */
        !          52652: int alp_rate[] ={                      /* baud/6 or zero */
        !          52653:        0,                              /* 0 */
        !          52654:        1*HZ,                           /* 50 */
        !          52655:        1*HZ,                           /* 75 */
        !          52656:        1*HZ,                           /* 110 */
        !          52657:        1*HZ,                           /* 134.5 */
        !          52658:        1*HZ,                           /* 150 */
        !          52659:        1*HZ,                           /* 200 */
        !          52660:        1*HZ,                           /* 300 */
        !          52661:        1*HZ,                           /* 600 */
        !          52662:        2*HZ,                           /* 1200 */
        !          52663:        3*HZ,                           /* 1800 */
        !          52664:        4*HZ,                           /* 2000 */
        !          52665:        4*HZ,                           /* 2400 */
        !          52666:        6*HZ,                           /* 3600 */
        !          52667:        8*HZ,                           /* 4800 */
        !          52668:        12*HZ,                          /* 7200 */
        !          52669:        16*HZ,                          /* 9600 */
        !          52670:        0,                              /* 19200 */
        !          52671:        0,                              /* EXTA */
        !          52672:        0                               /* EXTB */
        !          52673: };
        !          52674: 
        !          52675: /*
        !          52676:  *     the following is for debug only
        !          52677:  */
        !          52678: #if 0
        !          52679: #define CDUMP(text)    cdump(text);
        !          52680: 
        !          52681: cdump(message)
        !          52682: char *message;
        !          52683: {
        !          52684:        int i, b;
        !          52685: 
        !          52686:        for (i = 0; i < NUM_AL_PORTS; i++) {
        !          52687:                b = ((COM_DDP *)(tp_table[i]->t_ddp))->port;
        !          52688:                printf("%x:%x:%x:%x ", i+1, b, inb(b+MCR), inb(b+IER));
        !          52689:        }
        !          52690:        printf("poll=%d ", poll_rate);
        !          52691:        printf("%s\n", message);
        !          52692: }
        !          52693: #else
        !          52694: #define CDUMP(text)
        !          52695: #endif
        !          52696: 
        !          52697: /*
        !          52698:  * alxopen()
        !          52699:  */
        !          52700: alxopen(dev, mode, tp, irqtty)
        !          52701: dev_t  dev;
        !          52702: int    mode;
        !          52703: register TTY   *tp, **irqtty;
        !          52704: {
        !          52705:        register int    s;
        !          52706:        register int    b;
        !          52707:        register int    minor_h;  /* minor device number including high bit */
        !          52708:        unsigned char   msr;
        !          52709: 
        !          52710:        minor_h = minor(dev);     /* complete minor number */
        !          52711: 
        !          52712:        b = ALPORT;
        !          52713: 
        !          52714:        if ( inb(b+IER) & ~IENABLE ) { /* chip not found */
        !          52715:                u.u_error = ENXIO;
        !          52716:                return;
        !          52717:        }
        !          52718: 
        !          52719:        if ((tp->t_flags & T_EXCL) && !super()) {
        !          52720:                u.u_error = ENODEV;
        !          52721:                return;
        !          52722:        }
        !          52723: 
        !          52724:        if (drvl[major(dev)].d_time != 0) {     /* Modem settling */
        !          52725:                u.u_error = EDBUSY;
        !          52726:                return;
        !          52727:        }
        !          52728: 
        !          52729:        /*
        !          52730:         * Can't open a polled port if another driver is using polling.
        !          52731:         */
        !          52732:        if (dev & CPOLL && poll_owner & ~ POLL_AL) {
        !          52733:                u.u_error = EDBUSY;
        !          52734:                return;
        !          52735:        }
        !          52736: 
        !          52737:        /*
        !          52738:         * exclusion conditions:
        !          52739:         *      can't have same port polled and IRQ at once
        !          52740:         *      can't have both com[13] or both com[24] IRQ at once 
        !          52741:         */
        !          52742:        if (dev & CPOLL) {
        !          52743:                if (com_usage[AL_NUM] == COM_IRQ) {
        !          52744:                        u.u_error = EDBUSY;
        !          52745:                        return;
        !          52746:                }
        !          52747:        } else {
        !          52748:                if (com_usage[AL_NUM] == COM_POLLED
        !          52749:                   || com_usage[AL_NUM ^ 2] == COM_IRQ) {
        !          52750:                        u.u_error = EDBUSY;
        !          52751:                        return;
        !          52752:                }
        !          52753:        }
        !          52754: 
        !          52755:        if (tp->t_open == 0) {        /* not already open */
        !          52756:                /*
        !          52757:                 * Wait for pending last close (if any) to finish.
        !          52758:                 */
        !          52759:                while (AL_H_CLOSE) {
        !          52760:                        sleep((char *)(&AL_H_CLOSE), CVTTOUT, IVTTOUT,
        !          52761:                                SVTTOUT);
        !          52762:                }
        !          52763:                s = sphi();
        !          52764:                /*
        !          52765:                 * Raise basic modem control lines even if modem
        !          52766:                 * control hasn't been specified.
        !          52767:                 * MC_OUT2 turns on NON-open-collector IRQ line from the UART.
        !          52768:                 * since we can't have two UART's on same IRQ with MC_OUT2 on
        !          52769:                 */
        !          52770:                if (dev & CPOLL) {
        !          52771:                        outb(b+MCR, MC_RTS|MC_DTR);
        !          52772:                } else {
        !          52773:                        *irqtty = tp_table[AL_NUM];
        !          52774:                        outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          52775:                }
        !          52776:        
        !          52777:                outb(b+IER, IENABLE);        /* enable interrupts */
        !          52778:        
        !          52779:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          52780:                        tp->t_flags |= T_MODC | T_HOPEN; /* yes, set flags */
        !          52781:                        while (1) {     /* wait for carrier */
        !          52782:                                msr = inb(b+MSR);
        !          52783:                                AL_MSR_DELTAS |= msr;
        !          52784:                                if (msr & MS_RLSD)
        !          52785:                                        break;
        !          52786:                                sleep((char *)(&tp->t_open), CVTTOUT, IVTTOUT,
        !          52787:                                        SVTTOUT);       /* wait for carrier */
        !          52788:                                if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          52789:                                        outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          52790:                                        /*
        !          52791:                                         * make sure port is hungup
        !          52792:                                         * disable all ints except for TxI
        !          52793:                                         */
        !          52794:                                        outb(b+IER, IE_TxI);
        !          52795:                                        u.u_error = EINTR;
        !          52796:                                        spl(s);
        !          52797:                                        return;
        !          52798:                                }
        !          52799:                        }
        !          52800:                        tp->t_flags &= ~T_HOPEN; /* no longer hanging in open */
        !          52801:                } else {
        !          52802:                        tp->t_flags &= ~T_MODC;         /* no modem control */ 
        !          52803:                }
        !          52804:                tp->t_flags |= T_CARR;                  /* carrier on */
        !          52805:                ttopen(tp);                             /* stty inits */
        !          52806: 
        !          52807:                /*
        !          52808:                 * Allow custom modification of defaults.
        !          52809:                 */
        !          52810:                tp->t_sgttyb.sg_flags |=  al_sg_set;
        !          52811:                tp->t_sgttyb.sg_flags &= ~al_sg_clr;
        !          52812:                alxparam(tp);
        !          52813:                spl(s);
        !          52814:        } else {                                /* already open */
        !          52815:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          52816:                    if ((tp->t_flags & T_MODC)==0) { /* already not modem control? */
        !          52817:                        u.u_error = ENODEV;     /* yes, don't allow open */     
        !          52818:                        return;
        !          52819:                    }
        !          52820:                } else {                         /* don't want modem control */
        !          52821:                        if (tp->t_flags & T_MODC) { /* already modem control? */
        !          52822:                                u.u_error = ENODEV; /* yes, don't allow open */
        !          52823:                                return;
        !          52824:                        }
        !          52825:                }
        !          52826:        }
        !          52827:        tp->t_open++;
        !          52828:        ttsetgrp(tp, dev);
        !          52829: 
        !          52830:        /*
        !          52831:         * now that we've successfully opened, designate port as
        !          52832:         * polled or interrupt driven to avoid future conflicts
        !          52833:         */
        !          52834:        if (dev & CPOLL) {
        !          52835:                com_usage[AL_NUM] = COM_POLLED;
        !          52836:                set_poll_rate();
        !          52837:        } else {                                /* irq-driven port */
        !          52838:                com_usage[AL_NUM] = COM_IRQ;
        !          52839:        }
        !          52840: 
        !          52841:        CDUMP((dev&CPOLL)?"open polled":"open irq")
        !          52842: }
        !          52843: 
        !          52844: /*
        !          52845:  * alxclose()
        !          52846:  */
        !          52847: alxclose(dev, mode, tp)
        !          52848: dev_t  dev;
        !          52849: int    mode;
        !          52850: TTY    *tp;
        !          52851: {
        !          52852:        register unsigned holdflags;
        !          52853:        register int b;
        !          52854:        int state, maj;
        !          52855: 
        !          52856:        /*
        !          52857:         * Called at high priority by alclose after al_buff is drained
        !          52858:         */
        !          52859:        holdflags = tp->t_flags;        /* save flags */
        !          52860:        AL_H_CLOSE = 1;                 /* disallow reopen til done closing */
        !          52861:        ttclose(tp);                    /* clear flags */
        !          52862:        b = ALPORT;
        !          52863:        /*
        !          52864:         * ttclose() only emptied the output queue tp->t_oq;
        !          52865:         * now wait for the silo tp->rawout to empty
        !          52866:         * and allow a delay for the UART on-chip xmit buffer to empty
        !          52867:         * state 2: waiting for silo to empty
        !          52868:         * state 1: stalling so UART can empty xmit buffer
        !          52869:         * state 0: done!  ok to shut off IRQ for this chip by clearing MC_OUT2
        !          52870:         */
        !          52871:        state = 2;
        !          52872:        while (state) {
        !          52873:                timeout(&AL_TIM, 10, wakeup, (int)&AL_TIM);
        !          52874:                sleep((char *)&AL_TIM, CVTTOUT, IVTTOUT, SVTTOUT);
        !          52875:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          52876:                        state--;
        !          52877:        }
        !          52878: 
        !          52879:        /*
        !          52880:         * If not hanging in open
        !          52881:         */
        !          52882:        if ( (holdflags & T_HOPEN) == 0 ) {
        !          52883:                /*
        !          52884:                 * Disable all ints except TxI
        !          52885:                 */
        !          52886:                outb(b+IER, IE_TxI);
        !          52887:        } else {
        !          52888:                /*
        !          52889:                 * Flags for first open
        !          52890:                 */
        !          52891:                tp->t_flags = T_MODC | T_HOPEN;
        !          52892:        }
        !          52893: 
        !          52894:        /*
        !          52895:         * If hupcls
        !          52896:         */
        !          52897:        if (holdflags & T_HPCL) {
        !          52898:                /*
        !          52899:                 * Hangup port
        !          52900:                 */
        !          52901:                outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          52902: 
        !          52903:                /*
        !          52904:                 * Hold dtr low for timeout
        !          52905:                 */
        !          52906:                maj = major(dev);
        !          52907:                drvl[maj].d_time = 1;
        !          52908:                sleep((char *)&drvl[maj].d_time, CVTTOUT, IVTTOUT, SVTTOUT);
        !          52909:                drvl[maj].d_time = 0;
        !          52910:        }
        !          52911:        outb(b+MCR, inb(b+MCR)&(~MC_OUT2));
        !          52912:        com_usage[AL_NUM] = COM_UNUSED;
        !          52913:        set_poll_rate();
        !          52914:        AL_H_CLOSE = 0;         /* allow reopen - done closing */
        !          52915:        wakeup((char *)&AL_H_CLOSE);
        !          52916:        CDUMP("closed")
        !          52917: }
        !          52918: 
        !          52919: /*
        !          52920:  * Common c_timer routine for async ports.
        !          52921:  */
        !          52922: alxtimer(dev)
        !          52923: dev_t dev;
        !          52924: {
        !          52925:        if ( ++drvl[major(dev)].d_time > DTRTMOUT )
        !          52926:                wakeup((char *)&drvl[major(dev)].d_time);
        !          52927: }
        !          52928: 
        !          52929: 
        !          52930: /*
        !          52931:  * Common c_ioctl routine for async ports.
        !          52932:  */
        !          52933: alxioctl(dev, com, vec, tp)
        !          52934: dev_t  dev;
        !          52935: struct sgttyb *vec;
        !          52936: register TTY   *tp;
        !          52937: {
        !          52938:        register int    s, b;
        !          52939:        int stat1, stat2;
        !          52940:        unsigned char   msr;
        !          52941:        unsigned char ier_save;
        !          52942: 
        !          52943:        s = sphi();
        !          52944:        b = ALPORT;
        !          52945:        ier_save=inb(b+IER);
        !          52946:        stat1 = inb(b+MCR);             /* get current MCR register status */
        !          52947:        stat2 = inb(b+LCR);             /* get current LCR register status */
        !          52948: 
        !          52949:        switch(com) {
        !          52950:        case TIOCSBRK:                  /* set BREAK */         
        !          52951:                outb(b+LCR, stat2|LC_SBRK);
        !          52952:                break;
        !          52953:        case TIOCCBRK:                  /* clear BREAK */
        !          52954:                outb(b+LCR, stat2 & ~LC_SBRK);
        !          52955:                break;
        !          52956:        case TIOCSDTR:                  /* set DTR */
        !          52957:                outb(b+MCR, stat1|MC_DTR);
        !          52958:                break;  
        !          52959:        case TIOCCDTR:                  /* clear DTR */
        !          52960:                outb(b+MCR, stat1 & ~MC_DTR);   
        !          52961:                break;
        !          52962:        case TIOCSRTS:                  /* set RTS */
        !          52963:                outb(b+MCR, stat1|MC_RTS);      
        !          52964:                break;
        !          52965:        case TIOCCRTS:                  /* clear RTS */
        !          52966:                outb(b+MCR, stat1 & ~MC_RTS);   
        !          52967:                break;  
        !          52968:        case TIOCRSPEED:                /* set "raw" I/O speed divisor */
        !          52969:                outb(b+LCR, stat2|LC_DLAB);  /* set speed latch bit */
        !          52970:                outb(b+DLL, (unsigned) vec);
        !          52971:                outb(b+DLH, (unsigned) vec >> 8);
        !          52972:                outb(b+LCR, stat2);       /* reset latch bit */
        !          52973:                break;
        !          52974:        case TIOCWORDL:         /* set word length and stop bits */
        !          52975:                outb(b+LCR, ((stat2&~0x7) | ((unsigned) vec & 0x7)));
        !          52976:                break;
        !          52977:        case TIOCRMSR:          /* get CTS/DSR/RI/RLSD (MSR) */
        !          52978:                msr = inb(b+MSR);
        !          52979:                AL_MSR_DELTAS |= msr;
        !          52980:                stat1 = msr >> 4;
        !          52981:                kucopy(&stat1, (unsigned *) vec, sizeof(unsigned));
        !          52982:                break;  
        !          52983:        default:
        !          52984:                ttioctl(tp, com, vec);
        !          52985:        }
        !          52986:        outb(b+IER, ier_save);
        !          52987:        spl(s);
        !          52988: }
        !          52989: 
        !          52990: alxparam(tp)
        !          52991: TTY    *tp;
        !          52992: {
        !          52993:        register int    b;
        !          52994:        register int    baud;
        !          52995:        int s;
        !          52996: 
        !          52997:        b = ALPORT;
        !          52998: 
        !          52999:        /*
        !          53000:         * error if input speed not the same as output speed
        !          53001:         */
        !          53002:        if (tp->t_sgttyb.sg_ispeed!=tp->t_sgttyb.sg_ospeed) {
        !          53003:                u.u_error = ENODEV;       
        !          53004:                return;
        !          53005:        }
        !          53006: 
        !          53007:        if ((baud = albaud[tp->t_sgttyb.sg_ispeed]) == 0) {
        !          53008:                if (tp->t_flags & T_MODC) {  /* modem control? */
        !          53009:                        tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          53010:                        outb(b+MCR, inb(b+MCR) & MC_OUT2); /* hangup */
        !          53011:                }
        !          53012:        }
        !          53013: 
        !          53014:        if (baud) {
        !          53015:                unsigned char ier_save;
        !          53016: 
        !          53017:                s=sphi();
        !          53018:                ier_save=inb(b+IER);    /* some chips need this */
        !          53019:                outb(b+LCR, LC_DLAB);
        !          53020:                outb(b+DLL, baud);
        !          53021:                outb(b+DLH, baud >> 8);
        !          53022:                switch (tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW)) {
        !          53023:                case EVENP:
        !          53024:                        outb(b+LCR, LC_CS7 + LC_PARENB + LC_PAREVEN );
        !          53025:                        break;
        !          53026: 
        !          53027:                case ODDP:
        !          53028:                        outb(b+LCR, LC_CS7 + LC_PARENB );
        !          53029:                        break;
        !          53030: 
        !          53031:                default:
        !          53032:                        outb(b+LCR, LC_CS8 );
        !          53033:                        break;
        !          53034:                }
        !          53035:                outb(b+IER, ier_save);
        !          53036:                spl(s);
        !          53037:        }
        !          53038:        set_poll_rate();
        !          53039: }
        !          53040: 
        !          53041: /*
        !          53042:  * Middle level processor.
        !          53043:  *
        !          53044:  *     Invoked 10 times per second.
        !          53045:  *     Checks modem status for loss of carrier.
        !          53046:  *     Tranfers rawin buffer [from intr level] to canonical input queue.
        !          53047:  *     Transfers output queue to rawout buffer [for intr level].
        !          53048:  */
        !          53049: alxcycle( tp )
        !          53050: register TTY * tp;
        !          53051: {
        !          53052:        register int b;
        !          53053:        register int n;
        !          53054:        unsigned char   msr;
        !          53055:        int s;
        !          53056: 
        !          53057:        /*
        !          53058:         * Check modem status every clock tick.
        !          53059:         * Modem status interrupts are not enabled due to 8250 hardware bug.
        !          53060:         * Enabling modem status and receive interrupts may cause lockup.
        !          53061:         */
        !          53062:        if ( tp->t_flags & T_MODC ) {
        !          53063: 
        !          53064:                /*
        !          53065:                 * Get status
        !          53066:                 */
        !          53067:                s = sphi();
        !          53068:                msr = inb(ALPORT+MSR);
        !          53069:                AL_MSR_DELTAS |= msr;
        !          53070:                spl(s);
        !          53071: 
        !          53072:                /*
        !          53073:                 * Carrier changed.
        !          53074:                 */
        !          53075:                if ( AL_MSR_DELTAS & MS_DRLSD ) {
        !          53076:                        AL_MSR_DELTAS & ~MS_DRLSD;
        !          53077:                        /*
        !          53078:                         * wakeup open
        !          53079:                         */
        !          53080:                        if ( tp->t_open == 0 ) {
        !          53081:                                wakeup((char *)(&tp->t_open));
        !          53082:                        }
        !          53083: 
        !          53084:                        /*
        !          53085:                         * carrier off?
        !          53086:                         */
        !          53087:                        else if ( (msr & MS_RLSD) == 0 ) {
        !          53088:                                /*
        !          53089:                                 * clear carrier flag; send hangup signal
        !          53090:                                 */
        !          53091:                                tp->t_rawin.si_ox = tp->t_rawin.si_ix;
        !          53092:                                tthup( tp );
        !          53093:                        }
        !          53094:                }
        !          53095:        }
        !          53096: 
        !          53097:        /*
        !          53098:         * Empty raw input buffer.
        !          53099:         */
        !          53100:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          53101:                ttin( tp, tp->t_rawin.si_buf[ tp->t_rawin.si_ox ] );
        !          53102:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          53103:                        tp->t_rawin.si_ox = 0;
        !          53104:                else
        !          53105:                        tp->t_rawin.si_ox++;
        !          53106:        }
        !          53107: 
        !          53108:        /*
        !          53109:         * Calculate free output slot count.
        !          53110:         */
        !          53111:        n  = sizeof(tp->t_rawout.si_buf) - 1;
        !          53112:        n += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          53113:        n %= sizeof(tp->t_rawout.si_buf);
        !          53114: 
        !          53115:        /*
        !          53116:         * Fill raw output buffer.
        !          53117:         */
        !          53118:        while ( (--n >= 0) && ((b = ttout(tp)) >= 0) ) {
        !          53119:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = b;
        !          53120:                if ( tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1 )
        !          53121:                        tp->t_rawout.si_ix = 0;
        !          53122:                else
        !          53123:                        tp->t_rawout.si_ix++;
        !          53124:        }
        !          53125: 
        !          53126:        /*
        !          53127:         * (Re)start output, wake sleeping processes, etc.
        !          53128:         */
        !          53129:        ttstart( tp );
        !          53130: 
        !          53131:        /*
        !          53132:         * Schedule next cycle.
        !          53133:         */
        !          53134:        timeout( &tp->t_rawtim, HZ/10, alxcycle, tp );
        !          53135: }
        !          53136: 
        !          53137: /*
        !          53138:  * Serial Transmit Start Routine.
        !          53139:  */
        !          53140: alxstart( tp )
        !          53141: register TTY * tp;
        !          53142: {
        !          53143:        register int b;
        !          53144:        register int s;
        !          53145:        extern alxbreak();
        !          53146: 
        !          53147:        /*
        !          53148:         * Read line status register AFTER disabling interrupts.
        !          53149:         */
        !          53150:        s = sphi();
        !          53151:        b = inb(ALPORT+LSR);
        !          53152: 
        !          53153:        /*
        !          53154:         * Process break indication.
        !          53155:         * NOTE: Break indication cleared when line status register was read.
        !          53156:         */
        !          53157:        if ( b & LS_BREAK )
        !          53158:                defer( alxbreak, tp );
        !          53159: 
        !          53160:        /*
        !          53161:         * Transmitter is empty, output data is pending.
        !          53162:         */
        !          53163:        if ( (b & LS_TxRDY) && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          53164:                outb(   ALPORT+DREG,
        !          53165:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          53166:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          53167:                        tp->t_rawout.si_ox = 0;
        !          53168:        }
        !          53169:        spl( s );
        !          53170: }
        !          53171: 
        !          53172: /*
        !          53173:  * Serial Received Break Handler.
        !          53174:  */
        !          53175: alxbreak( tp )
        !          53176: register TTY * tp;
        !          53177: {
        !          53178:        ttsignal( tp, SIGINT );
        !          53179: }
        !          53180: 
        !          53181: /*
        !          53182:  * Serial Interrupt Handler.
        !          53183:  */
        !          53184: alxintr( tp )
        !          53185: register TTY * tp;
        !          53186: {
        !          53187:        register int    b;
        !          53188:        int port = ALPORT;
        !          53189: 
        !          53190: rescan:
        !          53191:        switch ( inb(port+IIR) ) {
        !          53192: 
        !          53193:        case LS_INTR:
        !          53194:                if ( inb(port+LSR) & LS_BREAK )
        !          53195:                        defer( alxbreak, tp );
        !          53196:                goto rescan;
        !          53197: 
        !          53198:        case Rx_INTR:
        !          53199:                b = inb(port+DREG);
        !          53200:                if ( tp->t_open == 0 )
        !          53201:                        goto rescan;
        !          53202:                /*
        !          53203:                 * Must recognize XOFF quickly to avoid transmit overrun.
        !          53204:                 * Recognize XON here as well to avoid race conditions.
        !          53205:                 */
        !          53206:                if ( (tp->t_sgttyb.sg_flags & RAWIN) == 0 ) {
        !          53207:                        /*
        !          53208:                         * XOFF.
        !          53209:                         */
        !          53210:                        if ( tp->t_tchars.t_stopc == (b & 0177) ) {
        !          53211:                                tp->t_flags |= T_STOP;
        !          53212:                                goto rescan;
        !          53213:                        }
        !          53214: 
        !          53215:                        /*
        !          53216:                         * XON.
        !          53217:                         */
        !          53218:                        if ( tp->t_tchars.t_startc == (b & 0177) ) {
        !          53219:                                tp->t_flags &= ~T_STOP;
        !          53220:                                goto rescan;
        !          53221:                        }
        !          53222:                }
        !          53223: 
        !          53224:                /*
        !          53225:                 * Save char in raw input buffer.
        !          53226:                 */
        !          53227:                tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          53228:                if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          53229:                        tp->t_rawin.si_ix = 0;
        !          53230:                goto rescan;
        !          53231: 
        !          53232:        case Tx_INTR:
        !          53233:                /*
        !          53234:                 * Do nothing if no raw output data or output is stopped.
        !          53235:                 */
        !          53236:                if ( tp->t_rawout.si_ix == tp->t_rawout.si_ox ) {
        !          53237:                        goto rescan;
        !          53238:                }
        !          53239:                if ( tp->t_flags & T_STOP )
        !          53240:                        goto rescan;
        !          53241: 
        !          53242:                /*
        !          53243:                 * Transmit next char in raw output buffer.
        !          53244:                 */
        !          53245:                outb(   port+DREG,
        !          53246:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          53247: 
        !          53248:                /*
        !          53249:                 * Adjust raw output buffer output index.
        !          53250:                 */
        !          53251:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          53252:                        tp->t_rawout.si_ox = 0;
        !          53253: 
        !          53254:                /*
        !          53255:                 * Try to fill buffer if now empty.
        !          53256:                 */
        !          53257:                if ( tp->t_rawout.si_ox == tp->t_rawout.si_ix ) {
        !          53258:                        defer( alxcycle, tp );
        !          53259:                }
        !          53260:                goto rescan;
        !          53261:                
        !          53262:        case MS_INTR:
        !          53263:                AL_MSR_DELTAS |= inb(port+MSR);
        !          53264:                goto rescan;
        !          53265:        }
        !          53266: }
        !          53267: 
        !          53268: /*
        !          53269:  * alxclk will be called every time T0 interrupts - if it returns 0,
        !          53270:  * the usual system timer interrupt stuff is done
        !          53271:  */
        !          53272: static int alxclk()
        !          53273: {
        !          53274:        static int count;
        !          53275:        int i;
        !          53276: 
        !          53277:        for (i = 0; i < NUM_AL_PORTS;  i++)
        !          53278:                if (com_usage[i] == COM_POLLED)
        !          53279:                        alxintr(tp_table[i]);
        !          53280:        count++;
        !          53281:        if (count >= poll_divisor)
        !          53282:                count = 0;
        !          53283:        return count;
        !          53284: }
        !          53285: 
        !          53286: /*
        !          53287:  * set_poll_rate is called when a port is opened or closed or changes speed
        !          53288:  * it sets the polling rate only as fast as needed, and shuts off polling
        !          53289:  * whenever possible
        !          53290:  */
        !          53291: static set_poll_rate()
        !          53292: {
        !          53293:        int port_num, max_rate, port_rate;
        !          53294: 
        !          53295:        /*
        !          53296:         * If another driver has the polling clock, do nothing.
        !          53297:         */
        !          53298:        if (poll_owner & ~ POLL_AL)
        !          53299:                return;
        !          53300: 
        !          53301:        /*
        !          53302:         * find highest valid polling rate in units of HZ/10
        !          53303:         */
        !          53304:        max_rate = 0;
        !          53305:        for (port_num = 0; port_num < NUM_AL_PORTS; port_num++) {
        !          53306:                if (com_usage[port_num] == COM_POLLED) {
        !          53307:                        port_rate = alp_rate[(tp_table[port_num])->t_sgttyb.sg_ispeed];
        !          53308:                        if (max_rate < port_rate)
        !          53309:                                max_rate = port_rate;
        !          53310:                }
        !          53311:        }
        !          53312:        /*
        !          53313:         * if max_rate is not current rate, adjust the system clock
        !          53314:         */
        !          53315:        if (max_rate != poll_rate) {
        !          53316:                poll_rate = max_rate;
        !          53317:                poll_divisor = poll_rate/HZ;  /* used in alxclk() */
        !          53318:                altclk_out();           /* stop previous polling */
        !          53319:                poll_owner &= ~ POLL_AL;
        !          53320:                if (max_rate) { /* resume polling at new rate if needed */
        !          53321:                        poll_owner |= POLL_AL;
        !          53322:                        altclk_in(poll_rate, alxclk);
        !          53323:                }
        !          53324:                CDUMP("new rate")
        !          53325:        }
        !          53326: }
        !          53327: @
        !          53328: 0707070064030104011004440000030000030000011777770507310665500006100000036361/newbits/kernel/USRSRC/i8086/drv/RCS/alx.c.310,vhead     1.1;
        !          53329: access   ;
        !          53330: symbols  ;
        !          53331: locks    bin:1.1;
        !          53332: comment  @ * @;
        !          53333: 
        !          53334: 
        !          53335: 1.1
        !          53336: date     91.06.10.14.45.42;  author bin;  state Exp;
        !          53337: branches ;
        !          53338: next   ;
        !          53339: 
        !          53340: 
        !          53341: desc
        !          53342: @initial version prov by hal
        !          53343: @
        !          53344: 
        !          53345: 
        !          53346: 
        !          53347: 1.1
        !          53348: log
        !          53349: @Initial revision
        !          53350: @
        !          53351: text
        !          53352: @/* (-lgl
        !          53353:  *     COHERENT Driver Kit Version 1.1.0
        !          53354:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          53355:  *     All rights reserved. May not be copied without permission.
        !          53356:  *
        !          53357:  * $Log:       /usr/src/sys/i8086/drv/RCS/alx.c,v $
        !          53358:  * Revision 1.2        91/02/21  11:21:40      hal
        !          53359:  * Used in COH Release 3.1.0 - add COM3/COM4 and polling
        !          53360:  * 
        !          53361:  * Revision 1.1        91/02/21  11:08:31      hal
        !          53362:  * Used in COH Release 3.0.0 - no COM3/COM4
        !          53363:  *
        !          53364:  -lgl) */
        !          53365: /*
        !          53366:  * Shared parts of IBM async port drivers.
        !          53367:  */
        !          53368: #include <coherent.h>
        !          53369: #include <i8086.h>
        !          53370: #include <al.h>
        !          53371: #include <con.h>
        !          53372: #include <errno.h>
        !          53373: #include <stat.h>
        !          53374: #include <tty.h>
        !          53375: #include <uproc.h>
        !          53376: #include <sys/timeout.h>
        !          53377: #include <clist.h>
        !          53378: #include <ins8250.h>
        !          53379: #include <sched.h>
        !          53380: 
        !          53381: #define ALPORT (((COM_DDP *)(tp->t_ddp))->port)
        !          53382: #define AL_TIM (((COM_DDP *)(tp->t_ddp))->tim)
        !          53383: #define AL_NUM (((COM_DDP *)(tp->t_ddp))->com_num)
        !          53384: 
        !          53385: #define DTRTMOUT  3    /* DTR timeout interval in seconds for close */
        !          53386: #define        IENABLE (IE_RxI+IE_TxI+IE_LSI)
        !          53387: 
        !          53388: int    al_sg_set = 0;
        !          53389: int    al_sg_clr = 0;
        !          53390: static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          53391: 
        !          53392: /*
        !          53393:  * functions herein
        !          53394:  */
        !          53395: int    alxopen();
        !          53396: int    alxclose();
        !          53397: int    alxtimer();
        !          53398: int    alxioctl();
        !          53399: int    alxparam();
        !          53400: int    alxcycle();
        !          53401: int    alxstart();
        !          53402: int    alxbreak();
        !          53403: int    alxintr();
        !          53404: static int     alxclk();
        !          53405: static set_poll_rate();
        !          53406: 
        !          53407: /*
        !          53408:  * Baud rate table and polling rate table.
        !          53409:  * Indexed by ioctl bit rates.
        !          53410:  */
        !          53411: int albaud[] ={
        !          53412:        0,                              /* 0 */
        !          53413:        2304,                           /* 50 */
        !          53414:        1536,                           /* 75 */
        !          53415:        1047,                           /* 110 */
        !          53416:        857,                            /* 134.5 */
        !          53417:        768,                            /* 150 */
        !          53418:        576,                            /* 200 */
        !          53419:        384,                            /* 300 */
        !          53420:        192,                            /* 600 */
        !          53421:        96,                             /* 1200 */
        !          53422:        64,                             /* 1800 */
        !          53423:        58,                             /* 2000 */
        !          53424:        48,                             /* 2400 */
        !          53425:        32,                             /* 3600 */
        !          53426:        24,                             /* 4800 */
        !          53427:        16,                             /* 7200 */
        !          53428:        12,                             /* 9600 */
        !          53429:        6,                              /* 19200 */
        !          53430:        0,                              /* EXTA */
        !          53431:        0                               /* EXTB */
        !          53432: };
        !          53433: 
        !          53434: /*
        !          53435:  *     alp_rate[] is tied to albaud[] - it gives the minimum polling
        !          53436:  *     rate for the corresponding port speed; it must be a multiple
        !          53437:  *     of 100 (system clock Hz) and >= baud/6
        !          53438:  */
        !          53439: int alp_rate[] ={                      /* baud/6 or zero */
        !          53440:        0,                              /* 0 */
        !          53441:        1*HZ,                           /* 50 */
        !          53442:        1*HZ,                           /* 75 */
        !          53443:        1*HZ,                           /* 110 */
        !          53444:        1*HZ,                           /* 134.5 */
        !          53445:        1*HZ,                           /* 150 */
        !          53446:        1*HZ,                           /* 200 */
        !          53447:        1*HZ,                           /* 300 */
        !          53448:        1*HZ,                           /* 600 */
        !          53449:        2*HZ,                           /* 1200 */
        !          53450:        3*HZ,                           /* 1800 */
        !          53451:        4*HZ,                           /* 2000 */
        !          53452:        4*HZ,                           /* 2400 */
        !          53453:        6*HZ,                           /* 3600 */
        !          53454:        8*HZ,                           /* 4800 */
        !          53455:        12*HZ,                          /* 7200 */
        !          53456:        16*HZ,                          /* 9600 */
        !          53457:        0,                              /* 19200 */
        !          53458:        0,                              /* EXTA */
        !          53459:        0                               /* EXTB */
        !          53460: };
        !          53461: 
        !          53462: /*
        !          53463:  *     the following is for debug only
        !          53464:  */
        !          53465: #if 0
        !          53466: #define CDUMP(text)    cdump(text);
        !          53467: 
        !          53468: cdump(message)
        !          53469: char *message;
        !          53470: {
        !          53471:        int i, b;
        !          53472: 
        !          53473:        for (i = 0; i < NUM_AL_PORTS; i++) {
        !          53474:                b = ((COM_DDP *)(tp_table[i]->t_ddp))->port;
        !          53475:                printf("%x:%x:%x:%x ", i+1, b, inb(b+MCR), inb(b+IER));
        !          53476:        }
        !          53477:        printf("poll=%d ", poll_rate);
        !          53478:        printf("%s\n", message);
        !          53479: }
        !          53480: #else
        !          53481: #define CDUMP(text)
        !          53482: #endif
        !          53483: 
        !          53484: alxopen(dev, mode, tp, irqtty)
        !          53485: dev_t  dev;
        !          53486: int    mode;
        !          53487: register TTY   *tp, **irqtty;
        !          53488: {
        !          53489:        register int    s;
        !          53490:        register int    b;
        !          53491:        register int    minor_h;  /* minor device number including high bit */
        !          53492: 
        !          53493:        minor_h = minor(dev);     /* complete minor number */
        !          53494: 
        !          53495:        b = ALPORT;
        !          53496: 
        !          53497:        if ( inb(b+IER) & ~IENABLE ) { /* chip not found */
        !          53498:                u.u_error = ENXIO;
        !          53499:                return;
        !          53500:        }
        !          53501: 
        !          53502:        if ((tp->t_flags & T_EXCL) && !super()) {
        !          53503:                u.u_error = ENODEV;
        !          53504:                return;
        !          53505:        }
        !          53506: 
        !          53507:        if (drvl[major(dev)].d_time != 0) {     /* Modem settling */
        !          53508:                u.u_error = EDBUSY;
        !          53509:                return;
        !          53510:        }
        !          53511: 
        !          53512:        /*
        !          53513:         * Can't open a polled port if another driver is using polling.
        !          53514:         */
        !          53515:        if (dev & CPOLL && poll_owner & ~ POLL_AL) {
        !          53516:                u.u_error = EDBUSY;
        !          53517:                return;
        !          53518:        }
        !          53519: 
        !          53520:        /*
        !          53521:         * exclusion conditions:
        !          53522:         *      can't have same port polled and IRQ at once
        !          53523:         *      can't have both com[13] or both com[24] IRQ at once 
        !          53524:         */
        !          53525:        if (dev & CPOLL) {
        !          53526:                if (com_usage[AL_NUM] == COM_IRQ) {
        !          53527:                        u.u_error = EDBUSY;
        !          53528:                        return;
        !          53529:                }
        !          53530:        } else {
        !          53531:                if (com_usage[AL_NUM] == COM_POLLED
        !          53532:                   || com_usage[AL_NUM ^ 2] == COM_IRQ) {
        !          53533:                        u.u_error = EDBUSY;
        !          53534:                        return;
        !          53535:                }
        !          53536:        }
        !          53537: 
        !          53538:        if (tp->t_open == 0) {        /* not already open */
        !          53539:                s = sphi();
        !          53540:                /*
        !          53541:                 * Raise basic modem control lines even if modem
        !          53542:                 * control hasn't been specified.
        !          53543:                 * MC_OUT2 turns on NON-open-collector IRQ line from the UART.
        !          53544:                 * since we can't have two UART's on same IRQ with MC_OUT2 on
        !          53545:                 */
        !          53546:                if (dev & CPOLL)
        !          53547:                        outb(b+MCR, MC_RTS|MC_DTR);
        !          53548:                else {
        !          53549:                        *irqtty = tp_table[AL_NUM];
        !          53550:                        outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          53551:                }
        !          53552:        
        !          53553:                outb(b+IER, IENABLE);        /* enable interrupts */
        !          53554:        
        !          53555:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          53556:                        tp->t_flags |= T_MODC | T_HOPEN; /* yes, set flags */
        !          53557:                        while ((inb(b+MSR) & MS_RLSD) == 0) { /* no carrier? */
        !          53558:                                sleep((char *)(&tp->t_open), CVTTOUT, IVTTOUT,
        !          53559:                                        SVTTOUT);       /* wait for carrier */
        !          53560:                                if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          53561:                                        outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          53562:                                        /*
        !          53563:                                         * make sure port is hungup
        !          53564:                                         * disable all ints except for TxI
        !          53565:                                         */
        !          53566:                                        outb(b+IER, IE_TxI);
        !          53567:                                        u.u_error = EINTR;
        !          53568:                                        spl(s);
        !          53569:                                        return;
        !          53570:                                }
        !          53571:                        }
        !          53572:                        tp->t_flags &= ~T_HOPEN; /* no longer hanging in open */
        !          53573:                } else {
        !          53574:                        tp->t_flags &= ~T_MODC;         /* no modem control */ 
        !          53575:                }
        !          53576:                tp->t_flags |= T_CARR;                  /* carrier on */
        !          53577:                ttopen(tp);                             /* stty inits */
        !          53578: 
        !          53579:                /*
        !          53580:                 * Allow custom modification of defaults.
        !          53581:                 */
        !          53582:                tp->t_sgttyb.sg_flags |=  al_sg_set;
        !          53583:                tp->t_sgttyb.sg_flags &= ~al_sg_clr;
        !          53584:                alxparam(tp);
        !          53585:                spl(s);
        !          53586:        } else {                                /* already open */
        !          53587:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          53588:                    if ((tp->t_flags & T_MODC)==0) { /* already not modem control? */
        !          53589:                        u.u_error = ENODEV;     /* yes, don't allow open */     
        !          53590:                        return;
        !          53591:                    }
        !          53592:                } else {                         /* don't want modem control */
        !          53593:                        if (tp->t_flags & T_MODC) { /* already modem control? */
        !          53594:                                u.u_error = ENODEV; /* yes, don't allow open */
        !          53595:                                return;
        !          53596:                        }
        !          53597:                }
        !          53598:        }
        !          53599:        tp->t_open++;
        !          53600:        ttsetgrp(tp, dev);
        !          53601: 
        !          53602:        /*
        !          53603:         * now that we've successfully opened, designate port as
        !          53604:         * polled or interrupt driven to avoid future conflicts
        !          53605:         */
        !          53606:        if (dev & CPOLL) {
        !          53607:                com_usage[AL_NUM] = COM_POLLED;
        !          53608:                set_poll_rate();
        !          53609:        } else {                                /* irq-driven port */
        !          53610:                com_usage[AL_NUM] = COM_IRQ;
        !          53611:        }
        !          53612: 
        !          53613:        CDUMP((dev&CPOLL)?"open polled":"open irq")
        !          53614: }
        !          53615: 
        !          53616: alxclose(dev, mode, tp)
        !          53617: dev_t  dev;
        !          53618: int    mode;
        !          53619: TTY    *tp;
        !          53620: {
        !          53621:        register unsigned holdflags;
        !          53622:        register int b;
        !          53623:        int state, maj;
        !          53624: 
        !          53625:        /*
        !          53626:         * Called at high priority by alclose after al_buff is drained
        !          53627:         */
        !          53628:        holdflags = tp->t_flags;       /* save flags */
        !          53629:        ttclose(tp);                   /* clear flags */
        !          53630:        b = ALPORT;
        !          53631: 
        !          53632:        /*
        !          53633:         * If not hanging in open
        !          53634:         */
        !          53635:        if ( (holdflags & T_HOPEN) == 0 ) {
        !          53636:                /*
        !          53637:                 * Disable all ints except TxI
        !          53638:                 */
        !          53639:                outb(b+IER, IE_TxI);
        !          53640:        } else {
        !          53641:                /*
        !          53642:                 * Flags for first open
        !          53643:                 */
        !          53644:                tp->t_flags = T_MODC | T_HOPEN;
        !          53645:        }
        !          53646: 
        !          53647:        /*
        !          53648:         * If hupcls
        !          53649:         */
        !          53650:        if (holdflags & T_HPCL) {
        !          53651:                /*
        !          53652:                 * Hangup port
        !          53653:                 */
        !          53654:                outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          53655:                /*
        !          53656:                 * Hold dtr low for timeout
        !          53657:                 */
        !          53658:                maj = major(dev);
        !          53659:                drvl[maj].d_time = 1;
        !          53660:                sleep((char *)&drvl[maj].d_time, CVTTOUT, IVTTOUT, SVTTOUT);
        !          53661:                drvl[maj].d_time = 0;
        !          53662:        }
        !          53663:        /*
        !          53664:         * ttclose() only emptied the output queue tp->t_oq;
        !          53665:         * now wait for the silo tp->rawout to empty
        !          53666:         * and allow a delay for the UART on-chip xmit buffer to empty
        !          53667:         * state 2: waiting for silo to empty
        !          53668:         * state 1: stalling so UART can empty xmit buffer
        !          53669:         * state 0: done!  ok to shut off IRQ for this chip by clearing MC_OUT2
        !          53670:         */
        !          53671:        state = 2;
        !          53672:        while (state) {
        !          53673:                timeout(&AL_TIM, 10, wakeup, (int)&AL_TIM);
        !          53674:                sleep((char *)&AL_TIM, CVTTOUT, IVTTOUT, SVTTOUT);
        !          53675:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          53676:                        state--;
        !          53677:        }
        !          53678:        outb(b+MCR, 0);
        !          53679:        com_usage[AL_NUM] = COM_UNUSED;
        !          53680:        set_poll_rate();
        !          53681:        CDUMP("closed")
        !          53682: }
        !          53683: 
        !          53684: /*
        !          53685:  * Common c_timer routine for async ports.
        !          53686:  */
        !          53687: alxtimer(dev)
        !          53688: dev_t dev;
        !          53689: {
        !          53690:        if ( ++drvl[major(dev)].d_time > DTRTMOUT )
        !          53691:                wakeup((char *)&drvl[major(dev)].d_time);
        !          53692: }
        !          53693: 
        !          53694: 
        !          53695: /*
        !          53696:  * Common c_ioctl routine for async ports.
        !          53697:  */
        !          53698: alxioctl(dev, com, vec, tp)
        !          53699: dev_t  dev;
        !          53700: struct sgttyb *vec;
        !          53701: register TTY   *tp;
        !          53702: {
        !          53703:        register int    s, b;
        !          53704:        int stat1, stat2;
        !          53705: 
        !          53706:        s = sphi();
        !          53707:        b = ALPORT;
        !          53708:        stat1 = inb(b+MCR);             /* get current MCR register status */
        !          53709:        stat2 = inb(b+LCR);             /* get current LCR register status */
        !          53710: 
        !          53711:        switch(com) {
        !          53712:        case TIOCSBRK:                  /* set BREAK */         
        !          53713:                outb(b+LCR, stat2|LC_SBRK);
        !          53714:                break;
        !          53715:        case TIOCCBRK:                  /* clear BREAK */
        !          53716:                outb(b+LCR, stat2 & ~LC_SBRK);
        !          53717:                break;
        !          53718:        case TIOCSDTR:                  /* set DTR */
        !          53719:                outb(b+MCR, stat1|MC_DTR);
        !          53720:                break;  
        !          53721:        case TIOCCDTR:                  /* clear DTR */
        !          53722:                outb(b+MCR, stat1 & ~MC_DTR);   
        !          53723:                break;
        !          53724:        case TIOCSRTS:                  /* set RTS */
        !          53725:                outb(b+MCR, stat1|MC_RTS);      
        !          53726:                break;
        !          53727:        case TIOCCRTS:                  /* clear RTS */
        !          53728:                outb(b+MCR, stat1 & ~MC_RTS);   
        !          53729:                break;  
        !          53730:        case TIOCRSPEED:                /* set "raw" I/O speed divisor */
        !          53731:                outb(b+LCR, stat2|LC_DLAB);  /* set speed latch bit */
        !          53732:                outb(b+DLL, (unsigned) vec);
        !          53733:                outb(b+DLH, (unsigned) vec >> 8);
        !          53734:                outb(b+LCR, stat2);       /* reset latch bit */
        !          53735:                break;
        !          53736:        case TIOCWORDL:         /* set word length and stop bits */
        !          53737:                outb(b+LCR, ((stat2&~0x7) | ((unsigned) vec & 0x7)));
        !          53738:                break;
        !          53739:        case TIOCRMSR:          /* get CTS/DSR/RI/RLSD (MSR) */
        !          53740:                stat1 = inb(b+MSR) >> 4;
        !          53741:                kucopy(&stat1, (unsigned *) vec, sizeof(unsigned));
        !          53742:                break;  
        !          53743:        default:
        !          53744:                ttioctl(tp, com, vec);
        !          53745:        }
        !          53746:        spl(s);
        !          53747: }
        !          53748: 
        !          53749: alxparam(tp)
        !          53750: TTY    *tp;
        !          53751: {
        !          53752:        register int    b;
        !          53753:        register int    baud;
        !          53754:        int s;
        !          53755: 
        !          53756:        b = ALPORT;
        !          53757: 
        !          53758:        /*
        !          53759:         * error if input speed not the same as output speed
        !          53760:         */
        !          53761:        if (tp->t_sgttyb.sg_ispeed!=tp->t_sgttyb.sg_ospeed) {
        !          53762:                u.u_error = ENODEV;       
        !          53763:                return;
        !          53764:        }
        !          53765: 
        !          53766:        if ((baud = albaud[tp->t_sgttyb.sg_ispeed]) == 0) {
        !          53767:                if (tp->t_flags & T_MODC) {  /* modem control? */
        !          53768:                        tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          53769:                        outb(b+MCR, inb(b+MCR) & MC_OUT2); /* hangup */
        !          53770:                }
        !          53771:        }
        !          53772: 
        !          53773:        if (baud) {
        !          53774:                char ier_save=inb(b+IER);       /* some chips need this */
        !          53775: 
        !          53776:                s=sphi();
        !          53777:                outb(b+LCR, LC_DLAB);
        !          53778:                outb(b+DLL, baud);
        !          53779:                outb(b+DLH, baud >> 8);
        !          53780:                switch (tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW)) {
        !          53781:                case EVENP:
        !          53782:                        outb(b+LCR, LC_CS7 + LC_PARENB + LC_PAREVEN );
        !          53783:                        break;
        !          53784: 
        !          53785:                case ODDP:
        !          53786:                        outb(b+LCR, LC_CS7 + LC_PARENB );
        !          53787:                        break;
        !          53788: 
        !          53789:                default:
        !          53790:                        outb(b+LCR, LC_CS8 );
        !          53791:                        break;
        !          53792:                }
        !          53793:                outb(b+IER, ier_save);
        !          53794:                spl(s);
        !          53795:        }
        !          53796:        set_poll_rate();
        !          53797: }
        !          53798: 
        !          53799: /*
        !          53800:  * Middle level processor.
        !          53801:  *
        !          53802:  *     Invoked 10 times per second.
        !          53803:  *     Checks modem status for loss of carrier.
        !          53804:  *     Tranfers rawin buffer [from intr level] to canonical input queue.
        !          53805:  *     Transfers output queue to rawout buffer [for intr level].
        !          53806:  */
        !          53807: alxcycle( tp )
        !          53808: register TTY * tp;
        !          53809: {
        !          53810:        register int b;
        !          53811:        register int n;
        !          53812: 
        !          53813:        /*
        !          53814:         * Check modem status every clock tick.
        !          53815:         * Modem status interrupts are not enabled due to 8250 hardware bug.
        !          53816:         * Enabling modem status and receive interrupts may cause lockup.
        !          53817:         */
        !          53818:        if ( tp->t_flags & T_MODC ) {
        !          53819: 
        !          53820:                /*
        !          53821:                 * Get status
        !          53822:                 */
        !          53823:                b = inb(ALPORT+MSR);
        !          53824: 
        !          53825:                /*
        !          53826:                 * Carrier changed.
        !          53827:                 */
        !          53828:                if ( b & MS_DRLSD ) {
        !          53829:                        /*
        !          53830:                         * wakeup open
        !          53831:                         */
        !          53832:                        if ( tp->t_open == 0 ) {
        !          53833:                                wakeup((char *)(&tp->t_open));
        !          53834:                        }
        !          53835: 
        !          53836:                        /*
        !          53837:                         * carrier off?
        !          53838:                         */
        !          53839:                        else if ( (b & MS_RLSD) == 0 ) {
        !          53840:                                /*
        !          53841:                                 * clear carrier flag; send hangup signal
        !          53842:                                 */
        !          53843:                                tp->t_rawin.si_ox = tp->t_rawin.si_ix;
        !          53844:                                tthup( tp );
        !          53845:                        }
        !          53846:                }
        !          53847:        }
        !          53848: 
        !          53849:        /*
        !          53850:         * Empty raw input buffer.
        !          53851:         */
        !          53852:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          53853:                ttin( tp, tp->t_rawin.si_buf[ tp->t_rawin.si_ox ] );
        !          53854:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          53855:                        tp->t_rawin.si_ox = 0;
        !          53856:                else
        !          53857:                        tp->t_rawin.si_ox++;
        !          53858:        }
        !          53859: 
        !          53860:        /*
        !          53861:         * Calculate free output slot count.
        !          53862:         */
        !          53863:        n  = sizeof(tp->t_rawout.si_buf) - 1;
        !          53864:        n += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          53865:        n %= sizeof(tp->t_rawout.si_buf);
        !          53866: 
        !          53867:        /*
        !          53868:         * Fill raw output buffer.
        !          53869:         */
        !          53870:        while ( (--n >= 0) && ((b = ttout(tp)) >= 0) ) {
        !          53871:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = b;
        !          53872:                if ( tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1 )
        !          53873:                        tp->t_rawout.si_ix = 0;
        !          53874:                else
        !          53875:                        tp->t_rawout.si_ix++;
        !          53876:        }
        !          53877: 
        !          53878:        /*
        !          53879:         * (Re)start output, wake sleeping processes, etc.
        !          53880:         */
        !          53881:        ttstart( tp );
        !          53882: 
        !          53883:        /*
        !          53884:         * Schedule next cycle.
        !          53885:         */
        !          53886:        timeout( &tp->t_rawtim, HZ/10, alxcycle, tp );
        !          53887: }
        !          53888: 
        !          53889: /*
        !          53890:  * Serial Transmit Start Routine.
        !          53891:  */
        !          53892: alxstart( tp )
        !          53893: register TTY * tp;
        !          53894: {
        !          53895:        register int b;
        !          53896:        register int s;
        !          53897:        extern alxbreak();
        !          53898: 
        !          53899:        /*
        !          53900:         * Read line status register AFTER disabling interrupts.
        !          53901:         */
        !          53902:        s = sphi();
        !          53903:        b = inb(ALPORT+LSR);
        !          53904: 
        !          53905:        /*
        !          53906:         * Process break indication.
        !          53907:         * NOTE: Break indication cleared when line status register was read.
        !          53908:         */
        !          53909:        if ( b & LS_BREAK )
        !          53910:                defer( alxbreak, tp );
        !          53911: 
        !          53912:        /*
        !          53913:         * Transmitter is empty, output data is pending.
        !          53914:         */
        !          53915:        if ( (b & LS_TxRDY) && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          53916:                outb(   ALPORT+DREG,
        !          53917:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          53918:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          53919:                        tp->t_rawout.si_ox = 0;
        !          53920:        }
        !          53921:        spl( s );
        !          53922: }
        !          53923: 
        !          53924: /*
        !          53925:  * Serial Received Break Handler.
        !          53926:  */
        !          53927: alxbreak( tp )
        !          53928: register TTY * tp;
        !          53929: {
        !          53930:        ttsignal( tp, SIGINT );
        !          53931: }
        !          53932: 
        !          53933: /*
        !          53934:  * Serial Interrupt Handler.
        !          53935:  */
        !          53936: alxintr( tp )
        !          53937: register TTY * tp;
        !          53938: {
        !          53939:        register int    b;
        !          53940: 
        !          53941: rescan:
        !          53942:        switch ( inb(ALPORT+IIR) ) {
        !          53943: 
        !          53944:        case LS_INTR:
        !          53945:                if ( inb(ALPORT+LSR) & LS_BREAK )
        !          53946:                        defer( alxbreak, tp );
        !          53947:                goto rescan;
        !          53948: 
        !          53949:        case Rx_INTR:
        !          53950:                b = inb(ALPORT+DREG);
        !          53951:                if ( tp->t_open == 0 )
        !          53952:                        goto rescan;
        !          53953:                /*
        !          53954:                 * Must recognize XOFF quickly to avoid transmit overrun.
        !          53955:                 * Recognize XON here as well to avoid race conditions.
        !          53956:                 */
        !          53957:                if ( (tp->t_sgttyb.sg_flags & RAWIN) == 0 ) {
        !          53958:                        /*
        !          53959:                         * XOFF.
        !          53960:                         */
        !          53961:                        if ( tp->t_tchars.t_stopc == (b & 0177) ) {
        !          53962:                                tp->t_flags |= T_STOP;
        !          53963:                                goto rescan;
        !          53964:                        }
        !          53965: 
        !          53966:                        /*
        !          53967:                         * XON.
        !          53968:                         */
        !          53969:                        if ( tp->t_tchars.t_startc == (b & 0177) ) {
        !          53970:                                tp->t_flags &= ~T_STOP;
        !          53971:                                goto rescan;
        !          53972:                        }
        !          53973:                }
        !          53974: 
        !          53975:                /*
        !          53976:                 * Save char in raw input buffer.
        !          53977:                 */
        !          53978:                tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          53979:                if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          53980:                        tp->t_rawin.si_ix = 0;
        !          53981:                goto rescan;
        !          53982: 
        !          53983:        case Tx_INTR:
        !          53984:                /*
        !          53985:                 * Do nothing if no raw output data or output is stopped.
        !          53986:                 */
        !          53987:                if ( tp->t_rawout.si_ix == tp->t_rawout.si_ox ) {
        !          53988:                        goto rescan;
        !          53989:                }
        !          53990:                if ( tp->t_flags & T_STOP )
        !          53991:                        goto rescan;
        !          53992: 
        !          53993:                /*
        !          53994:                 * Transmit next char in raw output buffer.
        !          53995:                 */
        !          53996:                outb(   ALPORT+DREG,
        !          53997:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          53998: 
        !          53999:                /*
        !          54000:                 * Adjust raw output buffer output index.
        !          54001:                 */
        !          54002:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          54003:                        tp->t_rawout.si_ox = 0;
        !          54004: 
        !          54005:                /*
        !          54006:                 * Try to fill buffer if now empty.
        !          54007:                 */
        !          54008:                if ( tp->t_rawout.si_ox == tp->t_rawout.si_ix ) {
        !          54009:                        defer( alxcycle, tp );
        !          54010:                }
        !          54011:                goto rescan;
        !          54012:        }
        !          54013: }
        !          54014: 
        !          54015: /*
        !          54016:  * alxclk will be called every time T0 interrupts - if it returns 0,
        !          54017:  * the usual system timer interrupt stuff is done
        !          54018:  */
        !          54019: static int alxclk()
        !          54020: {
        !          54021:        static int count;
        !          54022:        int i;
        !          54023: 
        !          54024:        for (i = 0; i < NUM_AL_PORTS;  i++)
        !          54025:                if (com_usage[i] == COM_POLLED)
        !          54026:                        alxintr(tp_table[i]);
        !          54027:        count++;
        !          54028:        if (count >= poll_divisor)
        !          54029:                count = 0;
        !          54030:        return count;
        !          54031: }
        !          54032: 
        !          54033: /*
        !          54034:  * set_poll_rate is called when a port is opened or closed or changes speed
        !          54035:  * it sets the polling rate only as fast as needed, and shuts off polling
        !          54036:  * whenever possible
        !          54037:  */
        !          54038: static set_poll_rate()
        !          54039: {
        !          54040:        int port_num, max_rate, port_rate;
        !          54041: 
        !          54042:        /*
        !          54043:         * If another driver has the polling clock, do nothing.
        !          54044:         */
        !          54045:        if (poll_owner & ~ POLL_AL)
        !          54046:                return;
        !          54047: 
        !          54048:        /*
        !          54049:         * find highest valid polling rate in units of HZ/10
        !          54050:         */
        !          54051:        max_rate = 0;
        !          54052:        for (port_num = 0; port_num < NUM_AL_PORTS; port_num++) {
        !          54053:                if (com_usage[port_num] == COM_POLLED) {
        !          54054:                        port_rate = alp_rate[(tp_table[port_num])->t_sgttyb.sg_ispeed];
        !          54055:                        if (max_rate < port_rate)
        !          54056:                                max_rate = port_rate;
        !          54057:                }
        !          54058:        }
        !          54059:        /*
        !          54060:         * if max_rate is not current rate, adjust the system clock
        !          54061:         */
        !          54062:        if (max_rate != poll_rate) {
        !          54063:                poll_rate = max_rate;
        !          54064:                poll_divisor = poll_rate/HZ;  /* used in alxclk() */
        !          54065:                altclk_out();           /* stop previous polling */
        !          54066:                poll_owner &= ~ POLL_AL;
        !          54067:                if (max_rate) { /* resume polling at new rate if needed */
        !          54068:                        poll_owner |= POLL_AL;
        !          54069:                        altclk_in(poll_rate, alxclk);
        !          54070:                }
        !          54071:                CDUMP("new rate")
        !          54072:        }
        !          54073: }
        !          54074: @
        !          54075: 0707070064030104001004440000030000030000011777770507310666100006100000040615/newbits/kernel/USRSRC/i8086/drv/RCS/alx.c.esa,vhead     1.1;
        !          54076: access   ;
        !          54077: symbols  ;
        !          54078: locks    bin:1.1;
        !          54079: comment  @ * @;
        !          54080: 
        !          54081: 
        !          54082: 1.1
        !          54083: date     91.06.10.14.46.06;  author bin;  state Exp;
        !          54084: branches ;
        !          54085: next   ;
        !          54086: 
        !          54087: 
        !          54088: desc
        !          54089: @initial version prov by hal
        !          54090: @
        !          54091: 
        !          54092: 
        !          54093: 
        !          54094: 1.1
        !          54095: log
        !          54096: @Initial revision
        !          54097: @
        !          54098: text
        !          54099: @/* (-lgl
        !          54100:  *     COHERENT Driver Kit Version 1.1.0
        !          54101:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          54102:  *     All rights reserved. May not be copied without permission.
        !          54103:  *
        !          54104:  * Add IE_ALL bit mask and use it when checking for UART existence.
        !          54105:  * Save delta status of CD - but not on per port basis.
        !          54106:  * Fix unconditional "hupcl" bug in 3.1.0 version.
        !          54107:  * Add RTS handshaking.
        !          54108:  * Add CTS handshaking.
        !          54109:  * Save and restore IER during alxioctl() call as well as alxparam().
        !          54110:  -lgl) */
        !          54111: /*
        !          54112:  * Shared parts of IBM async port drivers.
        !          54113:  */
        !          54114: #include <coherent.h>
        !          54115: #include <i8086.h>
        !          54116: #include <al.h>
        !          54117: #include <con.h>
        !          54118: #include <errno.h>
        !          54119: #include <stat.h>
        !          54120: #include <tty.h>
        !          54121: #include <uproc.h>
        !          54122: #include <sys/timeout.h>
        !          54123: #include <clist.h>
        !          54124: #include <ins8250.h>
        !          54125: #include <sched.h>
        !          54126: 
        !          54127: #define ALPORT (((COM_DDP *)(tp->t_ddp))->port)
        !          54128: #define AL_TIM (((COM_DDP *)(tp->t_ddp))->tim)
        !          54129: #define AL_NUM (((COM_DDP *)(tp->t_ddp))->com_num)
        !          54130: 
        !          54131: #define DTRTMOUT  3    /* DTR timeout interval in seconds for close */
        !          54132: #define        IENABLE (IE_RxI+IE_TxI+IE_LSI)
        !          54133: #define IE_ALL (IE_RxI|IE_TxI|IE_LSI|IE_MSI)
        !          54134: 
        !          54135: int    al_sg_set = 0;
        !          54136: int    al_sg_clr = 0;
        !          54137: static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          54138: static int drlsd;      /* delta carrier detect - set by alxintr(), read
        !          54139:                           by alxcycle() */
        !          54140: static int rawin_ct;   /* number of characters in input silo */                           
        !          54141: static int want_rts;
        !          54142: 
        !          54143: /*
        !          54144:  * functions herein
        !          54145:  */
        !          54146: int    alxopen();
        !          54147: int    alxclose();
        !          54148: int    alxtimer();
        !          54149: int    alxioctl();
        !          54150: int    alxparam();
        !          54151: int    alxcycle();
        !          54152: int    alxstart();
        !          54153: int    alxbreak();
        !          54154: int    alxintr();
        !          54155: static int     alxclk();
        !          54156: static set_poll_rate();
        !          54157: 
        !          54158: /*
        !          54159:  * Baud rate table and polling rate table.
        !          54160:  * Indexed by ioctl bit rates.
        !          54161:  */
        !          54162: int albaud[] ={
        !          54163:        0,                              /* 0 */
        !          54164:        2304,                           /* 50 */
        !          54165:        1536,                           /* 75 */
        !          54166:        1047,                           /* 110 */
        !          54167:        857,                            /* 134.5 */
        !          54168:        768,                            /* 150 */
        !          54169:        576,                            /* 200 */
        !          54170:        384,                            /* 300 */
        !          54171:        192,                            /* 600 */
        !          54172:        96,                             /* 1200 */
        !          54173:        64,                             /* 1800 */
        !          54174:        58,                             /* 2000 */
        !          54175:        48,                             /* 2400 */
        !          54176:        32,                             /* 3600 */
        !          54177:        24,                             /* 4800 */
        !          54178:        16,                             /* 7200 */
        !          54179:        12,                             /* 9600 */
        !          54180:        6,                              /* 19200 */
        !          54181:        0,                              /* EXTA */
        !          54182:        0                               /* EXTB */
        !          54183: };
        !          54184: 
        !          54185: /*
        !          54186:  *     alp_rate[] is tied to albaud[] - it gives the minimum polling
        !          54187:  *     rate for the corresponding port speed; it must be a multiple
        !          54188:  *     of 100 (system clock Hz) and >= baud/6
        !          54189:  */
        !          54190: int alp_rate[] ={                      /* baud/6 or zero */
        !          54191:        0,                              /* 0 */
        !          54192:        1*HZ,                           /* 50 */
        !          54193:        1*HZ,                           /* 75 */
        !          54194:        1*HZ,                           /* 110 */
        !          54195:        1*HZ,                           /* 134.5 */
        !          54196:        1*HZ,                           /* 150 */
        !          54197:        1*HZ,                           /* 200 */
        !          54198:        1*HZ,                           /* 300 */
        !          54199:        1*HZ,                           /* 600 */
        !          54200:        2*HZ,                           /* 1200 */
        !          54201:        3*HZ,                           /* 1800 */
        !          54202:        4*HZ,                           /* 2000 */
        !          54203:        4*HZ,                           /* 2400 */
        !          54204:        6*HZ,                           /* 3600 */
        !          54205:        8*HZ,                           /* 4800 */
        !          54206:        12*HZ,                          /* 7200 */
        !          54207:        16*HZ,                          /* 9600 */
        !          54208:        0,                              /* 19200 */
        !          54209:        0,                              /* EXTA */
        !          54210:        0                               /* EXTB */
        !          54211: };
        !          54212: 
        !          54213: /*
        !          54214:  *     the following is for debug only
        !          54215:  */
        !          54216: #if 0
        !          54217: #define CDUMP(text)    cdump(text);
        !          54218: 
        !          54219: cdump(message)
        !          54220: char *message;
        !          54221: {
        !          54222:        int i, b;
        !          54223: 
        !          54224:        for (i = 0; i < NUM_AL_PORTS; i++) {
        !          54225:                b = ((COM_DDP *)(tp_table[i]->t_ddp))->port;
        !          54226:                printf("%x:%x:%x:%x ", i+1, b, inb(b+MCR), inb(b+IER));
        !          54227:        }
        !          54228:        printf("poll=%d ", poll_rate);
        !          54229:        printf("%s\n", message);
        !          54230: }
        !          54231: #else
        !          54232: #define CDUMP(text)
        !          54233: #endif
        !          54234: 
        !          54235: alxopen(dev, mode, tp, irqtty)
        !          54236: dev_t  dev;
        !          54237: int    mode;
        !          54238: register TTY   *tp, **irqtty;
        !          54239: {
        !          54240:        register int    s;
        !          54241:        register int    b;
        !          54242:        register int    minor_h;  /* minor device number including high bit */
        !          54243: 
        !          54244:        minor_h = minor(dev);     /* complete minor number */
        !          54245: 
        !          54246:        b = ALPORT;
        !          54247: 
        !          54248:        if ( inb(b+IER) & ~IE_ALL ) { /* chip not found */
        !          54249:                u.u_error = ENXIO;
        !          54250:                return;
        !          54251:        }
        !          54252: 
        !          54253:        if ((tp->t_flags & T_EXCL) && !super()) {
        !          54254:                u.u_error = ENODEV;
        !          54255:                return;
        !          54256:        }
        !          54257: 
        !          54258:        if (drvl[major(dev)].d_time != 0) {     /* Modem settling */
        !          54259:                u.u_error = EDBUSY;
        !          54260:                return;
        !          54261:        }
        !          54262: 
        !          54263:        /*
        !          54264:         * Can't open a polled port if another driver is using polling.
        !          54265:         */
        !          54266:        if (dev & CPOLL && poll_owner & ~ POLL_AL) {
        !          54267:                u.u_error = EDBUSY;
        !          54268:                return;
        !          54269:        }
        !          54270: 
        !          54271:        /*
        !          54272:         * exclusion conditions:
        !          54273:         *      can't have same port polled and IRQ at once
        !          54274:         *      can't have both com[13] or both com[24] IRQ at once 
        !          54275:         */
        !          54276:        if (dev & CPOLL) {
        !          54277:                if (com_usage[AL_NUM] == COM_IRQ) {
        !          54278:                        u.u_error = EDBUSY;
        !          54279:                        return;
        !          54280:                }
        !          54281:        } else {
        !          54282:                if (com_usage[AL_NUM] == COM_POLLED
        !          54283:                   || com_usage[AL_NUM ^ 2] == COM_IRQ) {
        !          54284:                        u.u_error = EDBUSY;
        !          54285:                        return;
        !          54286:                }
        !          54287:        }
        !          54288: 
        !          54289:        if (tp->t_open == 0) {        /* not already open */
        !          54290:                s = sphi();
        !          54291:                /*
        !          54292:                 * Raise basic modem control lines even if modem
        !          54293:                 * control hasn't been specified.
        !          54294:                 * MC_OUT2 turns on NON-open-collector IRQ line from the UART.
        !          54295:                 * since we can't have two UART's on same IRQ with MC_OUT2 on
        !          54296:                 */
        !          54297:                if (dev & CPOLL)
        !          54298:                        outb(b+MCR, MC_RTS|MC_DTR);
        !          54299:                else {
        !          54300:                        *irqtty = tp_table[AL_NUM];
        !          54301:                        outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          54302:                }
        !          54303:                want_rts = 1;
        !          54304:        
        !          54305:                outb(b+IER, IENABLE);        /* enable interrupts */
        !          54306:        
        !          54307:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          54308:                        tp->t_flags |= T_MODC | T_HOPEN; /* yes, set flags */
        !          54309:                        while ((inb(b+MSR) & MS_RLSD) == 0) { /* no carrier? */
        !          54310:                                sleep((char *)(&tp->t_open), CVTTOUT, IVTTOUT,
        !          54311:                                        SVTTOUT);       /* wait for carrier */
        !          54312:                                if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          54313:                                        outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          54314:                                        want_rts = 0;
        !          54315:                                        /*
        !          54316:                                         * make sure port is hungup
        !          54317:                                         * disable all ints except for TxI
        !          54318:                                         */
        !          54319:                                        outb(b+IER, IE_TxI);
        !          54320:                                        u.u_error = EINTR;
        !          54321:                                        spl(s);
        !          54322:                                        return;
        !          54323:                                }
        !          54324:                        }
        !          54325:                        tp->t_flags &= ~T_HOPEN; /* no longer hanging in open */
        !          54326:                } else {
        !          54327:                        tp->t_flags &= ~T_MODC;         /* no modem control */ 
        !          54328:                }
        !          54329:                tp->t_flags |= T_CARR;                  /* carrier on */
        !          54330:                ttopen(tp);                             /* stty inits */
        !          54331: 
        !          54332:                /*
        !          54333:                 * Allow custom modification of defaults.
        !          54334:                 */
        !          54335:                tp->t_sgttyb.sg_flags |=  al_sg_set;
        !          54336:                tp->t_sgttyb.sg_flags &= ~al_sg_clr;
        !          54337:                alxparam(tp);
        !          54338:                spl(s);
        !          54339:        } else {                                /* already open */
        !          54340:                if ((minor_h & NMODC) == 0) {   /* want modem control? */
        !          54341:                    if ((tp->t_flags & T_MODC)==0) { /* already not modem control? */
        !          54342:                        u.u_error = ENODEV;     /* yes, don't allow open */     
        !          54343:                        return;
        !          54344:                    }
        !          54345:                } else {                         /* don't want modem control */
        !          54346:                        if (tp->t_flags & T_MODC) { /* already modem control? */
        !          54347:                                u.u_error = ENODEV; /* yes, don't allow open */
        !          54348:                                return;
        !          54349:                        }
        !          54350:                }
        !          54351:        }
        !          54352:        tp->t_open++;
        !          54353:        ttsetgrp(tp, dev);
        !          54354: 
        !          54355:        /*
        !          54356:         * now that we've successfully opened, designate port as
        !          54357:         * polled or interrupt driven to avoid future conflicts
        !          54358:         */
        !          54359:        if (dev & CPOLL) {
        !          54360:                com_usage[AL_NUM] = COM_POLLED;
        !          54361:                set_poll_rate();
        !          54362:        } else {                                /* irq-driven port */
        !          54363:                com_usage[AL_NUM] = COM_IRQ;
        !          54364:        }
        !          54365: 
        !          54366:        CDUMP((dev&CPOLL)?"open polled":"open irq")
        !          54367: }
        !          54368: 
        !          54369: alxclose(dev, mode, tp)
        !          54370: dev_t  dev;
        !          54371: int    mode;
        !          54372: TTY    *tp;
        !          54373: {
        !          54374:        register unsigned holdflags;
        !          54375:        register int b;
        !          54376:        int state, maj;
        !          54377: 
        !          54378:        /*
        !          54379:         * Called at high priority by alclose after al_buff is drained
        !          54380:         */
        !          54381:        holdflags = tp->t_flags;       /* save flags */
        !          54382:        ttclose(tp);                   /* clear flags */
        !          54383:        b = ALPORT;
        !          54384: 
        !          54385:        /*
        !          54386:         * If not hanging in open
        !          54387:         */
        !          54388:        if ( (holdflags & T_HOPEN) == 0 ) {
        !          54389:                /*
        !          54390:                 * Disable all ints except TxI
        !          54391:                 */
        !          54392:                outb(b+IER, IE_TxI);
        !          54393:        } else {
        !          54394:                /*
        !          54395:                 * Flags for first open
        !          54396:                 */
        !          54397:                tp->t_flags = T_MODC | T_HOPEN;
        !          54398:        }
        !          54399: 
        !          54400:        /*
        !          54401:         * If hupcls
        !          54402:         */
        !          54403:        if (holdflags & T_HPCL) {
        !          54404:                /*
        !          54405:                 * Hangup port
        !          54406:                 */
        !          54407:                outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          54408:                want_rts = 0;
        !          54409:                /*
        !          54410:                 * Hold dtr low for timeout
        !          54411:                 */
        !          54412:                maj = major(dev);
        !          54413:                drvl[maj].d_time = 1;
        !          54414:                sleep((char *)&drvl[maj].d_time, CVTTOUT, IVTTOUT, SVTTOUT);
        !          54415:                drvl[maj].d_time = 0;
        !          54416:        }
        !          54417:        /*
        !          54418:         * ttclose() only emptied the output queue tp->t_oq;
        !          54419:         * now wait for the silo tp->rawout to empty
        !          54420:         * and allow a delay for the UART on-chip xmit buffer to empty
        !          54421:         * state 2: waiting for silo to empty
        !          54422:         * state 1: stalling so UART can empty xmit buffer
        !          54423:         * state 0: done!  ok to shut off IRQ for this chip by clearing MC_OUT2
        !          54424:         */
        !          54425:        state = 2;
        !          54426:        while (state) {
        !          54427:                timeout(&AL_TIM, 10, wakeup, (int)&AL_TIM);
        !          54428:                sleep((char *)&AL_TIM, CVTTOUT, IVTTOUT, SVTTOUT);
        !          54429:                if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          54430:                        state--;
        !          54431:        }
        !          54432:        /*
        !          54433:         * Turn off MC_OUT2 so IRQ can be used by other port.
        !          54434:         */
        !          54435:        outb(b+MCR, inb(b+MCR)&(~MC_OUT2));
        !          54436:        com_usage[AL_NUM] = COM_UNUSED;
        !          54437:        set_poll_rate();
        !          54438:        CDUMP("closed")
        !          54439: }
        !          54440: 
        !          54441: /*
        !          54442:  * Common c_timer routine for async ports.
        !          54443:  */
        !          54444: alxtimer(dev)
        !          54445: dev_t dev;
        !          54446: {
        !          54447:        if ( ++drvl[major(dev)].d_time > DTRTMOUT )
        !          54448:                wakeup((char *)&drvl[major(dev)].d_time);
        !          54449: }
        !          54450: 
        !          54451: 
        !          54452: /*
        !          54453:  * Common c_ioctl routine for async ports.
        !          54454:  */
        !          54455: alxioctl(dev, com, vec, tp)
        !          54456: dev_t  dev;
        !          54457: struct sgttyb *vec;
        !          54458: register TTY   *tp;
        !          54459: {
        !          54460:        register int    s, b;
        !          54461:        int stat1, stat2;
        !          54462:        char ier_save;
        !          54463: 
        !          54464:        s = sphi();
        !          54465:        ier_save=inb(b+IER);    /* some chips need this */
        !          54466:        b = ALPORT;
        !          54467:        stat1 = inb(b+MCR);             /* get current MCR register status */
        !          54468:        stat2 = inb(b+LCR);             /* get current LCR register status */
        !          54469: 
        !          54470:        switch(com) {
        !          54471:        case TIOCSBRK:                  /* set BREAK */         
        !          54472:                outb(b+LCR, stat2|LC_SBRK);
        !          54473:                break;
        !          54474:        case TIOCCBRK:                  /* clear BREAK */
        !          54475:                outb(b+LCR, stat2 & ~LC_SBRK);
        !          54476:                break;
        !          54477:        case TIOCSDTR:                  /* set DTR */
        !          54478:                outb(b+MCR, stat1|MC_DTR);
        !          54479:                break;  
        !          54480:        case TIOCCDTR:                  /* clear DTR */
        !          54481:                outb(b+MCR, stat1 & ~MC_DTR);   
        !          54482:                break;
        !          54483:        case TIOCSRTS:                  /* set RTS */
        !          54484:                outb(b+MCR, stat1|MC_RTS);      
        !          54485:                break;
        !          54486:        case TIOCCRTS:                  /* clear RTS */
        !          54487:                outb(b+MCR, stat1 & ~MC_RTS);   
        !          54488:                break;  
        !          54489:        case TIOCRSPEED:                /* set "raw" I/O speed divisor */
        !          54490:                outb(b+LCR, stat2|LC_DLAB);  /* set speed latch bit */
        !          54491:                outb(b+DLL, (unsigned) vec);
        !          54492:                outb(b+DLH, (unsigned) vec >> 8);
        !          54493:                outb(b+LCR, stat2);       /* reset latch bit */
        !          54494:                break;
        !          54495:        case TIOCWORDL:         /* set word length and stop bits */
        !          54496:                outb(b+LCR, ((stat2&~0x7) | ((unsigned) vec & 0x7)));
        !          54497:                break;
        !          54498:        case TIOCRMSR:          /* get CTS/DSR/RI/RLSD (MSR) */
        !          54499:                stat1 = inb(b+MSR) >> 4;
        !          54500:                kucopy(&stat1, (unsigned *) vec, sizeof(unsigned));
        !          54501:                break;  
        !          54502:        default:
        !          54503:                ttioctl(tp, com, vec);
        !          54504:        }
        !          54505:        outb(b+IER, ier_save);
        !          54506:        spl(s);
        !          54507: }
        !          54508: 
        !          54509: alxparam(tp)
        !          54510: TTY    *tp;
        !          54511: {
        !          54512:        register int    b;
        !          54513:        register int    baud;
        !          54514:        int s;
        !          54515: 
        !          54516:        b = ALPORT;
        !          54517: 
        !          54518:        /*
        !          54519:         * error if input speed not the same as output speed
        !          54520:         */
        !          54521:        if (tp->t_sgttyb.sg_ispeed!=tp->t_sgttyb.sg_ospeed) {
        !          54522:                u.u_error = ENODEV;       
        !          54523:                return;
        !          54524:        }
        !          54525: 
        !          54526:        if ((baud = albaud[tp->t_sgttyb.sg_ispeed]) == 0) {
        !          54527:                if (tp->t_flags & T_MODC) {  /* modem control? */
        !          54528:                        tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          54529:                        outb(b+MCR, inb(b+MCR) & MC_OUT2); /* hangup */
        !          54530:                        want_rts = 0;
        !          54531:                }
        !          54532:        }
        !          54533: 
        !          54534:        if (baud) {
        !          54535:                char ier_save=inb(b+IER);       /* some chips need this */
        !          54536: 
        !          54537:                s=sphi();
        !          54538:                outb(b+LCR, LC_DLAB);
        !          54539:                outb(b+DLL, baud);
        !          54540:                outb(b+DLH, baud >> 8);
        !          54541:                switch (tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW)) {
        !          54542:                case EVENP:
        !          54543:                        outb(b+LCR, LC_CS7 + LC_PARENB + LC_PAREVEN );
        !          54544:                        break;
        !          54545: 
        !          54546:                case ODDP:
        !          54547:                        outb(b+LCR, LC_CS7 + LC_PARENB );
        !          54548:                        break;
        !          54549: 
        !          54550:                default:
        !          54551:                        outb(b+LCR, LC_CS8 );
        !          54552:                        break;
        !          54553:                }
        !          54554:                outb(b+IER, ier_save);
        !          54555:                spl(s);
        !          54556:        }
        !          54557:        set_poll_rate();
        !          54558: }
        !          54559: 
        !          54560: /*
        !          54561:  * Middle level processor.
        !          54562:  *
        !          54563:  *     Invoked 10 times per second.
        !          54564:  *     Checks modem status for loss of carrier.
        !          54565:  *     Tranfers rawin buffer [from intr level] to canonical input queue.
        !          54566:  *     Transfers output queue to rawout buffer [for intr level].
        !          54567:  */
        !          54568: alxcycle( tp )
        !          54569: register TTY * tp;
        !          54570: {
        !          54571:        register int b;
        !          54572:        register int n;
        !          54573: 
        !          54574:        /*
        !          54575:         * Check modem status every clock tick.
        !          54576:         * Modem status interrupts are not enabled due to 8250 hardware bug.
        !          54577:         * Enabling modem status and receive interrupts may cause lockup.
        !          54578:         */
        !          54579:        if ( tp->t_flags & T_MODC ) {
        !          54580: 
        !          54581:                /*
        !          54582:                 * Get status
        !          54583:                 */
        !          54584:                b = inb(ALPORT+MSR);
        !          54585: 
        !          54586:                /*
        !          54587:                 * Carrier changed.
        !          54588:                 */
        !          54589:                if ((b & MS_DRLSD) || drlsd) {
        !          54590:                        drlsd = 0;
        !          54591:                        /*
        !          54592:                         * wakeup open
        !          54593:                         */
        !          54594:                        if ( tp->t_open == 0 ) {
        !          54595:                                wakeup((char *)(&tp->t_open));
        !          54596:                        }
        !          54597: 
        !          54598:                        /*
        !          54599:                         * carrier off?
        !          54600:                         */
        !          54601:                        else if ( (b & MS_RLSD) == 0 ) {
        !          54602:                                /*
        !          54603:                                 * clear carrier flag; send hangup signal
        !          54604:                                 */
        !          54605:                                tp->t_rawin.si_ox = tp->t_rawin.si_ix;
        !          54606:                                rawin_ct = 0;
        !          54607:                                tthup( tp );
        !          54608:                        }
        !          54609:                }
        !          54610:        }
        !          54611: 
        !          54612:        /*
        !          54613:         * Empty raw input buffer.
        !          54614:         */
        !          54615:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          54616:                ttin( tp, tp->t_rawin.si_buf[ tp->t_rawin.si_ox ] );
        !          54617:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          54618:                        tp->t_rawin.si_ox = 0;
        !          54619:                else
        !          54620:                        tp->t_rawin.si_ox++;
        !          54621:        }
        !          54622:        rawin_ct = 0;
        !          54623:        if (want_rts)
        !          54624:                outb(b+MCR, inb(b+MCR) | MC_RTS);
        !          54625: 
        !          54626:        /*
        !          54627:         * Calculate free output slot count.
        !          54628:         */
        !          54629:        n  = sizeof(tp->t_rawout.si_buf) - 1;
        !          54630:        n += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          54631:        n %= sizeof(tp->t_rawout.si_buf);
        !          54632: 
        !          54633:        /*
        !          54634:         * Fill raw output buffer.
        !          54635:         */
        !          54636:        while ( (--n >= 0) && ((b = ttout(tp)) >= 0) ) {
        !          54637:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = b;
        !          54638:                if ( tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1 )
        !          54639:                        tp->t_rawout.si_ix = 0;
        !          54640:                else
        !          54641:                        tp->t_rawout.si_ix++;
        !          54642:        }
        !          54643: 
        !          54644:        /*
        !          54645:         * (Re)start output, wake sleeping processes, etc.
        !          54646:         */
        !          54647:        ttstart( tp );
        !          54648: 
        !          54649:        /*
        !          54650:         * Schedule next cycle.
        !          54651:         */
        !          54652:        timeout( &tp->t_rawtim, HZ/10, alxcycle, tp );
        !          54653: }
        !          54654: 
        !          54655: /*
        !          54656:  * Serial Transmit Start Routine.
        !          54657:  */
        !          54658: alxstart( tp )
        !          54659: register TTY * tp;
        !          54660: {
        !          54661:        register int b;
        !          54662:        register int s;
        !          54663:        extern alxbreak();
        !          54664: 
        !          54665:        /*
        !          54666:         * Read line status register AFTER disabling interrupts.
        !          54667:         */
        !          54668:        s = sphi();
        !          54669:        b = inb(ALPORT+LSR);
        !          54670: 
        !          54671:        /*
        !          54672:         * Process break indication.
        !          54673:         * NOTE: Break indication cleared when line status register was read.
        !          54674:         */
        !          54675:        if ( b & LS_BREAK )
        !          54676:                defer( alxbreak, tp );
        !          54677: 
        !          54678:        /*
        !          54679:         * Transmitter is empty, output data is pending.
        !          54680:         */
        !          54681:        if ( (b & LS_TxRDY) && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          54682:                outb(   ALPORT+DREG,
        !          54683:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          54684:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          54685:                        tp->t_rawout.si_ox = 0;
        !          54686:        }
        !          54687:        spl( s );
        !          54688: }
        !          54689: 
        !          54690: /*
        !          54691:  * Serial Received Break Handler.
        !          54692:  */
        !          54693: alxbreak( tp )
        !          54694: register TTY * tp;
        !          54695: {
        !          54696:        ttsignal( tp, SIGINT );
        !          54697: }
        !          54698: 
        !          54699: /*
        !          54700:  * Serial Interrupt Handler.
        !          54701:  */
        !          54702: alxintr( tp )
        !          54703: register TTY * tp;
        !          54704: {
        !          54705:        register int    b;
        !          54706: 
        !          54707: rescan:
        !          54708:        switch ( inb(ALPORT+IIR) ) {
        !          54709: 
        !          54710:        case LS_INTR:
        !          54711:                if ( inb(ALPORT+LSR) & LS_BREAK )
        !          54712:                        defer( alxbreak, tp );
        !          54713:                goto rescan;
        !          54714: 
        !          54715:        case Rx_INTR:
        !          54716:                b = inb(ALPORT+DREG);
        !          54717:                if ( tp->t_open == 0 )
        !          54718:                        goto rescan;
        !          54719:                /*
        !          54720:                 * Must recognize XOFF quickly to avoid transmit overrun.
        !          54721:                 * Recognize XON here as well to avoid race conditions.
        !          54722:                 */
        !          54723:                if ( (tp->t_sgttyb.sg_flags & RAWIN) == 0 ) {
        !          54724:                        /*
        !          54725:                         * XOFF.
        !          54726:                         */
        !          54727:                        if ( tp->t_tchars.t_stopc == (b & 0177) ) {
        !          54728:                                tp->t_flags |= T_STOP;
        !          54729:                                goto rescan;
        !          54730:                        }
        !          54731: 
        !          54732:                        /*
        !          54733:                         * XON.
        !          54734:                         */
        !          54735:                        if ( tp->t_tchars.t_startc == (b & 0177) ) {
        !          54736:                                tp->t_flags &= ~T_STOP;
        !          54737:                                goto rescan;
        !          54738:                        }
        !          54739:                }
        !          54740: 
        !          54741:                /*
        !          54742:                 * Save char in raw input buffer.
        !          54743:                 */
        !          54744:                tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          54745:                if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          54746:                        tp->t_rawin.si_ix = 0;
        !          54747:                        rawin_ct++;
        !          54748:                /*
        !          54749:                 * Preliminary code!
        !          54750:                 * De-assert RTS if we are close to filling the input silo.
        !          54751:                 */     
        !          54752:                if (want_rts && (sizeof(tp->t_rawin.si_buf) - rawin_ct < 4))
        !          54753:                        outb(b+MCR, inb(b+MCR) & ~MC_RTS);
        !          54754:                        goto rescan;
        !          54755: 
        !          54756:        case Tx_INTR:
        !          54757:                /*
        !          54758:                 * Do nothing if no raw output data or output is stopped.
        !          54759:                 */
        !          54760:                if ( tp->t_rawout.si_ix == tp->t_rawout.si_ox ) {
        !          54761:                        goto rescan;
        !          54762:                }
        !          54763:                if ( tp->t_flags & T_STOP )
        !          54764:                        goto rescan;
        !          54765: 
        !          54766:                /*
        !          54767:                 * Transmit next char in raw output buffer.
        !          54768:                 */
        !          54769:                outb(   ALPORT+DREG,
        !          54770:                        tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          54771: 
        !          54772:                /*
        !          54773:                 * Adjust raw output buffer output index.
        !          54774:                 */
        !          54775:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          54776:                        tp->t_rawout.si_ox = 0;
        !          54777: 
        !          54778:                /*
        !          54779:                 * Try to fill buffer if now empty.
        !          54780:                 */
        !          54781:                if ( tp->t_rawout.si_ox == tp->t_rawout.si_ix ) {
        !          54782:                        defer( alxcycle, tp );
        !          54783:                }
        !          54784:                goto rescan;
        !          54785:                
        !          54786:        case MS_INTR:
        !          54787:                /*
        !          54788:                 * This is preliminary code - use delta of CTS from
        !          54789:                 * modem to implement flow control.
        !          54790:                 *
        !          54791:                 * Sense delta of RLSD for use by alxcycle().
        !          54792:                 */
        !          54793:                b = inb(ALPORT+MSR);
        !          54794:                if (b & MS_DCTS)
        !          54795:                        if (b & MS_CTS)
        !          54796:                                tp->t_flags &= ~T_STOP;
        !          54797:                        else
        !          54798:                                tp->t_flags |= T_STOP;
        !          54799:                if (b & MS_DRLSD)
        !          54800:                        drlsd = 1;              
        !          54801:        }
        !          54802: }
        !          54803: 
        !          54804: /*
        !          54805:  * alxclk will be called every time T0 interrupts - if it returns 0,
        !          54806:  * the usual system timer interrupt stuff is done
        !          54807:  */
        !          54808: static int alxclk()
        !          54809: {
        !          54810:        static int count;
        !          54811:        int i;
        !          54812: 
        !          54813:        for (i = 0; i < NUM_AL_PORTS;  i++)
        !          54814:                if (com_usage[i] == COM_POLLED)
        !          54815:                        alxintr(tp_table[i]);
        !          54816:        count++;
        !          54817:        if (count >= poll_divisor)
        !          54818:                count = 0;
        !          54819:        return count;
        !          54820: }
        !          54821: 
        !          54822: /*
        !          54823:  * set_poll_rate is called when a port is opened or closed or changes speed
        !          54824:  * it sets the polling rate only as fast as needed, and shuts off polling
        !          54825:  * whenever possible
        !          54826:  */
        !          54827: static set_poll_rate()
        !          54828: {
        !          54829:        int port_num, max_rate, port_rate;
        !          54830: 
        !          54831:        /*
        !          54832:         * If another driver has the polling clock, do nothing.
        !          54833:         */
        !          54834:        if (poll_owner & ~ POLL_AL)
        !          54835:                return;
        !          54836: 
        !          54837:        /*
        !          54838:         * find highest valid polling rate in units of HZ/10
        !          54839:         */
        !          54840:        max_rate = 0;
        !          54841:        for (port_num = 0; port_num < NUM_AL_PORTS; port_num++) {
        !          54842:                if (com_usage[port_num] == COM_POLLED) {
        !          54843:                        port_rate = alp_rate[(tp_table[port_num])->t_sgttyb.sg_ispeed];
        !          54844:                        if (max_rate < port_rate)
        !          54845:                                max_rate = port_rate;
        !          54846:                }
        !          54847:        }
        !          54848:        /*
        !          54849:         * if max_rate is not current rate, adjust the system clock
        !          54850:         */
        !          54851:        if (max_rate != poll_rate) {
        !          54852:                poll_rate = max_rate;
        !          54853:                poll_divisor = poll_rate/HZ;  /* used in alxclk() */
        !          54854:                altclk_out();           /* stop previous polling */
        !          54855:                poll_owner &= ~ POLL_AL;
        !          54856:                if (max_rate) { /* resume polling at new rate if needed */
        !          54857:                        poll_owner |= POLL_AL;
        !          54858:                        altclk_in(poll_rate, alxclk);
        !          54859:                }
        !          54860:                CDUMP("new rate")
        !          54861:        }
        !          54862: }
        !          54863: @
        !          54864: 0707070064030103771004440000030000030000011777770507310666500006200000001725/newbits/kernel/USRSRC/i8086/drv/RCS/Mf.ssqtest,vhead     1.1;
        !          54865: branch   ;
        !          54866: access   ;
        !          54867: symbols  ;
        !          54868: locks    bin:1.1; strict;
        !          54869: comment  @@;
        !          54870: 
        !          54871: 
        !          54872: 1.1
        !          54873: date     91.06.10.10.19.54;  author bin;  state Exp;
        !          54874: branches ;
        !          54875: next     ;
        !          54876: 
        !          54877: 
        !          54878: desc
        !          54879: @initial version prov by hal
        !          54880: @
        !          54881: 
        !          54882: 
        !          54883: 
        !          54884: 1.1
        !          54885: log
        !          54886: @Initial revision
        !          54887: @
        !          54888: text
        !          54889: @#
        !          54890: # Makefile for test of ss queueing
        !          54891: #
        !          54892: AS=exec /bin/as
        !          54893: CC=exec /bin/cc
        !          54894: CPP=exec /lib/icpp
        !          54895: CFLAGS=-I.. -I../sys -I../.. -I../../sys -I/usr/include/sys
        !          54896: AFLAGS=-gx
        !          54897: OBJECTS=ssqtest.o objects/ssqueue.o
        !          54898: 
        !          54899: # Include directories
        !          54900: USRINC=/usr/include
        !          54901: SYSINC=/usr/include/sys
        !          54902: KERINC=/usr/src/sys/sys
        !          54903: DRVINC=/usr/src/sys/i8086/sys
        !          54904: USRSYS=/usr/sys
        !          54905: 
        !          54906: ssqtest: $(OBJECTS)
        !          54907:        $(CC) $(CFLAGS) -o ssqtest $(OBJECTS)
        !          54908: 
        !          54909: ssqtest.o: ssqtest.c
        !          54910:        $(CC) $(CFLAGS) -DVERBOSE=1 -c -o ssqtest.o ssqtest.c
        !          54911: 
        !          54912: objects/ssqueue.o:                     \
        !          54913:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          54914:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          54915:                                        $(SYSINC)/fun.h $(DRVINC)/mmu.h \
        !          54916:                $(SYSINC)/buf.h         \
        !          54917:                $(DRVINC)/scsiwork.h    \
        !          54918:                ssqueue.c
        !          54919:        $(CC) $(CFLAGS) -c -o $@@ ssqueue.c
        !          54920: @
        !          54921: 0707070064030103761004440000030000030000011777770507310666500005300000025247/newbits/kernel/USRSRC/i8086/drv/RCS/Mf2,vhead     1.1;
        !          54922: branch   ;
        !          54923: access   ;
        !          54924: symbols  ;
        !          54925: locks    bin:1.1; strict;
        !          54926: comment  @# @;
        !          54927: 
        !          54928: 
        !          54929: 1.1
        !          54930: date     91.06.10.10.20.00;  author bin;  state Exp;
        !          54931: branches ;
        !          54932: next     ;
        !          54933: 
        !          54934: 
        !          54935: desc
        !          54936: @initial version prov by hal
        !          54937: @
        !          54938: 
        !          54939: 
        !          54940: 
        !          54941: 1.1
        !          54942: log
        !          54943: @Initial revision
        !          54944: @
        !          54945: text
        !          54946: @#
        !          54947: # Makefile for AT specific Coherent drivers
        !          54948: #
        !          54949: AS=exec /bin/as
        !          54950: CC=exec /bin/cc
        !          54951: CPP=exec /lib/cpp
        !          54952: CFLAGS=-I.. -I../sys -I../.. -I../../sys -I/usr/include/sys
        !          54953: AFLAGS=-gx
        !          54954: 
        !          54955: # Include directories
        !          54956: USRINC=/usr/include
        !          54957: SYSINC=/usr/include/sys
        !          54958: KERINC=/usr/src/sys/sys
        !          54959: DRVINC=/usr/src/sys/i8086/sys
        !          54960: USRSYS=/usr/sys
        !          54961: 
        !          54962: ARCHIVES=$(USRSYS)/lib/al.a \
        !          54963:        $(USRSYS)/lib/ati.a \
        !          54964:        $(USRSYS)/lib/fl.a \
        !          54965:        $(USRSYS)/lib/gm.a \
        !          54966:        $(USRSYS)/lib/gr.a \
        !          54967:        $(USRSYS)/lib/hs.a \
        !          54968:        $(USRSYS)/lib/lp.a \
        !          54969:        $(USRSYS)/lib/mm.a \
        !          54970:        $(USRSYS)/lib/ms.a \
        !          54971:        $(USRSYS)/lib/rm.a \
        !          54972:        $(USRSYS)/lib/rp.a \
        !          54973:        $(USRSYS)/lib/rs.a \
        !          54974:        $(USRSYS)/lib/st.a \
        !          54975:        $(USRSYS)/lib/tn.a \
        !          54976: 
        !          54977: DRVOBJ=        objects/alx.o \
        !          54978:        objects/ms.o \
        !          54979:        objects/ati.o \
        !          54980:        objects/com1.o objects/com2.o \
        !          54981:        objects/fdisk.o \
        !          54982:        objects/fl.o \
        !          54983:        objects/fontw.o \
        !          54984:        objects/gr.o objects/gras.o objects/gmas.o \
        !          54985:        objects/hs.o objects/clocked.o \
        !          54986:        objects/kb.o objects/mm.o \
        !          54987:        objects/lp.o \
        !          54988:        objects/mmas.o \
        !          54989:        objects/rm.o \
        !          54990:        objects/rp.o objects/rpas.o \
        !          54991:        objects/rs0.o objects/rs1.o objects/rsas.o \
        !          54992:        objects/st.o \
        !          54993:        objects/tn.o objects/tnas.o \
        !          54994: 
        !          54995: install: $(ARCHIVES)
        !          54996:        @@exec /bin/sync
        !          54997: 
        !          54998: all:   $(DRVOBJ)
        !          54999:        @@exec /bin/sync
        !          55000: 
        !          55001: $(USRSYS)/lib/al.a: objects/com1.o objects/com2.o objects/alx.o
        !          55002:        rm -f $(USRSYS)/lib/al.a
        !          55003:        ar rc $(USRSYS)/lib/al.a objects/com1.o objects/com2.o objects/alx.o
        !          55004: $(USRSYS)/lib/ati.a: objects/mm.o objects/ati.o objects/kb.o
        !          55005:        rm -f $(USRSYS)/lib/ati.a
        !          55006:        ar rc $(USRSYS)/lib/ati.a objects/mm.o objects/ati.o objects/kb.o
        !          55007: $(USRSYS)/lib/fl.a: objects/fl.o
        !          55008:        rm -f $(USRSYS)/lib/fl.a
        !          55009:        ar rc $(USRSYS)/lib/fl.a objects/fl.o
        !          55010: $(USRSYS)/lib/gm.a: objects/mm.o objects/gr.o objects/gmas.o \
        !          55011:                                objects/fontw.o objects/kb.o
        !          55012:        rm -f $(USRSYS)/lib/gm.a
        !          55013:        ar rc $(USRSYS)/lib/gm.a objects/mm.o objects/gr.o objects/gmas.o \
        !          55014:                                objects/fontw.o objects/kb.o
        !          55015: $(USRSYS)/lib/gr.a: objects/mm.o objects/gr.o objects/gras.o \
        !          55016:                                objects/fontw.o objects/kb.o
        !          55017:        rm -f $(USRSYS)/lib/gr.a
        !          55018:        ar rc $(USRSYS)/lib/gr.a objects/mm.o objects/gr.o objects/gras.o \
        !          55019:                                objects/fontw.o objects/kb.o
        !          55020: $(USRSYS)/lib/hs.a: objects/hs.o objects/clocked.o
        !          55021:        rm -f $(USRSYS)/lib/hs.a
        !          55022:        ar rc $(USRSYS)/lib/hs.a objects/hs.o objects/clocked.o
        !          55023: $(USRSYS)/lib/lp.a: objects/lp.o
        !          55024:        rm -f $(USRSYS)/lib/lp.a
        !          55025:        ar rc $(USRSYS)/lib/lp.a objects/lp.o
        !          55026: $(USRSYS)/lib/mm.a: objects/mm.o objects/mmas.o objects/kb.o
        !          55027:                rm -f $(USRSYS)/lib/mm.a
        !          55028:        ar rc $(USRSYS)/lib/mm.a objects/mm.o objects/mmas.o objects/kb.o
        !          55029: $(USRSYS)/lib/ms.a: objects/ms.o
        !          55030:        rm -f $(USRSYS)/lib/ms.a
        !          55031:        ar rc $(USRSYS)/lib/ms.a objects/ms.o
        !          55032: $(USRSYS)/lib/rm.a: objects/rm.o
        !          55033:        rm -f $(USRSYS)/lib/rm.a
        !          55034:        ar rc $(USRSYS)/lib/rm.a objects/rm.o
        !          55035: $(USRSYS)/lib/rp.a: objects/rp.o objects/rpas.o
        !          55036:        rm -f $(USRSYS)/lib/rp.a
        !          55037:        ar rc $(USRSYS)/lib/rp.a objects/rp.o objects/rpas.o
        !          55038: $(USRSYS)/lib/rs.a: objects/rs0.o objects/rs1.o objects/rsas.o
        !          55039:        rm -f $(USRSYS)/lib/rs.a
        !          55040:        ar rc $(USRSYS)/lib/rs.a objects/rs0.o objects/rs1.o objects/rsas.o
        !          55041: $(USRSYS)/lib/st.a: objects/st.o
        !          55042:        rm -f $(USRSYS)/lib/st.a
        !          55043:        ar rc $(USRSYS)/lib/st.a objects/st.o
        !          55044: $(USRSYS)/lib/tn.a: objects/tn.o objects/tnas.o
        !          55045:        rm -f $(USRSYS)/lib/tn.a
        !          55046:        ar rc $(USRSYS)/lib/tn.a objects/tn.o objects/tnas.o
        !          55047: 
        !          55048: objects/alx.o:                         \
        !          55049:                $(KERINC)/clist.h       \
        !          55050:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55051:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55052:                                        $(SYSINC)/fun.h \
        !          55053:                $(SYSINC)/con.h         \
        !          55054:                $(USRINC)/errno.h       \
        !          55055:                $(DRVINC)/i8086.h       \
        !          55056:                $(DRVINC)/ins8250.h     \
        !          55057:                $(SYSINC)/sched.h       \
        !          55058:                $(SYSINC)/stat.h        \
        !          55059:                $(SYSINC)/timeout.h     \
        !          55060:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          55061:                $(SYSINC)/uproc.h       \
        !          55062:                alx.c
        !          55063:        $(CC) $(CFLAGS) -c -o $@@ alx.c
        !          55064: 
        !          55065: objects/ati.o: ati.s
        !          55066:        exec /lib/cpp -E -DATI_132=1 ati.s > ati.i
        !          55067:        exec /bin/as -gxo $@@ ati.i
        !          55068:        exec /bin/rm -f ati.i
        !          55069: 
        !          55070: #objects/clocked.o: clocked.s
        !          55071: #      $(AS) -go $@@ $<
        !          55072: objects/clocked.o: clocked.c
        !          55073: 
        !          55074: objects/com1.o:                        \
        !          55075:                $(KERINC)/clist.h       \
        !          55076:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55077:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55078:                                        $(SYSINC)/fun.h \
        !          55079:                $(SYSINC)/con.h         \
        !          55080:                $(USRINC)/errno.h       \
        !          55081:                $(DRVINC)/i8086.h       \
        !          55082:                $(DRVINC)/ins8250.h     \
        !          55083:                $(SYSINC)/sched.h       \
        !          55084:                $(SYSINC)/stat.h        \
        !          55085:                $(SYSINC)/timeout.h     \
        !          55086:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          55087:                $(SYSINC)/uproc.h       \
        !          55088:                al.c
        !          55089:        $(CC) $(CFLAGS) -DALCOM1=1 -c -o $@@ al.c
        !          55090: 
        !          55091: objects/com2.o:                        \
        !          55092:                $(KERINC)/clist.h       \
        !          55093:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55094:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55095:                                        $(SYSINC)/fun.h \
        !          55096:                $(SYSINC)/con.h         \
        !          55097:                $(USRINC)/errno.h       \
        !          55098:                $(DRVINC)/i8086.h       \
        !          55099:                $(DRVINC)/ins8250.h     \
        !          55100:                $(SYSINC)/sched.h       \
        !          55101:                $(SYSINC)/stat.h        \
        !          55102:                $(SYSINC)/timeout.h     \
        !          55103:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          55104:                $(SYSINC)/uproc.h       \
        !          55105:                al.c
        !          55106:        $(CC) $(CFLAGS) -DALCOM2=1 -c -o $@@ al.c
        !          55107: 
        !          55108: objects/dmareq.o:                      \
        !          55109:                $(SYSINC)/buf.h         \
        !          55110:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55111:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55112:                                        $(SYSINC)/fun.h \
        !          55113:                $(SYSINC)/con.h         \
        !          55114:                $(DRVINC)/dmac.h        \
        !          55115:                $(USRINC)/errno.h       \
        !          55116:                $(SYSINC)/io.h          \
        !          55117:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          55118:                $(SYSINC)/sched.h       \
        !          55119:                $(SYSINC)/seg.h         \
        !          55120:                $(SYSINC)/stat.h        \
        !          55121:                $(SYSINC)/uproc.h       \
        !          55122:                dmareq.c
        !          55123:        $(CC) $(CFLAGS) -c -o $@@ dmareq.c
        !          55124: 
        !          55125: objects/fdisk.o:                       \
        !          55126:                $(SYSINC)/buf.h         \
        !          55127:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55128:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55129:                                        $(SYSINC)/fun.h \
        !          55130:                $(SYSINC)/con.h         \
        !          55131:                $(USRINC)/errno.h       \
        !          55132:                $(SYSINC)/fdisk.h       \
        !          55133:                $(SYSINC)/inode.h       \
        !          55134:                $(SYSINC)/uproc.h       \
        !          55135:                fdisk.c
        !          55136:        $(CC) $(CFLAGS) -c -o $@@ fdisk.c
        !          55137: 
        !          55138: objects/fl.o:                          \
        !          55139:                $(SYSINC)/buf.h         \
        !          55140:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55141:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55142:                                        $(SYSINC)/fun.h \
        !          55143:                $(SYSINC)/con.h         \
        !          55144:                $(DRVINC)/dmac.h        \
        !          55145:                $(USRINC)/errno.h       \
        !          55146:                $(SYSINC)/fdioctl.h     \
        !          55147:                $(DRVINC)/i8086.h       \
        !          55148:                $(SYSINC)/sched.h       \
        !          55149:                $(SYSINC)/stat.h        \
        !          55150:                $(SYSINC)/timeout.h     \
        !          55151:                $(SYSINC)/uproc.h       \
        !          55152:                fl.c
        !          55153:        $(CC) $(CFLAGS) -c -o $@@ fl.c
        !          55154: 
        !          55155: objects/fontw.o: fontgen.c
        !          55156:        $(CC) -i fontgen.c
        !          55157:        exec ./fontgen > $*.s
        !          55158:        exec /bin/rm fontgen
        !          55159:        $(AS) -gxo $@@ $*.s
        !          55160:        exec /bin/rm $*.s
        !          55161: 
        !          55162: objects/gmas.o: gras.s
        !          55163:        exec /lib/cpp -E -DTECMAR gras.s > gmas.i
        !          55164:        exec /bin/as -gxo $@@ gmas.i
        !          55165:        exec /bin/rm -f gmas.i
        !          55166: 
        !          55167: objects/gr.o:                          \
        !          55168:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55169:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55170:                                        $(SYSINC)/fun.h \
        !          55171:                $(SYSINC)/con.h         \
        !          55172:                $(USRINC)/errno.h       \
        !          55173:                $(SYSINC)/sched.h       \
        !          55174:                $(SYSINC)/timeout.h     \
        !          55175:                $(SYSINC)/types.h       \
        !          55176:                $(SYSINC)/uproc.h       \
        !          55177:                gr.c
        !          55178:        $(CC) $(CFLAGS) -c -o $@@ gr.c
        !          55179: 
        !          55180: objects/gras.o: gras.s
        !          55181:        exec /lib/cpp -E gras.s > gras.i
        !          55182:        exec /bin/as -gxo $@@ gras.i
        !          55183:        exec /bin/rm -f gras.i
        !          55184: 
        !          55185: objects/hgas.o: gras.s
        !          55186:        exec /lib/cpp -E -DHERCULES gras.s > hgas.i
        !          55187:        exec /bin/as -gxo $@@ hgas.i
        !          55188:        exec /bin/rm -f hgas.i
        !          55189: 
        !          55190: objects/hd.o: hd.c
        !          55191:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          55192: 
        !          55193: objects/hs.o:                          \
        !          55194:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55195:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55196:                                        $(SYSINC)/fun.h \
        !          55197:                $(SYSINC)/con.h         \
        !          55198:                $(USRINC)/errno.h       \
        !          55199:                $(DRVINC)/ins8250.h     \
        !          55200:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          55201:                $(SYSINC)/stat.h        \
        !          55202:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          55203:                $(SYSINC)/uproc.h       \
        !          55204:                hs.c
        !          55205:        $(CC) $(CFLAGS) -c -o $@@ hs.c
        !          55206: 
        !          55207: objects/kb.o:                          \
        !          55208:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55209:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55210:                                        $(SYSINC)/fun.h \
        !          55211:                $(SYSINC)/con.h         \
        !          55212:                $(USRINC)/errno.h       \
        !          55213:                $(DRVINC)/i8086.h       \
        !          55214:                $(SYSINC)/sched.h       \
        !          55215:                $(USRINC)/signal.h      \
        !          55216:                $(SYSINC)/stat.h        \
        !          55217:                $(SYSINC)/timeout.h     \
        !          55218:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          55219:                $(SYSINC)/uproc.h       \
        !          55220:                kb.c
        !          55221:        $(CC) $(CFLAGS) -c -o $@@ kb.c
        !          55222: 
        !          55223: objects/lp.o:                          \
        !          55224:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55225:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55226:                                        $(SYSINC)/fun.h \
        !          55227:                $(SYSINC)/con.h         \
        !          55228:                $(USRINC)/errno.h       \
        !          55229:                $(DRVINC)/i8086.h       \
        !          55230:                $(SYSINC)/io.h          \
        !          55231:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          55232:                $(SYSINC)/stat.h        \
        !          55233:                $(SYSINC)/timeout.h     \
        !          55234:                $(SYSINC)/uproc.h       \
        !          55235:                lp.c
        !          55236:        $(CC) $(CFLAGS) -c -o $@@ lp.c
        !          55237: 
        !          55238: objects/mm.o:                          \
        !          55239:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55240:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55241:                                        $(SYSINC)/fun.h \
        !          55242:                $(SYSINC)/sched.h       \
        !          55243:                $(USRINC)/errno.h       \
        !          55244:                $(SYSINC)/stat.h        \
        !          55245:                $(SYSINC)/io.h          \
        !          55246:                $(SYSINC)/tty.h         $(KERINC)/ktty.h \
        !          55247:                $(SYSINC)/uproc.h       \
        !          55248:                $(SYSINC)/timeout.h     \
        !          55249:                mm.c
        !          55250:        $(CC) $(CFLAGS) -c -o $@@ mm.c
        !          55251: 
        !          55252: objects/mmas.o: mmas.s
        !          55253:        -/lib/cpp -E mmas.s > mmas.i
        !          55254:        exec /bin/as -gxo $@@ mmas.i
        !          55255:        exec /bin/rm -f mmas.i
        !          55256: 
        !          55257: objects/ms.o:                          \
        !          55258:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55259:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55260:                                        $(SYSINC)/fun.h \
        !          55261:                $(SYSINC)/uproc.h       \
        !          55262:                $(SYSINC)/con.h         \
        !          55263:                $(SYSINC)/ms.h          \
        !          55264:                $(USRINC)/errno.h       \
        !          55265:                ms.c
        !          55266:        $(CC) $(CFLAGS) -c -o $@@ ms.c
        !          55267: 
        !          55268: objects/rm.o: rm.c
        !          55269:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          55270: 
        !          55271: objects/rp.o:                          \
        !          55272:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55273:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55274:                                        $(SYSINC)/fun.h \
        !          55275:                $(SYSINC)/con.h         \
        !          55276:                $(USRINC)/errno.h       \
        !          55277:                $(SYSINC)/seg.h         \
        !          55278:                $(SYSINC)/sched.h       \
        !          55279:                $(SYSINC)/stat.h        \
        !          55280:                $(USRINC)/termio.h      \
        !          55281:                $(SYSINC)/uproc.h       \
        !          55282:                $(USRINC)/v7sgtty.h     \
        !          55283:                rp.c
        !          55284:        $(CC) $(CFLAGS) -c -o $@@ rp.c
        !          55285: 
        !          55286: objects/rpas.o: rpas.s
        !          55287:        $(AS) -gxo $@@ $<
        !          55288: 
        !          55289: objects/rs0.o:                         \
        !          55290:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55291:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55292:                                        $(SYSINC)/fun.h \
        !          55293:                $(SYSINC)/con.h         \
        !          55294:                $(USRINC)/errno.h       \
        !          55295:                $(DRVINC)/ins8250.h     \
        !          55296:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          55297:                $(SYSINC)/sched.h       \
        !          55298:                $(SYSINC)/stat.h        \
        !          55299:                $(USRINC)/termio.h      \
        !          55300:                $(SYSINC)/uproc.h       \
        !          55301:                rs.c
        !          55302:        $(CC) $(CFLAGS) -DRS0 -c -o $@@ rs.c
        !          55303: 
        !          55304: objects/rs1.o:                                 \
        !          55305:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55306:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55307:                                        $(SYSINC)/fun.h \
        !          55308:                $(SYSINC)/con.h         \
        !          55309:                $(USRINC)/errno.h       \
        !          55310:                $(DRVINC)/ins8250.h     \
        !          55311:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          55312:                $(SYSINC)/sched.h       \
        !          55313:                $(SYSINC)/stat.h        \
        !          55314:                $(USRINC)/termio.h      \
        !          55315:                $(SYSINC)/uproc.h       \
        !          55316:                rs.c
        !          55317:        $(CC) $(CFLAGS) -DRS1 -c -o $@@ rs.c
        !          55318: 
        !          55319: objects/rsas.o: rsas.s
        !          55320:        $(AS) -gxo $@@ $<
        !          55321: 
        !          55322: objects/st.o:                          \
        !          55323:                $(SYSINC)/buf.h         \
        !          55324:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55325:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55326:                                        $(SYSINC)/fun.h \
        !          55327:                $(SYSINC)/con.h         \
        !          55328:                $(SYSINC)/const.h       \
        !          55329:                $(USRINC)/errno.h       \
        !          55330:                $(SYSINC)/inode.h       \
        !          55331:                $(SYSINC)/mtioctl.h     \
        !          55332:                $(SYSINC)/sched.h       \
        !          55333:                $(SYSINC)/seg.h         \
        !          55334:                $(SYSINC)/stat.h        \
        !          55335:                $(SYSINC)/uproc.h       \
        !          55336:                st.c
        !          55337:        $(CC) $(CFLAGS) -c -o $@@ st.c
        !          55338: 
        !          55339: objects/tn.o:                          \
        !          55340:                $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          55341:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          55342:                                        $(SYSINC)/fun.h \
        !          55343:                $(SYSINC)/con.h         \
        !          55344:                $(USRINC)/errno.h       \
        !          55345:                $(SYSINC)/sched.h       \
        !          55346:                $(SYSINC)/timeout.h     \
        !          55347:                $(SYSINC)/types.h       \
        !          55348:                $(SYSINC)/uproc.h       \
        !          55349:                tn.c
        !          55350:        $(CC) $(CFLAGS) -c -o $@@ tn.c
        !          55351: 
        !          55352: objects/tnas.o: tnas.s
        !          55353:        $(AS) -gxo $@@ $<
        !          55354: @
        !          55355: 0707070064030103751004440000030000030000011777770507310667000005600000003726/newbits/kernel/USRSRC/i8086/drv/RCS/README,vhead     1.1;
        !          55356: branch   ;
        !          55357: access   ;
        !          55358: symbols  ;
        !          55359: locks    bin:1.1; strict;
        !          55360: comment  @# @;
        !          55361: 
        !          55362: 
        !          55363: 1.1
        !          55364: date     91.06.10.10.20.05;  author bin;  state Exp;
        !          55365: branches ;
        !          55366: next     ;
        !          55367: 
        !          55368: 
        !          55369: desc
        !          55370: @initial version prov by hal
        !          55371: @
        !          55372: 
        !          55373: 
        !          55374: 
        !          55375: 1.1
        !          55376: log
        !          55377: @Initial revision
        !          55378: @
        !          55379: text
        !          55380: @Here are two sets of diffs against the alx.c that I'm currently running.
        !          55381: It was derived from your RTS/CTS-enhanced version (that I dubbed "3.11").
        !          55382: 
        !          55383: The two sets of diffs are:
        !          55384: 
        !          55385: - version 3.10 alx.c against my current version
        !          55386: - your enhanced "version 3.11" alx.c against mine.
        !          55387: 
        !          55388: Important note:  I'm out of my league here.  I'm a reasonably competent
        !          55389: C programmer, but completely ignorant of asynch communications programming
        !          55390: and issues.  Don't look for deep insight in the changes that you see; in
        !          55391: many cases I merely removed code from your enhanced version that I didn't
        !          55392: understand, attempting to narrow down the number of changes involved.
        !          55393: 
        !          55394: I *have* tested and demonstrated that the code DOES toggle RTS correctly;
        !          55395: the persistent packet errors must be caused by delays in the chain well 
        !          55396: past the driver.
        !          55397: 
        !          55398: As I mentioned earlier, this version does cure the SSS (Sudden Sluggishness
        !          55399: Syndrome ;-) -- but introduces the following new anomalies:
        !          55400: 
        !          55401: - My version of ckermit does not get any response from the modem.  The modem
        !          55402:   lights indicate that the modem is sending stuff (e.g. after an ATN?), but
        !          55403:   nothing comes out.  The native plain old kermit does work.
        !          55404: 
        !          55405: - Recall that I use a fixed-at-9600 line speed, and let the Telebit cope
        !          55406:   with slower modems.  This has worked without incident in the past, but
        !          55407:   no longer.  While uucicos work  (with reduced speed), interactive 
        !          55408:   dial-ups at 2400 hang up the modem as soon as a "large" amount of 
        !          55409:   characters is sent (e.g. "ls -l").  The symptom is that the characters
        !          55410:   come across VERY slowly, and after the output is complete, further 
        !          55411:   keystrokes aren't echoed or responded to by the system.  It's almost as
        !          55412:   if the line speed gets changed from 9600 !?
        !          55413: 
        !          55414: I look forward to further testing material from you.
        !          55415: 
        !          55416: @
        !          55417: 0707070064030103741004440000030000030000011777770507310667100005500000104725/newbits/kernel/USRSRC/i8086/drv/RCS/ati.s,vhead     1.1;
        !          55418: branch   ;
        !          55419: access   ;
        !          55420: symbols  ;
        !          55421: locks    bin:1.1; strict;
        !          55422: comment  @@;
        !          55423: 
        !          55424: 
        !          55425: 1.1
        !          55426: date     91.06.10.10.20.27;  author bin;  state Exp;
        !          55427: branches ;
        !          55428: next     ;
        !          55429: 
        !          55430: 
        !          55431: desc
        !          55432: @initial version prov by hal
        !          55433: @
        !          55434: 
        !          55435: 
        !          55436: 
        !          55437: 1.1
        !          55438: log
        !          55439: @Initial revision
        !          55440: @
        !          55441: text
        !          55442: @/ (lgl-
        !          55443: /      COHERENT Driver Kit Version 1.1.0
        !          55444: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          55445: /      All rights reserved. May not be copied without permission.
        !          55446: / -lgl)
        !          55447: ////////
        !          55448: /
        !          55449: / Array Technologies Inc - Graphics Solution - Device Driver
        !          55450: /
        !          55451: /       Supports 40/80/132 column color text
        !          55452: /                   80/132 column monochrome text
        !          55453: /
        !          55454: / State driven code
        !          55455: /
        !          55456: /      Input:  DS:SI - input string
        !          55457: /              ES:DI - current screen location
        !          55458: /              SS:BP - terminal information
        !          55459: /              CX    - input count
        !          55460: /              BP    - references terminal information
        !          55461: /              AH    - character attributes
        !          55462: /              AL    - character
        !          55463: /              BH    - (usually) kept zeroed for efficiency
        !          55464: /              DH    - current row
        !          55465: /              DL    - current column
        !          55466: /
        !          55467: / 
        !          55468: ////////
        !          55469: 
        !          55470:        NCB     = 2             / number of horizontal bytes per char
        !          55471:        NCR     = 1             / number of horizontal lines per char
        !          55472:        NHB     = 160           / number of horizontal bytes per line
        !          55473:        NRB     = NCR*NHB       / number of bytes per character row
        !          55474: 
        !          55475:        ATTR    = ah            / attribute byte
        !          55476:        ZERO    = bh            / (almost) always zero
        !          55477:        ROW     = dh            / currently active vertical position
        !          55478:        COL     = dl            / currently active horizontal position
        !          55479:        POS     = di            / currently active display address
        !          55480: 
        !          55481:        INTENSE = 0x08          / high intensity attribute bit
        !          55482:        BLINK   = 0x80          / blinking attribute bit
        !          55483:        REVERSE = 0x70          / reverse video
        !          55484: 
        !          55485: ////////
        !          55486: /
        !          55487: / Magic constants from <sys/io.h>
        !          55488: /
        !          55489: ////////
        !          55490: 
        !          55491:        IO_SEG  = 0
        !          55492:        IO_IOC  = 2
        !          55493:        IO_BASE = 8
        !          55494: 
        !          55495:        IOSYS   = 0
        !          55496:        IOUSR   = 1
        !          55497: 
        !          55498: ////////
        !          55499: /
        !          55500: / Data
        !          55501: /
        !          55502: ////////
        !          55503: 
        !          55504: MM_FUNC                = 0             / current state
        !          55505: MM_PORT                = 2             / adapter base i/o port
        !          55506: MM_BASE                = 4             / adapter base memory address
        !          55507: MM_ROW         = 6             / screen row
        !          55508: MM_COL         = 7             / screen column
        !          55509: MM_POS         = 8             / screen position
        !          55510: MM_ATTR                = 10            / attributes
        !          55511: MM_N1          = 11            / numeric argument 1
        !          55512: MM_N2          = 12            / numeric argument 2
        !          55513: MM_BROW                = 13            / base row
        !          55514: MM_EROW                = 14            / end row
        !          55515: MM_LROW                = 15            / legal row limit
        !          55516: MM_SROW                = 16            / saved cursor row
        !          55517: MM_SCOL                = 17            / saved cursor column
        !          55518: MM_IBROW       = 18            / initial base row
        !          55519: MM_IEROW       = 19            / initial end row
        !          55520: MM_INVIS       = 20            / cursor invisible mask
        !          55521: MM_NCOL                = 22            / number of columns
        !          55522: MM_DATA                = 24            / pointer to crt data
        !          55523: MM_MODE                = 26            / mode register [0x21=col80/132,0x20=col40]
        !          55524: 
        !          55525:        .prvd
        !          55526: mmdata:        .word   mminit
        !          55527:        .word   0x03D4
        !          55528:        .word   0xB800
        !          55529:        .byte   0, 0
        !          55530:        .word   0
        !          55531:        .byte   0x7, 0, 0, 0, 23, 24, 0, 0, 0, 23
        !          55532:        .word   0
        !          55533:        .word   80
        !          55534:        .word   creg80
        !          55535:        .byte   0x21, 0x00
        !          55536:        .shri
        !          55537: 
        !          55538: ////////
        !          55539: /
        !          55540: / creg40, creg80, creg132 - crt register values for 40/80/132 column color
        !          55541: /         mreg80, mreg132 - crt register values for 80/132 column monochrome
        !          55542: /
        !          55543: ////////
        !          55544: 
        !          55545: creg40:        .byte   0x38, 0x28, 0x2D, 0x0A, 0x1F, 0x06, 0x19, 0x1C
        !          55546:        .byte   0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          55547: 
        !          55548: creg80:        .byte   0x71, 0x50, 0x5A, 0x0A, 0x1F, 0x06, 0x19, 0x1C
        !          55549:        .byte   0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          55550: 
        !          55551: mreg80:        .byte   0x61, 0x50, 0x52, 0x0F, 0x19, 0x06, 0x19, 0x19
        !          55552:        .byte   0x02, 0x0D, 0x0B, 0x0C, 0x00, 0x00, 0x00, 0x00
        !          55553: 
        !          55554: #ifdef ATI_132
        !          55555:        .globl  creg132
        !          55556: creg132:.byte  0xB5, 0x84, 0x97, 0x0A, 0x1F, 0x06, 0x19, 0x1C
        !          55557:        .byte   0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          55558: 
        !          55559:        .globl  mreg132
        !          55560: mreg132:.byte  0x9F, 0x84, 0x89, 0x0F, 0x19, 0x06, 0x19, 0x19
        !          55561:        .byte   0x02, 0x0D, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          55562: #endif
        !          55563: 
        !          55564: ////////
        !          55565: /
        !          55566: / mmgo( iop )
        !          55567: / IO *iop;
        !          55568: /
        !          55569: ////////
        !          55570: 
        !          55571:        .globl  mmgo_
        !          55572: 
        !          55573: mmgo_:
        !          55574:        push    si
        !          55575:        push    di
        !          55576:        push    bp
        !          55577:        mov     bp, sp
        !          55578:        push    ds
        !          55579:        push    es
        !          55580:        cld
        !          55581:        mov     bx, 8(bp)               / iop
        !          55582:        mov     si, IO_BASE(bx)         / iop->io_base
        !          55583:        mov     cx, IO_IOC(bx)          / iop->io_ioc
        !          55584:        cmp     IO_SEG(bx), $IOSYS
        !          55585:        je      0f
        !          55586:        mov     ds, uds_
        !          55587: 0:     mov     bp, $mmdata
        !          55588: 
        !          55589:        mov     dx, MM_PORT(bp)         / turn video off if color board
        !          55590:        cmp     dx, $0x3B4
        !          55591:        je      0f
        !          55592:        add     dx, $4
        !          55593:        movb    al, MM_MODE(bp)
        !          55594:        outb    dx, al
        !          55595: 0:
        !          55596:        movb    ROW, MM_ROW(bp)
        !          55597:        movb    COL, MM_COL(bp)
        !          55598:        mov     es,  MM_BASE(bp)
        !          55599:        mov     POS, MM_POS(bp)
        !          55600:        sub     bx, bx
        !          55601:        movb    ATTR, MM_ATTR(bp)
        !          55602:        ijmp    MM_FUNC(bp)
        !          55603: 
        !          55604: exit:  pop     bx
        !          55605:        pop     es
        !          55606:        pop     ds
        !          55607:        movb    MM_ATTR(bp), ATTR
        !          55608:        mov     MM_FUNC(bp), bx
        !          55609:        movb    MM_ROW(bp), ROW         / save row,column
        !          55610:        movb    MM_COL(bp), COL
        !          55611:        mov     MM_POS(bp), POS         / save position
        !          55612: 
        !          55613:        mov     dx, MM_PORT(bp)         / adjust cursor location
        !          55614:        mov     bx, POS
        !          55615:        or      bx, MM_INVIS(bp)
        !          55616:        shr     bx, $1
        !          55617: 
        !          55618:        movb    al, $14
        !          55619:        outb    dx, al
        !          55620:        inc     dx
        !          55621:        movb    al, bh
        !          55622:        outb    dx, al
        !          55623:        dec     dx
        !          55624:        movb    al, $15
        !          55625:        outb    dx, al
        !          55626:        inc     dx
        !          55627:        movb    al, bl
        !          55628:        outb    dx, al
        !          55629: 
        !          55630:        mov     dx, MM_PORT(bp)         / turn video on
        !          55631:        add     dx, $4
        !          55632:        movb    al, MM_MODE(bp)
        !          55633:        orb     al, $0x08
        !          55634:        outb    dx, al
        !          55635:        mov     mmvcnt_, $300           / 300 seconds before video disabled
        !          55636: 
        !          55637:        mov     bp, sp
        !          55638:        mov     bx, 8(bp)
        !          55639:        mov     ax, cx
        !          55640:        xchg    cx, IO_IOC(bx)
        !          55641:        sub     cx, IO_IOC(bx)
        !          55642:        add     IO_BASE(bx), cx
        !          55643:        pop     bp
        !          55644:        pop     di
        !          55645:        pop     si
        !          55646:        ret
        !          55647: 
        !          55648: ////////
        !          55649: /
        !          55650: / mminit - initialize screen
        !          55651: /
        !          55652: ////////
        !          55653: 
        !          55654: mminit:        movb    ss:mmesc_, $'c          / schedule keyboard initialization
        !          55655:        mov     MM_NCOL(bp), $80        / set 80 column mode
        !          55656:        movb    MM_MODE(bp), $0x21
        !          55657:        mov     MM_DATA(bp), $creg80
        !          55658: 
        !          55659: #ifdef ATI_132
        !          55660:        mov     dx, $0x3DF              / clear 132 column color
        !          55661:        movb    al, $0x00               / in mode select register
        !          55662:        outb    dx, al
        !          55663: 
        !          55664:        mov     dx, $0x3BA              / clear 132 column monochrome
        !          55665:        movb    al, $0x00               / in mode select register
        !          55666:        outb    dx, al
        !          55667: #endif
        !          55668: 
        !          55669:        call    int11_                  / read equipment status
        !          55670:        andb    al, $0x30               / isolate video bits
        !          55671:        cmpb    al, $0x30               / if monochrome
        !          55672:        jne     0f
        !          55673:        mov     MM_DATA(bp), $mreg80    /       set monochrome register info
        !          55674:        mov     MM_PORT(bp), $0x3B4     /       set monochrome port
        !          55675:        mov     MM_BASE(bp), $0xB000    /       set monochrome base
        !          55676:        mov     es, MM_BASE(bp)         /               and extra segment.
        !          55677: 
        !          55678: 0:     call    newcrt                  / reprogram crt registers
        !          55679: 
        !          55680: reinit:        sub     ax, ax                  / regenerate row table
        !          55681:        mov     bx, $rowtab
        !          55682: 1:     mov     ss:(bx), ax
        !          55683:        add     ax, MM_NCOL(bp)
        !          55684:        add     ax, MM_NCOL(bp)
        !          55685:        add     bx, $2
        !          55686:        cmp     bx, $rowend
        !          55687:        jb      1b
        !          55688: 
        !          55689:        mov     dx, MM_PORT(bp)         / zero display offset
        !          55690:        movb    al, $12
        !          55691:        outb    dx, al
        !          55692:        inc     dx
        !          55693:        subb    al, al
        !          55694:        outb    dx, al
        !          55695:        dec     dx
        !          55696:        movb    al, $13
        !          55697:        outb    dx, al
        !          55698:        inc     dx
        !          55699:        subb    al, al
        !          55700:        outb    dx, al
        !          55701: 
        !          55702:        mov     dx, MM_PORT(bp)         / reset border to black
        !          55703:        add     dx, $5
        !          55704:        subb    al, al
        !          55705:        outb    dx, al
        !          55706: 
        !          55707:        mov     MM_INVIS(bp), $0
        !          55708:        movb    ATTR, $0x07
        !          55709:        movb    MM_ATTR(bp), ATTR
        !          55710:        movb    ROW, MM_IBROW(bp)
        !          55711:        movb    MM_BROW(bp), ROW
        !          55712:        movb    bl, MM_IEROW(bp)
        !          55713:        movb    MM_EROW(bp), bl
        !          55714:        sub     bx, bx
        !          55715:        movb    MM_N1(bp), $2
        !          55716:        jmp     mm_ed
        !          55717: 
        !          55718: ////////
        !          55719: /
        !          55720: / newcrt -- reload crt registers
        !          55721: /
        !          55722: /      Action: Program crt registers with values defined in code space
        !          55723: /              at offset given by MM_DATA(bp).
        !          55724: /
        !          55725: /      Note:   AX, BX, DX, DI trashed on exit.
        !          55726: /
        !          55727: ////////
        !          55728: 
        !          55729: newcrt:        mov     dx, MM_PORT(bp)         / turn video off
        !          55730:        add     dx, $4
        !          55731:        movb    al, MM_MODE(bp)
        !          55732:        outb    dx, al
        !          55733: 
        !          55734:        mov     di, MM_DATA(bp)         / program crt registers, last to first
        !          55735:        mov     bx, $15                 / [delay between i/o]
        !          55736:        mov     dx, MM_PORT(bp)         / [NOTE:DI=obsolete screen offset]
        !          55737: 0:     movb    al, bl
        !          55738:        outb    dx, al
        !          55739:        movb    al, cs:(bx,di)
        !          55740:        inc     dx
        !          55741:        outb    dx, al
        !          55742:        dec     dx
        !          55743:        dec     bx
        !          55744:        jge     0b
        !          55745:        ret
        !          55746: 
        !          55747: ////////
        !          55748: /
        !          55749: / mm_so - stand out - define 40 column attributes
        !          55750: /
        !          55751: ////////
        !          55752: 
        !          55753: mm_so:
        !          55754:        cmp     MM_PORT(bp), $0x3D4     / if color card
        !          55755:        jne     mm_si
        !          55756: 
        !          55757:        mov     MM_NCOL(bp), $40        /       setup for 40 column color
        !          55758:        movb    MM_MODE(bp), $0x20
        !          55759:        mov     MM_DATA(bp), $creg40
        !          55760: 
        !          55761: #ifdef ATI_132
        !          55762:        mov     dx, $0x3DF              /       clear 132 column color
        !          55763:        movb    al, $0x00               /       in mode select register
        !          55764:        outb    dx, al                  /       [delay between i/o]
        !          55765: #endif
        !          55766: 
        !          55767:        call    newcrt                  / program crt registers
        !          55768:        jmp     reinit
        !          55769: 
        !          55770: ////////
        !          55771: /
        !          55772: / mm_si - define 80 column attributes
        !          55773: /
        !          55774: ////////
        !          55775: 
        !          55776: mm_si:
        !          55777:        cmp     MM_PORT(bp), $0x3D4     / if color card
        !          55778:        jne     0f
        !          55779: 
        !          55780:        mov     MM_NCOL(bp), $80
        !          55781:        movb    MM_MODE(bp), $0x21
        !          55782:        mov     MM_DATA(bp), $creg80
        !          55783: 
        !          55784: #ifdef ATI_132
        !          55785:        mov     dx, $0x3DF              /       clear 132 column color
        !          55786:        movb    al, $0x00               /       in mode select register
        !          55787:        outb    dx, al                  /       [delay between i/o]
        !          55788: #endif
        !          55789: 
        !          55790:        call    newcrt                  /       reprogram crt registers.
        !          55791:        jmp     reinit
        !          55792: 
        !          55793: 0:     mov     MM_NCOL(bp), $80
        !          55794:        mov     MM_DATA(bp), $mreg80
        !          55795:        movb    MM_MODE(bp), $0x21
        !          55796: 
        !          55797: #ifdef ATI_132
        !          55798:        mov     dx, $0x3BA              /       clear 132 column monochrome
        !          55799:        movb    al, $0x00               /       in mode select register
        !          55800:        outb    dx, al                  /       [delay between i/o]
        !          55801: #endif
        !          55802: 
        !          55803:        call    newcrt                  /       reprogram crt registers
        !          55804:        jmp     reinit
        !          55805: 
        !          55806: ////////
        !          55807: /
        !          55808: / mm_132 - define 132 column attributes
        !          55809: /
        !          55810: ////////
        !          55811: 
        !          55812: mm_132:
        !          55813:        cmp     MM_PORT(bp), $0x3D4     / if color card
        !          55814:        jne     0f
        !          55815: 
        !          55816: #ifdef ATI_132
        !          55817:        mov     MM_DATA(bp), $creg132   /       set color crt values
        !          55818:        mov     MM_NCOL(bp), $132       /       set columns to 132
        !          55819:        movb    MM_MODE(bp), $0x21
        !          55820: 
        !          55821:        call    newcrt                  /       set 132 column crt values
        !          55822:                                        /       BEFORE setting mode select reg
        !          55823: 
        !          55824:        mov     dx, $0x3DF              /       set 132 columns
        !          55825:        movb    al, $0x10               /               in mode select register
        !          55826:        outb    dx, al
        !          55827: #endif
        !          55828:        jmp     reinit
        !          55829: 
        !          55830: 0:
        !          55831: #ifdef ATI_132
        !          55832:        mov     MM_NCOL(bp), $132       /       set columns to 132
        !          55833:        movb    MM_MODE(bp), $0x21      /       set 80/132 column display mode
        !          55834:        mov     MM_DATA(bp), $mreg132   /       set monochrome crt values
        !          55835: 
        !          55836:        call    newcrt                  /       set 132 column crt values
        !          55837:                                        /       BEFORE setting mode select reg
        !          55838: 
        !          55839:        mov     dx, $0x3BA              /       set 132 columns monochrome
        !          55840:        movb    al, $0x08               /               in mode select register
        !          55841:        outb    dx, al
        !          55842: #endif
        !          55843:        jmp     reinit
        !          55844: 
        !          55845: ////////
        !          55846: /
        !          55847: / mmspec - schedule special keyboard function
        !          55848: /
        !          55849: ////////
        !          55850: 
        !          55851: mmspec:        movb    ss:mmesc_, al
        !          55852:        jmp     eval
        !          55853: 
        !          55854: ////////
        !          55855: /
        !          55856: / mmbell - schedule beep
        !          55857: /
        !          55858: ////////
        !          55859: 
        !          55860: mmbell:        movb    ss:mmbeeps_, $-1
        !          55861:        jmp     eval
        !          55862: 
        !          55863: ////////
        !          55864: /
        !          55865: / mm_cnl - cursor next line
        !          55866: /
        !          55867: /      Moves the active position to the first column of the next display line.
        !          55868: /      Scrolls the active display if necessary.
        !          55869: /
        !          55870: ////////
        !          55871: 
        !          55872: mm_cnl:        subb    COL, COL
        !          55873:        incb    ROW
        !          55874:        cmpb    ROW, MM_EROW(bp)
        !          55875:        jna     repos
        !          55876:        movb    ROW, MM_EROW(bp)
        !          55877: /      jmp     scrollup
        !          55878: 
        !          55879: ////////
        !          55880: /
        !          55881: / scrollup - scroll display upwards
        !          55882: /
        !          55883: ////////
        !          55884: 
        !          55885: scrollup:
        !          55886:        push    ds
        !          55887:        push    si
        !          55888:        push    cx
        !          55889:        mov     ds, MM_BASE(bp)
        !          55890:        movb    bl, MM_BROW(bp)
        !          55891:        shlb    bl, $1
        !          55892:        mov     di, ss:rowtab(bx)
        !          55893:        mov     si, ss:rowtab+2(bx)
        !          55894:        movb    bl, ROW
        !          55895:        shlb    bl, $1
        !          55896:        mov     cx, ss:rowtab(bx)
        !          55897:        push    cx
        !          55898:        sub     cx, di
        !          55899:        shr     cx, $1
        !          55900:        cld
        !          55901:        rep
        !          55902:        movsw
        !          55903:        movb    al, $' 
        !          55904:        pop     di
        !          55905:        mov     cx, MM_NCOL(bp)
        !          55906:        rep
        !          55907:        stosw
        !          55908:        pop     cx
        !          55909:        pop     si
        !          55910:        pop     ds
        !          55911:        movb    bl, COL                 / reposition to ROW and COL
        !          55912:        shlb    bl, $1
        !          55913:        mov     POS, cs:coltab(bx)
        !          55914:        movb    bl, ROW
        !          55915:        shlb    bl, $1
        !          55916:        add     POS, ss:rowtab(bx)
        !          55917:        call    exit
        !          55918:        jmp     eval
        !          55919: 
        !          55920: ////////
        !          55921: /
        !          55922: / repos - reposition cursor
        !          55923: /
        !          55924: ////////
        !          55925: 
        !          55926: repos: movb    bl, COL                 / reposition to ROW and COL
        !          55927:        shl     bx, $1                  / [trash BH]
        !          55928:        mov     POS, cs:coltab(bx)
        !          55929:        subb    bh, bh                  / [clear BH]
        !          55930:        movb    bl, ROW
        !          55931:        shlb    bl, $1
        !          55932:        add     POS, ss:rowtab(bx)
        !          55933: /      jmp     eval
        !          55934: 
        !          55935: ////////
        !          55936: /
        !          55937: / eval - evaluate input character
        !          55938: /
        !          55939: ////////
        !          55940: 
        !          55941: eval:  jcxz    ewait
        !          55942:        dec     cx                              / evaluate next char
        !          55943:        lodsb
        !          55944:        movb    bl, al
        !          55945:        shlb    bl, $1
        !          55946:        ijmp    cs:asctab(bx)
        !          55947: 
        !          55948: ////////
        !          55949: /
        !          55950: / mmputc - put character on screen
        !          55951: /
        !          55952: ////////
        !          55953: 
        !          55954: mmputc:        stosw
        !          55955:        incb    COL
        !          55956:        cmpb    COL, MM_NCOL(bp)
        !          55957:        jnb     0f
        !          55958:        jcxz    ewait
        !          55959:        dec     cx
        !          55960:        lodsb
        !          55961:        movb    bl, al
        !          55962:        shlb    bl, $1
        !          55963:        ijmp    cs:asctab(bx)
        !          55964: 
        !          55965: 0:     subb    COL, COL
        !          55966:        incb    ROW
        !          55967:        cmpb    ROW, MM_EROW(bp)
        !          55968:        jg      0f
        !          55969:        jcxz    ewait
        !          55970:        dec     cx
        !          55971:        lodsb
        !          55972:        movb    bl, al
        !          55973:        shlb    bl, $1
        !          55974:        ijmp    cs:asctab(bx)
        !          55975: 
        !          55976: 0:     movb    ROW, MM_EROW(bp)
        !          55977:        jmp     scrollup
        !          55978: 
        !          55979: ////////
        !          55980: /
        !          55981: / Ewait - wait for next input char to evaluate
        !          55982: /
        !          55983: ////////
        !          55984: 
        !          55985: ewait: call    exit
        !          55986:        jcxz    ewait
        !          55987:        dec     cx
        !          55988:        lodsb
        !          55989:        movb    bl, al
        !          55990:        shlb    bl, $1
        !          55991:        ijmp    cs:asctab(bx)
        !          55992: 
        !          55993: ////////
        !          55994: /
        !          55995: / mm_cr - carriage return
        !          55996: /
        !          55997: /      Moves the active position to first position of current display line.
        !          55998: /
        !          55999: ////////
        !          56000: 
        !          56001: mm_cr: subb    COL, COL
        !          56002:        movb    bl, ROW
        !          56003:        shlb    bl, $1
        !          56004:        mov     POS, ss:rowtab(bx)
        !          56005:        jcxz    ewait
        !          56006:        dec     cx
        !          56007:        lodsb
        !          56008:        movb    bl, al
        !          56009:        shlb    bl, $1
        !          56010:        ijmp    cs:asctab(bx)
        !          56011: 
        !          56012: ////////
        !          56013: /
        !          56014: / mm_cub - cursor backwards
        !          56015: /
        !          56016: ////////
        !          56017: 
        !          56018: mm_cub:        sub     POS, $2
        !          56019:        subb    COL, $1
        !          56020:        jnb     0f
        !          56021:        movb    COL, MM_NCOL(bp)
        !          56022:        decb    COL
        !          56023:        decb    ROW
        !          56024:        cmpb    ROW, MM_BROW(bp)
        !          56025:        jge     0f
        !          56026:        subb    COL, COL
        !          56027:        movb    ROW, MM_BROW(bp)
        !          56028:        movb    bl, ROW
        !          56029:        shlb    bl, $1
        !          56030:        mov     POS, ss:rowtab(bx)
        !          56031: 0:     jcxz    ewait
        !          56032:        dec     cx
        !          56033:        lodsb
        !          56034:        movb    bl, al
        !          56035:        shlb    bl, $1
        !          56036:        ijmp    cs:asctab(bx)
        !          56037: 
        !          56038: ////////
        !          56039: /
        !          56040: / Esc state - entered when last char was ESC - transient state.
        !          56041: /
        !          56042: ////////
        !          56043: 
        !          56044: 0:     call    exit
        !          56045: mm_esc:        jcxz    0b
        !          56046:        dec     cx
        !          56047:        lodsb
        !          56048:        movb    MM_N1(bp), ZERO
        !          56049:        movb    MM_N2(bp), ZERO
        !          56050:        movb    bl, al
        !          56051:        shlb    bl, $1
        !          56052:        jc      mmputc
        !          56053:        ijmp    cs:esctab(bx)
        !          56054: 
        !          56055: ////////
        !          56056: /
        !          56057: / Csi_n1 state - entered when last two chars were ESC [
        !          56058: /
        !          56059: /      Action: Evaluates numeric chars as numeric parameter 1.
        !          56060: /
        !          56061: ////////
        !          56062: 
        !          56063: 0:     call    exit
        !          56064: csi_n1:        jcxz    0b
        !          56065:        dec     cx
        !          56066:        lodsb
        !          56067:        cmpb    al, $';
        !          56068:        je      csi_n2
        !          56069:        movb    bl, al
        !          56070:        subb    bl, $'0
        !          56071:        cmpb    bl, $9
        !          56072:        ja      csival
        !          56073:        shlb    MM_N1(bp), $1   / n1 * 2
        !          56074:        movb    al, MM_N1(bp)   / n1 * 2
        !          56075:        shlb    al, $1          / n1 * 4
        !          56076:        shlb    al, $1          / n1 * 8
        !          56077:        addb    al, MM_N1(bp)   / n1 * 10
        !          56078:        addb    al, bl          / n1 * 10 + digit
        !          56079:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          56080:        jmp     csi_n1
        !          56081: 
        !          56082: ////////
        !          56083: /
        !          56084: / Csi_n2 state - entered after input sequence ESC [ n ;
        !          56085: /
        !          56086: ////////
        !          56087: 
        !          56088: 0:     call    exit
        !          56089: csi_n2:        jcxz    0b
        !          56090:        dec     cx
        !          56091:        lodsb
        !          56092:        movb    bl, al
        !          56093:        subb    bl, $'0
        !          56094:        cmpb    bl, $9
        !          56095:        ja      csival
        !          56096:        shlb    MM_N2(bp), $1   / n2 * 2
        !          56097:        movb    al, MM_N2(bp)   / n2 * 2
        !          56098:        shlb    al, $1          / n2 * 4
        !          56099:        shlb    al, $1          / n2 * 8
        !          56100:        addb    al, MM_N2(bp)   / n2 * 10
        !          56101:        addb    al, bl          / n2 * 10 + digit
        !          56102:        movb    MM_N2(bp), al   / n2 = (n2 * 10) + digit
        !          56103:        jmp     csi_n2
        !          56104: 
        !          56105: csival:        movb    bl, al
        !          56106:        shlb    bl, $1
        !          56107:        ijmp    cs:csitab(bx)
        !          56108: 
        !          56109: ////////
        !          56110: /
        !          56111: / Csi_gt state - entered after input sequence ESC [ >
        !          56112: /      
        !          56113: ////////
        !          56114: 
        !          56115: 0:     call    exit
        !          56116: csi_gt:        jcxz    0b
        !          56117:        dec     cx
        !          56118:        lodsb
        !          56119:        movb    bl, al
        !          56120:        subb    bl, $'0
        !          56121:        cmpb    bl, $9
        !          56122:        ja      1f
        !          56123:        shlb    MM_N1(bp), $1   / n1 * 2
        !          56124:        movb    al, MM_N1(bp)   / n1 * 2
        !          56125:        shlb    al, $1          / n1 * 4
        !          56126:        shlb    al, $1          / n1 * 8
        !          56127:        addb    al, MM_N1(bp)   / n1 * 10
        !          56128:        addb    al, bl          / n1 * 10 + digit
        !          56129:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          56130:        jmp     csi_gt
        !          56131: 
        !          56132: 1:     movb    bl, al
        !          56133:        shlb    bl, $1
        !          56134:        ijmp    cs:csgtab(bx)
        !          56135: 
        !          56136: ////////
        !          56137: /
        !          56138: / mm_cbt - cursor backward tabulation
        !          56139: /
        !          56140: /      Moves the active position horizontally in the backward direction
        !          56141: /      to the preceding in a series of predetermined positions.
        !          56142: /
        !          56143: ////////
        !          56144: 
        !          56145: mm_cbt:        orb     COL, $7                 / calculate next tab stop
        !          56146:        incb    COL
        !          56147:        subb    COL, $16                / step back two tab positions
        !          56148:        jnb     0f
        !          56149:        subb    COL, COL                / can't step past column 0
        !          56150: 0:     jmp     repos                   / reposition cursor
        !          56151: 
        !          56152: ////////
        !          56153: /
        !          56154: / mm_cgh - process 'ESC [ > N1 h' escape sequence
        !          56155: /
        !          56156: /      Recognized sequences:   ESC [ > 13 h    -- Set CRT saver enabled.
        !          56157: /
        !          56158: ////////
        !          56159: 
        !          56160: mm_cgh:        cmpb    MM_N1(bp), $13
        !          56161:        jne     0f
        !          56162:        mov     ss:mmcrtsav_, $1
        !          56163: 0:     jmp     eval
        !          56164: 
        !          56165: ////////
        !          56166: /
        !          56167: / mm_cgl - process 'ESC [ > N1 l' escape sequence
        !          56168: /
        !          56169: /      Recognized sequences:   ESC [ > 13 l    -- Reset CRT saver.
        !          56170: /
        !          56171: ////////
        !          56172: 
        !          56173: mm_cgl:        cmpb    MM_N1(bp), $13
        !          56174:        jne     0f
        !          56175:        mov     ss:mmcrtsav_, $0
        !          56176: 0:     jmp     eval
        !          56177: 
        !          56178: ////////
        !          56179: /
        !          56180: / mm_cha - cursor horizontal absolute
        !          56181: /
        !          56182: /      Advances the active position forward or backward along the active line
        !          56183: /      to the character position specified by the parameter.
        !          56184: /      A parameter value of zero or one moves the active position to the
        !          56185: /      first character position of the active line.
        !          56186: /      A parameter value of N moves the active position to character position
        !          56187: /      N of the active line.
        !          56188: /
        !          56189: ////////
        !          56190: 
        !          56191: mm_cha:        movb    COL, MM_N1(bp)
        !          56192:        orb     COL, COL
        !          56193:        je      0f
        !          56194:        decb    COL
        !          56195: 0:     cmpb    COL, MM_NCOL(bp)
        !          56196:        jb      0f
        !          56197:        movb    COL, MM_NCOL(bp)
        !          56198:        decb    COL
        !          56199: 0:     jmp     repos                   / reposition cursor
        !          56200: 
        !          56201: 
        !          56202: ////////
        !          56203: /
        !          56204: / mm_cht - cursor horizontal tabulation
        !          56205: /
        !          56206: /      Advances the active position horizontally to the next or following
        !          56207: /      in a series of predetermined positions.
        !          56208: /
        !          56209: ////////
        !          56210: 
        !          56211: mm_cht:        push    cx
        !          56212:        sub     cx, cx
        !          56213:        movb    cl, COL
        !          56214:        orb     cl, $7
        !          56215:        incb    cl
        !          56216:        subb    cl, COL
        !          56217:        addb    COL, cl
        !          56218:        movb    al, $' 
        !          56219:        rep
        !          56220:        stosw
        !          56221:        pop     cx
        !          56222:        cmpb    COL, MM_NCOL(bp)
        !          56223:        jb      0f
        !          56224:        subb    COL, MM_NCOL(bp)
        !          56225:        incb    ROW
        !          56226:        cmpb    ROW, MM_EROW(bp)
        !          56227:        jna     0f
        !          56228:        movb    ROW, MM_EROW(bp)
        !          56229:        jmp     scrollup
        !          56230: 0:     jmp     eval
        !          56231: 
        !          56232: ////////
        !          56233: /
        !          56234: / mm_cpl - cursor preceding line
        !          56235: /
        !          56236: /      Moves the active position to the first position of the preceding
        !          56237: /      display line.
        !          56238: /
        !          56239: ////////
        !          56240: 
        !          56241: mm_cpl:        subb    COL, COL
        !          56242:        decb    ROW
        !          56243:        cmpb    ROW, MM_BROW(bp)
        !          56244:        jnb     0f
        !          56245:        movb    ROW, MM_BROW(bp)
        !          56246:        jmp     scrolldown
        !          56247: 0:     jmp     repos                   / reposition cursor
        !          56248: 
        !          56249: ////////
        !          56250: /
        !          56251: / mm_cud - cursor down
        !          56252: /
        !          56253: /      Moves the active position downward without altering the
        !          56254: /      horizontal position.
        !          56255: /
        !          56256: ////////
        !          56257: 
        !          56258: mm_cud:        incb    ROW
        !          56259:        cmpb    ROW, MM_EROW(bp)
        !          56260:        jna     0f
        !          56261:        movb    ROW, MM_EROW(bp)
        !          56262: 0:     jmp     repos                   / reposition cursor
        !          56263: 
        !          56264: ////////
        !          56265: /
        !          56266: / mm_cuf - cursor forward
        !          56267: /
        !          56268: /      Moves the active position in the forward direction.
        !          56269: /
        !          56270: ////////
        !          56271: 
        !          56272: mm_cuf:        incb    COL
        !          56273:        cmpb    COL, MM_NCOL(bp)
        !          56274:        jb      0f
        !          56275:        subb    COL, MM_NCOL(bp)
        !          56276:        incb    ROW
        !          56277:        cmpb    ROW, MM_EROW(bp)
        !          56278:        jna     0f
        !          56279:        movb    ROW, MM_EROW(bp)
        !          56280:        movb    COL, MM_NCOL(bp)
        !          56281:        decb    COL
        !          56282: 0:     jmp     repos
        !          56283: 
        !          56284: ////////
        !          56285: /
        !          56286: / mm_cup - cursor position
        !          56287: /
        !          56288: /      Moves the active position to the position specified by two parameters.
        !          56289: /      The 1st parameter (mm_n1) specifies the vertical   position MM_ROW(bp).
        !          56290: /      The 2nd parameter (mm_n2) specifies the horizontal position MM_COL(bp).
        !          56291: /      A parameter value of 0 or 1 for the first or second parameter
        !          56292: /      moves the active position to the first line or column in the
        !          56293: /      display respectively.
        !          56294: /
        !          56295: ////////
        !          56296: 
        !          56297: mm_cup:        movb    ROW, MM_N1(bp)
        !          56298:        orb     ROW, ROW
        !          56299:        je      0f
        !          56300:        decb    ROW
        !          56301: 0:     addb    ROW, MM_BROW(bp)
        !          56302:        cmpb    ROW, MM_EROW(bp)
        !          56303:        jb      0f
        !          56304:        movb    ROW, MM_EROW(bp)
        !          56305: 0:     movb    COL, MM_N2(bp)
        !          56306:        orb     COL, COL
        !          56307:        je      0f
        !          56308:        decb    COL
        !          56309: 0:     cmpb    COL, MM_NCOL(bp)
        !          56310:        jb      0f
        !          56311:        movb    COL, MM_NCOL(bp)
        !          56312:        decb    COL
        !          56313: 0:     jmp     repos                   / reposition cursor
        !          56314: 
        !          56315: ////////
        !          56316: /
        !          56317: / mm_cuu - cursor up
        !          56318: /
        !          56319: /      Moves the active position upward without altering the horizontal
        !          56320: /      position.
        !          56321: /
        !          56322: ////////
        !          56323: 
        !          56324: mm_cuu:        decb    ROW
        !          56325:        cmpb    ROW, MM_BROW(bp)
        !          56326:        jge     0f
        !          56327:        movb    ROW, MM_BROW(bp)
        !          56328: 0:     jmp     repos                   / reposition cursor
        !          56329: 
        !          56330: ////////
        !          56331: /
        !          56332: / mm_dl - delete line
        !          56333: /
        !          56334: /      Removes the contents of the active line.
        !          56335: /      The contents of all following lines are shifted in a block
        !          56336: /      toward the active line.
        !          56337: /
        !          56338: ////////
        !          56339: 
        !          56340: mm_dl: push    ds
        !          56341:        push    si
        !          56342:        push    cx
        !          56343:        mov     ds, MM_BASE(bp)
        !          56344:        movb    bl, ROW
        !          56345:        shlb    bl, $1
        !          56346:        mov     di, ss:rowtab(bx)
        !          56347:        mov     si, ss:rowtab+2(bx)
        !          56348:        movb    bl, MM_EROW(bp)
        !          56349:        shlb    bl, $1
        !          56350:        mov     cx, ss:rowtab(bx)
        !          56351:        sub     cx, di
        !          56352:        jle     0f
        !          56353:        shr     cx, $1
        !          56354:        rep
        !          56355:        movsw
        !          56356:        mov     di, ss:rowtab(bx)
        !          56357:        mov     cx, MM_NCOL(bp)
        !          56358:        movb    al, $' 
        !          56359:        rep
        !          56360:        stosw
        !          56361:        subb    COL, COL
        !          56362:        movb    bl, ROW
        !          56363:        shlb    bl, $1
        !          56364:        mov     di, ss:rowtab(bx)
        !          56365: 0:     pop     cx
        !          56366:        pop     si
        !          56367:        pop     ds
        !          56368:        call    exit
        !          56369:        jmp     eval
        !          56370: 
        !          56371: ////////
        !          56372: /
        !          56373: / mm_dmi - disable manual input
        !          56374: /
        !          56375: /      Set flag preventing keyboard input, and causing cursor to vanish.
        !          56376: /
        !          56377: ////////
        !          56378: 
        !          56379: mm_dmi:
        !          56380:        mov     ss:islock_, $1
        !          56381:        jmp     eval
        !          56382: 
        !          56383: ////////
        !          56384: /
        !          56385: / mm_ea - erase in area
        !          56386: /
        !          56387: /      Erase some or all of the characters in the currently active area
        !          56388: /      according to the parameter:
        !          56389: /              0 - erase from active position to end inclusive (default)
        !          56390: /              1 - erase from start to active position inclusive
        !          56391: /              2 - erase all of active area
        !          56392: /
        !          56393: ////////
        !          56394: 
        !          56395: mm_ea: movb    al, MM_N1(bp)
        !          56396:        cmpb    al, $0
        !          56397:        jne     0f
        !          56398:        movb    bl, MM_EROW(bp)
        !          56399:        jmp     mm_e0
        !          56400: 0:     cmpb    al, $1
        !          56401:        jne     0f
        !          56402:        movb    bl, MM_BROW(bp)
        !          56403:        jmp     mm_e1
        !          56404: 0:     subb    COL, COL
        !          56405:        movb    ROW, MM_BROW(bp)
        !          56406:        movb    bl, ROW
        !          56407:        shlb    bl, $1
        !          56408:        mov     POS, ss:rowtab(bx)
        !          56409:        movb    bl, MM_EROW(bp)
        !          56410:        subb    bl, ROW
        !          56411:        jmp     mm_e2
        !          56412: 
        !          56413: 
        !          56414: ////////
        !          56415: /
        !          56416: / mm_ed - erase in display
        !          56417: /
        !          56418: /      Erase some or all of the characters in the display according to the
        !          56419: /      parameter
        !          56420: /              0 - erase from active position to end inclusive (default)
        !          56421: /              1 - erase from start to active position inclusive
        !          56422: /              2 - erase all of display
        !          56423: /
        !          56424: ////////
        !          56425: 
        !          56426: mm_ed: movb    al, MM_N1(bp)
        !          56427:        cmpb    al, $0
        !          56428:        jne     0f
        !          56429:        movb    bl, MM_LROW(bp)
        !          56430:        jmp     mm_e0
        !          56431: 0:     cmpb    al, $1
        !          56432:        jne     0f
        !          56433:        subb    bl, bl
        !          56434:        jmp     mm_e1
        !          56435: 0:     subb    COL, COL
        !          56436:        movb    ROW, MM_BROW(bp)
        !          56437:        sub     POS, POS
        !          56438:        movb    bl, MM_LROW(bp)
        !          56439:        jmp     mm_e2
        !          56440: 
        !          56441: ////////
        !          56442: /
        !          56443: / mm_el - erase in line
        !          56444: /
        !          56445: /      Erase some or all of the characters in the line according to the
        !          56446: /      parameter:
        !          56447: /              0 - erase from active position to end inclusive (default)
        !          56448: /              1 - erase from start to active position inclusive
        !          56449: /              2 - erase entire line
        !          56450: /
        !          56451: ////////
        !          56452: 
        !          56453: mm_el: movb    al, MM_N1(bp)
        !          56454:        movb    bl, ROW
        !          56455:        cmpb    al, $0
        !          56456:        je      mm_e0
        !          56457:        cmpb    al, $1
        !          56458:        je      mm_e1
        !          56459:        shlb    bl, $1
        !          56460:        mov     POS, ss:rowtab(bx)
        !          56461:        subb    COL, COL
        !          56462:        subb    bl, bl
        !          56463: /      jmp     mm_e2
        !          56464: 
        !          56465: mm_e2: push    cx
        !          56466:        movb    al, $' 
        !          56467: 0:     mov     cx, MM_NCOL(bp)
        !          56468:        rep
        !          56469:        stosw
        !          56470:        decb    bl
        !          56471:        jge     0b
        !          56472:        pop     cx
        !          56473:        jmp     repos
        !          56474: 
        !          56475: mm_e1: push    cx
        !          56476:        mov     cx, POS
        !          56477:        shlb    bl, $1
        !          56478:        mov     POS, ss:rowtab(bx)
        !          56479:        sub     cx, POS
        !          56480:        jl      0f
        !          56481:        movb    al, $' 
        !          56482:        shr     cx, $1
        !          56483:        rep
        !          56484:        stosw
        !          56485: 0:     pop     cx
        !          56486:        jmp     repos
        !          56487: 
        !          56488: mm_e0: push    cx
        !          56489:        shlb    bl, $1
        !          56490:        mov     cx, ss:rowtab+2(bx)
        !          56491:        sub     cx, POS
        !          56492:        jl      0f
        !          56493:        movb    al, $' 
        !          56494:        shr     cx, $1
        !          56495:        rep
        !          56496:        stosw
        !          56497: 0:     pop     cx
        !          56498:        jmp     repos
        !          56499: 
        !          56500: ////////
        !          56501: /
        !          56502: / mm_emi - enable manual input
        !          56503: /
        !          56504: /      Clear flag preventing keyboard input.
        !          56505: /
        !          56506: ////////
        !          56507: 
        !          56508: mm_emi:
        !          56509:        mov     ss:islock_, $0
        !          56510:        jmp     eval
        !          56511: 
        !          56512: ////////
        !          56513: /
        !          56514: / mm_il - insert line
        !          56515: /
        !          56516: /      Insert a erased line at the active line by shifting the contents
        !          56517: /      of the active line and all following lines away from the active line.
        !          56518: /      The contents of the last line in the scrolling region are removed.
        !          56519: /
        !          56520: ////////
        !          56521: 
        !          56522: scrolldown:
        !          56523: mm_il: push    ds
        !          56524:        push    si
        !          56525:        push    cx
        !          56526:        mov     ds, MM_BASE(bp)
        !          56527:        movb    bl, MM_EROW(bp)
        !          56528:        shlb    bl, $1
        !          56529:        mov     si, ss:rowtab(bx)
        !          56530:        mov     cx, si
        !          56531:        sub     si, $2
        !          56532:        mov     di, ss:rowtab+2(bx)
        !          56533:        sub     di, $2
        !          56534:        movb    bl, ROW
        !          56535:        shlb    bl, $1
        !          56536:        sub     cx, ss:rowtab(bx)
        !          56537:        jle     0f
        !          56538:        shr     cx, $1
        !          56539:        std
        !          56540:        rep
        !          56541:        movsw
        !          56542:        mov     di, ss:rowtab(bx)
        !          56543:        mov     cx, MM_NCOL(bp)
        !          56544:        movb    al, $' 
        !          56545:        cld
        !          56546:        rep
        !          56547:        stosw
        !          56548:        subb    COL, COL
        !          56549:        movb    bl, ROW
        !          56550:        shlb    bl, $1
        !          56551:        mov     di, ss:rowtab(bx)
        !          56552: 0:     pop     cx
        !          56553:        pop     si
        !          56554:        pop     ds
        !          56555:        call    exit
        !          56556:        jmp     eval
        !          56557: 
        !          56558: ////////
        !          56559: /
        !          56560: / mm_hpa - horizontal position absolute
        !          56561: /
        !          56562: /      Moves the active position within the active line to the position
        !          56563: /      specified by the parameter.  A parameter value of zero or one
        !          56564: /      moves the active position to the first position of the active line.
        !          56565: /
        !          56566: ////////
        !          56567: 
        !          56568: mm_hpa:        movb    COL, MM_N1(bp)
        !          56569:        orb     COL, COL
        !          56570:        je      0f
        !          56571:        decb    COL
        !          56572: 0:     cmpb    COL, MM_NCOL(bp)
        !          56573:        jb      0f
        !          56574:        movb    COL, MM_NCOL(bp)
        !          56575:        decb    COL
        !          56576: 0:     jmp     repos                   / reposition cursor
        !          56577: 
        !          56578: ////////
        !          56579: /
        !          56580: / mm_hpr - horizontal position relative
        !          56581: /
        !          56582: /      Moves the active position forward the number of positions specified
        !          56583: /      by the parameter.  A parameter value of zero or one indicates a
        !          56584: /      single-position move.
        !          56585: /
        !          56586: ////////
        !          56587: 
        !          56588: mm_hpr:        movb    al, MM_N1(bp)
        !          56589:        orb     al, al
        !          56590:        jne     0f
        !          56591:        incb    al
        !          56592: 0:     addb    COL, al
        !          56593:        cmpb    COL, MM_NCOL(bp)
        !          56594:        jb      0f
        !          56595:        movb    COL, MM_NCOL(bp)
        !          56596:        decb    COL
        !          56597: 0:     jmp     repos                   / reposition cursor
        !          56598: 
        !          56599: ////////
        !          56600: /
        !          56601: / mm_hvp - horizontal and vertical position
        !          56602: /
        !          56603: /      Moves the active position to the position specified by two parameters.
        !          56604: /      The first parameter specifies the vertical position (MM_ROW(bp)).
        !          56605: /      The second parameter specifies the horizontal position (MM_COL(bp)).
        !          56606: /      A parameter value of zero or one moves the active position to the
        !          56607: /      first line or column in the display.
        !          56608: /
        !          56609: ////////
        !          56610: 
        !          56611: mm_hvp:        movb    ROW, MM_N1(bp)
        !          56612:        orb     ROW, ROW
        !          56613:        je      0f
        !          56614:        decb    ROW
        !          56615: 0:     cmpb    ROW, MM_LROW(bp)
        !          56616:        jna     0f
        !          56617:        movb    ROW, MM_LROW(bp)
        !          56618: 0:     movb    COL, MM_N2(bp)
        !          56619:        orb     COL, COL
        !          56620:        je      0f
        !          56621:        decb    COL
        !          56622: 0:     cmpb    COL, MM_NCOL(bp)
        !          56623:        jb      0f
        !          56624:        movb    COL, MM_NCOL(bp)
        !          56625:        decb    COL
        !          56626: 0:     jmp     repos                   / reposition cursor
        !          56627: 
        !          56628: ////////
        !          56629: /
        !          56630: / mm_ind - index
        !          56631: /
        !          56632: /      Causes the active position to move downward one line without changing
        !          56633: /      the horizontal position.  Scrolling occurs if below scrolling region.
        !          56634: /
        !          56635: ////////
        !          56636: 
        !          56637: mm_ind:        incb    ROW
        !          56638:        cmpb    ROW, MM_EROW(bp)
        !          56639:        jg      0f
        !          56640:        jmp     repos
        !          56641: 0:     movb    ROW, MM_EROW(bp)
        !          56642:        jmp     scrollup
        !          56643: 
        !          56644: ////////
        !          56645: /
        !          56646: / mm_new - save cursor position
        !          56647: /
        !          56648: ////////
        !          56649: 
        !          56650: mm_new:        movb    MM_SCOL(bp), COL
        !          56651:        movb    MM_SROW(bp), ROW
        !          56652:        jmp     eval
        !          56653: 
        !          56654: ////////
        !          56655: /
        !          56656: / mm_old - restore old cursor position
        !          56657: /
        !          56658: ////////
        !          56659: 
        !          56660: mm_old:        movb    COL, MM_SCOL(bp)
        !          56661:        movb    ROW, MM_SROW(bp)
        !          56662:        jmp     repos
        !          56663: 
        !          56664: ////////
        !          56665: /
        !          56666: / mm_ri - reverse index
        !          56667: /
        !          56668: /      Moves the active position to the same horizontal position on the
        !          56669: /      preceding line.  Scrolling occurs if above scrolling region.
        !          56670: /
        !          56671: ////////
        !          56672: 
        !          56673: mm_ri: decb    ROW
        !          56674:        cmpb    ROW, MM_BROW(bp)
        !          56675:        jge     0f
        !          56676:        movb    ROW, MM_BROW(bp)
        !          56677:        jmp     scrolldown
        !          56678: 0:     jmp     repos
        !          56679: 
        !          56680: ////////
        !          56681: /
        !          56682: / mm_scr - select cursor rendition
        !          56683: /
        !          56684: /      Invokes the cursor rendition specified by the parameter.
        !          56685: /
        !          56686: /      Recognized renditions are:      0 - cursor visible
        !          56687: /                                      1 - cursor invisible
        !          56688: ////////
        !          56689: 
        !          56690: mm_scr:        decb     MM_N1(bp)
        !          56691:        je      0f
        !          56692:        jg      1f
        !          56693:        mov     MM_INVIS(bp), $0
        !          56694:        jmp     eval
        !          56695: 
        !          56696: 0:     mov     MM_INVIS(bp), $-1
        !          56697: 1:     jmp     eval
        !          56698: 
        !          56699: ////////
        !          56700: /
        !          56701: / mm_sgr - select graphic rendition
        !          56702: /
        !          56703: /      Invokes the graphic rendition specified by the parameter.
        !          56704: /      All following characters in the data stream are rendered
        !          56705: /      according to the parameters until the next occurrence of
        !          56706: /      SGR in the data stream.
        !          56707: /
        !          56708: /      Recognized renditions are:      1 - high intensity
        !          56709: /                                      4 - underline
        !          56710: /                                      5 - slow blink
        !          56711: /                                      7 - reverse video
        !          56712: /                                      30-37 - foreground color
        !          56713: /                                      40-47 - background color
        !          56714: /                                      50-57 - border color
        !          56715: /
        !          56716: ////////
        !          56717: 
        !          56718: mm_sgr:        movb    al, MM_N1(bp)
        !          56719:        cmpb    al, $0
        !          56720:        jne     0f
        !          56721:        movb    ATTR, $0x07
        !          56722: 1:     jmp     eval
        !          56723: 0:     cmpb    al, $1          / bold
        !          56724:        jne     0f
        !          56725:        orb     ATTR, $INTENSE
        !          56726:        jmp     1b
        !          56727: 0:     cmpb    al, $4          / underline
        !          56728:        jne     0f
        !          56729:        cmp     MM_PORT(bp), $0x03D4    / color card?
        !          56730:        je      1b                      / yes, ignore underline
        !          56731:        andb    ATTR, $~0x77
        !          56732:        orb     ATTR, $0x01
        !          56733:        jmp     1b
        !          56734: 0:     cmpb    al, $5          / blinking
        !          56735:        jne     0f
        !          56736:        orb     ATTR, $BLINK
        !          56737:        jmp     1b
        !          56738: 0:     cmpb    al, $7          / reverse video
        !          56739:        jne     0f
        !          56740:        movb    al, $0x70
        !          56741:        cmp     MM_PORT(bp), $0x3D4     / color card?
        !          56742:        jne     2f
        !          56743:        movb    al, ah                  / yes, exchange foreground/background
        !          56744:        andb    al, $0x77
        !          56745:        rolb    al, $1
        !          56746:        rolb    al, $1
        !          56747:        rolb    al, $1
        !          56748:        rolb    al, $1
        !          56749: 2:     andb    ATTR, $~0x77
        !          56750:        orb     ATTR, al
        !          56751:        jmp     1b
        !          56752: 0:     cmp     MM_PORT(bp), $0x03D4    / color card?
        !          56753:        jne     1b                      / no, ignore remaining options
        !          56754: 0:     subb    al, $30         / foreground color
        !          56755:        jl      1f
        !          56756:        cmpb    al, $7
        !          56757:        jg      0f
        !          56758:        movb    bl, al
        !          56759:        andb    ATTR, $~0x07
        !          56760:        orb     ATTR, cs:fcolor(bx)
        !          56761:        jmp     1f
        !          56762: 0:     subb    al, $10
        !          56763:        jl      1f
        !          56764:        cmpb    al, $7
        !          56765:        jg      0f
        !          56766:        movb    bl, al
        !          56767:        andb    ATTR, $~0x70
        !          56768:        orb     ATTR, cs:bcolor(bx)
        !          56769:        jmp     1f
        !          56770: 0:     subb    al, $10
        !          56771:        jl      1f
        !          56772:        cmpb    al, $7
        !          56773:        jg      0f
        !          56774:        movb    bl, al
        !          56775:        movb    al, cs:fcolor(bx)
        !          56776:        push    dx
        !          56777:        mov     dx, MM_PORT(bp)
        !          56778:        add     dx, $5
        !          56779:        outb    dx, al
        !          56780:        pop     dx
        !          56781: /      jmp     1f
        !          56782: 0:
        !          56783: 1:     jmp     eval
        !          56784: 
        !          56785: ////////
        !          56786: /
        !          56787: / mm_ssr - set scrolling region
        !          56788: /
        !          56789: ////////
        !          56790: 
        !          56791: mm_ssr:        movb    al, MM_N1(bp)
        !          56792:        decb    al
        !          56793:        jge     0f
        !          56794:        subb    al, al
        !          56795: 0:     cmpb    al, MM_LROW(bp)
        !          56796:        ja      1f
        !          56797:        movb    bl, MM_N2(bp)
        !          56798:        decb    bl
        !          56799:        jge     0f
        !          56800:        subb    bl, bl
        !          56801: 0:     cmpb    bl, MM_LROW(bp)
        !          56802:        ja      1f
        !          56803:        cmpb    al, bl
        !          56804:        ja      1f
        !          56805:        movb    MM_BROW(bp), al
        !          56806:        movb    MM_EROW(bp), bl
        !          56807:        movb    ROW, al
        !          56808:        subb    COL, COL
        !          56809: 1:     jmp     repos
        !          56810: 
        !          56811: ////////
        !          56812: /
        !          56813: / mm_vpa - vertical position absolute
        !          56814: /
        !          56815: /      Moves the active position to the line specified by the parameter
        !          56816: /      without changing the horizontal position.
        !          56817: /      A parameter value of 0 or 1 moves the active position vertically
        !          56818: /      to the first line.
        !          56819: /
        !          56820: ////////
        !          56821: 
        !          56822: mm_vpa:        movb    ROW, MM_N1(bp)
        !          56823:        decb    ROW
        !          56824:        jg      0f
        !          56825:        subb    ROW, ROW
        !          56826: 0:     cmpb    ROW, MM_LROW(bp)
        !          56827:        jna     0f
        !          56828:        movb    ROW, MM_LROW(bp)
        !          56829: 0:     jmp     repos                   / reposition cursor
        !          56830: 
        !          56831: ////////
        !          56832: /
        !          56833: / mm_vpr - vertical position relative
        !          56834: /
        !          56835: /      Moves the active position downward the number of lines specified
        !          56836: /      by the parameter without changing the horizontal position.
        !          56837: /      A parameter value of zero or one moves the active position
        !          56838: /      one line downward.
        !          56839: /
        !          56840: ////////
        !          56841: 
        !          56842: mm_vpr:        movb    al, MM_N1(bp)
        !          56843:        orb     al, al
        !          56844:        jne     0f
        !          56845:        incb    al
        !          56846: 0:     addb    ROW, al
        !          56847:        cmpb    ROW, MM_LROW(bp)
        !          56848:        jb      0f
        !          56849:        movb    ROW, MM_LROW(bp)
        !          56850: 0:     jmp     repos                   / reposition cursor
        !          56851: 
        !          56852: ////////
        !          56853: /
        !          56854: / asctab - table of functions indexed by ascii characters
        !          56855: /
        !          56856: ////////
        !          56857: 
        !          56858: asctab:        .word   eval,   eval,   eval,   eval    /       NUL  SOH  STX  ETX
        !          56859:        .word   eval,   eval,   eval,   mmbell  /       EOT  ENQ  ACK  BEL
        !          56860:        .word   mm_cub, mm_cht, mm_cnl, mm_ind  /       BS   HT   LF   VT
        !          56861:        .word   eval,   mm_cr,  mm_so,  mm_si   /       FF   CR   SO   SI
        !          56862:        .word   eval,   eval,   eval,   eval    /       DLE  DC1  DC2  DC3
        !          56863: / DEBUG: mm_132 is only inserted temporarily, for testing - 86/05/26
        !          56864:        .word   eval,   eval,   eval,   mm_132  /       DC4  NAK  SYN  ETB
        !          56865:        .word   eval,   eval,   eval,   mm_esc  /       CAN  EM   SUB  ESC
        !          56866:        .word   eval,   eval,   eval,   eval    /       FS   GS   RS   US
        !          56867:        .word   mmputc, mmputc, mmputc, mmputc  /         ! " # \040 - \043
        !          56868:        .word   mmputc, mmputc, mmputc, mmputc  /       $ % & ' \044 - \047
        !          56869:        .word   mmputc, mmputc, mmputc, mmputc  /       ( ) * + \050 - \053
        !          56870:        .word   mmputc, mmputc, mmputc, mmputc  /       , - . / \054 - \057
        !          56871:        .word   mmputc, mmputc, mmputc, mmputc  /       0 1 2 3 \060 - \063
        !          56872:        .word   mmputc, mmputc, mmputc, mmputc  /       4 5 6 7 \064 - \067
        !          56873:        .word   mmputc, mmputc, mmputc, mmputc  /       8 9 : ; \070 - \073
        !          56874:        .word   mmputc, mmputc, mmputc, mmputc  /       < = > ? \074 - \077
        !          56875:        .word   mmputc, mmputc, mmputc, mmputc  /       @@ A B C \100 - \103
        !          56876:        .word   mmputc, mmputc, mmputc, mmputc  /       D E F G \104 - \107
        !          56877:        .word   mmputc, mmputc, mmputc, mmputc  /       H I J K \110 - \113
        !          56878:        .word   mmputc, mmputc, mmputc, mmputc  /       L M N O \114 - \117
        !          56879:        .word   mmputc, mmputc, mmputc, mmputc  /       P Q R S \120 - \123
        !          56880:        .word   mmputc, mmputc, mmputc, mmputc  /       T U V W \124 - \127
        !          56881:        .word   mmputc, mmputc, mmputc, mmputc  /       X Y Z [ \130 - \133
        !          56882:        .word   mmputc, mmputc, mmputc, mmputc  /       \ ] ^ _ \134 - \137
        !          56883:        .word   mmputc, mmputc, mmputc, mmputc  /       ` a b c \140 - \143
        !          56884:        .word   mmputc, mmputc, mmputc, mmputc  /       d e f g \144 - \147
        !          56885:        .word   mmputc, mmputc, mmputc, mmputc  /       h i j k \150 - \153
        !          56886:        .word   mmputc, mmputc, mmputc, mmputc  /       l m n o \154 - \157
        !          56887:        .word   mmputc, mmputc, mmputc, mmputc  /       p q r s \160 - \163
        !          56888:        .word   mmputc, mmputc, mmputc, mmputc  /       t u v w \164 - \167
        !          56889:        .word   mmputc, mmputc, mmputc, mmputc  /       x y z { \170 - \173
        !          56890:        .word   mmputc, mmputc, mmputc, mmputc  /       | } ~ ? \174 - \177
        !          56891: 
        !          56892: ////////
        !          56893: /
        !          56894: / esctab - table of functions indexed by escape characters.
        !          56895: /
        !          56896: ////////
        !          56897: 
        !          56898: esctab:        .word   mmputc, mmputc, mmputc, mmputc  /       NUL  SOH  STX  ETX
        !          56899:        .word   mmputc, mmputc, mmputc, mmputc  /       EOT  ENQ  ACK  BEL
        !          56900:        .word   mmputc, mmputc, mmputc, mmputc  /       BS   HT   LF   VT
        !          56901:        .word   mmputc, mmputc, mmputc, mmputc  /       FF   CR   SO   SI
        !          56902:        .word   mmputc, mmputc, mmputc, mmputc  /       DLE  DC1  DC2  DC3
        !          56903:        .word   mmputc, mmputc, mmputc, mmputc  /       DC4  NAK  SYN  ETB
        !          56904:        .word   mmputc, mmputc, mmputc, mmputc  /       CAN  EM   SUB  ESC
        !          56905:        .word   mmputc, mmputc, mmputc, mmputc  /       FS   GS   RS   US
        !          56906:        .word   eval,   eval,   eval,   eval    /         ! " # \040 - \043
        !          56907:        .word   eval,   eval,   eval,   eval    /       $ % & ' \044 - \047
        !          56908:        .word   eval,   eval,   eval,   eval    /       ( ) * + \050 - \053
        !          56909:        .word   eval,   eval,   eval,   eval    /       , - . / \054 - \057
        !          56910:        .word   eval,   eval,   eval,   eval    /       0 1 2 3 \060 - \063
        !          56911:        .word   eval,   eval,   eval,   mm_new  /       4 5 6 7 \064 - \067
        !          56912:        .word   mm_old, eval,   eval,   eval    /       8 9 : ; \070 - \073
        !          56913:        .word   eval,   mmspec, mmspec, eval    /       < = > ? \074 - \077
        !          56914:        .word   eval,   eval,   eval,   eval    /       @@ A B C \100 - \103
        !          56915:        .word   mm_ind, mm_cnl, eval,   eval    /       D E F G \104 - \107
        !          56916:        .word   eval,   eval,   eval,   eval    /       H I J K \110 - \113
        !          56917:        .word   eval,   mm_ri,  eval,   eval    /       L M N O \114 - \117
        !          56918:        .word   eval,   eval,   eval,   eval    /       P Q R S \120 - \123
        !          56919:        .word   eval,   eval,   eval,   eval    /       T U V W \124 - \127
        !          56920:        .word   eval,   eval,   eval,   csi_n1  /       X Y Z [ \130 - \133
        !          56921:        .word   eval,   eval,   eval,   eval    /       \ ] ^ _ \134 - \137
        !          56922:        .word   mm_dmi, eval,   mm_emi, mminit  /       ` a b c \140 - \143
        !          56923:        .word   eval,   eval,   eval,   eval    /       d e f g \144 - \147
        !          56924:        .word   eval,   eval,   eval,   eval    /       h i j k \150 - \153
        !          56925:        .word   eval,   eval,   eval,   eval    /       l m n o \154 - \157
        !          56926:        .word   eval,   eval,   eval,   eval    /       p q r s \160 - \163
        !          56927:        .word   mmspec, mmspec, eval,   eval    /       t u v w \164 - \167
        !          56928:        .word   eval,   eval,   eval,   eval    /       x y z { \170 - \173
        !          56929:        .word   eval,   eval,   eval,   eval    /       | } ~ ? \174 - \177
        !          56930: 
        !          56931: ////////
        !          56932: /
        !          56933: / csitab - table of functions indexed by ESC [ characters.
        !          56934: /
        !          56935: ////////
        !          56936: 
        !          56937: csitab:        .word   eval,   eval,   eval,   eval    /       NUL  SOH  STX  ETX
        !          56938:        .word   eval,   eval,   eval,   eval    /       EOT  ENQ  ACK  BEL
        !          56939:        .word   eval,   eval,   eval,   eval    /       BS   HT   LF   VT
        !          56940:        .word   eval,   eval,   eval,   eval    /       FF   CR   SO   SI
        !          56941:        .word   eval,   eval,   eval,   eval    /       DLE  DC1  DC2  DC3
        !          56942:        .word   eval,   eval,   eval,   eval    /       DC4  NAK  SYN  ETB
        !          56943:        .word   eval,   eval,   eval,   eval    /       CAN  EM   SUB  ESC
        !          56944:        .word   eval,   eval,   eval,   eval    /       FS   GS   RS   US
        !          56945:        .word   eval,   eval,   eval,   eval    /         ! " # \040 - \043
        !          56946:        .word   eval,   eval,   eval,   eval    /       $ % & ' \044 - \047
        !          56947:        .word   eval,   eval,   eval,   eval    /       ( ) * + \050 - \053
        !          56948:        .word   eval,   eval,   eval,   eval    /       , - . / \054 - \057
        !          56949:        .word   eval,   eval,   eval,   eval    /       0 1 2 3 \060 - \063
        !          56950:        .word   eval,   eval,   eval,   eval    /       4 5 6 7 \064 - \067
        !          56951:        .word   eval,   eval,   eval,   eval    /       8 9 : ; \070 - \073
        !          56952:        .word   eval,   eval,   csi_gt, eval    /       < = > ? \074 - \077
        !          56953:        .word   eval,   mm_cuu, mm_cud, mm_cuf  /       @@ A B C \100 - \103
        !          56954:        .word   mm_cub, mm_cnl, mm_cpl, mm_cha  /       D E F G \104 - \107
        !          56955:        .word   mm_cup, mm_cht, mm_ed,  mm_el   /       H I J K \110 - \113
        !          56956:        .word   mm_il,  mm_dl,  eval,   mm_ea   /       L M N O \114 - \117
        !          56957:        .word   eval,   eval,   eval,   mm_ind  /       P Q R S \120 - \123
        !          56958:        .word   mm_ri,  eval,   eval,   eval    /       T U V W \124 - \127
        !          56959:        .word   eval,   eval,   mm_cbt, eval    /       X Y Z [ \130 - \133
        !          56960:        .word   eval,   eval,   eval,   eval    /       \ ] ^ _ \134 - \137
        !          56961:        .word   mm_hpa, mm_hpr, eval,   eval    /       ` a b c \140 - \143
        !          56962:        .word   mm_vpa, mm_vpr, mm_hvp, mm_cup  /       d e f g \144 - \147
        !          56963:        .word   eval,   eval,   eval,   eval    /       h i j k \150 - \153
        !          56964:        .word   eval,   mm_sgr, eval,   eval    /       l m n o \154 - \157
        !          56965:        .word   eval,   eval,   mm_ssr, eval    /       p q r s \160 - \163
        !          56966:        .word   eval,   eval,   mm_scr, eval    /       t u v w \164 - \167
        !          56967:        .word   eval,   eval,   eval,   eval    /       x y z { \170 - \173
        !          56968:        .word   eval,   eval,   eval,   eval    /       | } ~ ? \174 - \177
        !          56969: 
        !          56970: ////////
        !          56971: /
        !          56972: / csgtab - table of functions indexed by ESC [ > characters.
        !          56973: /
        !          56974: ////////
        !          56975: 
        !          56976: csgtab:        .word   eval,   eval,   eval,   eval    /       NUL  SOH  STX  ETX
        !          56977:        .word   eval,   eval,   eval,   eval    /       EOT  ENQ  ACK  BEL
        !          56978:        .word   eval,   eval,   eval,   eval    /       BS   HT   LF   VT
        !          56979:        .word   eval,   eval,   eval,   eval    /       FF   CR   SO   SI
        !          56980:        .word   eval,   eval,   eval,   eval    /       DLE  DC1  DC2  DC3
        !          56981:        .word   eval,   eval,   eval,   eval    /       DC4  NAK  SYN  ETB
        !          56982:        .word   eval,   eval,   eval,   eval    /       CAN  EM   SUB  ESC
        !          56983:        .word   eval,   eval,   eval,   eval    /       FS   GS   RS   US
        !          56984:        .word   eval,   eval,   eval,   eval    /         ! " # \040 - \043
        !          56985:        .word   eval,   eval,   eval,   eval    /       $ % & ' \044 - \047
        !          56986:        .word   eval,   eval,   eval,   eval    /       ( ) * + \050 - \053
        !          56987:        .word   eval,   eval,   eval,   eval    /       , - . / \054 - \057
        !          56988:        .word   eval,   eval,   eval,   eval    /       0 1 2 3 \060 - \063
        !          56989:        .word   eval,   eval,   eval,   eval    /       4 5 6 7 \064 - \067
        !          56990:        .word   eval,   eval,   eval,   eval    /       8 9 : ; \070 - \073
        !          56991:        .word   eval,   eval,   eval,   eval    /       < = > ? \074 - \077
        !          56992:        .word   eval,   eval,   eval,   eval    /       @@ A B C \100 - \103
        !          56993:        .word   eval,   eval,   eval,   eval    /       D E F G \104 - \107
        !          56994:        .word   eval,   eval,   eval,   eval    /       H I J K \110 - \113
        !          56995:        .word   eval,   eval,   eval,   eval    /       L M N O \114 - \117
        !          56996:        .word   eval,   eval,   eval,   eval    /       P Q R S \120 - \123
        !          56997:        .word   eval,   eval,   eval,   eval    /       T U V W \124 - \127
        !          56998:        .word   eval,   eval,   eval,   eval    /       X Y Z [ \130 - \133
        !          56999:        .word   eval,   eval,   eval,   eval    /       \ ] ^ _ \134 - \137
        !          57000:        .word   eval,   eval,   eval,   eval    /       ` a b c \140 - \143
        !          57001:        .word   eval,   eval,   eval,   eval    /       d e f g \144 - \147
        !          57002:        .word   mm_cgh, eval,   eval,   eval    /       h i j k \150 - \153
        !          57003:        .word   mm_cgl, eval,   eval,   eval    /       l m n o \154 - \157
        !          57004:        .word   eval,   eval,   eval,   eval    /       p q r s \160 - \163
        !          57005:        .word   eval,   eval,   eval,   eval    /       t u v w \164 - \167
        !          57006:        .word   eval,   eval,   eval,   eval    /       x y z { \170 - \173
        !          57007:        .word   eval,   eval,   eval,   eval    /       | } ~ ? \174 - \177
        !          57008: 
        !          57009: ////////
        !          57010: /
        !          57011: / coltab - integer array of offsets to each column - up to 132 columns
        !          57012: /
        !          57013: ////////
        !          57014: 
        !          57015: coltab:        .word     0*NCB,   1*NCB,   2*NCB,   3*NCB
        !          57016:        .word     4*NCB,   5*NCB,   6*NCB,   7*NCB
        !          57017:        .word     8*NCB,   9*NCB,  10*NCB,  11*NCB
        !          57018:        .word    12*NCB,  13*NCB,  14*NCB,  15*NCB
        !          57019:        .word    16*NCB,  17*NCB,  18*NCB,  19*NCB
        !          57020:        .word    20*NCB,  21*NCB,  22*NCB,  23*NCB
        !          57021:        .word    24*NCB,  25*NCB,  26*NCB,  27*NCB
        !          57022:        .word    28*NCB,  29*NCB,  30*NCB,  31*NCB
        !          57023:        .word    32*NCB,  33*NCB,  34*NCB,  35*NCB
        !          57024:        .word    36*NCB,  37*NCB,  38*NCB,  39*NCB
        !          57025:        .word    40*NCB,  41*NCB,  42*NCB,  43*NCB
        !          57026:        .word    44*NCB,  45*NCB,  46*NCB,  47*NCB
        !          57027:        .word    48*NCB,  49*NCB,  50*NCB,  51*NCB
        !          57028:        .word    52*NCB,  53*NCB,  54*NCB,  55*NCB
        !          57029:        .word    56*NCB,  57*NCB,  58*NCB,  59*NCB
        !          57030:        .word    60*NCB,  61*NCB,  62*NCB,  63*NCB
        !          57031:        .word    64*NCB,  65*NCB,  66*NCB,  67*NCB
        !          57032:        .word    68*NCB,  69*NCB,  70*NCB,  71*NCB
        !          57033:        .word    72*NCB,  73*NCB,  74*NCB,  75*NCB
        !          57034:        .word    76*NCB,  77*NCB,  78*NCB,  79*NCB
        !          57035:        .word    80*NCB,  81*NCB,  82*NCB,  83*NCB
        !          57036:        .word    84*NCB,  85*NCB,  86*NCB,  87*NCB
        !          57037:        .word    88*NCB,  89*NCB,  90*NCB,  91*NCB
        !          57038:        .word    92*NCB,  93*NCB,  94*NCB,  95*NCB
        !          57039:        .word    96*NCB,  97*NCB,  98*NCB,  99*NCB
        !          57040:        .word   100*NCB, 101*NCB, 102*NCB, 103*NCB
        !          57041:        .word   104*NCB, 105*NCB, 106*NCB, 107*NCB
        !          57042:        .word   108*NCB, 109*NCB, 110*NCB, 111*NCB
        !          57043:        .word   112*NCB, 113*NCB, 114*NCB, 115*NCB
        !          57044:        .word   116*NCB, 117*NCB, 118*NCB, 119*NCB
        !          57045:        .word   120*NCB, 121*NCB, 122*NCB, 123*NCB
        !          57046:        .word   124*NCB, 125*NCB, 126*NCB, 127*NCB
        !          57047:        .word   128*NCB, 129*NCB, 130*NCB, 131*NCB
        !          57048: 
        !          57049: ////////
        !          57050: /
        !          57051: / rowtab - array of offsets to each row - up to 44 rows
        !          57052: /         automatically regenerated by reinit().
        !          57053: /
        !          57054: /      NOTE: In kernel data space to allow modification in protected mode.
        !          57055: /
        !          57056: ////////
        !          57057: 
        !          57058:        .shrd
        !          57059: rowtab:        .word    0*NRB,  1*NRB,  2*NRB,  3*NRB
        !          57060:        .word    4*NRB,  5*NRB,  6*NRB,  7*NRB
        !          57061:        .word    8*NRB,  9*NRB, 10*NRB, 11*NRB
        !          57062:        .word   12*NRB, 13*NRB, 14*NRB, 15*NRB
        !          57063:        .word   16*NRB, 17*NRB, 18*NRB, 19*NRB
        !          57064:        .word   20*NRB, 21*NRB, 22*NRB, 23*NRB
        !          57065:        .word   24*NRB, 25*NRB, 26*NRB, 27*NRB
        !          57066:        .word   28*NRB, 29*NRB, 30*NRB, 31*NRB
        !          57067:        .word   32*NRB, 33*NRB, 34*NRB, 35*NRB
        !          57068:        .word   36*NRB, 37*NRB, 38*NRB, 39*NRB
        !          57069:        .word   40*NRB, 41*NRB, 42*NRB, 43*NRB
        !          57070: rowend:
        !          57071:        .shri
        !          57072: 
        !          57073: ////////
        !          57074: /
        !          57075: / fcolor - foreground color
        !          57076: / bcolor - background color
        !          57077: /
        !          57078: /      indexed by ansi color (black,red,green,brown,blue,magenta,cyan,white)
        !          57079: /      yields graphics color (black,blue,green,cyan,red,magenta,brown,white)
        !          57080: /              which is properly shifted for installation in attribute byte.
        !          57081: /
        !          57082: ////////
        !          57083: 
        !          57084: fcolor:        .byte   0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07
        !          57085: bcolor:        .byte   0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70
        !          57086: 
        !          57087: ////////
        !          57088: /
        !          57089: / mm_voff()    -- Disable video display.
        !          57090: /
        !          57091: ////////
        !          57092:        .globl  mm_voff_
        !          57093: mm_voff_:
        !          57094:        mov     dx, mmdata+MM_PORT
        !          57095:        add     dx, $4
        !          57096:        movb    al, mmdata+MM_MODE
        !          57097:        outb    dx, al
        !          57098:        ret
        !          57099: 
        !          57100: ////////
        !          57101: /
        !          57102: / mm_von()     -- Enable video display
        !          57103: /
        !          57104: ////////
        !          57105:        .globl  mm_von_
        !          57106: mm_von_:
        !          57107:        mov     dx, mmdata+MM_PORT      / enable video display
        !          57108:        add     dx, $4
        !          57109:        movb    al, mmdata+MM_MODE
        !          57110:        orb     al, $0x08
        !          57111:        outb    dx, al
        !          57112:        mov     mmvcnt_, $300           / 300 seconds before video disabled
        !          57113:        ret
        !          57114: @
        !          57115: 0707070064030103731004440000030000030000011777770507310670000006100000006335/newbits/kernel/USRSRC/i8086/drv/RCS/clocked.s,vhead     1.1;
        !          57116: branch   ;
        !          57117: access   ;
        !          57118: symbols  ;
        !          57119: locks    bin:1.1; strict;
        !          57120: comment  @@;
        !          57121: 
        !          57122: 
        !          57123: 1.1
        !          57124: date     91.06.10.10.20.56;  author bin;  state Exp;
        !          57125: branches ;
        !          57126: next     ;
        !          57127: 
        !          57128: 
        !          57129: desc
        !          57130: @initial version prov by hal
        !          57131: @
        !          57132: 
        !          57133: 
        !          57134: 
        !          57135: 1.1
        !          57136: log
        !          57137: @Initial revision
        !          57138: @
        !          57139: text
        !          57140: @////////
        !          57141: /
        !          57142: / Clocked Functions - schedule function 'f' to be periodically invoked.
        !          57143: /                  - invocation is at clock interrupt level
        !          57144: /                  - only one function can be clocked
        !          57145: /
        !          57146: /      clocked( f, hz )
        !          57147: /      void (*f)();
        !          57148: /      int hz;
        !          57149: /
        !          57150: ////////
        !          57151: 
        !          57152:        .globl  clocked_
        !          57153: 
        !          57154: ////////
        !          57155: /
        !          57156: / Hardware Dependant Constants
        !          57157: /
        !          57158: ////////
        !          57159: 
        !          57160:        EOI     = 0x20          / Non-specific End of Interrupt command
        !          57161:        PIC     = 0x20          / 8259 pic   base address
        !          57162:        PIT     = 0x40          / 8253 timer base address
        !          57163: 
        !          57164: ////////
        !          57165: /
        !          57166: / Private Data Declarations
        !          57167: /
        !          57168: ////////
        !          57169: 
        !          57170:        .bssd
        !          57171: stack: .blkb   256             / Run time stack for the clocked function.
        !          57172: stktop:
        !          57173: 
        !          57174:        .shri   / CODE SPACE!
        !          57175: uss:   .word   0               / User stack segment
        !          57176: usp:   .word   0               / User stack pointer
        !          57177: kds:   .word   0               / Kernel data segment
        !          57178: oldclk:        .word   0               / Previous clock interrupt entry point.
        !          57179: reload:        .word   0               / Number of polls per logical clock tick.
        !          57180: resid: .word   0               / Number of polls left in logical clock tick.
        !          57181: cfunc: .word   0               / Clocked function
        !          57182:        .shri
        !          57183: 
        !          57184: ////////
        !          57185: /
        !          57186: / clocked( f, hz )
        !          57187: / void (*f)();
        !          57188: / int hz;
        !          57189: /
        !          57190: /      Input:  f  = function to be clocked.
        !          57191: /              hz = desired clock rate in invocations/second.
        !          57192: /
        !          57193: /      Action: Calculate the number of polls per logical clock tick.
        !          57194: /              Seize the clock hardware interrupt.
        !          57195: /              Preserve the previous clock interrupt handler.
        !          57196: /              Reprogram the hardware clock to the desired rate.
        !          57197: /
        !          57198: /      Return:  0 = clock interrupt seized.
        !          57199: /              -1 = clock interrupt previously seized.
        !          57200: /
        !          57201: /      Notes:  The logical clock rate to the OS will be unchanged.
        !          57202: /
        !          57203: ////////
        !          57204: 
        !          57205: clocked_:
        !          57206:        pop     ax              / Convert IP into PSW,CS,IP so can use iret.
        !          57207:        pushf
        !          57208:        push    cs
        !          57209:        push    ax
        !          57210: 
        !          57211:        mov     cs:kds, ds      / Remember the kernel data segment
        !          57212: 
        !          57213:        cli                     / Disable interrupts
        !          57214: 
        !          57215:        push    es              / Seize clock interrupt vector
        !          57216:        sub     ax, ax
        !          57217:        mov     es, ax
        !          57218:        mov     ax, es:0x0020
        !          57219:        cmp     ax, $clocker
        !          57220:        jne     0f
        !          57221:        mov     ax, $-1
        !          57222:        pop     es
        !          57223:        iret
        !          57224: 
        !          57225: 0:     mov     cs:oldclk, ax
        !          57226:        mov     es:0x0020, $clocker
        !          57227:        pop     es
        !          57228: 
        !          57229:        mov     bx, sp          / Remember the function to be clocked.
        !          57230:        mov     ax, ss:6(bx)
        !          57231:        mov     cs:cfunc, ax
        !          57232: 
        !          57233:        mov     ax, ss:8(bx)    / Compute polling rate relative to 20 hz.
        !          57234:        sub     dx, dx
        !          57235:        mov     cx, $20
        !          57236:        div     cx
        !          57237:        mov     cs:reload, ax
        !          57238:        mov     cs:resid, ax
        !          57239: 
        !          57240:        movb    al, $0x36       / Timer 0, LSB, MSB, mode 3
        !          57241:        outb    PIT+3, al
        !          57242:        mov     ax, $59659
        !          57243:        sub     dx, dx
        !          57244:        div     cs:reload
        !          57245:        outb    PIT, al         / LSB of 59659/reload
        !          57246:        jmp     0f
        !          57247: 0:     movb    al, ah
        !          57248:        outb    PIT, al         / MSB of 59659/reload
        !          57249: 
        !          57250:        sub     ax, ax
        !          57251:        iret
        !          57252: 
        !          57253: ////////
        !          57254: /
        !          57255: /      clocker()       - initiate clocked function.
        !          57256: /
        !          57257: /      Action: Every hardware clock tick, invoke the clocked function.
        !          57258: /              Every 'reload' hardware clock ticks,
        !          57259: /                      simulate a logical clock interrupt to the OS.
        !          57260: /
        !          57261: ////////
        !          57262: 
        !          57263: clocker:
        !          57264:        push    ax              / Save registers.
        !          57265:        push    bx
        !          57266:        push    cx
        !          57267:        push    dx
        !          57268:        push    ds
        !          57269:        push    es
        !          57270: 
        !          57271:        mov     cs:uss, ss      / Save current stack.
        !          57272:        mov     cs:usp, sp
        !          57273: 
        !          57274:        mov     ax, cs:kds      / Remap Data/Extra/Stack Segments into Kernel.
        !          57275:        mov     ds, ax
        !          57276:        mov     es, ax
        !          57277:        mov     ss, ax
        !          57278:        mov     sp, $stktop     / Remap stack pointer onto private intr stack.
        !          57279: 
        !          57280:        icall   cs:cfunc        / Call the clocked function.
        !          57281: 
        !          57282:        mov     ss, cs:uss      / Restore previous stack.
        !          57283:        mov     sp, cs:usp
        !          57284:        
        !          57285:        pop     es              / Restore registers.
        !          57286:        pop     ds
        !          57287:        pop     dx
        !          57288:        pop     cx
        !          57289:        pop     bx
        !          57290: 
        !          57291:        dec     cs:resid
        !          57292:        je      0f
        !          57293:        movb    al, $EOI
        !          57294:        outb    PIC, al
        !          57295:        pop     ax
        !          57296:        iret
        !          57297: 
        !          57298: 0:     mov     ax, cs:reload
        !          57299:        mov     cs:resid, ax
        !          57300:        pop     ax
        !          57301:        ijmp    cs:oldclk
        !          57302: @
        !          57303: 0707070064030104321004440000030000030000011777770507310670100006100000002767/newbits/kernel/USRSRC/i8086/drv/RCS/console.c,vhead     1.4;
        !          57304: branch   ;
        !          57305: access   ;
        !          57306: symbols  ;
        !          57307: locks    bin:1.4; strict;
        !          57308: comment  @ * @;
        !          57309: 
        !          57310: 
        !          57311: 1.4
        !          57312: date     91.06.20.14.48.41;  author bin;  state Exp;
        !          57313: branches ;
        !          57314: next     1.3;
        !          57315: 
        !          57316: 1.3
        !          57317: date     91.06.18.08.11.19;  author bin;  state Exp;
        !          57318: branches ;
        !          57319: next     1.2;
        !          57320: 
        !          57321: 1.2
        !          57322: date     91.06.17.12.30.06;  author bin;  state Exp;
        !          57323: branches ;
        !          57324: next     1.1;
        !          57325: 
        !          57326: 1.1
        !          57327: date     91.06.10.10.20.59;  author bin;  state Exp;
        !          57328: branches ;
        !          57329: next     ;
        !          57330: 
        !          57331: 
        !          57332: desc
        !          57333: @initial version prov by hal
        !          57334: @
        !          57335: 
        !          57336: 
        !          57337: 1.4
        !          57338: log
        !          57339: @update provided by hal
        !          57340: @
        !          57341: text
        !          57342: @/* $Header: /usr/src/sys/i8086/drv/RCS/console.c,v 2.1 88/09/03 13:03:39 src Exp $ */
        !          57343: /*
        !          57344:  * Tiny console driver.
        !          57345:  * 8086/8088 Coherent, IBM PC.
        !          57346:  *
        !          57347:  * $Log:       /usr/src/sys/i8086/drv/RCS/console.c,v $
        !          57348:  * Revision 2.1        88/09/03  13:03:39      src
        !          57349:  * *** empty log message ***
        !          57350:  * 
        !          57351:  * Revision 1.1        88/03/24  17:04:25      src
        !          57352:  * Initial revision
        !          57353:  * 
        !          57354:  * 86/11/19    Allan Cornish           /usr/src/sys/i8086/drv/console.c
        !          57355:  * putchar() initializes the (new) (IO).io_flag field to 0.
        !          57356:  */
        !          57357: #include <sys/coherent.h>
        !          57358: #include <sys/inode.h>
        !          57359: #include <sys/stat.h>
        !          57360: #include <sys/con.h>
        !          57361: #include <sys/io.h>
        !          57362: 
        !          57363: dev_t condev = makedev(2,0);
        !          57364: 
        !          57365: putchar(c)
        !          57366: int c;
        !          57367: {
        !          57368:        static coninit;
        !          57369:        IO iob;
        !          57370: 
        !          57371:        if (coninit == 0) {
        !          57372:                ++coninit;
        !          57373:                dopen( condev, IPW, DFCHR );
        !          57374:        }
        !          57375: 
        !          57376:        if (c == '\n')
        !          57377:                putchar('\r');
        !          57378: 
        !          57379:        iob.io_seg  = IOSYS;
        !          57380:        iob.io_ioc  = 1;
        !          57381:        iob.io_base = &c;
        !          57382:        iob.io_flag = 0;
        !          57383:        dwrite( condev, &iob );
        !          57384: }
        !          57385: @
        !          57386: 
        !          57387: 
        !          57388: 1.3
        !          57389: log
        !          57390: @update provided by hal
        !          57391: @
        !          57392: text
        !          57393: @d16 1
        !          57394: a16 1
        !          57395: #include <coherent.h>
        !          57396: @
        !          57397: 
        !          57398: 
        !          57399: 1.2
        !          57400: log
        !          57401: @new version provided y hal for v321
        !          57402: @
        !          57403: text
        !          57404: @@
        !          57405: 
        !          57406: 
        !          57407: 1.1
        !          57408: log
        !          57409: @Initial revision
        !          57410: @
        !          57411: text
        !          57412: @@
        !          57413: 0707070064030103721004440000030000030000011777770507310670100006000000011334/newbits/kernel/USRSRC/i8086/drv/RCS/dmareq.c,vhead     1.4;
        !          57414: branch   ;
        !          57415: access   ;
        !          57416: symbols  ;
        !          57417: locks    bin:1.4; strict;
        !          57418: comment  @ * @;
        !          57419: 
        !          57420: 
        !          57421: 1.4
        !          57422: date     91.06.20.14.48.52;  author bin;  state Exp;
        !          57423: branches ;
        !          57424: next     1.3;
        !          57425: 
        !          57426: 1.3
        !          57427: date     91.06.18.08.11.32;  author bin;  state Exp;
        !          57428: branches ;
        !          57429: next     1.2;
        !          57430: 
        !          57431: 1.2
        !          57432: date     91.06.17.12.30.25;  author bin;  state Exp;
        !          57433: branches ;
        !          57434: next     1.1;
        !          57435: 
        !          57436: 1.1
        !          57437: date     91.06.10.10.22.13;  author bin;  state Exp;
        !          57438: branches ;
        !          57439: next     ;
        !          57440: 
        !          57441: 
        !          57442: desc
        !          57443: @initial version prov by hal
        !          57444: @
        !          57445: 
        !          57446: 
        !          57447: 1.4
        !          57448: log
        !          57449: @update provided by hal
        !          57450: @
        !          57451: text
        !          57452: @/* $Header: /usr/src/sys/i8086/drv/RCS/dmareq.c,v 2.1 88/09/03 13:03:47 src Exp $ */
        !          57453: /* (lgl-
        !          57454:  *     The information contained herein is a trade secret of Mark Williams
        !          57455:  *     Company, and  is confidential information.  It is provided  under a
        !          57456:  *     license agreement,  and may be  copied or disclosed  only under the
        !          57457:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          57458:  *     material without the express written authorization of Mark Williams
        !          57459:  *     Company or persuant to the license agreement is unlawful.
        !          57460:  *
        !          57461:  *     COHERENT Version 2.3.37
        !          57462:  *     Copyright (c) 1982, 1983, 1984.
        !          57463:  *     An unpublished work by Mark Williams Company, Chicago.
        !          57464:  *     All rights reserved.
        !          57465:  -lgl) */
        !          57466: 
        !          57467: /*
        !          57468:  * Like ioreq, but guarantee that no DMA straddle occurs.
        !          57469:  * And assume we are called by fl.c, xt.c, dv.c or someone
        !          57470:  * else who obeys the parameter rules that they do.
        !          57471:  *
        !          57472:  * $Log:       /usr/src/sys/i8086/drv/RCS/dmareq.c,v $
        !          57473:  * Revision 2.1        88/09/03  13:03:47      src
        !          57474:  * *** empty log message ***
        !          57475:  * 
        !          57476:  * Revision 1.1        88/03/24  17:04:28      src
        !          57477:  * Initial revision
        !          57478:  * 
        !          57479:  * 87/11/25    Allan Cornish           /usr/src/sys/i8086/drv/dmareq.c
        !          57480:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          57481:  *
        !          57482:  * 87/01/05    Allan Cornish           /usr/src/sys/i8086/drv/dmareq.c
        !          57483:  * dmareq() now wakes &stimer only if the swap timer is active.
        !          57484:  */
        !          57485: #include <sys/coherent.h>
        !          57486: #include <sys/buf.h>
        !          57487: #include <sys/con.h>
        !          57488: #include <errno.h>
        !          57489: #include <sys/io.h>
        !          57490: #include <sys/proc.h>
        !          57491: #include <sys/sched.h>
        !          57492: #include <sys/seg.h>
        !          57493: #include <sys/stat.h>
        !          57494: #include <sys/uproc.h>
        !          57495: #include <sys/dmac.h>
        !          57496: 
        !          57497: dmareq(bp, iop, dev, req)
        !          57498: register BUF *bp;
        !          57499: register IO *iop;
        !          57500: dev_t dev;
        !          57501: {
        !          57502:        register int n;
        !          57503:        register SEG *sp;
        !          57504:        register CON *cp;
        !          57505:        dold_t dold;
        !          57506:        long l;
        !          57507:        BUF *tbp;
        !          57508: 
        !          57509:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          57510:                return;
        !          57511:        lock(bp->b_gate);
        !          57512:        n = cp->c_flag;
        !          57513:        drest(dold);
        !          57514:        if (blocko(iop->io_seek) != 0) {
        !          57515:                u.u_error = EIO;
        !          57516:                goto out;
        !          57517:        }
        !          57518:        if ((sp=iomapvp(iop, bp)) == NULL) {
        !          57519:                u.u_error = EIO;
        !          57520:                goto out;
        !          57521:        }
        !          57522:        bp->b_dev = dev;
        !          57523:        bp->b_flag = 0;
        !          57524:        sp->s_lrefc++;
        !          57525:        bp->b_faddr = ptov( bp->b_paddr, (fsize_t) bp->b_count );
        !          57526:        /*
        !          57527:         * The dma address is 20 bits; 16 bit offset counter from a 4 bit
        !          57528:         * base segment.  Since io_ioc is limited to 32Kb positive, we
        !          57529:         * have at most two raw transfers separated by a block which
        !          57530:         * straddles the segment boundary.
        !          57531:         * Life would be simpler if we assumed io_ioc % BSIZE, but
        !          57532:         * flioctl comes through here with it's short format buffer.
        !          57533:         */
        !          57534:        while (iop->io_ioc > 0 && (bp->b_flag&BFERR) == 0) {
        !          57535:                l = dmaseg(bp->b_paddr+iop->io_ioc-1) - bp->b_paddr;
        !          57536:                if (l < 0)
        !          57537:                        n = iop->io_ioc;
        !          57538:                else
        !          57539:                        n = l & ~((long)BSIZE-1);
        !          57540:                l = blockn(iop->io_seek);
        !          57541:                if (n == 0) {
        !          57542:                        /* Straddle block */
        !          57543:                        tbp = bp;               /* Save the raw buffer */
        !          57544:                        n = BSIZE;
        !          57545:                        if (n > iop->io_ioc)
        !          57546:                                n = iop->io_ioc;
        !          57547:                        bp = bclaim(dev, l);
        !          57548:                        bp->b_count = n;
        !          57549:                        bp->b_req = req;
        !          57550:                        if (req != BREAD)
        !          57551:                                ioread(iop, FP_OFF(bp->b_faddr), n);
        !          57552:                        dmabuf(bp, dev);
        !          57553:                        if ((bp->b_flag&BFERR) == 0) {
        !          57554:                                if (req == BREAD)
        !          57555:                                        iowrite(iop, FP_OFF(bp->b_faddr), n);
        !          57556:                        } else {
        !          57557:                                tbp->b_flag = bp->b_flag;
        !          57558:                                tbp->b_err = bp->b_err;
        !          57559:                                if (req != BREAD)
        !          57560:                                        iop->io_ioc += bp->b_resid;
        !          57561:                        }
        !          57562:                        bp->b_flag |= BFERR;
        !          57563:                        brelease(bp);
        !          57564:                        bp = tbp;               /* Reclaim raw buffer */
        !          57565:                } else {
        !          57566:                        /* Raw transfer */
        !          57567:                        bp->b_count = n;
        !          57568:                        bp->b_req = req;
        !          57569:                        bp->b_bno = l;
        !          57570:                        dmabuf(bp, dev);
        !          57571:                        if ((bp->b_flag&BFERR) != 0)
        !          57572:                                n -= bp->b_resid;
        !          57573:                        iop->io_ioc -= n;       /* cookedio do these */
        !          57574:                        iop->io_base += n;      /* for everyone */
        !          57575:                }
        !          57576:                FP_OFF(bp->b_faddr) += n;
        !          57577:                bp->b_paddr  += n;
        !          57578:                iop->io_seek += n;
        !          57579:                /* And continue for the next chunk */
        !          57580:        }
        !          57581:        vrelse( bp->b_faddr );
        !          57582:        sp->s_lrefc--;
        !          57583:        if ( stimer.t_last != 0 )
        !          57584:                wakeup((char *)&stimer);
        !          57585:        if ((bp->b_flag&BFERR) != 0 && (u.u_error = bp->b_err) == 0)
        !          57586:                u.u_error = EIO;
        !          57587: out:
        !          57588:        unlock(bp->b_gate);
        !          57589: }
        !          57590: 
        !          57591: static
        !          57592: dmabuf(bp, dev)
        !          57593: register BUF *bp;
        !          57594: dev_t dev;
        !          57595: {
        !          57596:        register int s;
        !          57597:        bp->b_flag = BFRAW|BFBLK|BFIOC|BFNTP;
        !          57598:        s = sphi();
        !          57599:        dblock(dev, bp);
        !          57600:        while ((bp->b_flag&BFNTP) != 0)
        !          57601:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          57602:        spl(s);
        !          57603: }
        !          57604: @
        !          57605: 
        !          57606: 
        !          57607: 1.3
        !          57608: log
        !          57609: @update provided by hal
        !          57610: @
        !          57611: text
        !          57612: @d34 3
        !          57613: a36 3
        !          57614: #include <coherent.h>
        !          57615: #include <buf.h>
        !          57616: #include <con.h>
        !          57617: d38 7
        !          57618: a44 7
        !          57619: #include <io.h>
        !          57620: #include <proc.h>
        !          57621: #include <sched.h>
        !          57622: #include <seg.h>
        !          57623: #include <stat.h>
        !          57624: #include <uproc.h>
        !          57625: #include <dmac.h>
        !          57626: @
        !          57627: 
        !          57628: 
        !          57629: 1.2
        !          57630: log
        !          57631: @new version provided y hal for v321
        !          57632: @
        !          57633: text
        !          57634: @@
        !          57635: 
        !          57636: 
        !          57637: 1.1
        !          57638: log
        !          57639: @Initial revision
        !          57640: @
        !          57641: text
        !          57642: @@
        !          57643: 0707070064030107001004440000030000030000011777770507310670300005700000001074/newbits/kernel/USRSRC/i8086/drv/RCS/errlist,vhead     1.1;
        !          57644: branch   ;
        !          57645: access   ;
        !          57646: symbols  ;
        !          57647: locks    bin:1.1; strict;
        !          57648: comment  @# @;
        !          57649: 
        !          57650: 
        !          57651: 1.1
        !          57652: date     91.06.10.10.22.15;  author bin;  state Exp;
        !          57653: branches ;
        !          57654: next     ;
        !          57655: 
        !          57656: 
        !          57657: desc
        !          57658: @initial version prov by hal
        !          57659: @
        !          57660: 
        !          57661: 
        !          57662: 
        !          57663: 1.1
        !          57664: log
        !          57665: @Initial revision
        !          57666: @
        !          57667: text
        !          57668: @make:         exited with status 256
        !          57669: ./.. -I../../sys -I/usr/include/sys -c -o objects/scsi.o scsi.c
        !          57670: 306: scsi.c: identifier "w" is not defined
        !          57671: 306: scsi.c: missing ';'
        !          57672: 306: scsi.c: Strict: variable "mode" (line 263) is not used
        !          57673: 306: scsi.c: Strict: label "xxx" is not used
        !          57674: 312: scsi.c: Strict: variable "dev" (line 308) is not used
        !          57675: @
        !          57676: 0707070064030106771004440000030000030000011777770507310670300006100000030116/newbits/kernel/USRSRC/i8086/drv/RCS/esa.diffs,vhead     1.1;
        !          57677: branch   ;
        !          57678: access   ;
        !          57679: symbols  ;
        !          57680: locks    bin:1.1; strict;
        !          57681: comment  @@;
        !          57682: 
        !          57683: 
        !          57684: 1.1
        !          57685: date     91.06.10.10.22.16;  author bin;  state Exp;
        !          57686: branches ;
        !          57687: next     ;
        !          57688: 
        !          57689: 
        !          57690: desc
        !          57691: @initial version prov by hal
        !          57692: @
        !          57693: 
        !          57694: 
        !          57695: 
        !          57696: 1.1
        !          57697: log
        !          57698: @Initial revision
        !          57699: @
        !          57700: text
        !          57701: @From emory.mathcs.emory.edu!cyclone!esa  Mon Feb 18 13:14:39 1991 remote from uunet
        !          57702: Received: by mwc.UUCP (smail2.5)
        !          57703:        id AA17103; 18 Feb 91 13:14:39 
        !          57704: Received: from emory.mathcs.emory.edu by uunet.UU.NET (5.61/1.14) with UUCP 
        !          57705:        id AA04365; Mon, 18 Feb 91 04:16:30 -0500
        !          57706: Received: from emory.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
        !          57707:        id AA27253; Mon, 18 Feb 91 00:22:09 EST
        !          57708: Received: from cyclone.UUCP by
        !          57709:        emory.mathcs.emory.edu (5.59/2.17.EUCC-MathCS) via UUCP
        !          57710:        id AA07538 ; Sun, 17 Feb 91 23:42:17 EST
        !          57711: Received: by cyclone.UUCP (smail2.5)
        !          57712:        id AA04284; 17 Feb 91 23:40:45 
        !          57713: X-Mailer: W-MAIL 3.63/Coherent (11/12/90)
        !          57714: To: mwc!hal
        !          57715: Subject: diffs
        !          57716: Message-Id: <9102172340.AA04282@@cyclone.UUCP>
        !          57717: Date: 17 Feb 91 23:40:43 
        !          57718: From: uunet!emory.mathcs.emory.edu!cyclone!esa (Esa Ahola)
        !          57719: 
        !          57720: #! /bin/sh
        !          57721: # This is a shell archive.  Remove anything before this line, then unpack
        !          57722: # it by saving it into a file and typing "sh file".  To overwrite existing
        !          57723: # files, type "sh file -c".  You can also feed this as standard input via
        !          57724: # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
        !          57725: # will see the following message at the end:
        !          57726: #              "End of shell archive."
        !          57727: # Contents:  README 310.diff 311.diff
        !          57728: # Wrapped by root@@cyclone on Sun Feb 17 23:39:49 1991
        !          57729: PATH=/bin:/usr/bin:/usr/ucb ; export PATH
        !          57730: if test -f 'README' -a "${1}" != "-c" ; then 
        !          57731:   echo shar: Will not clobber existing file \"'README'\"
        !          57732: else
        !          57733: echo shar: Extracting \"'README'\" \(1760 characters\)
        !          57734: sed "s/^X//" >'README' <<'END_OF_FILE'
        !          57735: XHere are two sets of diffs against the alx.c that I'm currently running.
        !          57736: XIt was derived from your RTS/CTS-enhanced version (that I dubbed "3.11").
        !          57737: X
        !          57738: XThe two sets of diffs are:
        !          57739: X
        !          57740: X- version 3.10 alx.c against my current version
        !          57741: X- your enhanced "version 3.11" alx.c against mine.
        !          57742: X
        !          57743: XImportant note:  I'm out of my league here.  I'm a reasonably competent
        !          57744: XC programmer, but completely ignorant of asynch communications programming
        !          57745: Xand issues.  Don't look for deep insight in the changes that you see; in
        !          57746: Xmany cases I merely removed code from your enhanced version that I didn't
        !          57747: Xunderstand, attempting to narrow down the number of changes involved.
        !          57748: X
        !          57749: XI *have* tested and demonstrated that the code DOES toggle RTS correctly;
        !          57750: Xthe persistent packet errors must be caused by delays in the chain well 
        !          57751: Xpast the driver.
        !          57752: X
        !          57753: XAs I mentioned earlier, this version does cure the SSS (Sudden Sluggishness
        !          57754: XSyndrome ;-) -- but introduces the following new anomalies:
        !          57755: X
        !          57756: X- My version of ckermit does not get any response from the modem.  The modem
        !          57757: X  lights indicate that the modem is sending stuff (e.g. after an ATN?), but
        !          57758: X  nothing comes out.  The native plain old kermit does work.
        !          57759: X
        !          57760: X- Recall that I use a fixed-at-9600 line speed, and let the Telebit cope
        !          57761: X  with slower modems.  This has worked without incident in the past, but
        !          57762: X  no longer.  While uucicos work  (with reduced speed), interactive 
        !          57763: X  dial-ups at 2400 hang up the modem as soon as a "large" amount of 
        !          57764: X  characters is sent (e.g. "ls -l").  The symptom is that the characters
        !          57765: X  come across VERY slowly, and after the output is complete, further 
        !          57766: X  keystrokes aren't echoed or responded to by the system.  It's almost as
        !          57767: X  if the line speed gets changed from 9600 !?
        !          57768: X
        !          57769: XI look forward to further testing material from you.
        !          57770: X
        !          57771: END_OF_FILE
        !          57772: if test 1760 -ne `wc -c <'README'`; then
        !          57773:     echo shar: \"'README'\" unpacked with wrong size!
        !          57774: fi
        !          57775: # end of 'README'
        !          57776: fi
        !          57777: if test -f '310.diff' -a "${1}" != "-c" ; then 
        !          57778:   echo shar: Will not clobber existing file \"'310.diff'\"
        !          57779: else
        !          57780: echo shar: Extracting \"'310.diff'\" \(4270 characters\)
        !          57781: sed "s/^X//" >'310.diff' <<'END_OF_FILE'
        !          57782: X*** alx310.c  Sat Feb  2 16:44:45 1991
        !          57783: X--- alx.c     Sat Feb 16 01:27:53 1991
        !          57784: X***************
        !          57785: X*** 25,34 ****
        !          57786: X--- 25,42 ----
        !          57787: X  
        !          57788: X  #define DTRTMOUT  3 /* DTR timeout interval in seconds for close */
        !          57789: X  #define     IENABLE (IE_RxI+IE_TxI+IE_LSI)
        !          57790: X+ #define IE_ALL      (IE_RxI|IE_TxI|IE_LSI|IE_MSI)
        !          57791: X  
        !          57792: X+ #define RTS_ON()    { outb(ALPORT+MCR, inb(ALPORT+MCR) | MC_RTS); }
        !          57793: X+ #define RTS_OFF()   { outb(ALPORT+MCR, inb(ALPORT+MCR) & ~MC_RTS); }
        !          57794: X+ 
        !          57795: X  int al_sg_set = 0;
        !          57796: X  int al_sg_clr = 0;
        !          57797: X  static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          57798: X+ static int drlsd;   /* delta carrier detect - set by alxintr(), read
        !          57799: X+                        by alxcycle() */
        !          57800: X+ static int rawin_ct;        /* number of characters in input silo */                           
        !          57801: X+ static int want_rts;
        !          57802: X  
        !          57803: X  /*
        !          57804: X   * functions herein
        !          57805: X***************
        !          57806: X*** 135,141 ****
        !          57807: X  
        !          57808: X      b = ALPORT;
        !          57809: X  
        !          57810: X!     if ( inb(b+IER) & ~IENABLE ) { /* chip not found */
        !          57811: X              u.u_error = ENXIO;
        !          57812: X              return;
        !          57813: X      }
        !          57814: X--- 143,149 ----
        !          57815: X  
        !          57816: X      b = ALPORT;
        !          57817: X  
        !          57818: X!     if ( inb(b+IER) & ~IE_ALL ) { /* chip not found */
        !          57819: X              u.u_error = ENXIO;
        !          57820: X              return;
        !          57821: X      }
        !          57822: X***************
        !          57823: X*** 190,195 ****
        !          57824: X--- 198,205 ----
        !          57825: X                      *irqtty = tp_table[AL_NUM];
        !          57826: X                      outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          57827: X              }
        !          57828: X+             RTS_ON();
        !          57829: X+             want_rts = 0;
        !          57830: X      
        !          57831: X              outb(b+IER, IENABLE);        /* enable interrupts */
        !          57832: X      
        !          57833: X***************
        !          57834: X*** 316,322 ****
        !          57835: X              if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          57836: X                      state--;
        !          57837: X      }
        !          57838: X!     outb(b+MCR, 0);
        !          57839: X      com_usage[AL_NUM] = COM_UNUSED;
        !          57840: X      set_poll_rate();
        !          57841: X      CDUMP("closed")
        !          57842: X--- 326,335 ----
        !          57843: X              if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          57844: X                      state--;
        !          57845: X      }
        !          57846: X!     /*
        !          57847: X!      * Turn off MC_OUT2 so IRQ can be used by other port.
        !          57848: X!      */
        !          57849: X!     outb(b+MCR, inb(b+MCR)&(~MC_OUT2));
        !          57850: X      com_usage[AL_NUM] = COM_UNUSED;
        !          57851: X      set_poll_rate();
        !          57852: X      CDUMP("closed")
        !          57853: X***************
        !          57854: X*** 343,350 ****
        !          57855: X--- 356,365 ----
        !          57856: X  {
        !          57857: X      register int    s, b;
        !          57858: X      int stat1, stat2;
        !          57859: X+     char ier_save;
        !          57860: X  
        !          57861: X      s = sphi();
        !          57862: X+     ier_save=inb(b+IER);    /* some chips need this */
        !          57863: X      b = ALPORT;
        !          57864: X      stat1 = inb(b+MCR);             /* get current MCR register status */
        !          57865: X      stat2 = inb(b+LCR);             /* get current LCR register status */
        !          57866: X***************
        !          57867: X*** 384,389 ****
        !          57868: X--- 399,405 ----
        !          57869: X      default:
        !          57870: X              ttioctl(tp, com, vec);
        !          57871: X      }
        !          57872: X+     outb(b+IER, ier_save);
        !          57873: X      spl(s);
        !          57874: X  }
        !          57875: X  
        !          57876: X***************
        !          57877: X*** 466,472 ****
        !          57878: X              /*
        !          57879: X               * Carrier changed.
        !          57880: X               */
        !          57881: X!             if ( b & MS_DRLSD ) {
        !          57882: X                      /*
        !          57883: X                       * wakeup open
        !          57884: X                       */
        !          57885: X--- 482,489 ----
        !          57886: X              /*
        !          57887: X               * Carrier changed.
        !          57888: X               */
        !          57889: X!             if ((b & MS_DRLSD) || drlsd) {
        !          57890: X!                     drlsd = 0;
        !          57891: X                      /*
        !          57892: X                       * wakeup open
        !          57893: X                       */
        !          57894: X***************
        !          57895: X*** 482,487 ****
        !          57896: X--- 499,505 ----
        !          57897: X                               * clear carrier flag; send hangup signal
        !          57898: X                               */
        !          57899: X                              tp->t_rawin.si_ox = tp->t_rawin.si_ix;
        !          57900: X+                             rawin_ct = 0;
        !          57901: X                              tthup( tp );
        !          57902: X                      }
        !          57903: X              }
        !          57904: X***************
        !          57905: X*** 497,502 ****
        !          57906: X--- 515,521 ----
        !          57907: X              else
        !          57908: X                      tp->t_rawin.si_ox++;
        !          57909: X      }
        !          57910: X+     rawin_ct = 0;
        !          57911: X  
        !          57912: X      /*
        !          57913: X       * Calculate free output slot count.
        !          57914: X***************
        !          57915: X*** 520,530 ****
        !          57916: X       * (Re)start output, wake sleeping processes, etc.
        !          57917: X       */
        !          57918: X      ttstart( tp );
        !          57919: X  
        !          57920: X      /*
        !          57921: X       * Schedule next cycle.
        !          57922: X       */
        !          57923: X!     timeout( &tp->t_rawtim, HZ/10, alxcycle, tp );
        !          57924: X  }
        !          57925: X  
        !          57926: X  /*
        !          57927: X--- 539,554 ----
        !          57928: X       * (Re)start output, wake sleeping processes, etc.
        !          57929: X       */
        !          57930: X      ttstart( tp );
        !          57931: X+     
        !          57932: X+     if (want_rts) {
        !          57933: X+             RTS_ON();
        !          57934: X+             want_rts = 0;
        !          57935: X+     }
        !          57936: X  
        !          57937: X      /*
        !          57938: X       * Schedule next cycle.
        !          57939: X       */
        !          57940: X!     timeout( &tp->t_rawtim, HZ/20, alxcycle, tp );
        !          57941: X  }
        !          57942: X  
        !          57943: X  /*
        !          57944: X***************
        !          57945: X*** 619,624 ****
        !          57946: X--- 643,659 ----
        !          57947: X              tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          57948: X              if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          57949: X                      tp->t_rawin.si_ix = 0;
        !          57950: X+                     
        !          57951: X+             /*
        !          57952: X+              * Preliminary code!
        !          57953: X+              * De-assert RTS if we are close to filling the input silo.
        !          57954: X+              */     
        !          57955: X+             rawin_ct++;
        !          57956: X+             if (!want_rts && rawin_ct > SI_BUFSIZ / 4) {
        !          57957: X+                     RTS_OFF();
        !          57958: X+                     want_rts = 1;
        !          57959: X+             }
        !          57960: X+             
        !          57961: X              goto rescan;
        !          57962: X  
        !          57963: X      case Tx_INTR:
        !          57964: X***************
        !          57965: X*** 650,655 ****
        !          57966: X--- 685,707 ----
        !          57967: X                      defer( alxcycle, tp );
        !          57968: X              }
        !          57969: X              goto rescan;
        !          57970: X+             
        !          57971: X+     case MS_INTR:
        !          57972: X+             /*
        !          57973: X+              * This is preliminary code - use delta of CTS from
        !          57974: X+              * modem to implement flow control.
        !          57975: X+              *
        !          57976: X+              * Sense delta of RLSD for use by alxcycle().
        !          57977: X+              */
        !          57978: X+             b = inb(ALPORT+MSR);
        !          57979: X+             if (b & MS_DCTS)
        !          57980: X+                     if (b & MS_CTS)
        !          57981: X+                             tp->t_flags &= ~T_STOP;
        !          57982: X+                     else
        !          57983: X+                             tp->t_flags |= T_STOP;
        !          57984: X+             if (b & MS_DRLSD)
        !          57985: X+                     drlsd = 1;              
        !          57986: X+             goto rescan;
        !          57987: X      }
        !          57988: X  }
        !          57989: X  
        !          57990: END_OF_FILE
        !          57991: if test 4270 -ne `wc -c <'310.diff'`; then
        !          57992:     echo shar: \"'310.diff'\" unpacked with wrong size!
        !          57993: fi
        !          57994: chmod +x '310.diff'
        !          57995: # end of '310.diff'
        !          57996: fi
        !          57997: if test -f '311.diff' -a "${1}" != "-c" ; then 
        !          57998:   echo shar: Will not clobber existing file \"'311.diff'\"
        !          57999: else
        !          58000: echo shar: Extracting \"'311.diff'\" \(3284 characters\)
        !          58001: sed "s/^X//" >'311.diff' <<'END_OF_FILE'
        !          58002: X*** alx311.c  Sat Feb  2 16:45:12 1991
        !          58003: X--- alx.c     Sat Feb 16 01:27:53 1991
        !          58004: X***************
        !          58005: X*** 27,32 ****
        !          58006: X--- 27,35 ----
        !          58007: X  #define     IENABLE (IE_RxI+IE_TxI+IE_LSI)
        !          58008: X  #define IE_ALL      (IE_RxI|IE_TxI|IE_LSI|IE_MSI)
        !          58009: X  
        !          58010: X+ #define RTS_ON()    { outb(ALPORT+MCR, inb(ALPORT+MCR) | MC_RTS); }
        !          58011: X+ #define RTS_OFF()   { outb(ALPORT+MCR, inb(ALPORT+MCR) & ~MC_RTS); }
        !          58012: X+ 
        !          58013: X  int al_sg_set = 0;
        !          58014: X  int al_sg_clr = 0;
        !          58015: X  static int poll_divisor;  /* set by set_poll_rate(), read by alxclk() */
        !          58016: X***************
        !          58017: X*** 195,201 ****
        !          58018: X                      *irqtty = tp_table[AL_NUM];
        !          58019: X                      outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          58020: X              }
        !          58021: X!             want_rts = 1;
        !          58022: X      
        !          58023: X              outb(b+IER, IENABLE);        /* enable interrupts */
        !          58024: X      
        !          58025: X--- 198,205 ----
        !          58026: X                      *irqtty = tp_table[AL_NUM];
        !          58027: X                      outb(b+MCR, MC_RTS|MC_DTR|MC_OUT2);
        !          58028: X              }
        !          58029: X!             RTS_ON();
        !          58030: X!             want_rts = 0;
        !          58031: X      
        !          58032: X              outb(b+IER, IENABLE);        /* enable interrupts */
        !          58033: X      
        !          58034: X***************
        !          58035: X*** 206,212 ****
        !          58036: X                                      SVTTOUT);       /* wait for carrier */
        !          58037: X                              if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          58038: X                                      outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          58039: X-                                     want_rts = 0;
        !          58040: X                                      /*
        !          58041: X                                       * make sure port is hungup
        !          58042: X                                       * disable all ints except for TxI
        !          58043: X--- 210,215 ----
        !          58044: X***************
        !          58045: X*** 300,306 ****
        !          58046: X               * Hangup port
        !          58047: X               */
        !          58048: X              outb(b+MCR, inb(b+MCR)&MC_OUT2);
        !          58049: X-             want_rts = 0;
        !          58050: X              /*
        !          58051: X               * Hold dtr low for timeout
        !          58052: X               */
        !          58053: X--- 303,308 ----
        !          58054: X***************
        !          58055: X*** 422,428 ****
        !          58056: X              if (tp->t_flags & T_MODC) {  /* modem control? */
        !          58057: X                      tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          58058: X                      outb(b+MCR, inb(b+MCR) & MC_OUT2); /* hangup */
        !          58059: X-                     want_rts = 0;
        !          58060: X              }
        !          58061: X      }
        !          58062: X  
        !          58063: X--- 424,429 ----
        !          58064: X***************
        !          58065: X*** 515,522 ****
        !          58066: X                      tp->t_rawin.si_ox++;
        !          58067: X      }
        !          58068: X      rawin_ct = 0;
        !          58069: X-     if (want_rts)
        !          58070: X-             outb(b+MCR, inb(b+MCR) | MC_RTS);
        !          58071: X  
        !          58072: X      /*
        !          58073: X       * Calculate free output slot count.
        !          58074: X--- 516,521 ----
        !          58075: X***************
        !          58076: X*** 540,550 ****
        !          58077: X       * (Re)start output, wake sleeping processes, etc.
        !          58078: X       */
        !          58079: X      ttstart( tp );
        !          58080: X  
        !          58081: X      /*
        !          58082: X       * Schedule next cycle.
        !          58083: X       */
        !          58084: X!     timeout( &tp->t_rawtim, HZ/10, alxcycle, tp );
        !          58085: X  }
        !          58086: X  
        !          58087: X  /*
        !          58088: X--- 539,554 ----
        !          58089: X       * (Re)start output, wake sleeping processes, etc.
        !          58090: X       */
        !          58091: X      ttstart( tp );
        !          58092: X+     
        !          58093: X+     if (want_rts) {
        !          58094: X+             RTS_ON();
        !          58095: X+             want_rts = 0;
        !          58096: X+     }
        !          58097: X  
        !          58098: X      /*
        !          58099: X       * Schedule next cycle.
        !          58100: X       */
        !          58101: X!     timeout( &tp->t_rawtim, HZ/20, alxcycle, tp );
        !          58102: X  }
        !          58103: X  
        !          58104: X  /*
        !          58105: X***************
        !          58106: X*** 639,652 ****
        !          58107: X              tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          58108: X              if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          58109: X                      tp->t_rawin.si_ix = 0;
        !          58110: X!                     rawin_ct++;
        !          58111: X              /*
        !          58112: X               * Preliminary code!
        !          58113: X               * De-assert RTS if we are close to filling the input silo.
        !          58114: X               */     
        !          58115: X!             if (want_rts && (sizeof(tp->t_rawin.si_buf) - rawin_ct < 4))
        !          58116: X!                     outb(b+MCR, inb(b+MCR) & ~MC_RTS);
        !          58117: X!                     goto rescan;
        !          58118: X  
        !          58119: X      case Tx_INTR:
        !          58120: X              /*
        !          58121: X--- 643,660 ----
        !          58122: X              tp->t_rawin.si_buf[ tp->t_rawin.si_ix ] = b;
        !          58123: X              if ( ++tp->t_rawin.si_ix >= sizeof(tp->t_rawin.si_buf) )
        !          58124: X                      tp->t_rawin.si_ix = 0;
        !          58125: X!                     
        !          58126: X              /*
        !          58127: X               * Preliminary code!
        !          58128: X               * De-assert RTS if we are close to filling the input silo.
        !          58129: X               */     
        !          58130: X!             rawin_ct++;
        !          58131: X!             if (!want_rts && rawin_ct > SI_BUFSIZ / 4) {
        !          58132: X!                     RTS_OFF();
        !          58133: X!                     want_rts = 1;
        !          58134: X!             }
        !          58135: X!             
        !          58136: X!             goto rescan;
        !          58137: X  
        !          58138: X      case Tx_INTR:
        !          58139: X              /*
        !          58140: X***************
        !          58141: X*** 693,698 ****
        !          58142: X--- 701,707 ----
        !          58143: X                              tp->t_flags |= T_STOP;
        !          58144: X              if (b & MS_DRLSD)
        !          58145: X                      drlsd = 1;              
        !          58146: X+             goto rescan;
        !          58147: X      }
        !          58148: X  }
        !          58149: X  
        !          58150: END_OF_FILE
        !          58151: if test 3284 -ne `wc -c <'311.diff'`; then
        !          58152:     echo shar: \"'311.diff'\" unpacked with wrong size!
        !          58153: fi
        !          58154: chmod +x '311.diff'
        !          58155: # end of '311.diff'
        !          58156: fi
        !          58157: echo shar: End of shell archive.
        !          58158: exit 0
        !          58159: &&
        !          58160: @
        !          58161: 0707070064030104301004440000030000030000011777770507310670600005400000060162/newbits/kernel/USRSRC/i8086/drv/RCS/fl.c,vhead     1.2;
        !          58162: branch   ;
        !          58163: access   ;
        !          58164: symbols  ;
        !          58165: locks    bin:1.2; strict;
        !          58166: comment  @ * @;
        !          58167: 
        !          58168: 
        !          58169: 1.2
        !          58170: date     91.06.20.14.49.02;  author bin;  state Exp;
        !          58171: branches ;
        !          58172: next     1.1;
        !          58173: 
        !          58174: 1.1
        !          58175: date     91.06.10.10.22.22;  author bin;  state Exp;
        !          58176: branches ;
        !          58177: next     ;
        !          58178: 
        !          58179: 
        !          58180: desc
        !          58181: @initial version prov by hal
        !          58182: @
        !          58183: 
        !          58184: 
        !          58185: 1.2
        !          58186: log
        !          58187: @update provided by hal
        !          58188: @
        !          58189: text
        !          58190: @/* (-lgl
        !          58191:  *     COHERENT Driver Kit Version 1.1.0
        !          58192:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          58193:  *     All rights reserved. May not be copied without permission.
        !          58194:  -lgl) */
        !          58195: /*
        !          58196:  * This is a driver for the IBM AT or PC/XT
        !          58197:  * floppy, using interrupts and DMA on
        !          58198:  * the NEC 756 floppy chip. Ugh.
        !          58199:  * Handles single, double and quad
        !          58200:  * density drives, 8, 9, 15 or 18 sectors per track.
        !          58201:  * 15 and 18 sectors per track only available on the IBM_AT.
        !          58202:  *
        !          58203:  * Minor device assignments: xxuuhkkk
        !          58204:  *     uu - unit = 0/1/2/3
        !          58205:  *     kkk - kind, struct fdata infra.
        !          58206:  *     h - alternating head rather than side by side
        !          58207:  *
        !          58208:  */
        !          58209: 
        !          58210: #include       <sys/coherent.h>
        !          58211: #include       <sys/i8086.h>
        !          58212: #include       <sys/buf.h>
        !          58213: #include       <sys/con.h>
        !          58214: #include       <sys/stat.h>
        !          58215: #include       <errno.h>
        !          58216: #include       <sys/uproc.h>
        !          58217: #include       <sys/fdioctl.h>
        !          58218: #include       <sys/sched.h>
        !          58219: #include       <sys/dmac.h>
        !          58220: 
        !          58221: #define                BIT(n)          (1 << (n))
        !          58222: 
        !          58223: /*
        !          58224:  * Patchable parameters (default to IBM PC/XT values).
        !          58225:  */
        !          58226: 
        !          58227: int    fl_srt = 0xC;   /* Floppy seek step rate, in unit 2 millisec */
        !          58228:                        /* NOT DIRECTLY ENCODED */
        !          58229:                        /* COMPAQ wants 0xD */
        !          58230: int    fl_hlt = 1;     /* Floppy head load time, in unit 4 millisec */
        !          58231: int    fl_hut = 0xF;   /* Floppy head unload time, in unit 32 millisec */
        !          58232: 
        !          58233: int    flload();
        !          58234: int    flunload();
        !          58235: int    flopen();
        !          58236: int    flblock();
        !          58237: int    flread();
        !          58238: int    flwrite();
        !          58239: int    flioctl();
        !          58240: int    fldelay();
        !          58241: int    flintr();
        !          58242: int    fltimeout();
        !          58243: int    nulldev();
        !          58244: int    nonedev();
        !          58245: 
        !          58246: #define        FDCMAJ  4                       /* Major # */
        !          58247: 
        !          58248: CON    flcon   = {
        !          58249:        DFBLK|DFCHR,                    /* Flags */
        !          58250:        FDCMAJ,                         /* Major index */
        !          58251:        flopen,                         /* Open */
        !          58252:        nulldev,                        /* Close */
        !          58253:        flblock,                        /* Block */
        !          58254:        flread,                         /* Read */
        !          58255:        flwrite,                        /* Write */
        !          58256:        flioctl,                        /* Ioctl */
        !          58257:        nulldev,                        /* Powerfail */
        !          58258:        fltimeout,                      /* Timeout */
        !          58259:        flload,                         /* Load */
        !          58260:        flunload                        /* Unload */
        !          58261: };
        !          58262: 
        !          58263: #define        MTIMER  5                       /* Motor timeout */
        !          58264: #define        FDCDOR  0x3F2                   /* Digital output */
        !          58265: #define        FDCDAT  0x3F5                   /* Data register */
        !          58266: #define        FDCMSR  0x3F4                   /* Main status register */
        !          58267: #define        FDCRATE 0x3F7                   /* Transfer rate (500,300,250 Kbps) */
        !          58268: 
        !          58269: #define        DORDS   0x03                    /* Drive select bits */
        !          58270: #define        DORNMR  0x04                    /* Not master reset */
        !          58271: #define        DORIEN  0x08                    /* Interrupt, DMA enable */
        !          58272: #define        DORMS   0xF0                    /* Motor enables */
        !          58273: 
        !          58274: #define        MSRDB   0x0F                    /* Drive busy */
        !          58275: #define        MSRCB   0x10                    /* Control busy */
        !          58276: #define        MSRNDMA 0x20                    /* Not DMA */
        !          58277: #define        MSRDIO  0x40                    /* Data direction */
        !          58278: #define        MSRRQM  0x80                    /* Request for master */
        !          58279: 
        !          58280: /*
        !          58281:  * Status Register 0 - Bit Definitions.
        !          58282:  */
        !          58283: #define        ST0_US0 0x01                    /* Unit Select 0 */
        !          58284: #define        ST0_US1 0x02                    /* Unit Select 1 */
        !          58285: #define        ST0_HD  0x04                    /* Head Address */
        !          58286: #define        ST0_NR  0x08                    /* Not Ready */
        !          58287: #define        ST0_EC  0x10                    /* Equipment Check */
        !          58288: #define        ST0_SE  0x20                    /* Seek End */
        !          58289: #define        ST0_IC  0xC0                    /* Interrupt code */
        !          58290: #define        ST0_NT  0x00                    /* Normal Termination */
        !          58291: 
        !          58292: /*
        !          58293:  * Status Register 1 - Bit Definitions.
        !          58294:  */
        !          58295: #define        ST1_MA  0x01                    /* Missing Address Mark */
        !          58296: #define        ST1_NW  0x02                    /* Not writeable */
        !          58297: #define        ST1_ND  0x04                    /* No Data */
        !          58298:        /*      0x08 */                 /* Not used - always 0 */
        !          58299: #define        ST1_OR  0x10                    /* Overrun */
        !          58300: #define        ST1_DE  0x20                    /* Data Error */
        !          58301:        /*      0x40 */                 /* Not used - always 0 */
        !          58302: #define        ST1_EN  0x80                    /* End of Cylinder */
        !          58303: 
        !          58304: /*
        !          58305:  * Status Register 2 - Bit Definitions.
        !          58306:  */
        !          58307: #define        ST2_MD  0x01                    /* Missing Address Mark in Data Field */
        !          58308: #define        ST2_BC  0x02                    /* Bad Cylinder */
        !          58309: #define        ST2_SN  0x04                    /* Scan Not Satisfied */
        !          58310: #define        ST2_SH  0x08                    /* Scan Equal Hit */
        !          58311: #define        ST2_WC  0x10                    /* Wrong Cylinder */
        !          58312: #define        ST2_DD  0x20                    /* Data Error in Data Field */
        !          58313: #define        ST2_CM  0x40                    /* Control Mark */
        !          58314:        /*      0x80 */                 /* Not used - always 0 */
        !          58315: 
        !          58316: /*
        !          58317:  * Status Register 3 - Bit Definitions.
        !          58318:  */
        !          58319: #define        ST3_US0 0x01                    /* Unit Select 0 */
        !          58320: #define        ST3_US1 0x02                    /* Unit Select 1 */
        !          58321: #define        ST3_HD  0x04                    /* Head Address */
        !          58322: #define        ST3_TS  0x08                    /* Two Sides */
        !          58323: #define        ST3_T0  0x10                    /* Track 0 */
        !          58324: #define        ST3_RDY 0x20                    /* Ready */
        !          58325: #define        ST3_WP  0x40                    /* Write Protected */
        !          58326: #define        ST3_FT  0x80                    /* Fault */
        !          58327: 
        !          58328: /*
        !          58329:  * Controller Commands.
        !          58330:  */
        !          58331: #define        CMDSPEC 0x03                    /* Specify */
        !          58332: #define        CMDRCAL 0x07                    /* Recal */
        !          58333: #define        CMDSEEK 0x0F                    /* Seek */
        !          58334: #define        CMDRDAT 0x66                    /* Read data */
        !          58335: #define        CMDWDAT 0x45                    /* Write data */
        !          58336: #define        CMDSINT 0x08                    /* Sense status */
        !          58337: #define        CMDFMT  0x4D                    /* Format track */
        !          58338: 
        !          58339: /*
        !          58340:  * Driver States.
        !          58341:  */
        !          58342: #define        SIDLE   0                       /* Idle */
        !          58343: #define        SSEEK   1                       /* Need seek */
        !          58344: #define        SRDWR   2                       /* Need read/write command */
        !          58345: #define        SENDIO  3                       /* Need end I/O processing */
        !          58346: #define        SDELAY  4                       /* Delay before next disk operation */
        !          58347: #define        SHDLY   5                       /* Head settling delay before r/w */
        !          58348: #define SLOCK  6                       /* Got DMA controller lock */
        !          58349: 
        !          58350: #define funit(x)       (minor(x)>>4)   /* Unit/drive number */
        !          58351: #define fkind(x)       (minor(x)&0x7)  /* Kind of format */
        !          58352: #define        fhbyh(x)        (minor(x)&0x8)  /* 0=Side by side, 1=Head by head */
        !          58353: 
        !          58354: static
        !          58355: struct fdata {
        !          58356:        int     fd_size;        /* Blocks per diskette */
        !          58357:        int     fd_nhds;        /* Heads per drive */
        !          58358:        int     fd_trks;        /* Tracks per side */
        !          58359:        int     fd_offs;        /* Sector base */
        !          58360:        int     fd_nspt;        /* Sectors per track */
        !          58361:        char    fd_GPL[4];      /* Controller gap param (indexed by rate) */
        !          58362:        char    fd_N;           /* Controller size param */
        !          58363:        char    fd_FGPL;        /* Format gap length */
        !          58364: } fdata[] = {
        !          58365: /* 8 sectors per track, surface by surface seek. */
        !          58366:        {  320,1,40,0, 8, { 0x00,0x23,0x2A }, 2,0x50 }, /* Single sided */
        !          58367:        {  640,2,40,0, 8, { 0x00,0x23,0x2A }, 2,0x50 }, /* Double sided */
        !          58368:        { 1280,2,80,0, 8, { 0x00,0x23,0x2A }, 2,0x50 }, /* Quad density */
        !          58369: /* 9 sectors per track, surface by surface seek. */
        !          58370:        {  360,1,40,0, 9, { 0x00,0x23,0x2A }, 2,0x50 }, /* Single sided */
        !          58371:        {  720,2,40,0, 9, { 0x00,0x23,0x2A }, 2,0x50 }, /* Double sided */
        !          58372:        { 1440,2,80,0, 9, { 0x00,0x23,0x2A }, 2,0x50 }, /* Quad density */
        !          58373: /* 15 sectors per track, surface by surface seek. */
        !          58374:        { 2400,2,80,0,15, { 0x1B,0x00,0x00 }, 2,0x54 }, /* High capacity */
        !          58375: /* 18 sectors per track, surface by surface seek. */
        !          58376:        { 2880,2,80,0,18, { 0x1B,0x00,0x00 }, 2,0x54 }  /* 1.44 3.5" */
        !          58377: };
        !          58378: 
        !          58379: 
        !          58380: static
        !          58381: struct fl      {
        !          58382:        BUF     *fl_actf;               /* Queue, forward */
        !          58383:        BUF     *fl_actl;               /* Queue, backward */
        !          58384:        paddr_t fl_addr;                /* Address */
        !          58385:        int     fl_nsec;                /* # of sectors */
        !          58386:        int     fl_secn;                /* Current sector */
        !          58387:        struct  fdata fl_fd;            /* Disk kind data */
        !          58388:        int     fl_fcyl;                /* Floppy cylinder # */
        !          58389:        char    fl_incal[4];            /* Disk in cal flags */
        !          58390:        char    fl_ndsk;                /* # of 5 1/4" drives */
        !          58391:        char    fl_unit;                /* Unit # */
        !          58392:        char    fl_mask;                /* Handy unit mask */
        !          58393:        char    fl_hbyh;                /* 0/1 = Side by side/Head by head */
        !          58394:        char    fl_nerr;                /* Error count */
        !          58395:        int     fl_ncmdstat;            /* Number of cmd status bytes recvd */
        !          58396:        char    fl_cmdstat[8];          /* Command Status buffer */
        !          58397:        int     fl_nintstat;            /* Number of intr status bytes recvd */
        !          58398:        char    fl_intstat[4];          /* Interrupt Status buffer */
        !          58399:        int     fl_fsec;                /* Floppy sector # */
        !          58400:        int     fl_head;                /* Floppy head */
        !          58401:        char    fl_init;                /* FDC init done flag */
        !          58402:        char    fl_state;               /* Processing state */
        !          58403:        char    fl_mstatus;             /* Motor status */
        !          58404:        char    fl_time[4];             /* Motor timeout */
        !          58405:        char    fl_rate;                /* Data rate: 500,300,250,?? kbps */
        !          58406:        char    fl_type[4];             /* Type of drive: 2 = HiCap */
        !          58407:        int     fl_wflag;               /* Write operation  */
        !          58408:        int     fl_recov;               /* Recovery initiated */
        !          58409: }      fl;
        !          58410: 
        !          58411: static BUF     flbuf;
        !          58412: static TIM     fltim;
        !          58413: static TIM     fldmalck;       /* DMA lock deferred function structure.     */
        !          58414: 
        !          58415: /*
        !          58416:  * The load routine asks the
        !          58417:  * switches how many drives are present
        !          58418:  * in the machine, and sets up the field
        !          58419:  * in the floppy database. It also grabs
        !          58420:  * the level 6 interrupt vector.
        !          58421:  */
        !          58422: static
        !          58423: flload()
        !          58424: {
        !          58425:        register int    eflag;
        !          58426:        register int    s;
        !          58427: 
        !          58428:        /*
        !          58429:         * Ensure DMA channel 2 is turned off.
        !          58430:         * The Computerland ROM does not disable DMA channel after autoboot
        !          58431:         * from hard disk.  The Western Digital controller board appears to
        !          58432:         * send a dma burst when the floppy controller chip is reset.
        !          58433:         */
        !          58434:        dmaoff( 2 );
        !          58435: 
        !          58436:        /*
        !          58437:         * Read floppy equipment byte from CMOS ram
        !          58438:         *      drive 0 is in high nibble, drive 1 is in low nibble.
        !          58439:         */
        !          58440:        outb( 0x70, 0x10 );
        !          58441:        /* delay */
        !          58442:        eflag = inb( 0x71 );
        !          58443: 
        !          58444:        /*
        !          58445:         * Flag hardware as an IBM AT if neither equipment byte nibble is
        !          58446:         * greater than 4 (since 5 through 15 are reserved nibble values - see
        !          58447:         * IBM AT Technical Reference manual, page 1-50).  Note that this
        !          58448:         * relies on the fact that in the XT, this byte will "float" high.
        !          58449:         * NOTE: 1.44 Mbyte 3.5 inch drives are type 4
        !          58450:         */
        !          58451:        if ( (eflag & 0x88) == 0 ) {
        !          58452: 
        !          58453:                /*
        !          58454:                 * Reinitialize patchable parameters for IBM AT.
        !          58455:                 */
        !          58456:                fl_srt = 0xD;   /* Floppy seek step rate, in unit 2 ms */
        !          58457:                                /* NOT DIRECTLY ENCODED */
        !          58458:                fl_hlt = 25;    /* Floppy head load time, in unit 4 ms */
        !          58459: 
        !          58460:                /*
        !          58461:                 * Define AT drive information.
        !          58462:                 */
        !          58463:                fl.fl_type[0]   = eflag >> 4;
        !          58464:                fl.fl_type[1]   = eflag & 15;
        !          58465:                fl.fl_rate      = 1; /* Must not be 2 */
        !          58466: 
        !          58467:                /*
        !          58468:                 * Determine number of AT floppy drives.
        !          58469:                 */
        !          58470:                if ( eflag & 0xF0 ) {
        !          58471:                        fl.fl_ndsk++;
        !          58472:                        if ( eflag & 0x0F )
        !          58473:                                fl.fl_ndsk++;
        !          58474:                }
        !          58475:        } else {
        !          58476:                /*
        !          58477:                 * Define XT drive information.
        !          58478:                 */
        !          58479:                eflag           = int11();
        !          58480:                fl.fl_rate      = 2;
        !          58481:                if ( eflag & 1 )
        !          58482:                        fl.fl_ndsk = ((eflag >> 6) & 0x03) + 1;
        !          58483:        }
        !          58484: 
        !          58485:        if ( fl.fl_ndsk ) {
        !          58486: 
        !          58487:                s = sphi();
        !          58488:                outb(FDCDOR, 0);
        !          58489:                setivec(6, &flintr);
        !          58490: 
        !          58491:                outb(FDCDOR, 0);
        !          58492:                outb(FDCDOR, DORNMR);
        !          58493: 
        !          58494:                if ( fl.fl_rate != 2 )
        !          58495:                        outb(FDCRATE, fl.fl_rate );
        !          58496: 
        !          58497:                flput(CMDSPEC);
        !          58498:                flput((fl_srt<<4)|fl_hut);
        !          58499:                flput(fl_hlt<<1);
        !          58500:                spl( s );
        !          58501:        }
        !          58502: }
        !          58503: 
        !          58504: /*
        !          58505:  * Release resources.
        !          58506:  */
        !          58507: flunload()
        !          58508: {
        !          58509:        /*
        !          58510:         * Clear interrupt vector.
        !          58511:         */
        !          58512:        if ( fl.fl_ndsk )
        !          58513:                clrivec(6);
        !          58514: 
        !          58515:        /*
        !          58516:         * Cancel timed function.
        !          58517:         */
        !          58518:        timeout( &fltim, 0, NULL, NULL );
        !          58519: 
        !          58520:        /*
        !          58521:         * Cancel periodic [1 second] invocation.
        !          58522:         */
        !          58523:        drvl[FDCMAJ].d_time = 0;
        !          58524: 
        !          58525:        /*
        !          58526:         * Turn motors off.
        !          58527:         */
        !          58528:        outb(FDCDOR, DORNMR | DORIEN );
        !          58529: }
        !          58530: 
        !          58531: /*
        !          58532:  * The open routine screens out
        !          58533:  * opens of illegal minor devices and
        !          58534:  * performs the NEC specify command if
        !          58535:  * this is the very first floppy disk
        !          58536:  * open call.
        !          58537:  */
        !          58538: 
        !          58539: static
        !          58540: flopen( dev, mode )
        !          58541: 
        !          58542: dev_t  dev;
        !          58543: int    mode;
        !          58544: 
        !          58545: {
        !          58546:        /*
        !          58547:         * Validate existence and data rate [Gap length != 0].
        !          58548:         */
        !          58549:        if ( ( funit(dev) >= fl.fl_ndsk )
        !          58550:          || ( fdata[ fkind(dev) ].fd_GPL[ flrate(dev) ] == 0 ) ) {
        !          58551: 
        !          58552:                u.u_error = ENXIO;
        !          58553:                return;
        !          58554:        }
        !          58555: }
        !          58556: 
        !          58557: /*
        !          58558:  * The read routine just calls
        !          58559:  * off to the common raw I/O processing
        !          58560:  * code, using a static buffer header in
        !          58561:  * the driver.
        !          58562:  */
        !          58563: 
        !          58564: static
        !          58565: flread( dev, iop )
        !          58566: 
        !          58567: dev_t  dev;
        !          58568: IO     *iop;
        !          58569: 
        !          58570: {
        !          58571:        dmareq(&flbuf, iop, dev, BREAD);
        !          58572: }
        !          58573: 
        !          58574: /*
        !          58575:  * The write routine is just like the
        !          58576:  * read routine, except that the function code
        !          58577:  * is write instead of read.
        !          58578:  */
        !          58579: 
        !          58580: static
        !          58581: flwrite( dev, iop )
        !          58582: 
        !          58583: dev_t  dev;
        !          58584: IO     *iop;
        !          58585: 
        !          58586: {
        !          58587:        dmareq(&flbuf, iop, dev, BWRITE);
        !          58588: }
        !          58589: 
        !          58590: /*
        !          58591:  * The ioctl routine simply queues a format request
        !          58592:  * using flbuf.
        !          58593:  * The only valid command is to format a track.
        !          58594:  * The parameter block contains the header records supplied to the controller.
        !          58595:  */
        !          58596: 
        !          58597: static
        !          58598: flioctl( dev, com, par )
        !          58599: 
        !          58600: dev_t  dev;
        !          58601: int    com;
        !          58602: char   *par;
        !          58603: 
        !          58604: {
        !          58605:        register unsigned s;
        !          58606:        register struct fdata *fdp;
        !          58607:        unsigned hd, cyl;
        !          58608: 
        !          58609:        if (com != FDFORMAT) {
        !          58610:                u.u_error = EINVAL;
        !          58611:                return;
        !          58612:        }
        !          58613: 
        !          58614:        fdp = &fdata[ fkind(dev) ];
        !          58615:        cyl = getubd(par);
        !          58616:        hd  = getubd(par+1);
        !          58617: 
        !          58618:        if (hd > 1 || cyl >= fdp->fd_trks) {
        !          58619:                u.u_error = EINVAL;
        !          58620:                return;
        !          58621:        }
        !          58622: 
        !          58623:        /*
        !          58624:         * The following may need some explanation.
        !          58625:         * dmareq will:
        !          58626:         *      claim the buffer,
        !          58627:         *      bounds check the parameter buffer,
        !          58628:         *      lock the parameter buffer in memory,
        !          58629:         *      convert io_seek to b_bno,
        !          58630:         *      dispatch the request,
        !          58631:         *      wait for completion,
        !          58632:         *      and unlock the parameter buffer.
        !          58633:         * The b_bno is reconverted to hd, cyl in flfsm.
        !          58634:         */
        !          58635: 
        !          58636:        s = fhbyh(dev) ? (cyl * fdp->fd_nhds + hd) : (hd * fdp->fd_trks + cyl);
        !          58637:        s *= fdp->fd_nspt;
        !          58638:        u.u_io.io_seek = ((long)s) * BSIZE;
        !          58639:        u.u_io.io_base = par;
        !          58640:        u.u_io.io_ioc = fdp->fd_nspt * 4;
        !          58641:        dmareq(&flbuf, &u.u_io, dev, FDFORMAT);
        !          58642: }
        !          58643: 
        !          58644: /*
        !          58645:  * Start up block I/O on a
        !          58646:  * buffer. Check that the block number
        !          58647:  * is not out of range, given the style of
        !          58648:  * the disk. Put the buffer header into the
        !          58649:  * device queue. Start up the disk if the
        !          58650:  * device is idle.
        !          58651:  */
        !          58652: 
        !          58653: static
        !          58654: flblock( bp )
        !          58655: 
        !          58656: register BUF   *bp;
        !          58657: 
        !          58658: {
        !          58659:        register int    s;
        !          58660:        register unsigned bno;
        !          58661: 
        !          58662:        bno = bp->b_bno + (bp->b_count >> 9) - 1;
        !          58663:        if ((unsigned)bp->b_bno > fdata[ fkind(bp->b_dev) ].fd_size) {
        !          58664:                bp->b_flag |= BFERR;
        !          58665:                bdone(bp);
        !          58666:                return;
        !          58667:        }
        !          58668:        if (bp->b_req != FDFORMAT && bno >= fdata[ fkind(bp->b_dev) ].fd_size) {
        !          58669:                bp->b_resid = bp->b_count;
        !          58670:                if (bp->b_flag & BFRAW)
        !          58671:                        bp->b_flag |= BFERR;
        !          58672:                bdone(bp);              /* return w/ b_resid != 0 */
        !          58673:                return;
        !          58674:        }
        !          58675: 
        !          58676:        if ((bp->b_count&0x1FF) != 0) {
        !          58677:                if (bp->b_req != FDFORMAT) {
        !          58678:                        bp->b_flag |= BFERR;
        !          58679:                        bdone(bp);
        !          58680:                        return;
        !          58681:                }
        !          58682:        }
        !          58683: 
        !          58684:        bp->b_actf = NULL;
        !          58685:        s = sphi();     /* s was already == sphi() on at least PC/XT. */
        !          58686: 
        !          58687:        if (fl.fl_actf == NULL)
        !          58688:                fl.fl_actf = bp;
        !          58689:        else
        !          58690:                fl.fl_actl->b_actf = bp;
        !          58691: 
        !          58692:        fl.fl_actl = bp;
        !          58693: 
        !          58694:        if (fl.fl_state == SIDLE)
        !          58695:                flfsm();
        !          58696: 
        !          58697:        spl( s );
        !          58698: }
        !          58699: 
        !          58700: /*
        !          58701:  * This finite state machine is
        !          58702:  * responsible for all sequencing on the disk.
        !          58703:  * It builds the commands, does the seeks, spins up
        !          58704:  * the drive motor for 1 second on the first call,
        !          58705:  * and so on.
        !          58706:  * Note that the format command is rather obscurely shoehorned into this.
        !          58707:  */
        !          58708: 
        !          58709: static
        !          58710: flfsm()
        !          58711: {
        !          58712:        register BUF    *bp;
        !          58713:        register int    flcmd;
        !          58714:        register int    i;
        !          58715: 
        !          58716: again:
        !          58717:        bp = fl.fl_actf;
        !          58718: 
        !          58719:        switch (fl.fl_state) {
        !          58720: 
        !          58721:        case SIDLE:
        !          58722:                drvl[FDCMAJ].d_time = 1;
        !          58723: 
        !          58724:                if ( bp == NULL )
        !          58725:                        break;
        !          58726: 
        !          58727:                fl.fl_fd   = fdata[ fkind(bp->b_dev) ];
        !          58728:                fl.fl_unit = funit( bp->b_dev );
        !          58729:                fl.fl_hbyh = fhbyh( bp->b_dev );
        !          58730: 
        !          58731:                fl.fl_mask = 0x10 << fl.fl_unit;
        !          58732: 
        !          58733:                fl.fl_addr = bp->b_paddr;
        !          58734:                fl.fl_secn = bp->b_bno;
        !          58735:                fl.fl_time[fl.fl_unit] = 0;
        !          58736: 
        !          58737:                if ((fl.fl_nsec = bp->b_count>>9) == 0)
        !          58738:                        fl.fl_nsec = 1;
        !          58739: 
        !          58740:                fl.fl_nerr = 0;
        !          58741: 
        !          58742:                /*
        !          58743:                 * Set data rate if changed.
        !          58744:                 * NOTE: XT never changes data rate.
        !          58745:                 */
        !          58746:                if ( (i = flrate(bp->b_dev)) != fl.fl_rate )
        !          58747:                        outb(FDCRATE, fl.fl_rate = i );
        !          58748: 
        !          58749:                /*
        !          58750:                 * Motor is turned off - turn it on, wait 1 second.
        !          58751:                 */
        !          58752:                if ((fl.fl_mstatus&fl.fl_mask) == 0) {
        !          58753: 
        !          58754:                        fl.fl_mstatus |= fl.fl_mask;
        !          58755:                        outb(FDCDOR, DORNMR|DORIEN|fl.fl_mstatus|fl.fl_unit);
        !          58756:                        flsense();
        !          58757: 
        !          58758:                        timeout( &fltim, HZ, fldelay, SSEEK );
        !          58759:                        fl.fl_time[fl.fl_unit] = 0;
        !          58760:                        fl.fl_state = SDELAY;
        !          58761:                        break;
        !          58762:                }
        !          58763:                /* no break */
        !          58764: 
        !          58765:        case SSEEK:
        !          58766:                fl.fl_time[fl.fl_unit] = 0;
        !          58767:                outb(FDCDOR, DORNMR|DORIEN|fl.fl_mstatus|fl.fl_unit);
        !          58768:                flsense();
        !          58769: 
        !          58770:                /*
        !          58771:                 * Drive is not calibrated - seek to track 0.
        !          58772:                 */
        !          58773:                if (fl.fl_incal[fl.fl_unit] == 0) {
        !          58774:                        ++fl.fl_incal[fl.fl_unit];
        !          58775:                        flput(CMDRCAL);
        !          58776:                        flput(fl.fl_unit);
        !          58777:                        fl.fl_state = SSEEK;
        !          58778:                        break;
        !          58779:                }
        !          58780: 
        !          58781:                fl.fl_fsec = (fl.fl_secn % fl.fl_fd.fd_nspt) + 1;
        !          58782: 
        !          58783:                /*
        !          58784:                 * Seek cylinder by cylinder (XENIX/DOS compatible).
        !          58785:                 */
        !          58786:                if (fl.fl_hbyh) {
        !          58787:                        fl.fl_head = fl.fl_secn / fl.fl_fd.fd_nspt;
        !          58788:                        fl.fl_fcyl = fl.fl_head / fl.fl_fd.fd_nhds;
        !          58789:                        fl.fl_head = fl.fl_head % fl.fl_fd.fd_nhds;
        !          58790:                }
        !          58791:                
        !          58792:                /*
        !          58793:                 * Seek surface by surface.
        !          58794:                 */
        !          58795:                else {
        !          58796:                        fl.fl_fcyl = fl.fl_secn / fl.fl_fd.fd_nspt;
        !          58797:                        fl.fl_head = fl.fl_fcyl / fl.fl_fd.fd_trks;
        !          58798:                        fl.fl_fcyl = fl.fl_fcyl % fl.fl_fd.fd_trks;
        !          58799:                }
        !          58800: 
        !          58801:                flput(CMDSEEK);
        !          58802:                flput((fl.fl_head<<2) | fl.fl_unit);
        !          58803: 
        !          58804:                if ( fl.fl_fd.fd_trks == 80 )
        !          58805:                        flput(fl.fl_fcyl);
        !          58806:                else if ( fl.fl_type[fl.fl_unit] == 2 )
        !          58807:                        flput(fl.fl_fcyl << 1);         /* double step */
        !          58808:                else if ( fl.fl_type[fl.fl_unit] == 4 )
        !          58809:                        flput(fl.fl_fcyl << 1);         /* double step */
        !          58810:                else
        !          58811:                        flput(fl.fl_fcyl);
        !          58812: 
        !          58813:                fl.fl_state = SHDLY;
        !          58814:                break;
        !          58815: 
        !          58816:        case SHDLY:
        !          58817:                /*
        !          58818:                 * Delay for minimum 15 milliseconds after seek before w/fmt.
        !          58819:                 * 2 clock ticks would give 10-20 millisecond [100 Hz clock].
        !          58820:                 * 3 clock ticks gives      20-30 millisecond [100 Hz clock].
        !          58821:                 */
        !          58822:                if ( bp->b_req != BREAD ) {
        !          58823:                        timeout( &fltim, 3, fldelay, SRDWR );
        !          58824:                        fl.fl_state = SDELAY;
        !          58825:                        break;
        !          58826:                }
        !          58827:                /* no break */
        !          58828: 
        !          58829:        case SRDWR:
        !          58830:                /*
        !          58831:                 * Disable watchdog timer while waiting to lock DMA controller.
        !          58832:                 */
        !          58833:                fl.fl_time[fl.fl_unit] = -1;
        !          58834: 
        !          58835:                /*
        !          58836:                 * Next state will be DMA locked state.
        !          58837:                 */
        !          58838:                fl.fl_state = SLOCK;
        !          58839: 
        !          58840:                /*
        !          58841:                 * If DMA controller locked by someone else, exit for now.
        !          58842:                 */
        !          58843:                if ( dmalock( &fldmalck, flfsm, 0 ) != 0 )
        !          58844:                        return;
        !          58845: 
        !          58846:        case SLOCK:
        !          58847:                /*
        !          58848:                 * Reset watchdog timer to restart timeout sequence.
        !          58849:                 */
        !          58850:                fl.fl_time[fl.fl_unit] = 0;
        !          58851: 
        !          58852:                flcmd = CMDRDAT;
        !          58853:                fl.fl_wflag = 0;
        !          58854: 
        !          58855:                if (bp->b_req == BREAD)
        !          58856:                        ;
        !          58857: 
        !          58858:                else if (bp->b_req == BWRITE) {
        !          58859:                        fl.fl_wflag = 1;
        !          58860:                        flcmd = CMDWDAT;
        !          58861:                }
        !          58862:                
        !          58863:                else {
        !          58864:                        fl.fl_wflag = 1;
        !          58865:                        flcmd = CMDFMT;
        !          58866: 
        !          58867:                        if(dmaon(2, fl.fl_addr, bp->b_count, fl.fl_wflag) == 0)
        !          58868:                                goto straddle;
        !          58869: 
        !          58870:                        else
        !          58871:                                goto command;
        !          58872:                }
        !          58873: 
        !          58874:                if (dmaon(2, fl.fl_addr, 512, fl.fl_wflag) == 0) {
        !          58875: straddle:
        !          58876:                        devmsg(bp->b_dev, "fd: DMA page straddle at %x:%x",
        !          58877:                                fl.fl_addr);
        !          58878:                        dmaunlock( &fldmalck );
        !          58879:                        bp->b_flag |= BFERR;
        !          58880:                        fldone( bp );
        !          58881:                        goto again;
        !          58882:                }
        !          58883: command:
        !          58884:                dmago(2);
        !          58885:                flput(flcmd);
        !          58886:                flput((fl.fl_head<<2) | fl.fl_unit);
        !          58887: 
        !          58888:                if (bp->b_req == FDFORMAT) {
        !          58889:                        flput(fl.fl_fd.fd_N);           /* N */
        !          58890:                        flput(fl.fl_fd.fd_nspt);        /* SC */
        !          58891:                        flput(fl.fl_fd.fd_FGPL);        /* GPL */
        !          58892:                        flput(0xF6);                    /* D */
        !          58893:                }
        !          58894:                
        !          58895:                else {
        !          58896:                        flput(fl.fl_fcyl);
        !          58897:                        flput(fl.fl_head);
        !          58898:                        flput(fl.fl_fsec);
        !          58899:                        flput(fl.fl_fd.fd_N);           /* N */
        !          58900:                        flput(fl.fl_fd.fd_nspt);        /* EOT */
        !          58901:                        flput(fl.fl_fd.fd_GPL[fl.fl_rate]); /* GPL */
        !          58902:                        flput(0xFF);                    /* DTL */
        !          58903:                }
        !          58904: 
        !          58905:                fl.fl_state = SENDIO;
        !          58906:                break;
        !          58907: 
        !          58908:        case SENDIO:
        !          58909:                fl.fl_time[fl.fl_unit] = 0;
        !          58910:                dmaoff(2);
        !          58911:                dmaunlock( &fldmalck );
        !          58912: 
        !          58913:                if ((fl.fl_cmdstat[0]&ST0_IC) != ST0_NT) {
        !          58914:                        if (++fl.fl_nerr < 5) {
        !          58915:                                fl.fl_incal[fl.fl_unit] = 0;
        !          58916:                                fl.fl_state = SSEEK;
        !          58917:                        }
        !          58918:                        
        !          58919:                        else {
        !          58920:                                flstatus();
        !          58921:                                bp->b_flag |= BFERR;
        !          58922:                                fldone(bp);
        !          58923:                        }
        !          58924:                }
        !          58925: 
        !          58926:                else if (--fl.fl_nsec == 0) {
        !          58927:                        bp->b_resid = 0;
        !          58928:                        fldone(bp);
        !          58929:                }
        !          58930:                
        !          58931:                else {
        !          58932:                        ++fl.fl_secn;
        !          58933:                        fl.fl_addr += 512;      /* 512 == fl.fl_fd.fd_nbps */
        !          58934:                        fl.fl_state = SSEEK;
        !          58935:                }
        !          58936: 
        !          58937:                /*
        !          58938:                 * Delay for minimum 1.5 msecs after writing before seek.
        !          58939:                 */
        !          58940:                if ( fl.fl_wflag ) {
        !          58941:                        timeout( &fltim, 2, fldelay, fl.fl_state );
        !          58942:                        fl.fl_state = SDELAY;
        !          58943:                        break;
        !          58944:                }
        !          58945: 
        !          58946:                goto again;
        !          58947: 
        !          58948:        case SDELAY:
        !          58949:                /*
        !          58950:                 * Ignore interrupts until timeout occurs.
        !          58951:                 */
        !          58952:                break;
        !          58953: 
        !          58954:        default:
        !          58955:                panic("fds");
        !          58956:        }
        !          58957: }
        !          58958: 
        !          58959: /*
        !          58960:  * Delay before initiating next operation.
        !          58961:  * This allows the floppy motor to turn on,
        !          58962:  * the head to settle before writing,
        !          58963:  * the erase head to turn off after writing, etc.
        !          58964:  */
        !          58965: static
        !          58966: fldelay( state )
        !          58967: int state;
        !          58968: {
        !          58969:        int s;
        !          58970: 
        !          58971:        s = sphi();
        !          58972:        if ( fl.fl_state == SDELAY ) {
        !          58973:                fl.fl_state = state;
        !          58974:                flfsm();
        !          58975:        }
        !          58976:        spl( s );
        !          58977: }
        !          58978: 
        !          58979: /*
        !          58980:  * The flrate function returns the data rate for the flopen and flfsm routines.
        !          58981:  */
        !          58982: static int
        !          58983: flrate( dev )
        !          58984: register dev_t dev;
        !          58985: {
        !          58986:        register int rate;
        !          58987: 
        !          58988:        /*
        !          58989:         * Default is 250 Kbps.
        !          58990:         */
        !          58991:        rate = 2;
        !          58992: 
        !          58993:        /*
        !          58994:         * Check for high capacity drive.
        !          58995:         */
        !          58996:        if ( fl.fl_type[ funit(dev) ] == 2 ) {
        !          58997: 
        !          58998:                /*
        !          58999:                 * 300 Kbps.
        !          59000:                 */
        !          59001:                rate--;
        !          59002: 
        !          59003:                /*                             
        !          59004:                 * Check for high capacity media.
        !          59005:                 */
        !          59006:                if ( fdata[ fkind(dev) ].fd_nspt == 15 ) {
        !          59007: 
        !          59008:                        /*
        !          59009:                         * 500 Kbps.
        !          59010:                         */
        !          59011:                        rate--;
        !          59012:                }
        !          59013:        } else if (fl.fl_type[funit(dev)] == 4 && fkind(dev) == 7)
        !          59014:                rate = 0;
        !          59015: 
        !          59016:        return( rate );
        !          59017: }
        !          59018: 
        !          59019: /*
        !          59020:  * This routine is called by the
        !          59021:  * clock handler every second. If the drive
        !          59022:  * has been idle for a long time it turns off
        !          59023:  * the motor and shuts off the timeouts.
        !          59024:  */
        !          59025: 
        !          59026: static
        !          59027: fltimeout()
        !          59028: {
        !          59029:        register int    unit;
        !          59030:        register int    mask;
        !          59031:        register int    s;
        !          59032: 
        !          59033:        s = sphi();
        !          59034: 
        !          59035:        /*
        !          59036:         * Scan all drives, looking for motor timeouts.
        !          59037:         */
        !          59038:        for ( unit=0, mask=0x10; unit < 4; unit++, mask <<= 1 ) {
        !          59039: 
        !          59040:                /*
        !          59041:                 * Ignore drives which aren't spinning.
        !          59042:                 */
        !          59043:                if ( (fl.fl_mstatus & mask) == 0 )
        !          59044:                        continue;
        !          59045: 
        !          59046:                /*
        !          59047:                 * If timer is disabled (i.e. we are waiting for the DMA
        !          59048:                 * controller), go on to the next drive.
        !          59049:                 */
        !          59050:                if ( fl.fl_time[unit] < 0 )
        !          59051:                        continue;
        !          59052: 
        !          59053:                /*
        !          59054:                 * Leave recently accessed (in last 4 seconds) drives spinning.
        !          59055:                 */
        !          59056:                if ( ++fl.fl_time[unit] < MTIMER )
        !          59057:                        continue;
        !          59058: 
        !          59059:                /*
        !          59060:                 * Timeout drives which have been inactive for 5 seconds.
        !          59061:                 */
        !          59062:                fl.fl_mstatus &= ~mask;
        !          59063: 
        !          59064:                /*
        !          59065:                 * Not selected drive, or selected drive is idle.
        !          59066:                 */
        !          59067:                if ( (unit != fl.fl_unit) || (fl.fl_state == SIDLE) )
        !          59068:                        continue;
        !          59069: 
        !          59070:                /*
        !          59071:                 * Active drive did not complete operation within 5 seconds.
        !          59072:                 * Attempt recovery.
        !          59073:                 */
        !          59074:                flrecov();
        !          59075: 
        !          59076:                /*
        !          59077:                 * Initiate next block request.
        !          59078:                 */
        !          59079:                if ( fl.fl_state == SIDLE )
        !          59080:                        flfsm();
        !          59081:        }
        !          59082: 
        !          59083:        /*
        !          59084:         * Physically turn off drives which timed out.
        !          59085:         */
        !          59086:        outb(FDCDOR, DORNMR | DORIEN | fl.fl_mstatus | fl.fl_unit);
        !          59087: 
        !          59088:        /*
        !          59089:         * Stop checking once all drives have been stopped.
        !          59090:         */
        !          59091:        if ( fl.fl_mstatus == 0 )
        !          59092:                drvl[FDCMAJ].d_time = 0;
        !          59093: 
        !          59094:        spl(s);
        !          59095: }
        !          59096: 
        !          59097: /*
        !          59098:  * The recovery routine resets and reprograms the floppy controller,
        !          59099:  * and discards any queued requests on the current drive.
        !          59100:  * This is required if the floppy door is open, or diskette is missing.
        !          59101:  */
        !          59102: 
        !          59103: flrecov()
        !          59104: {
        !          59105:        register BUF * bp;
        !          59106:        register dev_t dev;
        !          59107: 
        !          59108:        /*
        !          59109:         * Disable DMA transfer.
        !          59110:         * Reset floppy controller.
        !          59111:         */
        !          59112:        dmaoff( 2 );
        !          59113: 
        !          59114:        /*
        !          59115:         * Unlock the controller if locked by us.
        !          59116:         */
        !          59117:        dmaunlock( &fldmalck );
        !          59118: 
        !          59119:        outb(FDCDOR, 0);
        !          59120:        outb(FDCDOR, DORNMR);
        !          59121: 
        !          59122:        /*
        !          59123:         * Program transfer bps.
        !          59124:         */
        !          59125:        if ( fl.fl_rate != 2 )
        !          59126:                outb( FDCRATE, fl.fl_rate );
        !          59127: 
        !          59128:        /*
        !          59129:         * Program floppy controller.
        !          59130:         */
        !          59131:        flput( CMDSPEC );
        !          59132:        flput( (fl_srt << 4) | fl_hut );
        !          59133:        flput( fl_hlt << 1 );
        !          59134: 
        !          59135:        /*
        !          59136:         * Drives are no longer in calibration.
        !          59137:         */
        !          59138:        fl.fl_incal[0] =
        !          59139:        fl.fl_incal[1] =
        !          59140:        fl.fl_incal[2] =
        !          59141:        fl.fl_incal[3] = 0;
        !          59142: 
        !          59143:        /*
        !          59144:         * Abort all block requests on current drive after 1st recov attempt.
        !          59145:         */
        !          59146:        if ( bp = fl.fl_actf ) {
        !          59147:                printf("fd%d: <Door Open>\n", fl.fl_unit );
        !          59148:                dev = bp->b_dev;
        !          59149:                do {
        !          59150:                        bp->b_flag |= BFERR;
        !          59151:                        fldone( bp );
        !          59152:                } while ( (bp = fl.fl_actf) && (bp->b_dev == dev) );
        !          59153:        }
        !          59154: 
        !          59155:        /*
        !          59156:         * Delay before setting controller state to idle.
        !          59157:         * This gives time for spurious floppy interrupts to occur.
        !          59158:         * NOTE: Can't call flfsm(), since it may call us [future revision].
        !          59159:         */
        !          59160:        timeout( &fltim, HZ/4, fldelay, SIDLE );
        !          59161:        fl.fl_state = SDELAY;
        !          59162: }
        !          59163: 
        !          59164: /*
        !          59165:  * The interrupt routine gets all
        !          59166:  * the status bytes the controller chip
        !          59167:  * will give it, then issues a sense interrupt
        !          59168:  * status command (which is necessary for a seek
        !          59169:  * to complete!) and throws all of the status
        !          59170:  * bytes away.
        !          59171:  */
        !          59172: 
        !          59173: static
        !          59174: flintr()
        !          59175: {
        !          59176:        register int s;
        !          59177: 
        !          59178:        s = sphi();
        !          59179:        flsense();
        !          59180: 
        !          59181:        if (fl.fl_state != SIDLE)
        !          59182:                flfsm();
        !          59183: 
        !          59184:        spl(s);
        !          59185: }
        !          59186: 
        !          59187: /*
        !          59188:  * Fldone() returns current request to operating system.
        !          59189:  */
        !          59190: fldone( bp )
        !          59191: register BUF * bp;
        !          59192: {
        !          59193:        fl.fl_actf  = bp->b_actf;
        !          59194:        fl.fl_state = SIDLE;
        !          59195:        bdone( bp );
        !          59196: }
        !          59197: 
        !          59198: /*
        !          59199:  * Flsense() issues a sense interrupt status command
        !          59200:  * to restore the controller to a quiescent state.
        !          59201:  */
        !          59202: 
        !          59203: static
        !          59204: flsense()
        !          59205: {
        !          59206:        register int    b;
        !          59207:        register int    n;
        !          59208:        register int    i = 0;
        !          59209:        register int    s;
        !          59210: 
        !          59211:        s = sphi();
        !          59212: 
        !          59213:        /*
        !          59214:         * Read all the status bytes the controller will give us.
        !          59215:         */
        !          59216:        n = 0;
        !          59217: 
        !          59218:        for (;;) {
        !          59219:                while (((b=inb(FDCMSR))&MSRRQM) == 0) {
        !          59220:                        if ( --i == 0 ) {
        !          59221:                                printf("flintr: timeout\n");
        !          59222:                                break;
        !          59223:                        }
        !          59224:                }
        !          59225: 
        !          59226:                if ((b&MSRDIO) == 0)
        !          59227:                        break;
        !          59228: 
        !          59229:                b = inb(FDCDAT);
        !          59230:                if ( n < sizeof(fl.fl_cmdstat) )
        !          59231:                        fl.fl_cmdstat[n++] = b;
        !          59232:        }
        !          59233: 
        !          59234:        fl.fl_ncmdstat = n;
        !          59235: 
        !          59236:        /*
        !          59237:         * Issue a sense interrupt command and discard result.
        !          59238:         */
        !          59239:        outb(FDCDAT, CMDSINT);
        !          59240: 
        !          59241:        n = 0;
        !          59242:        for (;;) {
        !          59243:                while (((b=inb(FDCMSR))&MSRRQM) == 0) {
        !          59244:                        if ( --i == 0 ) {
        !          59245:                                printf("flsense: timeout\n");
        !          59246:                                break;
        !          59247:                        }
        !          59248:                }
        !          59249: 
        !          59250:                if ((b&MSRDIO) == 0)
        !          59251:                        break;
        !          59252: 
        !          59253:                b = inb(FDCDAT);
        !          59254:                if ( n < sizeof(fl.fl_intstat) )
        !          59255:                        fl.fl_intstat[n++] = b;
        !          59256:        }
        !          59257:        fl.fl_nintstat = n;
        !          59258: 
        !          59259:        spl( s );
        !          59260: }
        !          59261: 
        !          59262: /*
        !          59263:  * Send a command byte to the
        !          59264:  * NEC chip, first waiting until the chip
        !          59265:  * says that it is ready. No timeout is
        !          59266:  * performed; if the chip dies, we do too!
        !          59267:  */
        !          59268: 
        !          59269: static
        !          59270: flput( b )
        !          59271: 
        !          59272: int    b;
        !          59273: 
        !          59274: {
        !          59275:        register int i = 0;
        !          59276: 
        !          59277:        while ( (inb(FDCMSR) & (MSRRQM|MSRDIO)) != MSRRQM ) {
        !          59278:                if ( --i == 0 ) {
        !          59279:                        printf("flput: timeout\n");
        !          59280:                        return;
        !          59281:                }
        !          59282:        }
        !          59283: 
        !          59284:        outb(FDCDAT, b);
        !          59285: }
        !          59286: 
        !          59287: /*
        !          59288:  * Dissassemble the floppy error status for user reference.
        !          59289:  */
        !          59290: 
        !          59291: static
        !          59292: flstatus()
        !          59293: {
        !          59294:        printf("fd%d: head=%u cyl=%u",
        !          59295:                fl.fl_cmdstat[0] & 3,
        !          59296:                fl.fl_head, fl.fl_fcyl );
        !          59297: 
        !          59298:        /*
        !          59299:         * Report on ST0 bits.
        !          59300:         */
        !          59301:        if ( fl.fl_ncmdstat >= 1 ) {
        !          59302:                if ( fl.fl_cmdstat[0] & ST0_NR )
        !          59303:                        printf(" <Not Ready>");
        !          59304: 
        !          59305:                if ( fl.fl_cmdstat[0] & ST0_EC )
        !          59306:                        printf(" <Equipment Check>");
        !          59307:        }
        !          59308: 
        !          59309:        /*
        !          59310:         * Report on ST1 bits.
        !          59311:         */
        !          59312:        if ( fl.fl_ncmdstat >= 2 ) {
        !          59313:                if ( fl.fl_cmdstat[1] & ST1_MA )
        !          59314:                        printf(" <Missing Address Mark>");
        !          59315: 
        !          59316:                if ( fl.fl_cmdstat[1] & ST1_NW )
        !          59317:                        printf(" <Write Protected>");
        !          59318: 
        !          59319:                if ( fl.fl_cmdstat[1] & ST1_ND )
        !          59320:                        printf(" <No Data>");
        !          59321: 
        !          59322:                if ( fl.fl_cmdstat[1] & ST1_OR )
        !          59323:                        printf(" <Overrun>");
        !          59324: 
        !          59325:                if ( fl.fl_cmdstat[1] & ST1_DE )
        !          59326:                        printf(" <Data Error>");
        !          59327: 
        !          59328:                if ( fl.fl_cmdstat[1] & ST1_EN )
        !          59329:                        printf(" <End of Cyl>");
        !          59330:        }
        !          59331: 
        !          59332:        /*
        !          59333:         * Report on ST2 bits.
        !          59334:         */
        !          59335:        if ( fl.fl_ncmdstat >= 3 ) {
        !          59336:                if ( fl.fl_cmdstat[2] & ST2_MD )
        !          59337:                        printf(" <Missing Data Address Mark>");
        !          59338: 
        !          59339:                if ( fl.fl_cmdstat[2] & ST2_BC )
        !          59340:                        printf(" <Bad Cylinder>");
        !          59341: 
        !          59342:                if ( fl.fl_cmdstat[2] & ST2_WC )
        !          59343:                        printf(" <Wrong Cylinder>");
        !          59344: 
        !          59345:                if ( fl.fl_cmdstat[2] & ST2_DD )
        !          59346:                        printf(" <Bad Data CRC>");
        !          59347: 
        !          59348:                if ( fl.fl_cmdstat[2] & ST2_CM )
        !          59349:                        printf(" <Data Deleted>");
        !          59350:        }
        !          59351: 
        !          59352:        printf("\n");
        !          59353: }
        !          59354: @
        !          59355: 
        !          59356: 
        !          59357: 1.1
        !          59358: log
        !          59359: @Initial revision
        !          59360: @
        !          59361: text
        !          59362: @d21 2
        !          59363: a22 2
        !          59364: #include       "coherent.h"
        !          59365: #include       "i8086.h"
        !          59366: a27 1
        !          59367: #include       <sys/timeout.h>
        !          59368: d30 1
        !          59369: a30 1
        !          59370: #include       "dmac.h"
        !          59371: @
        !          59372: 0707070064030106751004440000030000030000011777770507310671400005300000013273/newbits/kernel/USRSRC/i8086/drv/RCS/fo2,vhead     1.1;
        !          59373: branch   ;
        !          59374: access   ;
        !          59375: symbols  ;
        !          59376: locks    bin:1.1; strict;
        !          59377: comment  @# @;
        !          59378: 
        !          59379: 
        !          59380: 1.1
        !          59381: date     91.06.10.10.22.29;  author bin;  state Exp;
        !          59382: branches ;
        !          59383: next     ;
        !          59384: 
        !          59385: 
        !          59386: desc
        !          59387: @initial version prov by hal
        !          59388: @
        !          59389: 
        !          59390: 
        !          59391: 
        !          59392: 1.1
        !          59393: log
        !          59394: @Initial revision
        !          59395: @
        !          59396: text
        !          59397: @/usr/src/sys/coh/bio.c:                       sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          59398: /usr/src/sys/coh/bio.c:                        sleep((char *)&bufneed, CVBLKIO, IVBLKIO, SVBLKIO);
        !          59399: /usr/src/sys/coh/bio.c:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          59400: /usr/src/sys/coh/bio.c:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          59401: /usr/src/sys/coh/clist.c:              sleep((char *)&cltwant, CVCLIST, IVCLIST, SVCLIST);
        !          59402: /usr/src/sys/coh/pipe.c:               sleep((char *)&ip->i_prx, CVPIPE, IVPIPE, SVPIPE);
        !          59403: /usr/src/sys/coh/pipe.c:                       sleep((char *)&ip->i_pwx, CVPIPE, IVPIPE, SVPIPE);
        !          59404: /usr/src/sys/coh/poll.c:                        * Wake process if it is sleeping.
        !          59405: /usr/src/sys/coh/proc.c:  * wakes us up.  Since it is possible for many people to sleep on the
        !          59406: /usr/src/sys/coh/proc.c:  * was waiting for has completed and if not, go to sleep again.  `cl'
        !          59407: /usr/src/sys/coh/proc.c:  * of the sleep.  `sr' is the swap value that allows us to get swapped
        !          59408: /usr/src/sys/coh/proc.c: sleep(e, cl, sl, sr)
        !          59409: /usr/src/sys/coh/proc.c:        * Get ready to go to sleep and do so.
        !          59410: /usr/src/sys/coh/proc.c:  * Defer function to wake up all processes sleeping on the event `e'.
        !          59411: /usr/src/sys/coh/proc.c:  * Wake up all processes sleeping on the event `e'.
        !          59412: /usr/src/sys/coh/proc.c:               sleep((char *)g, CVGATE, IVGATE, SVGATE);
        !          59413: /usr/src/sys/coh/seg.c:                        sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          59414: /usr/src/sys/coh/sig.c:                sleep((char *)&pts.pt_busy, CVPTSET, IVPTSET, SVPTSET);
        !          59415: /usr/src/sys/coh/sig.c:                        sleep((char *)&pts.pt_req, CVPTRET, IVPTRET, SVPTRET);
        !          59416: /usr/src/sys/coh/sys1.c:  * Pause.  Go to sleep on a channel that nobody will wakeup so that only
        !          59417: /usr/src/sys/coh/sys1.c:               sleep((char *)&u, CVPAUSE, IVPAUSE, SVPAUSE);
        !          59418: /usr/src/sys/coh/sys1.c:               sleep((char *)ppp, CVWAIT, IVWAIT, SVWAIT);
        !          59419: /usr/src/sys/coh/sys2.c:               sleep( &cprocp->p_polls, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59420: /usr/src/sys/i8086/drv/aha.c:          sleep( ccb, CVBLKIO, IVBLKIO, SVBLKIO );
        !          59421: /usr/src/sys/i8086/drv/alx.c:                          sleep((char *)(&AL_H_CLOSE), CVTTOUT, IVTTOUT,
        !          59422: /usr/src/sys/i8086/drv/alx.c:                          sleep((char *)(&tp->t_open), CVTTOUT, IVTTOUT,
        !          59423: /usr/src/sys/i8086/drv/alx.c:          sleep((char *)&AL_TIM, CVTTOUT, IVTTOUT, SVTTOUT);
        !          59424: /usr/src/sys/i8086/drv/alx.c:          sleep((char *)&drvl[maj].d_time, CVTTOUT, IVTTOUT, SVTTOUT);
        !          59425: /usr/src/sys/i8086/drv/alx.c:   * (Re)start output, wake sleeping processes, etc.
        !          59426: /usr/src/sys/i8086/drv/dg.c:  * Use kernel function sleep(), which is NOT the system call by that name.
        !          59427: /usr/src/sys/i8086/drv/dg.c:   sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
        !          59428: /usr/src/sys/i8086/drv/dmareq.c:               sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          59429: /usr/src/sys/i8086/drv/gc.c:                   sleep((char *)&hstim, CVTTOUT, IVTTOUT, SVTTOUT);
        !          59430: /usr/src/sys/i8086/drv/hs.c:                   sleep((char *)&hstim, CVTTOUT, IVTTOUT, SVTTOUT);
        !          59431: /usr/src/sys/i8086/drv/lp.c:  * sleep for a while.
        !          59432: /usr/src/sys/i8086/drv/lp.c:                   sleep((char *)p, 0, 0, 0);
        !          59433: /usr/src/sys/i8086/drv/lp.c:            * Check for sleeping process on ready printer.
        !          59434: /usr/src/sys/i8086/drv/mm.c:                           sleep((char*) &istty.t_oq,
        !          59435: /usr/src/sys/i8086/drv/ms.c:           sleep(&u_stts, 0x7fff, 0x7fff, 0);
        !          59436: /usr/src/sys/i8086/drv/msg.c:  * Msgsnd() now checks for queue removal after waking from sleep.
        !          59437: /usr/src/sys/i8086/drv/msg.c:  * since system calls are synchronous unless they sleep or are interrupted.
        !          59438: /usr/src/sys/i8086/drv/msg.c:           * Wakeup processes sleeping on the removed message queue.
        !          59439: /usr/src/sys/i8086/drv/msg.c:                  sleep( qp, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59440: /usr/src/sys/i8086/drv/msg.c:                  sleep( msqs, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59441: /usr/src/sys/i8086/drv/msg.c:          sleep( qp, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59442: /usr/src/sys/i8086/drv/rp.c:           sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59443: /usr/src/sys/i8086/drv/rp.c:                   sleep( rp->q_ogate, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59444: /usr/src/sys/i8086/drv/rp.c:           sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59445: /usr/src/sys/i8086/drv/rs.c:                   sleep( &rstty.rt_crefc,
        !          59446: /usr/src/sys/i8086/drv/rs.c:                   sleep( &rstty.rt_drefc, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59447: /usr/src/sys/i8086/drv/rs.c:           sleep( &rstty.rt_irefc, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59448: /usr/src/sys/i8086/drv/rs.c:           sleep( &rstty.rt_orefc, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59449: /usr/src/sys/i8086/drv/rs.c:                   sleep( &rstty.rt_drefc, CVTTOUT, IVTTOUT, SVTTOUT);
        !          59450: /usr/src/sys/i8086/drv/sem.c:  sleep( ep, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59451: /usr/src/sys/i8086/drv/ss.c: #define LOPRI_RETRIES     5       /* # of retries with sleep between tries */
        !          59452: /usr/src/sys/i8086/drv/ss.c:   sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
        !          59453: /usr/src/sys/i8086/drv/st.c:           sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59454: /usr/src/sys/i8086/drv/st.c:           sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59455: /usr/src/sys/i8086/drv/st.c:           sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59456: /usr/src/sys/i8086/drv/st.c:  *                Wake sleeping processes if appropriate.
        !          59457: /usr/src/sys/i8086/drv/st.c:           sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59458: /usr/src/sys/i8086/drv/tn.c:           sleep( &tp->RxReq[code], CVTTIN, IVTTIN, SVTTIN );
        !          59459: /usr/src/sys/i8086/drv/tn.c:           sleep( &tp->TxReq, CVTTOUT, IVTTOUT, SVTTOUT );
        !          59460: /usr/src/sys/i8086/src/clist.s:        call    sleep_
        !          59461: /usr/src/sys/ker/swap.c:               sleep((char *)&stimer, CVSWAP, IVSWAP, SVSWAP);
        !          59462: /usr/src/sys/ttydrv/tty.c:                     sleep((char *)&tp->t_oq, CVTTOUT, IVTTOUT, SVTTOUT);
        !          59463: /usr/src/sys/ttydrv/tty.c:                     sleep((char *)&tp->t_iq, CVTTIN, IVTTIN, SVTTIN);
        !          59464: /usr/src/sys/ttydrv/tty.c:                     sleep((char *)&tp->t_oq, CVTTOUT, IVTTOUT, SVTTOUT);
        !          59465: /usr/src/sys/ttydrv/tty.c:                     sleep((char *)&tp->t_oq, CVTTOUT, IVTTOUT, SVTTOUT);
        !          59466: /usr/src/sys/ldrv/ldmain.c:            sleep( (char *)&nopen, CVSWAP, IVSWAP, SVSWAP );
        !          59467: /usr/src/sys/ldrv/ldswap.c:            sleep( (char *)&stimer, CVSWAP, IVSWAP, SVSWAP );
        !          59468: @
        !          59469: 0707070064030106741004440000030000030000011777770507310671500006100000004016/newbits/kernel/USRSRC/i8086/drv/RCS/fontgen.c,vhead     1.1;
        !          59470: branch   ;
        !          59471: access   ;
        !          59472: symbols  ;
        !          59473: locks    bin:1.1; strict;
        !          59474: comment  @ * @;
        !          59475: 
        !          59476: 
        !          59477: 1.1
        !          59478: date     91.06.10.10.22.32;  author bin;  state Exp;
        !          59479: branches ;
        !          59480: next     ;
        !          59481: 
        !          59482: 
        !          59483: desc
        !          59484: @initial version prov by hal
        !          59485: @
        !          59486: 
        !          59487: 
        !          59488: 
        !          59489: 1.1
        !          59490: log
        !          59491: @Initial revision
        !          59492: @
        !          59493: text
        !          59494: @/*
        !          59495:  * fontgen - generate 16x8 font assembler source on stdout.
        !          59496:  */
        !          59497: 
        !          59498: #define        BIT(n)  (1 << (n))
        !          59499: #define        BITS(n) (((n) >= 4) ? (3 << (((n) - 4) * 2)) : (3 << (((n) + 4) * 2)))
        !          59500: 
        !          59501: unsigned char ibuf[1024];
        !          59502: unsigned char odef[] = "\tB________ = 0000000\n";
        !          59503: unsigned char obuf[] = "\t.word\tB________\n";
        !          59504: 
        !          59505: main()
        !          59506: {
        !          59507:        register unsigned s;
        !          59508:        register unsigned j;
        !          59509:        register unsigned i;
        !          59510:        extern long lseek();
        !          59511: 
        !          59512:        /*
        !          59513:         * Read fonts from /dev/mem at offset 0xFFA6E.
        !          59514:         */
        !          59515:        close(0);
        !          59516:        if (open("/dev/mem", 0) != 0)
        !          59517:                fatal("/dev/mem: can't open\n");
        !          59518:        if (lseek( 0, 0xFFA6EL, 0) != 0xFFA6EL)
        !          59519:                fatal("/dev/mem: can't seek to fonts");
        !          59520:        if (read( 0, ibuf, sizeof ibuf ) != sizeof ibuf)
        !          59521:                fatal("/dev/mem: can't read fonts");
        !          59522: 
        !          59523:        /*
        !          59524:         * Define symbolic constants.
        !          59525:         */
        !          59526:        for (i=0; i < 256; ++i) {
        !          59527:                /* Generate constant's name. */
        !          59528:                s = i;
        !          59529:                for (j=10; --j >= 2; s>>=1)
        !          59530:                        odef[j] = (s&1) ? 'X' : '_';
        !          59531: 
        !          59532:                /* Convert 8 pixel width to 16 pixels */
        !          59533:                s = 0;
        !          59534:                for (j=0; j < 8; ++j)
        !          59535:                        if (i & BIT(j))
        !          59536:                                s |= BITS(j);
        !          59537: 
        !          59538:                /* Generate constant's value */
        !          59539:                for (j=19; j >= 14; --j) {
        !          59540:                        odef[j] = (s & 7) + '0';
        !          59541:                        s >>= 3;
        !          59542:                }
        !          59543: 
        !          59544:                /* Print constant's name and value */
        !          59545:                send( odef );
        !          59546:        }
        !          59547:        send( "\n\t.globl\tfontw_\nfontw_:" );
        !          59548: 
        !          59549:        /*
        !          59550:         * Define fonts for 128 characters.
        !          59551:         */
        !          59552:        for (i=0; i < sizeof ibuf; ++i) {
        !          59553: 
        !          59554:                /* Format and print one pixel line */
        !          59555:                j = 16;
        !          59556:                s = ibuf[i];
        !          59557:                while ( --j >= 8 ) {
        !          59558:                        obuf[j] = (s&1) ? 'X' : '_' ;
        !          59559:                        s >>= 1;
        !          59560:                }
        !          59561:                send( obuf );
        !          59562: 
        !          59563:                /* Insert blank line between characters for readability */
        !          59564:                if ( (i & 7) == 7 )
        !          59565:                        send( "\n" );
        !          59566:        }
        !          59567:        exit( 0 );
        !          59568: }
        !          59569: 
        !          59570: /*
        !          59571:  * Fatal( msg ) - report error, and abort.
        !          59572:  */
        !          59573: 
        !          59574: fatal( msg )
        !          59575: register char *msg;
        !          59576: {
        !          59577:        write( 2, msg, strlen(msg) );
        !          59578:        exit( 1 );
        !          59579: }
        !          59580: 
        !          59581: /*
        !          59582:  * send( s ) - write null-terminated string to standard output.
        !          59583:  */
        !          59584: 
        !          59585: send( s )
        !          59586: register char *s;
        !          59587: {
        !          59588:        write( 1, s, strlen(s) );
        !          59589: }
        !          59590: @
        !          59591: 0707070064030106731004440000030000030000011777770507310671600005400000022700/newbits/kernel/USRSRC/i8086/drv/RCS/gc.c,vhead     1.1;
        !          59592: branch   ;
        !          59593: access   ;
        !          59594: symbols  ;
        !          59595: locks    bin:1.1; strict;
        !          59596: comment  @ * @;
        !          59597: 
        !          59598: 
        !          59599: 1.1
        !          59600: date     91.06.10.10.22.36;  author bin;  state Exp;
        !          59601: branches ;
        !          59602: next     ;
        !          59603: 
        !          59604: 
        !          59605: desc
        !          59606: @initial version prov by hal
        !          59607: @
        !          59608: 
        !          59609: 
        !          59610: 
        !          59611: 1.1
        !          59612: log
        !          59613: @Initial revision
        !          59614: @
        !          59615: text
        !          59616: @/*
        !          59617:  * Interrupt Driver Multi-Port Device Driver.
        !          59618:  * - supports version 7 compatible ioctl
        !          59619:  */
        !          59620: 
        !          59621: #include "coherent.h"
        !          59622: #include "ins8250.h"
        !          59623: #include <sys/stat.h>
        !          59624: #include <sys/uproc.h>
        !          59625: #include <sys/proc.h>
        !          59626: #include <sys/tty.h>           /* indirectly includes sgtty.h */
        !          59627: #include <sys/con.h>
        !          59628: #include <errno.h>
        !          59629: #include <sys/timeout.h>       /* TIM */
        !          59630: #include <sched.h>             /* CVTTOUT, IVTTOUT, SVTTOUT */
        !          59631: #include <poll_clk.h>
        !          59632: 
        !          59633: /*
        !          59634:  * Definitions.
        !          59635:  *
        !          59636:  * MAX_GCNUM is the maximum number of devices that can be polled
        !          59637:  *   using this driver and can be revised up or down
        !          59638:  * PORT is a convenience macro for the base address of a port
        !          59639:  * port_config is the structure of the initial configuration for each
        !          59640:  *   polled port;  note that "speed" is NOT the actual baud rate, but
        !          59641:  *   the value of the symbol for that baud rate as defined in
        !          59642:  *   /usr/include/sgtty.h
        !          59643:  * GCINT is the IRQ number for the interrupt belonging to the board.
        !          59644:  *   On the AT, IRQ2 is mapped to the same vector as IRQ9.
        !          59645:  */
        !          59646: #define MAX_GCNUM      8
        !          59647: #define        PORT    ((int)(tp->t_ddp))
        !          59648: struct port_config {
        !          59649:        int     addr;   /* base address of the 8250-family UART */
        !          59650:        int     speed;  /* B0..B19200 */
        !          59651: };
        !          59652: #define GCINT          2
        !          59653: 
        !          59654: /*
        !          59655:  * Export Variables - these can be patched without recompiling and linking
        !          59656:  *
        !          59657:  * GCNUM is the actual number of polled serial ports, and should be
        !          59658:  *   less than or equal to MAX_GCNUM
        !          59659:  * GCIRPT is the I/O address of the multiport interrupt register;
        !          59660:  *   a value of 0 in bit 0..3 means a pending interrupt for port 0..3
        !          59661:  * GC_PORTS is an array of address/speed pairs, one for each port
        !          59662:  */
        !          59663: int    GCNUM = 4;
        !          59664: int    GCIRPT = 0x2BF;
        !          59665: /*
        !          59666:  * Defaults are for PC COM4, Enhanced Mode, High Address.
        !          59667:  */
        !          59668: struct port_config GC_PORTS[MAX_GCNUM] = {
        !          59669:        { 0x2A0, B9600 },
        !          59670:        { 0x2A8, B9600 },
        !          59671:        { 0x2B0, B9600 },
        !          59672:        { 0x2B8, B9600 }
        !          59673: };
        !          59674: 
        !          59675: /*
        !          59676:  * Export Functions.
        !          59677:  */
        !          59678: int    gcload();
        !          59679: int    gcopen();
        !          59680: int    gcclose();
        !          59681: int    gcread();
        !          59682: int    gcwrite();
        !          59683: int    gcioctl();
        !          59684: int    gcunload();
        !          59685: int    gcpoll();
        !          59686: 
        !          59687: int    gccycle();
        !          59688: int    gcintr();
        !          59689: int    gcparam();
        !          59690: int    gcstart();
        !          59691: 
        !          59692: /*
        !          59693:  * Import Functions
        !          59694:  */
        !          59695: int    nulldev();
        !          59696: int    nonedev();
        !          59697: 
        !          59698: /*
        !          59699:  * Configuration table.
        !          59700:  */
        !          59701: CON gccon ={
        !          59702:        DFCHR|DFPOL,                    /* Flags */
        !          59703:        GCINT,                          /* Major index */
        !          59704:        gcopen,                         /* Open */
        !          59705:        gcclose,                        /* Close */
        !          59706:        nulldev,                        /* Block */
        !          59707:        gcread,                         /* Read */
        !          59708:        gcwrite,                        /* Write */
        !          59709:        gcioctl,                        /* Ioctl */
        !          59710:        nulldev,                        /* Powerfail */
        !          59711:        nulldev,                        /* Timeout */
        !          59712:        gcload,                         /* Load */
        !          59713:        gcunload,                       /* Unload */
        !          59714:        gcpoll                          /* Poll */
        !          59715: };
        !          59716: 
        !          59717: /*
        !          59718:  * Local variables.
        !          59719:  */
        !          59720: static TTY *hstty;
        !          59721: static TTY *hslimtty;
        !          59722: static TIM hstim;
        !          59723: 
        !          59724: /*
        !          59725:  * Time constant table.
        !          59726:  * Indexed by ioctl baud rate.
        !          59727:  */
        !          59728: static
        !          59729: int timeconst[] = {
        !          59730:        0,                              /* 0 */
        !          59731:        2304,                           /* 50 */
        !          59732:        1536,                           /* 75 */
        !          59733:        1047,                           /* 110 */
        !          59734:        857,                            /* 134.5 */
        !          59735:        768,                            /* 150 */
        !          59736:        576,                            /* 200 */
        !          59737:        384,                            /* 300 */
        !          59738:        192,                            /* 600 */
        !          59739:        96,                             /* 1200 */
        !          59740:        64,                             /* 1800 */
        !          59741:        58,                             /* 2000 */
        !          59742:        48,                             /* 2400 */
        !          59743:        32,                             /* 3600 */
        !          59744:        24,                             /* 4800 */
        !          59745:        16,                             /* 7200 */
        !          59746:        12,                             /* 9600 */
        !          59747:        6,                              /* 19200 */
        !          59748:        6,                              /* EXTA */
        !          59749:        6                               /* EXTB */
        !          59750: };
        !          59751: 
        !          59752: /*
        !          59753:  * Load Routine.
        !          59754:  */
        !          59755: static gcload()
        !          59756: {
        !          59757:        register TTY * tp;
        !          59758:        register int port;
        !          59759:        int i, b, s;
        !          59760: 
        !          59761:        if ((hstty = (TTY *)kalloc(GCNUM*sizeof(TTY))) == 0) {
        !          59762:                printf("gcload: can't allocate tty's\n");
        !          59763:                return;
        !          59764:        }
        !          59765:        kclear(hstty, GCNUM*sizeof(TTY));
        !          59766: 
        !          59767:        s = sphi();
        !          59768:        for (i = 0; i < GCNUM; i++) {
        !          59769:                port = GC_PORTS[i].addr;
        !          59770:                tp = hstty + i;
        !          59771: 
        !          59772:                outb( port+MCR, 0 );
        !          59773:                outb( port+IER, 0 );
        !          59774: 
        !          59775:                if ( inb( port+IER ) )
        !          59776:                        break;
        !          59777: 
        !          59778:                tp->t_cs_sel  = cs_sel();
        !          59779:                tp->t_start   = gcstart;
        !          59780:                tp->t_param   = gcparam;
        !          59781:                tp->t_sgttyb.sg_ospeed = tp->t_sgttyb.sg_ispeed = 
        !          59782:                tp->t_dispeed = tp->t_dospeed = GC_PORTS[i].speed;
        !          59783:                tp->t_ddp     = port;
        !          59784: 
        !          59785:                b = timeconst[ tp->t_sgttyb.sg_ospeed ];
        !          59786:                outb( port+LCR, LC_DLAB );
        !          59787:                outb( port+DLL, b );
        !          59788:                outb( port+DLH, b >> 8);
        !          59789:                outb( port+LCR, LC_CS8);
        !          59790: 
        !          59791:                hslimtty = tp;
        !          59792:        }
        !          59793:        setivec(GCINT, gcintr);
        !          59794:        spl(s);
        !          59795: }
        !          59796: 
        !          59797: static gcunload()
        !          59798: {
        !          59799:        clrivec(GCINT);
        !          59800:        kfree(hstty);
        !          59801: }
        !          59802: 
        !          59803: /*
        !          59804:  * Open Routine.
        !          59805:  */
        !          59806: gcopen( dev, mode )
        !          59807: dev_t dev;
        !          59808: {
        !          59809:        register TTY * tp = &hstty[ dev & 15 ];
        !          59810:        register int b;
        !          59811:        int s;
        !          59812: 
        !          59813:        /*
        !          59814:         * Verify hardware exists.
        !          59815:         */
        !          59816:        if ( (PORT == 0) || (inb(PORT+IER) & ~IE_TxI) ) {
        !          59817:                u.u_error = ENXIO;
        !          59818:                return;
        !          59819:        }
        !          59820: 
        !          59821:        /*
        !          59822:         * Initialize if not already open.
        !          59823:         */
        !          59824:        if ( ++tp->t_open == 1 ) {
        !          59825:                ttopen( tp );
        !          59826: 
        !          59827:                if ( dev & 0x80 ) {
        !          59828:                        s = sphi();
        !          59829:                        b = inb(PORT+MSR);
        !          59830:                        tp->t_flags |= T_MODC + T_STOP;
        !          59831:                        if ( b & MS_CTS )
        !          59832:                                tp->t_flags &= ~T_STOP;
        !          59833:                        if ( b & MS_DSR )
        !          59834:                                tp->t_flags |=  T_CARR;
        !          59835:                        spl( s );
        !          59836:                } else  {
        !          59837:                        tp->t_flags &= ~T_MODC;
        !          59838:                        tp->t_flags |=  T_CARR;
        !          59839:                }
        !          59840:                gccycle( tp );
        !          59841:        }
        !          59842:        ttsetgrp( tp, dev );
        !          59843: }
        !          59844: 
        !          59845: /*
        !          59846:  * Close Routine.
        !          59847:  */
        !          59848: gcclose( dev )
        !          59849: dev_t dev;
        !          59850: {
        !          59851:        register TTY * tp = &hstty[ dev & 15 ];
        !          59852: 
        !          59853:        /*
        !          59854:         * Reset if last close.
        !          59855:         */
        !          59856:        if ( tp->t_open == 1 ) {
        !          59857:                int state;
        !          59858: 
        !          59859:                ttclose( tp );
        !          59860:                /*
        !          59861:                 * ttclose() only emptied the output queue tp->t_oq;
        !          59862:                 * now wait 0.1 sec for the silo tp->rawout to empty
        !          59863:                 * and allow a delay for the UART on-chip xmit buffer to empty
        !          59864:                 *
        !          59865:                 * state 2: waiting for silo to empty
        !          59866:                 * state 1: stalling so UART can empty xmit buffer
        !          59867:                 * state 0: done!
        !          59868:                 */
        !          59869:                state = 2;
        !          59870:                while (state) {
        !          59871:                        timeout(&hstim, 10, wakeup, (int)&hstim);
        !          59872:                        sleep((char *)&hstim, CVTTOUT, IVTTOUT, SVTTOUT);
        !          59873:                        if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          59874:                                state--;
        !          59875:                }
        !          59876:        }
        !          59877: 
        !          59878:        --tp->t_open;
        !          59879: }
        !          59880: 
        !          59881: /*
        !          59882:  * Read Routine.
        !          59883:  */
        !          59884: gcread( dev, iop )
        !          59885: dev_t dev;
        !          59886: register IO * iop;
        !          59887: {
        !          59888:        ttread( &hstty[ dev & 15 ], iop, 0 );
        !          59889: }
        !          59890: 
        !          59891: /*
        !          59892:  * Write Routine.
        !          59893:  */
        !          59894: gcwrite( dev, iop )
        !          59895: dev_t dev;
        !          59896: register IO * iop;
        !          59897: {
        !          59898:        ttwrite( &hstty[ dev & 15 ], iop, 0 );
        !          59899: }
        !          59900: 
        !          59901: /*
        !          59902:  * Ioctl Routine.
        !          59903:  */
        !          59904: gcioctl( dev, com, vec )
        !          59905: dev_t dev;
        !          59906: int com;
        !          59907: struct sgttyb * vec;
        !          59908: {
        !          59909:        ttioctl( &hstty[ dev & 15 ], com, vec );
        !          59910: }
        !          59911: 
        !          59912: /*
        !          59913:  * Polling Routine.
        !          59914:  */
        !          59915: gcpoll( dev, ev, msec )
        !          59916: dev_t dev;
        !          59917: int ev;
        !          59918: int msec;
        !          59919: {
        !          59920:        return ttpoll( &hstty[ dev & 15 ], ev, msec );
        !          59921: }
        !          59922: 
        !          59923: /*
        !          59924:  * Cyclic routine - invoked every clock tick to perform raw input/output.
        !          59925:  *
        !          59926:  *     Notes:  Invoked 10 times per second.
        !          59927:  */
        !          59928: gccycle( tp )
        !          59929: register TTY * tp;
        !          59930: {
        !          59931:        register int resid;
        !          59932:        register int c;
        !          59933: 
        !          59934:        /*
        !          59935:         * Process rawin buf.
        !          59936:         */
        !          59937:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          59938: 
        !          59939:                ttin( tp, tp->t_rawin.si_buf[ tp->t_rawin.si_ox ] );
        !          59940: 
        !          59941:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          59942:                        tp->t_rawin.si_ox = 0;
        !          59943:                else
        !          59944:                        tp->t_rawin.si_ox++;
        !          59945:        }
        !          59946: 
        !          59947:        /*
        !          59948:         * Calculate free output slot count.
        !          59949:         */
        !          59950:        resid  = sizeof(tp->t_rawout.si_buf) - 1;
        !          59951:        resid += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          59952:        resid %= sizeof(tp->t_rawout.si_buf);
        !          59953: 
        !          59954:        /*
        !          59955:         * Fill raw output buffer.
        !          59956:         */
        !          59957:        while ( (--resid >= 0) && ((c = ttout(tp)) >= 0) ) {
        !          59958: 
        !          59959:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = c;
        !          59960: 
        !          59961:                if ( tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1 )
        !          59962:                        tp->t_rawout.si_ix = 0;
        !          59963:                else
        !          59964:                        tp->t_rawout.si_ix++;
        !          59965:        }
        !          59966: 
        !          59967:        /*
        !          59968:         * (Re)start output, waking processes waiting to output, etc.
        !          59969:         */
        !          59970:        ttstart( tp );
        !          59971: 
        !          59972:        /*
        !          59973:         * Schedule next cycle.
        !          59974:         */
        !          59975:        if ( tp->t_open != 0 )
        !          59976:                timeout( &tp->t_rawtim, HZ/10, gccycle, tp );
        !          59977: }
        !          59978: 
        !          59979: /*
        !          59980:  * Interrupt driven Polling routine.
        !          59981:  */
        !          59982: gcintr()
        !          59983: {
        !          59984:        register TTY * tp = &hstty[0];
        !          59985:        register int b;
        !          59986: 
        !          59987:        do {
        !          59988:                if ( tp->t_open == 0 )
        !          59989:                        continue;
        !          59990: 
        !          59991:                /*
        !          59992:                 * Check modem status if modem control is enabled.
        !          59993:                 */
        !          59994:                if ( tp->t_flags & T_MODC ) {
        !          59995: 
        !          59996:                        b = inb( PORT+MSR );
        !          59997: 
        !          59998:                        if ( b & (MS_DCTS|MS_DDSR) ) {
        !          59999: 
        !          60000:                                if ( b & MS_DCTS ) {
        !          60001:                                        if ( b & MS_CTS )
        !          60002:                                                tp->t_flags &= ~T_STOP;
        !          60003:                                        else
        !          60004:                                                tp->t_flags |=  T_STOP;
        !          60005:                                }
        !          60006:                                if ( b & MS_DDSR ) {
        !          60007:                                        if ( b & MS_DSR )
        !          60008:                                                tp->t_flags |=  T_CARR;
        !          60009:                                        else {
        !          60010:                                                tp->t_flags &= ~T_CARR;
        !          60011:                                                tthup( tp );
        !          60012:                                        }
        !          60013:                                }
        !          60014:                        }
        !          60015:                }
        !          60016: 
        !          60017:                b = inb( PORT+LSR );
        !          60018: 
        !          60019:                if ( (b & LS_BREAK) && (tp->t_flags & T_CARR) )
        !          60020:                        ttsignal( tp, SIGINT );
        !          60021: 
        !          60022:                /*
        !          60023:                 * Receive ready.
        !          60024:                 */
        !          60025:                if ( b & LS_RxRDY ) {
        !          60026: 
        !          60027:                        tp->t_rawin.si_buf[tp->t_rawin.si_ix] = inb(PORT+DREG);
        !          60028: 
        !          60029:                        if ( tp->t_flags & T_CARR ) {
        !          60030: 
        !          60031:                                if ( ++(tp->t_rawin.si_ix) >=
        !          60032:                                                sizeof(tp->t_rawin.si_buf) )
        !          60033:                                        tp->t_rawin.si_ix = 0;
        !          60034:                        }
        !          60035:                }
        !          60036: 
        !          60037:                /*
        !          60038:                 * Transmit ready and raw output data exists.
        !          60039:                 */
        !          60040:                if ( (b & LS_TxRDY) && ((tp->t_flags & T_STOP) == 0)
        !          60041:                  && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          60042: 
        !          60043:                        outb(   PORT+DREG,
        !          60044:                                tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          60045: 
        !          60046:                        if ( ++(tp->t_rawout.si_ox) >=
        !          60047:                                        sizeof(tp->t_rawout.si_buf) )
        !          60048:                                tp->t_rawout.si_ox = 0;
        !          60049:                }
        !          60050: 
        !          60051:        } while ( ++tp <= hslimtty );
        !          60052: }
        !          60053: 
        !          60054: /*
        !          60055:  * Set hardware parameters.
        !          60056:  */
        !          60057: gcparam( tp )
        !          60058: register TTY * tp;
        !          60059: {
        !          60060:        register int b;
        !          60061:        int s;
        !          60062: 
        !          60063:        s = sphi();
        !          60064:        /*
        !          60065:         * Assert required modem control lines (DTR, RTS).
        !          60066:         */
        !          60067:        b = 0;
        !          60068:        if ( tp->t_sgttyb.sg_ospeed != B0 )
        !          60069:                b |=  MC_DTR | MC_RTS;
        !          60070:        outb( PORT+MCR, b );
        !          60071: 
        !          60072:        /*
        !          60073:         * Program baud rate.
        !          60074:         */
        !          60075:        if (b = timeconst[ tp->t_sgttyb.sg_ospeed ]) {
        !          60076:                outb( PORT+LCR, LC_DLAB );
        !          60077:                outb( PORT+DLL, b );
        !          60078:                outb( PORT+DLH, b >> 8 );
        !          60079:        }
        !          60080: 
        !          60081:        /*
        !          60082:         * Program character size, parity.
        !          60083:         */
        !          60084:        switch ( tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW) ) {
        !          60085:        case ODDP:              b = LC_CS7|LC_PARENB;            break;
        !          60086:        case EVENP:             b = LC_CS7|LC_PARENB|LC_PAREVEN; break;
        !          60087:        default:                b = LC_CS8;                      break;
        !          60088:        }
        !          60089:        outb( PORT+LCR, b );
        !          60090: 
        !          60091:        /*
        !          60092:         * Enable Transmit Buffer Empty Interrupts.
        !          60093:         */
        !          60094:        outb( PORT+IER, IE_TxI );
        !          60095: 
        !          60096:        spl(s);
        !          60097: }
        !          60098: 
        !          60099: /*
        !          60100:  * Start Routine.
        !          60101:  */
        !          60102: gcstart( tp )
        !          60103: register TTY * tp;
        !          60104: {
        !          60105:        register int s;
        !          60106: 
        !          60107:        /*
        !          60108:         * Transmit buffer is empty, and raw output buffer is not.
        !          60109:         */
        !          60110:        s = sphi();
        !          60111:        if ( (inb( PORT+LSR ) & LS_TxRDY)
        !          60112:          && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          60113: 
        !          60114:                /*
        !          60115:                 * Send next char from raw output buffer.
        !          60116:                 */
        !          60117:                outb( PORT+DREG, tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          60118: 
        !          60119:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          60120:                        tp->t_rawout.si_ox = 0;
        !          60121:        }
        !          60122:        spl( s );
        !          60123: }
        !          60124: @
        !          60125: 0707070064030106761004440000030000030000011777770507310672000005400000002745/newbits/kernel/USRSRC/i8086/drv/RCS/gr.c,vhead     1.3;
        !          60126: branch   ;
        !          60127: access   ;
        !          60128: symbols  ;
        !          60129: locks    bin:1.3; strict;
        !          60130: comment  @ * @;
        !          60131: 
        !          60132: 
        !          60133: 1.3
        !          60134: date     91.06.20.14.49.36;  author bin;  state Exp;
        !          60135: branches ;
        !          60136: next     1.2;
        !          60137: 
        !          60138: 1.2
        !          60139: date     91.06.17.12.31.06;  author bin;  state Exp;
        !          60140: branches ;
        !          60141: next     1.1;
        !          60142: 
        !          60143: 1.1
        !          60144: date     91.06.10.10.22.39;  author bin;  state Exp;
        !          60145: branches ;
        !          60146: next     ;
        !          60147: 
        !          60148: 
        !          60149: desc
        !          60150: @initial version prov by hal
        !          60151: @
        !          60152: 
        !          60153: 
        !          60154: 1.3
        !          60155: log
        !          60156: @update provided by hal
        !          60157: @
        !          60158: text
        !          60159: @/* (-lgl
        !          60160:  *     COHERENT Driver Kit Version 1.1.0
        !          60161:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          60162:  *     All rights reserved. May not be copied without permission.
        !          60163:  -lgl) */
        !          60164: /*
        !          60165:  * Graphics Display Driver for PC Color Card
        !          60166:  */
        !          60167: 
        !          60168: #include <sys/coherent.h>
        !          60169: #include <sys/sched.h>
        !          60170: #include <sys/types.h>
        !          60171: #include <sys/uproc.h>
        !          60172: #include <errno.h>
        !          60173: #include <sys/con.h>
        !          60174: 
        !          60175: int grread();
        !          60176: int grwrite();
        !          60177: int nonedev();
        !          60178: int nulldev();
        !          60179: 
        !          60180: /*
        !          60181:  * Driver Configuration.
        !          60182:  */
        !          60183: #define        MAJOR   30
        !          60184: 
        !          60185: CON
        !          60186: grcon = {
        !          60187:        DFCHR,                          /* Flags                          */
        !          60188:        MAJOR,                          /* Major Index                    */
        !          60189:        nulldev,                        /* Open                           */
        !          60190:        nulldev,                        /* Close                          */
        !          60191:        nonedev,                        /* Block                          */
        !          60192:        grread,                         /* Read                           */
        !          60193:        grwrite,                        /* Write                          */
        !          60194:        nonedev,                        /* Ioctl                          */
        !          60195:        nulldev,                        /* Power fail                     */
        !          60196:        nulldev,                        /* Timeout                        */
        !          60197:        nulldev,                        /* Load                           */
        !          60198:        nulldev                         /* Unload                         */
        !          60199: };
        !          60200: @
        !          60201: 
        !          60202: 
        !          60203: 1.2
        !          60204: log
        !          60205: @new version provided y hal for v321
        !          60206: @
        !          60207: text
        !          60208: @d10 1
        !          60209: a10 2
        !          60210: #include <coherent.h>
        !          60211: #include <sys/timeout.h>
        !          60212: @
        !          60213: 
        !          60214: 
        !          60215: 1.1
        !          60216: log
        !          60217: @Initial revision
        !          60218: @
        !          60219: text
        !          60220: @d12 3
        !          60221: a14 3
        !          60222: #include <sched.h>
        !          60223: #include <types.h>
        !          60224: #include <uproc.h>
        !          60225: d16 1
        !          60226: a16 1
        !          60227: #include <con.h>
        !          60228: @
        !          60229: 0707070064030106711004440000030000030000011777770507310672100005600000113750/newbits/kernel/USRSRC/i8086/drv/RCS/gras.s,vhead     1.1;
        !          60230: branch   ;
        !          60231: access   ;
        !          60232: symbols  ;
        !          60233: locks    bin:1.1; strict;
        !          60234: comment  @@;
        !          60235: 
        !          60236: 
        !          60237: 1.1
        !          60238: date     91.06.10.10.22.42;  author bin;  state Exp;
        !          60239: branches ;
        !          60240: next     ;
        !          60241: 
        !          60242: 
        !          60243: desc
        !          60244: @initial version prov by hal
        !          60245: @
        !          60246: 
        !          60247: 
        !          60248: 
        !          60249: 1.1
        !          60250: log
        !          60251: @Initial revision
        !          60252: @
        !          60253: text
        !          60254: @/ (lgl-
        !          60255: /      COHERENT Driver Kit Version 1.1.0
        !          60256: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          60257: /      All rights reserved. May not be copied without permission.
        !          60258: / -lgl)
        !          60259:        .globl  grread_
        !          60260:        .globl  grwrite_
        !          60261:        .globl  mmgo_
        !          60262: 
        !          60263: ////////
        !          60264: /
        !          60265: / State driven code
        !          60266: /
        !          60267: /      Input:  DS:SI - input string
        !          60268: /              ES:DI - current screen location
        !          60269: /              SS:BP - terminal attributes
        !          60270: /              CX    - input count
        !          60271: /              BP    - references terminal information
        !          60272: /              AL    - character
        !          60273: /              BH    - (usually) kept zeroed for efficiency
        !          60274: /              DH    - current row
        !          60275: /              DL    - current column
        !          60276: /
        !          60277: ////////
        !          60278: 
        !          60279: #ifdef HERCULES
        !          60280:        VSEG    = 0xB000        / Video Display Segment
        !          60281:        BANKSZ  = 8192          / Size of Display Banks
        !          60282:        LROW    = 24            / Last legal row
        !          60283:        NCR     = 8             / number of horizontal lines per char
        !          60284:        NCR2    = 4             / number of horizontal lines per char / 2
        !          60285:        NCR4    = 2             / number of horizontal lines per char / 4
        !          60286:        NHB     = 90            / number of horizontal bytes per line
        !          60287: #else
        !          60288: #ifdef TECMAR
        !          60289:        VSEG    = 0xA000        / Video Display Segment
        !          60290:        BANKSZ  = 32768         / Size of Display Banks
        !          60291:        LROW    = 24            / Last legal row
        !          60292:        NCR     = 16            / number of horizontal lines per char
        !          60293:        NCR2    = 8             / number of horizontal lines per char / 2
        !          60294:        NCR4    = 4             / number of horizontal lines per char / 4
        !          60295:        NHB     = 80            / number of horizontal bytes per line
        !          60296: #else
        !          60297:        VSEG    = 0xB800        / Video Display Segment
        !          60298:        BANKSZ  = 8192          / Size of Display Banks
        !          60299:        LROW    = 24            / Last legal row
        !          60300:        NCR     = 8             / number of horizontal lines per char
        !          60301:        NCR2    = 4             / number of horizontal lines per char / 2
        !          60302:        NCR4    = 2             / number of horizontal lines per char / 4
        !          60303:        NHB     = 80            / number of horizontal bytes per line
        !          60304: #endif
        !          60305: #endif
        !          60306: 
        !          60307:        NRB     = NHB*NCR       / number of bytes per character row
        !          60308:        NRB2    = NHB*NCR2      / number of bytes per character row / 2
        !          60309:        NRB4    = NHB*NCR4      / number of bytes per character row / 4
        !          60310: 
        !          60311:        ZERO    = bh            / (almost) always zero
        !          60312:        ROW     = dh            / currently active vertical position
        !          60313:        COL     = dl            / currently active horizontal position
        !          60314:        POS     = di            / currently active display address
        !          60315: 
        !          60316:        CSR     = 0x3D9         / Color Select Register
        !          60317:        MSR     = 0x3D8         / Mode Select Register
        !          60318:        XMSR    = 0x3DA         / Extended Mode Select Register
        !          60319: 
        !          60320: 
        !          60321: ////////
        !          60322: /
        !          60323: / Magic constants from <sys/io.h>
        !          60324: /
        !          60325: ////////
        !          60326: 
        !          60327:        IO_SEG  = 0
        !          60328:        IO_IOC  = 2
        !          60329:        IO_SEEK = 4
        !          60330:        IO_BASE = 8
        !          60331: 
        !          60332:        IOSYS   = 0
        !          60333: 
        !          60334: ////////
        !          60335: /
        !          60336: / Data
        !          60337: /
        !          60338: ////////
        !          60339: 
        !          60340: MM_FUNC                = 0             / current state
        !          60341: MM_PORT                = 2             / adapter base i/o port
        !          60342: MM_BASE                = 4             / adapter base memory address
        !          60343: MM_ROW         = 6             / screen row
        !          60344: MM_COL         = 7             / screen column
        !          60345: MM_POS         = 8             / screen position
        !          60346: MM_ATTR                = 10            / attributes
        !          60347: MM_N1          = 11            / numeric argument 1
        !          60348: MM_N2          = 12            / numeric argument 2
        !          60349: MM_BROW                = 13            / base row
        !          60350: MM_EROW                = 14            / end row
        !          60351: MM_LROW                = 15            / legal row limit
        !          60352: MM_SROW                = 16            / saved cursor row
        !          60353: MM_SCOL                = 17            / saved cursor column
        !          60354: MM_IBROW       = 18            / initial base row
        !          60355: MM_IEROW       = 19            / initial end row
        !          60356: MM_FLIP                = 20
        !          60357: MM_MASK                = 22
        !          60358: MM_ULINE       = 24
        !          60359: MM_CURSE       = 26
        !          60360: MM_VIS         = 28            / set to -1 to make cursor visible
        !          60361: MM_NCOL                = 30
        !          60362: MM_WRAP                = 31
        !          60363: 
        !          60364:        .prvd
        !          60365: mmdata:        .word   mminit, 0x03D4, VSEG
        !          60366:        .byte   0, 0
        !          60367:        .word   0
        !          60368:        .byte   0x7, 0, 0, 0, LROW-1, LROW, 0, 0, 0, LROW-1
        !          60369:        .word   0, -1, 0, 0xff
        !          60370:        .word   0
        !          60371:        .byte   80
        !          60372:        .byte   1
        !          60373: 
        !          60374:        .shri
        !          60375: #ifdef HERCULES
        !          60376: crtdata:.byte   54,  45,  45,   8,  91,   1,  86,  88
        !          60377:        .byte     2,   3,  32,   0,   0,   0,   0,   0
        !          60378: #else
        !          60379: #ifdef TECMAR
        !          60380: crtdata:.byte   56,  40,  43,   8, 127,   6, 100, 112
        !          60381:        .byte     3,   1,  32,   0,   0,   0,   0,   0
        !          60382: #else
        !          60383: crtdata:.byte   56,  40,  43,   8, 127,   6, 100, 112
        !          60384:        .byte     2,   1,  32,   0,   0,   0,   0,   0
        !          60385: #endif
        !          60386: #endif
        !          60387:        .shri
        !          60388: 
        !          60389: ////////
        !          60390: /
        !          60391: / mmgo( iop )          - Entry point for text stream output
        !          60392: / IO *iop;
        !          60393: /
        !          60394: ////////
        !          60395: 
        !          60396: mmgo_:
        !          60397:        push    si
        !          60398:        push    di
        !          60399:        push    bp
        !          60400:        mov     bp, sp
        !          60401:        push    ds
        !          60402:        push    es
        !          60403:        cld
        !          60404:        mov     bx, 8(bp)               / iop
        !          60405:        mov     si, IO_BASE(bx)         / iop->io_base
        !          60406:        mov     cx, IO_IOC(bx)          / iop->io_ioc
        !          60407:        cmp     IO_SEG(bx), $IOSYS
        !          60408:        je      0f
        !          60409:        mov     bx, uds_
        !          60410:        mov     ds, bx
        !          60411: 0:     mov     bp, $mmdata
        !          60412:        movb    ROW, MM_ROW(bp)
        !          60413:        movb    COL, MM_COL(bp)
        !          60414:        mov     es,  MM_BASE(bp)
        !          60415:        mov     POS, MM_POS(bp)
        !          60416:        mov     ax, MM_CURSE(bp)
        !          60417:        and     ax, MM_VIS(bp)
        !          60418: #ifdef TECMAR
        !          60419:        xor     es:[NHB*6](POS), ax
        !          60420:        xor     es:[NHB*6]+BANKSZ(POS), ax
        !          60421:        xor     es:[NHB*7](POS), ax
        !          60422:        xor     es:[NHB*7]+BANKSZ(POS), ax
        !          60423: #else
        !          60424:        xor     es:[NHB*3](POS), ax     / turn cursor off
        !          60425:        xor     es:[NHB*3]+BANKSZ(POS), ax
        !          60426: #endif
        !          60427:        sub     bx, bx
        !          60428:        ijmp    MM_FUNC(bp)
        !          60429: 
        !          60430: exit:  movb    bl, ROW                 / reposition to ROW and COL
        !          60431:        shlb    bl, $1
        !          60432:        mov     POS, cs:rowtab(bx)
        !          60433:        movb    bl, COL
        !          60434:        cmpb    MM_NCOL(bp), $40
        !          60435:        jne     0f
        !          60436:        shlb    bl, $1
        !          60437: 0:     add     POS, bx
        !          60438:        mov     ax, MM_CURSE(bp)
        !          60439:        and     ax, MM_VIS(bp)
        !          60440: #ifdef TECMAR
        !          60441:        xor     es:[NHB*6](POS), ax     / turn cursor on
        !          60442:        xor     es:[NHB*6]+BANKSZ(POS), ax
        !          60443:        xor     es:[NHB*7](POS), ax
        !          60444:        xor     es:[NHB*7]+BANKSZ(POS), ax
        !          60445: #else
        !          60446:        xor     es:[NHB*3](POS), ax     / turn cursor on
        !          60447:        xor     es:[NHB*3]+BANKSZ(POS), ax
        !          60448: #endif
        !          60449:        pop     bx
        !          60450:        pop     es
        !          60451:        pop     ds
        !          60452:        mov     MM_FUNC(bp), bx
        !          60453:        movb    MM_ROW(bp), ROW         / save row,column
        !          60454:        movb    MM_COL(bp), COL
        !          60455:        mov     MM_POS(bp), POS         / save position
        !          60456: 
        !          60457:        mov     dx, $MSR                / enable video display
        !          60458:        movb    al, $0x1A
        !          60459:        outb    dx, al
        !          60460:        mov     mmvcnt_, $480           / 480 seconds before video disabled
        !          60461: 
        !          60462:        mov     bp, sp
        !          60463:        mov     bx, 8(bp)
        !          60464:        mov     ax, cx                  / Return the residual count.
        !          60465:        xchg    cx, IO_IOC(bx)
        !          60466:        sub     cx, IO_IOC(bx)
        !          60467:        add     IO_BASE(bx), cx
        !          60468:        pop     bp
        !          60469:        pop     di
        !          60470:        pop     si
        !          60471:        ret
        !          60472: 
        !          60473: ////////
        !          60474: /
        !          60475: / mminit - initialize screen
        !          60476: /
        !          60477: ////////
        !          60478: 
        !          60479: mminit:        movb    ss:mmesc_, $'c          / schedule keyboard initialization
        !          60480:        mov     dx, $MSR                / disable video display
        !          60481:        movb    al, $0x12
        !          60482:        outb    dx, al
        !          60483: 
        !          60484:        push    cx                      / program registers, last to first
        !          60485:        mov     bx, $15
        !          60486:        mov     dx, MM_PORT(bp)
        !          60487: 0:     movb    al, bl
        !          60488:        outb    dx, al
        !          60489:        inc     dx
        !          60490:        movb    al, cs:crtdata(bx)
        !          60491:        outb    dx, al
        !          60492:        dec     dx
        !          60493:        dec     bx
        !          60494:        jge     0b
        !          60495:        pop     cx
        !          60496: 
        !          60497:        mov     dx, $CSR
        !          60498:        movb    al, $0x0F
        !          60499:        outb    dx, al
        !          60500: 
        !          60501:        mov     dx, $XMSR
        !          60502: #ifdef TECMAR
        !          60503:        movb    al, $31
        !          60504: #else
        !          60505:        movb    al, $0
        !          60506: #endif
        !          60507:        outb    dx, al
        !          60508: 
        !          60509: /      mov     dx, $XMSR
        !          60510: 0:     inb     al, dx          / wait for vertical retrace
        !          60511:        andb    al, $8
        !          60512:        je      0b
        !          60513: 
        !          60514:        mov     dx, $MSR
        !          60515:        movb    al, $0x1A       / video display on
        !          60516:        outb    dx, al
        !          60517: 
        !          60518:        mov     MM_VIS(bp), $-1
        !          60519:        mov     MM_MASK(bp), $0xAAAA
        !          60520:        mov     MM_FLIP(bp), $0
        !          60521:        mov     MM_ULINE(bp), $0
        !          60522:        mov     MM_CURSE(bp), $0x00ff
        !          60523:        movb    MM_WRAP(bp), $1
        !          60524:        movb    MM_NCOL(bp), $80
        !          60525:        subb    COL, COL
        !          60526:        movb    ROW, MM_IBROW(bp)
        !          60527:        movb    MM_BROW(bp), ROW
        !          60528:        movb    bl, MM_IEROW(bp)
        !          60529:        movb    MM_EROW(bp), bl
        !          60530:        sub     bx, bx
        !          60531:        movb    MM_N1(bp), $2
        !          60532:        jmp     mm_ed
        !          60533: 
        !          60534: ////////
        !          60535: /
        !          60536: / mmbell - schedule beep
        !          60537: /
        !          60538: ////////
        !          60539: 
        !          60540: mmbell:        movb    ss:mmbeeps_, $-1
        !          60541:        jmp     eval
        !          60542: 
        !          60543: ////////
        !          60544: /
        !          60545: / mmspec - pass special characters on to keyboard routine(s).
        !          60546: /
        !          60547: ////////
        !          60548: 
        !          60549: mmspec:        movb    ss:mmesc_, al
        !          60550:        jmp     eval
        !          60551: 
        !          60552: ////////
        !          60553: /
        !          60554: / mm_cnl - cursor next line
        !          60555: /
        !          60556: /      Moves the active position to the first column of the next display line.
        !          60557: /      Scrolls the active display if necessary.
        !          60558: /      Returns to mmwrite() to allow flow control on each output line.
        !          60559: /
        !          60560: ////////
        !          60561: 
        !          60562: mm_cnl:        subb    COL, COL
        !          60563:        incb    ROW
        !          60564:        cmpb    ROW, MM_EROW(bp)
        !          60565:        jle     repos
        !          60566:        movb    ROW, MM_EROW(bp)
        !          60567: /      jmp     scrollup
        !          60568: 
        !          60569: ////////
        !          60570: /
        !          60571: / scrollup - scroll display upwards
        !          60572: /
        !          60573: ////////
        !          60574: 
        !          60575: scrollup:
        !          60576:        push    ds
        !          60577:        push    si
        !          60578:        push    cx
        !          60579:        mov     ds, MM_BASE(bp)
        !          60580:        movb    bl, MM_BROW(bp)
        !          60581:        shlb    bl, $1
        !          60582:        mov     di, cs:rowtab(bx)
        !          60583:        mov     si, cs:rowtab+2(bx)
        !          60584:        movb    bl, ROW
        !          60585:        shlb    bl, $1
        !          60586:        mov     cx, cs:rowtab(bx)
        !          60587:        push    cx
        !          60588:        sub     cx, di
        !          60589:        shr     cx, $1
        !          60590:        push    si
        !          60591:        push    di
        !          60592:        push    cx
        !          60593:        rep
        !          60594:        movsw
        !          60595:        pop     cx
        !          60596:        pop     di
        !          60597:        pop     si
        !          60598:        add     si, $BANKSZ
        !          60599:        add     di, $BANKSZ
        !          60600:        rep
        !          60601:        movsw
        !          60602:        mov     ax, MM_FLIP(bp)
        !          60603:        and     ax, MM_MASK(bp)
        !          60604:        pop     di
        !          60605:        push    di
        !          60606:        mov     cx, $NRB4
        !          60607:        rep
        !          60608:        stosw
        !          60609:        pop     di
        !          60610:        add     di, $BANKSZ
        !          60611:        mov     cx, $NRB4
        !          60612:        rep
        !          60613:        stosw
        !          60614:        pop     cx
        !          60615:        pop     si
        !          60616:        pop     ds
        !          60617:        jmp     ewait
        !          60618: 
        !          60619: ////////
        !          60620: /
        !          60621: / repos - reposition cursor
        !          60622: /
        !          60623: ////////
        !          60624: 
        !          60625: repos: movb    bl, ROW                 / reposition to ROW and COL
        !          60626:        shlb    bl, $1
        !          60627:        mov     POS, cs:rowtab(bx)
        !          60628:        movb    bl, COL
        !          60629:        cmpb    MM_NCOL(bp), $40
        !          60630:        jne     0f
        !          60631:        shlb    bl, $1
        !          60632: 0:     add     POS, bx
        !          60633: /      jmp     eval
        !          60634: 
        !          60635: ////////
        !          60636: /
        !          60637: / eval - evaluate input character
        !          60638: /
        !          60639: ////////
        !          60640: 
        !          60641: eval:  jcxz    ewait0
        !          60642:        dec     cx                              / evaluate next char
        !          60643:        lodsb
        !          60644:        movb    bl, al
        !          60645:        shlb    bl, $1
        !          60646:        ijmp    cs:asctab(bx)
        !          60647: 
        !          60648: ewait0:        call    exit
        !          60649:        jcxz    0b
        !          60650:        dec     cx
        !          60651:        lodsb
        !          60652:        movb    bl, al
        !          60653:        shlb    bl, $1
        !          60654:        ijmp    cs:asctab(bx)
        !          60655: 
        !          60656: ////////
        !          60657: /
        !          60658: / mmputc - put character on screen
        !          60659: /
        !          60660: ////////
        !          60661: 
        !          60662: mmputc:        cmpb    MM_NCOL(bp), $40
        !          60663:        jne     putc8
        !          60664: 
        !          60665: 
        !          60666: putc16:        push    ds
        !          60667:        push    si
        !          60668:        subb    ah, ah
        !          60669:        shlb    al, $1
        !          60670:        shl     ax, $1
        !          60671:        shl     ax, $1
        !          60672:        shl     ax, $1
        !          60673:        add     ax, $fontw_
        !          60674:        mov     si, ax
        !          60675:        mov     ax, cs
        !          60676:        mov     ds, ax
        !          60677:        mov     bx, $BANKSZ-2
        !          60678: 
        !          60679:        lodsw                           / row 0
        !          60680:        xor     ax, MM_FLIP(bp)
        !          60681:        and     ax, MM_MASK(bp)
        !          60682:        stosw
        !          60683:        push    di                      / save position for next char
        !          60684: #ifdef TECMAR
        !          60685:        mov     es:(bx,di), ax
        !          60686:        add     di, $78
        !          60687: #endif
        !          60688:        lodsw                           / row 1
        !          60689:        xor     ax, MM_FLIP(bp)
        !          60690:        and     ax, MM_MASK(bp)
        !          60691: #ifdef TECMAR
        !          60692:        stosw
        !          60693: #endif
        !          60694:        mov     es:(bx,di), ax
        !          60695:        add     di, $78
        !          60696: 
        !          60697:        lodsw                           / row 2
        !          60698:        xor     ax, MM_FLIP(bp)
        !          60699:        and     ax, MM_MASK(bp)
        !          60700:        stosw
        !          60701: #ifdef TECMAR
        !          60702:        mov     es:(bx,di), ax
        !          60703:        add     di, $78
        !          60704: #endif
        !          60705: 
        !          60706:        lodsw                           / row 3
        !          60707:        xor     ax, MM_FLIP(bp)
        !          60708:        and     ax, MM_MASK(bp)
        !          60709: #ifdef TECMAR
        !          60710:        stosw
        !          60711: #endif
        !          60712:        mov     es:(bx,di), ax
        !          60713:        add     di, $78
        !          60714: 
        !          60715:        lodsw                           / row 4
        !          60716:        xor     ax, MM_FLIP(bp)
        !          60717:        and     ax, MM_MASK(bp)
        !          60718:        stosw
        !          60719: #ifdef TECMAR
        !          60720:        mov     es:(bx,di), ax
        !          60721:        add     di, $78
        !          60722: #endif
        !          60723: 
        !          60724:        lodsw                           / row 5
        !          60725:        xor     ax, MM_FLIP(bp)
        !          60726:        and     ax, MM_MASK(bp)
        !          60727: #ifdef TECMAR
        !          60728:        stosw
        !          60729: #endif
        !          60730:        mov     es:(bx,di), ax
        !          60731:        add     di, $78
        !          60732: 
        !          60733:        lodsw                           / row 6
        !          60734:        xor     ax, MM_FLIP(bp)
        !          60735:        and     ax, MM_MASK(bp)
        !          60736:        stosw
        !          60737: #ifdef TECMAR
        !          60738:        mov     es:(bx,di), ax
        !          60739:        add     di, $78
        !          60740: #endif
        !          60741:        lodsw                           / row 7
        !          60742:        or      ax, MM_ULINE(bp)
        !          60743:        xor     ax, MM_FLIP(bp)
        !          60744:        and     ax, MM_MASK(bp)
        !          60745: #ifdef TECMAR
        !          60746:        stosw
        !          60747: #endif
        !          60748:        mov     es:(bx,di), ax
        !          60749: 
        !          60750: 
        !          60751:        pop     di                      / restore position for next char
        !          60752:        pop     si
        !          60753:        pop     ds
        !          60754: 
        !          60755:        sub     bx, bx
        !          60756:        incb    COL
        !          60757:        cmpb    COL, MM_NCOL(bp)
        !          60758:        jge     0f
        !          60759:        jcxz    ewait1
        !          60760:        dec     cx
        !          60761:        lodsb
        !          60762:        movb    bl, al
        !          60763:        shlb    bl, $1
        !          60764:        ijmp    cs:asctab(bx)
        !          60765: 
        !          60766: 0:     subb    COL, COL
        !          60767:        incb    ROW
        !          60768:        cmpb    ROW, MM_EROW(bp)
        !          60769:        jg      0f
        !          60770:        jmp     repos
        !          60771: 
        !          60772: 0:     movb    ROW, MM_EROW(bp)
        !          60773:        jmp     scrollup
        !          60774: 
        !          60775: ewait1:        jmp     ewait
        !          60776: 
        !          60777: putc8: push    ds
        !          60778:        push    si
        !          60779:        subb    ah, ah
        !          60780:        shlb    al, $1
        !          60781:        shl     ax, $1
        !          60782:        shl     ax, $1
        !          60783:        add     ax, $0xFA6E
        !          60784:        mov     si, ax
        !          60785:        mov     ax, $0xF000
        !          60786:        mov     ds, ax
        !          60787:        mov     bx, $BANKSZ-1
        !          60788: 
        !          60789:        lodsw
        !          60790:        xor     ax, MM_FLIP(bp)
        !          60791:        stosb                           / row 0
        !          60792:        push    di                      / save position for next char
        !          60793: #ifdef TECMAR
        !          60794:        movb    es:(bx,di), al
        !          60795:        movb    es:79(di), ah           / row 1
        !          60796:        movb    es:80(bx,di), ah
        !          60797:        add     di, $79+80
        !          60798: #else
        !          60799:        movb    es:(bx,di), ah          / row 1
        !          60800:        add     di, $79
        !          60801: #endif
        !          60802: 
        !          60803:        lodsw
        !          60804:        xor     ax, MM_FLIP(bp)
        !          60805:        stosb                           / row 2
        !          60806: #ifdef TECMAR
        !          60807:        movb    es:(bx,di), al
        !          60808:        movb    es:79(di), ah
        !          60809:        movb    es:80(bx,di), ah        / row 3
        !          60810:        add     di, $79+80
        !          60811: #else
        !          60812:        movb    es:(bx,di), ah          / row 3
        !          60813:        add     di, $79
        !          60814: #endif
        !          60815: 
        !          60816:        lodsw
        !          60817:        xor     ax, MM_FLIP(bp)
        !          60818:        stosb                           / row 4
        !          60819: #ifdef TECMAR
        !          60820:        movb    es:(bx,di), al
        !          60821:        movb    es:79(di), ah           / row 5
        !          60822:        movb    es:80(bx,di), ah
        !          60823:        add     di, $79+80
        !          60824: #else
        !          60825:        movb    es:(bx,di), ah          / row 5
        !          60826:        add     di, $79
        !          60827: #endif
        !          60828: 
        !          60829:        lodsw
        !          60830:        orb     ah, MM_ULINE(bp)
        !          60831:        xor     ax, MM_FLIP(bp)
        !          60832:        stosb                           / row 6
        !          60833: #ifdef TECMAR
        !          60834:        movb    es:(bx,di), al
        !          60835:        movb    es:79(di), ah
        !          60836:        movb    es:80(bx,di), ah
        !          60837: #else
        !          60838:        movb    es:(bx,di), ah          / row 7
        !          60839: #endif
        !          60840: 
        !          60841:        pop     di                      / restore position for next char
        !          60842:        pop     si
        !          60843:        pop     ds
        !          60844: 
        !          60845:        sub     bx, bx
        !          60846:        incb    COL
        !          60847:        cmpb    COL, MM_NCOL(bp)
        !          60848:        jge     0f
        !          60849:        jcxz    ewait
        !          60850:        dec     cx
        !          60851:        lodsb
        !          60852:        movb    bl, al
        !          60853:        shlb    bl, $1
        !          60854:        ijmp    cs:asctab(bx)
        !          60855: 
        !          60856: 0:     subb    COL, COL
        !          60857:        incb    ROW
        !          60858:        cmpb    ROW, MM_EROW(bp)
        !          60859:        jg      0f
        !          60860:        jmp     repos
        !          60861: 
        !          60862: 0:     movb    ROW, MM_EROW(bp)
        !          60863:        jmp     scrollup
        !          60864: 
        !          60865: ////////
        !          60866: /
        !          60867: / Ewait - wait for next input char to evaluate
        !          60868: /
        !          60869: ////////
        !          60870: 
        !          60871: ewait: call    exit
        !          60872:        jcxz    ewait
        !          60873:        dec     cx
        !          60874:        lodsb
        !          60875:        movb    bl, al
        !          60876:        shlb    bl, $1
        !          60877:        ijmp    cs:asctab(bx)
        !          60878: 
        !          60879: ////////
        !          60880: /
        !          60881: / mm_cr - carriage return
        !          60882: /
        !          60883: /      Moves the active position to first position of current display line.
        !          60884: /
        !          60885: ////////
        !          60886: 
        !          60887: mm_cr: subb    COL, COL
        !          60888:        movb    bl, ROW
        !          60889:        shlb    bl, $1
        !          60890:        mov     POS, cs:rowtab(bx)
        !          60891:        jcxz    ewait
        !          60892:        dec     cx
        !          60893:        lodsb
        !          60894:        movb    bl, al
        !          60895:        shlb    bl, $1
        !          60896:        ijmp    cs:asctab(bx)
        !          60897: 
        !          60898: ////////
        !          60899: /
        !          60900: / mm_cub - cursor backwards
        !          60901: /
        !          60902: ////////
        !          60903: 
        !          60904: mm_cub:        decb    COL
        !          60905:        jge     0f
        !          60906:        movb    COL, MM_NCOL(bp)
        !          60907:        decb    COL
        !          60908:        decb    ROW
        !          60909:        cmpb    ROW, MM_BROW(bp)
        !          60910:        jge     0f
        !          60911:        subb    COL, COL
        !          60912:        movb    ROW, MM_BROW(bp)
        !          60913: 0:     jmp     repos
        !          60914: 
        !          60915: ////////
        !          60916: /
        !          60917: / Esc state - entered when last char was ESC - transient state.
        !          60918: /
        !          60919: ////////
        !          60920: 
        !          60921: 0:     call    exit
        !          60922: mm_esc:        jcxz    0b
        !          60923:        dec     cx
        !          60924:        lodsb
        !          60925:        movb    MM_N1(bp), ZERO
        !          60926:        movb    MM_N2(bp), ZERO
        !          60927:        movb    bl, al
        !          60928:        shlb    bl, $1
        !          60929:        ijmp    cs:esctab(bx)
        !          60930: 
        !          60931: ////////
        !          60932: /
        !          60933: / Csi_n1 state - entered when last two chars were ESC [
        !          60934: /
        !          60935: /      Action: Evaluates numeric chars as numeric parameter 1.
        !          60936: /
        !          60937: ////////
        !          60938: 
        !          60939: 0:     call    exit
        !          60940: csi_n1:        jcxz    0b
        !          60941:        dec     cx
        !          60942:        lodsb
        !          60943:        cmpb    al, $';
        !          60944:        je      csi_n2
        !          60945:        movb    bl, al
        !          60946:        subb    bl, $'0
        !          60947:        cmpb    bl, $9
        !          60948:        ja      csival
        !          60949:        shlb    MM_N1(bp), $1   / n1 * 2
        !          60950:        movb    al, MM_N1(bp)   / n1 * 2
        !          60951:        shlb    al, $1          / n1 * 4
        !          60952:        shlb    al, $1          / n1 * 8
        !          60953:        addb    al, MM_N1(bp)   / n1 * 10
        !          60954:        addb    al, bl          / n1 * 10 + digit
        !          60955:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          60956:        jmp     csi_n1
        !          60957: 
        !          60958: ////////
        !          60959: /
        !          60960: / Csi_n2 state - entered after input sequence ESC [ n ;
        !          60961: /
        !          60962: ////////
        !          60963: 
        !          60964: 0:     call    exit
        !          60965: csi_n2:        jcxz    0b
        !          60966:        dec     cx
        !          60967:        lodsb
        !          60968:        movb    bl, al
        !          60969:        subb    bl, $'0
        !          60970:        cmpb    bl, $9
        !          60971:        ja      csival
        !          60972:        shlb    MM_N2(bp), $1   / n2 * 2
        !          60973:        movb    al, MM_N2(bp)   / n2 * 2
        !          60974:        shlb    al, $1          / n2 * 4
        !          60975:        shlb    al, $1          / n2 * 8
        !          60976:        addb    al, MM_N2(bp)   / n2 * 10
        !          60977:        addb    al, bl          / n2 * 10 + digit
        !          60978:        movb    MM_N2(bp), al   / n2 = (n2 * 10) + digit
        !          60979:        jmp     csi_n2
        !          60980: 
        !          60981: csival:        movb    bl, al
        !          60982:        shlb    bl, $1
        !          60983:        ijmp    cs:csitab(bx)
        !          60984: 
        !          60985: ////////
        !          60986: /
        !          60987: / Csi_gt state - entered after input sequence ESC [ >
        !          60988: /      
        !          60989: ////////
        !          60990: 
        !          60991: 0:     call    exit
        !          60992: csi_gt:        jcxz    0b
        !          60993:        dec     cx
        !          60994:        lodsb
        !          60995:        movb    bl, al
        !          60996:        subb    bl, $'0
        !          60997:        cmpb    bl, $9
        !          60998:        ja      0f
        !          60999:        shlb    MM_N1(bp), $1   / n1 * 2
        !          61000:        movb    al, MM_N1(bp)   / n1 * 2
        !          61001:        shlb    al, $1          / n1 * 4
        !          61002:        shlb    al, $1          / n1 * 8
        !          61003:        addb    al, MM_N1(bp)   / n1 * 10
        !          61004:        addb    al, bl          / n1 * 10 + digit
        !          61005:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          61006:        jmp     csi_gt
        !          61007: 
        !          61008: 0:     cmpb    al, $'h
        !          61009:        je      mm_cgh
        !          61010:        cmpb    al, $'l
        !          61011:        je      mm_cgl
        !          61012:        jmp     eval
        !          61013: 
        !          61014: ////////
        !          61015: /
        !          61016: / Csi_q state - entered after input sequence ESC [ ?
        !          61017: /      
        !          61018: ////////
        !          61019: 
        !          61020: 0:     call    exit
        !          61021: csi_q: jcxz    0b
        !          61022:        dec     cx
        !          61023:        lodsb
        !          61024:        movb    bl, al
        !          61025:        subb    bl, $'0
        !          61026:        cmpb    bl, $9
        !          61027:        ja      0f
        !          61028:        shlb    MM_N1(bp), $1   / n1 * 2
        !          61029:        movb    al, MM_N1(bp)   / n1 * 2
        !          61030:        shlb    al, $1          / n1 * 4
        !          61031:        shlb    al, $1          / n1 * 8
        !          61032:        addb    al, MM_N1(bp)   / n1 * 10
        !          61033:        addb    al, bl          / n1 * 10 + digit
        !          61034:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          61035:        jmp     csi_q
        !          61036: 
        !          61037: 0:     cmpb    al, $'h
        !          61038:        je      mm_cqh
        !          61039:        cmpb    al, $'l
        !          61040:        je      mm_cql
        !          61041:        jmp     eval
        !          61042: 
        !          61043: ////////
        !          61044: /
        !          61045: / mm_cbt - cursor backward tabulation
        !          61046: /
        !          61047: /      Moves the active position horizontally in the backward direction
        !          61048: /      to the preceding in a series of predetermined positions.
        !          61049: /
        !          61050: ////////
        !          61051: 
        !          61052: mm_cbt:        orb     COL, $7                 / calculate next tab stop
        !          61053:        incb    COL
        !          61054:        subb    COL, $16                / step back two tab positions
        !          61055:        jg      0f
        !          61056:        subb    COL, COL                / can't step past column 0
        !          61057: 0:     jmp     repos                   / reposition cursor
        !          61058: 
        !          61059: ////////
        !          61060: /
        !          61061: / mm_cgh - process 'ESC [ > N1 h' escape sequence
        !          61062: /
        !          61063: /      Recognized sequences:   ESC [ > 13 h    -- Set CRT saver enabled.
        !          61064: /
        !          61065: ////////
        !          61066: 
        !          61067: mm_cgh:        cmpb    MM_N1(bp), $13
        !          61068:        jne     0f
        !          61069:        mov     ss:mmcrtsav_, $1
        !          61070: 0:     jmp     eval
        !          61071: 
        !          61072: ////////
        !          61073: /
        !          61074: / mm_cgl - process 'ESC [ > N1 l' escape sequence
        !          61075: /
        !          61076: /      Recognized sequences:   ESC [ > 13 l    -- Reset CRT saver.
        !          61077: /
        !          61078: ////////
        !          61079: 
        !          61080: mm_cgl:        cmpb    MM_N1(bp), $13
        !          61081:        jne     0f
        !          61082:        mov     ss:mmcrtsav_, $0
        !          61083: 0:     jmp     eval
        !          61084: 
        !          61085: ////////
        !          61086: /
        !          61087: / mm_cha - cursor horizontal absolute
        !          61088: /
        !          61089: /      Advances the active position forward or backward along the active line
        !          61090: /      to the character position specified by the parameter.
        !          61091: /      A parameter value of zero or one moves the active position to the
        !          61092: /      first character position of the active line.
        !          61093: /      A parameter value of N moves the active position to character position
        !          61094: /      N of the active line.
        !          61095: /
        !          61096: ////////
        !          61097: 
        !          61098: mm_cha:        movb    COL, MM_N1(bp)
        !          61099:        decb    COL
        !          61100:        jge     0f
        !          61101:        subb    COL, COL
        !          61102: 0:     cmpb    COL, MM_NCOL(bp)
        !          61103:        jb      0f
        !          61104:        movb    COL, MM_NCOL(bp)
        !          61105:        decb    COL
        !          61106: 0:     jmp     repos                   / reposition cursor
        !          61107: 
        !          61108: 
        !          61109: ////////
        !          61110: /
        !          61111: / mm_cht - cursor horizontal tabulation
        !          61112: /
        !          61113: /      Advances the active position horizontally to the next or following
        !          61114: /      in a series of predetermined positions.
        !          61115: /
        !          61116: ////////
        !          61117: 
        !          61118: mm_cht:        mov     bx, $BANKSZ
        !          61119:        push    cx
        !          61120:        push    si
        !          61121:        sub     cx, cx
        !          61122:        movb    cl, COL
        !          61123:        orb     cl, $7
        !          61124:        incb    cl
        !          61125:        subb    cl, COL
        !          61126:        addb    COL, cl
        !          61127: 
        !          61128:        mov     si, MM_MASK(bp)
        !          61129:        cmpb    MM_NCOL(bp), $80
        !          61130:        jne     0f
        !          61131:        mov     si, $-1
        !          61132:        inc     cx
        !          61133:        shr     cx, $1
        !          61134: 
        !          61135: 0:     mov     ax, MM_FLIP(bp)
        !          61136:        and     ax, si
        !          61137: #ifdef TECMAR
        !          61138:        stosw                           / row 0
        !          61139:        mov     es:[NHB*0]-2(di,bx), ax
        !          61140:        mov     es:[NHB*1]-2(di), ax    / row 1
        !          61141:        mov     es:[NHB*1]-2(di,bx), ax
        !          61142:        mov     es:[NHB*2]-2(di), ax    / row 2
        !          61143:        mov     es:[NHB*2]-2(di,bx), ax
        !          61144:        mov     es:[NHB*3]-2(di), ax    / row 3
        !          61145:        mov     es:[NHB*3]-2(di,bx), ax
        !          61146:        mov     es:[NHB*4]-2(di), ax    / row 4
        !          61147:        mov     es:[NHB*4]-2(di,bx), ax
        !          61148:        mov     es:[NHB*5]-2(di), ax    / row 5
        !          61149:        mov     es:[NHB*5]-2(di,bx), ax
        !          61150:        mov     es:[NHB*6]-2(di), ax    / row 6
        !          61151:        mov     es:[NHB*6]-2(di,bx), ax
        !          61152:        or      ax, MM_ULINE(bp)
        !          61153:        and     ax, si
        !          61154:        mov     es:[NHB*7]-2(di), ax    / row 7
        !          61155:        mov     es:[NHB*7]-2(di,bx), ax
        !          61156: #else
        !          61157:        stosw                           / row 0
        !          61158:        mov     es:[NHB*0]-2(di,bx), ax / row 1
        !          61159:        mov     es:[NHB*1]-2(di), ax    / row 2
        !          61160:        mov     es:[NHB*1]-2(di,bx), ax / row 3
        !          61161:        mov     es:[NHB*2]-2(di), ax    / row 4
        !          61162:        mov     es:[NHB*2]-2(di,bx), ax / row 5
        !          61163:        mov     es:[NHB*3]-2(di), ax    / row 6
        !          61164:        or      ax, MM_ULINE(bp)
        !          61165:        and     ax, si
        !          61166:        mov     es:[NHB*3]-2(di,bx), ax / row 7
        !          61167: #endif
        !          61168:        loop    0b
        !          61169:        sub     bx, bx
        !          61170:        pop     si
        !          61171:        pop     cx
        !          61172:        cmpb    COL, MM_NCOL(bp)
        !          61173:        jl      0f
        !          61174:        subb    COL, MM_NCOL(bp)
        !          61175:        incb    ROW
        !          61176:        cmpb    ROW, MM_EROW(bp)
        !          61177:        jle     0f
        !          61178:        movb    ROW, MM_EROW(bp)
        !          61179:        jmp     scrollup
        !          61180: 0:     jmp     repos
        !          61181: 
        !          61182: ////////
        !          61183: /
        !          61184: / mm_cpl - cursor preceding line
        !          61185: /
        !          61186: /      Moves the active position to the first position of the preceding
        !          61187: /      display line.
        !          61188: /
        !          61189: ////////
        !          61190: 
        !          61191: mm_cpl:        subb    COL, COL
        !          61192:        decb    ROW
        !          61193:        cmpb    ROW, MM_BROW(bp)
        !          61194:        jnb     0f
        !          61195:        movb    ROW, MM_BROW(bp)
        !          61196:        jmp     scrolldown
        !          61197: 0:     jmp     repos                   / reposition cursor
        !          61198: 
        !          61199: ////////
        !          61200: /
        !          61201: / mm_cqh - process 'ESC [ ? N1 h' escape sequence
        !          61202: /
        !          61203: /      Recognized sequences:   ESC [ ? 7 h     -- Set wraparound.
        !          61204: /
        !          61205: ////////
        !          61206: 
        !          61207: mm_cqh:
        !          61208:        cmpb    MM_N1(bp), $7           / Wraparound.
        !          61209:        jne     0f
        !          61210:        movb    MM_WRAP(bp), $1
        !          61211: 0:     jmp     eval
        !          61212: 
        !          61213: ////////
        !          61214: /
        !          61215: / mm_cql - process 'ESC [ ? N1 l' escape sequence
        !          61216: /
        !          61217: /      Recognized sequences:   ESC [ ? 7 l     -- Reset wraparound.
        !          61218: /
        !          61219: ////////
        !          61220: 
        !          61221: mm_cql:
        !          61222:        cmpb    MM_N1(bp), $7           / No wraparound.
        !          61223:        jne     0f
        !          61224:        movb    MM_WRAP(bp), $0
        !          61225: 0:     jmp     eval
        !          61226: 
        !          61227: ////////
        !          61228: /
        !          61229: / mm_cud - cursor down
        !          61230: /
        !          61231: /      Moves the active position downward without altering the
        !          61232: /      horizontal position.
        !          61233: /
        !          61234: ////////
        !          61235: 
        !          61236: mm_cud:        incb    ROW
        !          61237:        cmpb    ROW, MM_EROW(bp)
        !          61238:        jna     0f
        !          61239:        movb    ROW, MM_EROW(bp)
        !          61240: 0:     jmp     repos                   / reposition cursor
        !          61241: 
        !          61242: ////////
        !          61243: /
        !          61244: / mm_cuf - cursor forward
        !          61245: /
        !          61246: /      Moves the active position in the forward direction.
        !          61247: /
        !          61248: ////////
        !          61249: 
        !          61250: mm_cuf:        incb    COL
        !          61251:        cmpb    COL, MM_NCOL(bp)
        !          61252:        jb      0f
        !          61253:        subb    COL, MM_NCOL(bp)
        !          61254:        incb    ROW
        !          61255:        cmpb    ROW, MM_EROW(bp)
        !          61256:        jna     0f
        !          61257:        movb    ROW, MM_EROW(bp)
        !          61258:        movb    COL, MM_NCOL(bp)
        !          61259:        decb    COL
        !          61260: 0:     jmp     repos
        !          61261: 
        !          61262: ////////
        !          61263: /
        !          61264: / mm_cup - cursor position
        !          61265: /
        !          61266: /      Moves the active position to the position specified by two parameters.
        !          61267: /      The first parameter (mm_n1) specifies the vertical position (MM_ROW(bp)).
        !          61268: /      The second parameter (mm_n2) specifies the horizontal position (MM_COL(bp)).
        !          61269: /      A parameter value of 0 or 1 for the first or second parameter
        !          61270: /      moves the active position to the first line or column in the
        !          61271: /      display respectively.
        !          61272: /
        !          61273: ////////
        !          61274: 
        !          61275: mm_cup:        movb    ROW, MM_N1(bp)
        !          61276:        decb    ROW
        !          61277:        jg      0f
        !          61278:        subb    ROW, ROW
        !          61279: 0:     addb    ROW, MM_BROW(bp)
        !          61280:        cmpb    ROW, MM_EROW(bp)
        !          61281:        jb      0f
        !          61282:        movb    ROW, MM_EROW(bp)
        !          61283: 0:     movb    COL, MM_N2(bp)
        !          61284:        decb    COL
        !          61285:        jg      0f
        !          61286:        subb    COL, COL
        !          61287: 0:     cmpb    COL, MM_NCOL(bp)
        !          61288:        jb      0f
        !          61289:        movb    COL, MM_NCOL(bp)
        !          61290:        decb    COL
        !          61291: 0:     jmp     repos                   / reposition cursor
        !          61292: 
        !          61293: ////////
        !          61294: /
        !          61295: / mm_cuu - cursor up
        !          61296: /
        !          61297: /      Moves the active position upward without altering the horizontal
        !          61298: /      position.
        !          61299: /
        !          61300: ////////
        !          61301: 
        !          61302: mm_cuu:        decb    ROW
        !          61303:        cmpb    ROW, MM_BROW(bp)
        !          61304:        jge     0f
        !          61305:        movb    ROW, MM_BROW(bp)
        !          61306: 0:     jmp     repos                   / reposition cursor
        !          61307: 
        !          61308: ////////
        !          61309: /
        !          61310: / mm_dl - delete line
        !          61311: /
        !          61312: /      Removes the contents of the active line.
        !          61313: /      The contents of all following lines are shifted in a block
        !          61314: /      toward the active line.
        !          61315: /
        !          61316: ////////
        !          61317: 
        !          61318: mm_dl: push    ds
        !          61319:        push    si
        !          61320:        push    cx
        !          61321:        mov     ds, MM_BASE(bp)
        !          61322:        movb    bl, ROW
        !          61323:        shlb    bl, $1
        !          61324:        mov     di, cs:rowtab(bx)
        !          61325:        mov     si, cs:rowtab+2(bx)
        !          61326:        movb    bl, MM_EROW(bp)
        !          61327:        shlb    bl, $1
        !          61328:        mov     cx, cs:rowtab(bx)
        !          61329:        sub     cx, di
        !          61330:        jle     0f
        !          61331:        shr     cx, $1
        !          61332:        push    si
        !          61333:        push    di
        !          61334:        push    cx
        !          61335:        rep
        !          61336:        movsw
        !          61337:        pop     cx
        !          61338:        pop     di
        !          61339:        pop     si
        !          61340:        add     si, $BANKSZ
        !          61341:        add     di, $BANKSZ
        !          61342:        rep
        !          61343:        movsw
        !          61344:        mov     di, cs:rowtab(bx)
        !          61345:        push    di
        !          61346:        mov     cx, $NRB4
        !          61347:        mov     ax, MM_FLIP(bp)
        !          61348:        and     ax, MM_MASK(bp)
        !          61349:        rep
        !          61350:        stosw
        !          61351:        pop     di
        !          61352:        add     di, $BANKSZ
        !          61353:        mov     cx, $NRB4
        !          61354:        rep
        !          61355:        stosw
        !          61356:        subb    COL, COL
        !          61357: 0:     pop     cx
        !          61358:        pop     si
        !          61359:        pop     ds
        !          61360:        jmp     repos
        !          61361: 
        !          61362: ////////
        !          61363: /
        !          61364: / mm_dmi - disable manual input
        !          61365: /
        !          61366: /      Set flag preventing keyboard input.
        !          61367: /
        !          61368: ////////
        !          61369: 
        !          61370: mm_dmi:
        !          61371:        mov     ss:islock_, $1
        !          61372:        jmp     eval
        !          61373: 
        !          61374: ////////
        !          61375: /
        !          61376: / mm_ea - erase in area
        !          61377: /
        !          61378: /      Erase some or all of the characters in the currently active area
        !          61379: /      according to the parameter:
        !          61380: /              0 - erase from active position to end inclusive (default)
        !          61381: /              1 - erase from start to active position inclusive
        !          61382: /              2 - erase all of active area
        !          61383: /
        !          61384: ////////
        !          61385: 
        !          61386: mm_ea: movb    al, MM_N1(bp)
        !          61387:        cmpb    al, $0
        !          61388:        jne     0f
        !          61389:        movb    bl, MM_EROW(bp)
        !          61390:        jmp     mm_e0
        !          61391: 0:     cmpb    al, $1
        !          61392:        jne     0f
        !          61393:        movb    bl, MM_BROW(bp)
        !          61394:        jmp     mm_e1
        !          61395: 0:     subb    COL, COL
        !          61396:        movb    ROW, MM_BROW(bp)
        !          61397:        movb    bl, ROW
        !          61398:        shlb    bl, $1
        !          61399:        mov     POS, cs:rowtab(bx)
        !          61400:        movb    bl, MM_EROW(bp)
        !          61401:        subb    bl, ROW
        !          61402:        jmp     mm_e2
        !          61403: 
        !          61404: ////////
        !          61405: /
        !          61406: / mm_ed - erase in display
        !          61407: /
        !          61408: /      Erase some or all of the characters in the display according to the
        !          61409: /      parameter
        !          61410: /              0 - erase from active position to end inclusive (default)
        !          61411: /              1 - erase from start to active position inclusive
        !          61412: /              2 - erase all of display
        !          61413: /
        !          61414: ////////
        !          61415: 
        !          61416: mm_ed: movb    al, MM_N1(bp)
        !          61417:        cmpb    al, $0
        !          61418:        jne     0f
        !          61419:        movb    bl, MM_LROW(bp)
        !          61420:        jmp     mm_e0
        !          61421: 0:     cmpb    al, $1
        !          61422:        jne     0f
        !          61423:        subb    bl, bl
        !          61424:        jmp     mm_e1
        !          61425: 0:     subb    COL, COL
        !          61426:        movb    ROW, MM_BROW(bp)
        !          61427:        sub     POS, POS
        !          61428:        movb    bl, MM_LROW(bp)
        !          61429:        jmp     mm_e2
        !          61430: 
        !          61431: ////////
        !          61432: /
        !          61433: / mm_el - erase in line
        !          61434: /
        !          61435: /      Erase some or all of the characters in the line according to the
        !          61436: /      parameter:
        !          61437: /              0 - erase from active position to end inclusive (default)
        !          61438: /              1 - erase from start to active position inclusive
        !          61439: /              2 - erase entire line
        !          61440: /
        !          61441: ////////
        !          61442: 
        !          61443: mm_el: movb    al, MM_N1(bp)
        !          61444:        movb    bl, ROW
        !          61445:        cmpb    al, $0
        !          61446:        je      mm_e0
        !          61447:        cmpb    al, $1
        !          61448:        je      mm_e1
        !          61449:        shlb    bl, $1
        !          61450:        mov     POS, cs:rowtab(bx)
        !          61451:        subb    COL, COL
        !          61452:        subb    bl, bl
        !          61453: /      jmp     mm_e2
        !          61454: 
        !          61455: ////////
        !          61456: /
        !          61457: / mm_e2 - erase from POS for BL rows (minimum 1 row)
        !          61458: /
        !          61459: ////////
        !          61460: 
        !          61461: mm_e2: push    cx
        !          61462:        mov     ax, MM_FLIP(bp)
        !          61463:        and     ax, MM_MASK(bp)
        !          61464: 0:     mov     cx, $NRB4
        !          61465:        rep
        !          61466:        stosw
        !          61467:        add     di, $BANKSZ-NRB2
        !          61468:        mov     cx, $NRB4
        !          61469:        rep
        !          61470:        stosw
        !          61471:        sub     di, $BANKSZ
        !          61472:        decb    bl
        !          61473:        jge     0b
        !          61474:        pop     cx
        !          61475:        jmp     repos
        !          61476: 
        !          61477: ////////
        !          61478: /
        !          61479: / mm_e1 - erase from row BL to current cursor position.
        !          61480: /
        !          61481: ////////
        !          61482: 
        !          61483: mm_e1: push    dx
        !          61484:        push    cx
        !          61485:        push    di
        !          61486:        mov     ax, MM_FLIP(bp)
        !          61487:        and     ax, MM_MASK(bp)
        !          61488:        shlb    bl, $1
        !          61489:        mov     di, cs:rowtab(bx)
        !          61490:        movb    bl, ROW
        !          61491:        shlb    bl, $1
        !          61492:        mov     cx, cs:rowtab(bx)
        !          61493:        sub     cx, di
        !          61494:        jle     0f
        !          61495:        shr     cx, $1
        !          61496:        push    di
        !          61497:        push    cx
        !          61498:        rep
        !          61499:        stosw
        !          61500:        pop     cx
        !          61501:        pop     di
        !          61502:        add     di, $BANKSZ
        !          61503:        rep
        !          61504:        stosw
        !          61505: 0:     pop     cx
        !          61506:        movb    bl, ROW
        !          61507:        shlb    bl, $1
        !          61508:        mov     di, cs:rowtab(bx)
        !          61509:        sub     cx, di
        !          61510:        jle     0f
        !          61511: 
        !          61512:        mov     dx, di
        !          61513:        mov     bx, cx
        !          61514:        rep                     / erase row 0
        !          61515:        stosb
        !          61516:        add     dx, $80
        !          61517:        mov     di, dx
        !          61518:        mov     cx, bx
        !          61519: #ifdef TECMAR
        !          61520:        rep                     / erase row 1
        !          61521:        stosb
        !          61522:        add     dx, $80
        !          61523:        mov     di, dx
        !          61524:        mov     cx, bx
        !          61525: #endif
        !          61526:        rep                     / erase row 2
        !          61527:        stosb
        !          61528:        add     dx, $80
        !          61529:        mov     di, dx
        !          61530:        mov     cx, bx
        !          61531: #ifdef TECMAR
        !          61532:        rep                     / erase row 3
        !          61533:        stosb
        !          61534:        add     dx, $80
        !          61535:        mov     di, dx
        !          61536:        mov     cx, bx
        !          61537: #endif
        !          61538:        rep                     / erase row 4
        !          61539:        stosb
        !          61540:        add     dx, $80
        !          61541:        mov     di, dx
        !          61542:        mov     cx, bx
        !          61543: #ifdef TECMAR
        !          61544:        rep                     / erase row 5
        !          61545:        stosb
        !          61546:        add     dx, $80
        !          61547:        mov     di, dx
        !          61548:        mov     cx, bx
        !          61549: #endif
        !          61550:        rep                     / erase row 6
        !          61551:        stosb
        !          61552: #ifdef TECMAR
        !          61553:        add     dx, $80
        !          61554:        mov     di, dx
        !          61555:        mov     cx, bx
        !          61556:        rep                     / erase row 7
        !          61557:        stosb
        !          61558:        add     dx, $BANKSZ-560
        !          61559: #else
        !          61560:        add     dx, $BANKSZ-240
        !          61561: #endif
        !          61562:        mov     di, dx
        !          61563:        mov     cx, bx
        !          61564: #ifdef TECMAR
        !          61565:        rep                     / erase row 0
        !          61566:        stosb
        !          61567:        add     dx, $80
        !          61568:        mov     di, dx
        !          61569:        mov     cx, bx
        !          61570: #endif
        !          61571:        rep                     / erase row 1
        !          61572:        stosb
        !          61573:        add     dx, $80
        !          61574:        mov     di, dx
        !          61575:        mov     cx, bx
        !          61576: #ifdef TECMAR
        !          61577:        rep                     / erase row 2
        !          61578:        stosb
        !          61579:        add     dx, $80
        !          61580:        mov     di, dx
        !          61581:        mov     cx, bx
        !          61582: #endif
        !          61583:        rep                     / erase row 3
        !          61584:        stosb
        !          61585:        add     dx, $80
        !          61586:        mov     di, dx
        !          61587:        mov     cx, bx
        !          61588: #ifdef TECMAR
        !          61589:        rep                     / erase row 4
        !          61590:        stosb
        !          61591:        add     dx, $80
        !          61592:        mov     di, dx
        !          61593:        mov     cx, bx
        !          61594: #endif
        !          61595:        rep                     / erase row 5
        !          61596:        stosb
        !          61597:        add     dx, $80
        !          61598:        mov     di, dx
        !          61599:        mov     cx, bx
        !          61600: #ifdef TECMAR
        !          61601:        rep                     / erase row 6
        !          61602:        stosb
        !          61603:        add     dx, $80
        !          61604:        mov     di, dx
        !          61605:        mov     cx, bx
        !          61606: #endif
        !          61607:        rep                     / erase row 7
        !          61608:        stosb
        !          61609: 1:     sub     bx, bx
        !          61610:        pop     cx
        !          61611:        pop     dx
        !          61612:        jmp     repos
        !          61613: 
        !          61614: ////////
        !          61615: /
        !          61616: / mm_e0 - erase from current cursor position to row BL inclusive.
        !          61617: /
        !          61618: ////////
        !          61619: 
        !          61620: mm_e0: push    dx
        !          61621:        push    cx
        !          61622:        push    di
        !          61623:        mov     ax, MM_FLIP(bp)
        !          61624:        and     ax, MM_MASK(bp)
        !          61625:        shlb    bl, $1
        !          61626:        mov     cx, cs:rowtab+2(bx)
        !          61627:        movb    bl, ROW
        !          61628:        shlb    bl, $1
        !          61629:        mov     di, cs:rowtab+2(bx)
        !          61630:        sub     cx, di
        !          61631:        jle     0f
        !          61632:        shr     cx, $1
        !          61633:        push    di
        !          61634:        push    cx
        !          61635:        rep
        !          61636:        stosw
        !          61637:        pop     cx
        !          61638:        pop     di
        !          61639:        add     di, $BANKSZ
        !          61640:        rep
        !          61641:        stosw
        !          61642: 0:     pop     di
        !          61643:        sub     cx, cx
        !          61644:        movb    cl, MM_NCOL(bp)
        !          61645:        subb    cl, COL
        !          61646:        cmpb    MM_NCOL(bp), $40
        !          61647:        jne     0f
        !          61648:        shlb    cl, $1
        !          61649: 0:     mov     dx, di
        !          61650:        mov     bx, cx
        !          61651:        rep                     / erase row 0
        !          61652:        stosb
        !          61653:        add     dx, $80
        !          61654:        mov     di, dx
        !          61655:        mov     cx, bx
        !          61656: #ifdef TECMAR
        !          61657:        rep                     / erase row 1
        !          61658:        stosb
        !          61659:        add     dx, $80
        !          61660:        mov     di, dx
        !          61661:        mov     cx, bx
        !          61662: #endif
        !          61663:        rep                     / erase row 2
        !          61664:        stosb
        !          61665:        add     dx, $80
        !          61666:        mov     di, dx
        !          61667:        mov     cx, bx
        !          61668: #ifdef TECMAR
        !          61669:        rep                     / erase row 3
        !          61670:        stosb
        !          61671:        add     dx, $80
        !          61672:        mov     di, dx
        !          61673:        mov     cx, bx
        !          61674: #endif
        !          61675:        rep                     / erase row 4
        !          61676:        stosb
        !          61677:        add     dx, $80
        !          61678:        mov     di, dx
        !          61679:        mov     cx, bx
        !          61680: #ifdef TECMAR
        !          61681:        rep                     / erase row 5
        !          61682:        stosb
        !          61683:        add     dx, $80
        !          61684:        mov     di, dx
        !          61685:        mov     cx, bx
        !          61686: #endif
        !          61687:        rep                     / erase row 6
        !          61688:        stosb
        !          61689: #ifdef TECMAR
        !          61690:        add     dx, $80
        !          61691:        mov     di, dx
        !          61692:        mov     cx, bx
        !          61693:        rep                     / erase row 7
        !          61694:        stosb
        !          61695:        add     dx, $BANKSZ-560
        !          61696: #else
        !          61697:        add     dx, $BANKSZ-240
        !          61698: #endif
        !          61699:        mov     di, dx
        !          61700:        mov     cx, bx
        !          61701: #ifdef TECMAR
        !          61702:        rep                     / erase row 0
        !          61703:        stosb
        !          61704:        add     dx, $80
        !          61705:        mov     di, dx
        !          61706:        mov     cx, bx
        !          61707: #endif
        !          61708:        rep                     / erase row 1
        !          61709:        stosb
        !          61710:        add     dx, $80
        !          61711:        mov     di, dx
        !          61712:        mov     cx, bx
        !          61713: #ifdef TECMAR
        !          61714:        rep                     / erase row 2
        !          61715:        stosb
        !          61716:        add     dx, $80
        !          61717:        mov     di, dx
        !          61718:        mov     cx, bx
        !          61719: #endif
        !          61720:        rep                     / erase row 3
        !          61721:        stosb
        !          61722:        add     dx, $80
        !          61723:        mov     di, dx
        !          61724:        mov     cx, bx
        !          61725: #ifdef TECMAR
        !          61726:        rep                     / erase row 4
        !          61727:        stosb
        !          61728:        add     dx, $80
        !          61729:        mov     di, dx
        !          61730:        mov     cx, bx
        !          61731: #endif
        !          61732:        rep                     / erase row 5
        !          61733:        stosb
        !          61734:        add     dx, $80
        !          61735:        mov     di, dx
        !          61736:        mov     cx, bx
        !          61737: #ifdef TECMAR
        !          61738:        rep                     / erase row 6
        !          61739:        stosb
        !          61740:        add     dx, $80
        !          61741:        mov     di, dx
        !          61742:        mov     cx, bx
        !          61743: #endif
        !          61744:        rep                     / erase row 7
        !          61745:        stosb
        !          61746: 1:     sub     bx, bx
        !          61747:        pop     cx
        !          61748:        pop     dx
        !          61749:        jmp     repos
        !          61750: 
        !          61751: ////////
        !          61752: /
        !          61753: / mm_emi - enable manual input
        !          61754: /
        !          61755: /      Clear flag preventing keyboard input.
        !          61756: /
        !          61757: ////////
        !          61758: 
        !          61759: mm_emi:
        !          61760:        mov     ss:islock_, $0
        !          61761:        jmp     eval
        !          61762: 
        !          61763: ////////
        !          61764: /
        !          61765: / mm_il - insert line
        !          61766: /
        !          61767: /      Insert a erased line at the active line by shifting the contents
        !          61768: /      of the active line and all following lines away from the active line.
        !          61769: /      The contents of the last line in the scrolling region are removed.
        !          61770: /
        !          61771: ////////
        !          61772: 
        !          61773: scrolldown:
        !          61774: mm_il: push    ds
        !          61775:        push    si
        !          61776:        push    cx
        !          61777:        mov     ds, MM_BASE(bp)
        !          61778:        movb    bl, MM_EROW(bp)
        !          61779:        shlb    bl, $1
        !          61780:        mov     si, cs:rowtab(bx)
        !          61781:        mov     cx, si
        !          61782:        sub     si, $2
        !          61783:        mov     di, cs:rowtab+2(bx)
        !          61784:        sub     di, $2
        !          61785:        movb    bl, ROW
        !          61786:        shlb    bl, $1
        !          61787:        sub     cx, cs:rowtab(bx)
        !          61788:        jle     0f
        !          61789:        shr     cx, $1
        !          61790:        push    si
        !          61791:        push    di
        !          61792:        push    cx
        !          61793:        std
        !          61794:        rep
        !          61795:        movsw
        !          61796:        pop     cx
        !          61797:        pop     di
        !          61798:        pop     si
        !          61799:        add     si, $BANKSZ
        !          61800:        add     di, $BANKSZ
        !          61801:        rep
        !          61802:        movsw
        !          61803:        mov     di, cs:rowtab(bx)
        !          61804:        push    di
        !          61805:        mov     cx, $NRB4
        !          61806:        mov     ax, MM_FLIP(bp)
        !          61807:        and     ax, MM_MASK(bp)
        !          61808:        cld
        !          61809:        rep
        !          61810:        stosw
        !          61811:        pop     di
        !          61812:        add     di, $BANKSZ
        !          61813:        mov     cx, $NRB4
        !          61814:        rep
        !          61815:        stosw
        !          61816:        subb    COL, COL
        !          61817: 0:     pop     cx
        !          61818:        pop     si
        !          61819:        pop     ds
        !          61820:        jmp     repos
        !          61821: 
        !          61822: ////////
        !          61823: /
        !          61824: / mm_hpa - horizontal position absolute
        !          61825: /
        !          61826: /      Moves the active position within the active line to the position
        !          61827: /      specified by the parameter.  A parameter value of zero or one
        !          61828: /      moves the active position to the first position of the active line.
        !          61829: /
        !          61830: ////////
        !          61831: 
        !          61832: mm_hpa:        movb    COL, MM_N1(bp)
        !          61833:        decb    COL
        !          61834:        jg      0f
        !          61835:        subb    COL, COL
        !          61836: 0:     cmpb    COL, MM_NCOL(bp)
        !          61837:        jb      0f
        !          61838:        movb    COL, MM_NCOL(bp)
        !          61839:        decb    COL
        !          61840: 0:     jmp     repos                   / reposition cursor
        !          61841: 
        !          61842: ////////
        !          61843: /
        !          61844: / mm_hpr - horizontal position relative
        !          61845: /
        !          61846: /      Moves the active position forward the number of positions specified
        !          61847: /      by the parameter.  A parameter value of zero or one indicates a
        !          61848: /      single-position move.
        !          61849: /
        !          61850: ////////
        !          61851: 
        !          61852: mm_hpr:        movb    al, MM_N1(bp)
        !          61853:        orb     al, al
        !          61854:        jne     0f
        !          61855:        incb    al
        !          61856: 0:     addb    COL, al
        !          61857:        cmpb    COL, MM_NCOL(bp)
        !          61858:        jb      0f
        !          61859:        movb    COL, MM_NCOL(bp)
        !          61860:        decb    COL
        !          61861: 0:     jmp     repos                   / reposition cursor
        !          61862: 
        !          61863: ////////
        !          61864: /
        !          61865: / mm_hvp - horizontal and vertical position
        !          61866: /
        !          61867: /      Moves the active position to the position specified by two parameters.
        !          61868: /      The first parameter specifies the vertical position (MM_ROW(bp)).
        !          61869: /      The second parameter specifies the horizontal position (MM_COL(bp)).
        !          61870: /      A parameter value of zero or one moves the active position to the
        !          61871: /      first line or column in the display.
        !          61872: /
        !          61873: ////////
        !          61874: 
        !          61875: mm_hvp:        movb    ROW, MM_N1(bp)
        !          61876:        decb    ROW
        !          61877:        jg      0f
        !          61878:        subb    ROW, ROW
        !          61879: 0:     cmpb    ROW, MM_LROW(bp)
        !          61880:        jna     0f
        !          61881:        movb    ROW, MM_LROW(bp)
        !          61882: 0:     movb    COL, MM_N2(bp)
        !          61883:        decb    COL
        !          61884:        jg      0f
        !          61885:        subb    COL, COL
        !          61886: 0:     cmpb    COL, MM_NCOL(bp)
        !          61887:        jb      0f
        !          61888:        movb    COL, MM_NCOL(bp)
        !          61889:        decb    COL
        !          61890: 0:     jmp     repos                   / reposition cursor
        !          61891: 
        !          61892: ////////
        !          61893: /
        !          61894: / mm_ind - index
        !          61895: /
        !          61896: /      Causes the active position to move downward one line without changing
        !          61897: /      the horizontal position.  Scrolling occurs if below scrolling region.
        !          61898: /
        !          61899: ////////
        !          61900: 
        !          61901: mm_ind:        incb    ROW
        !          61902:        cmpb    ROW, MM_EROW(bp)
        !          61903:        jg      0f
        !          61904:        jmp     repos
        !          61905: 0:     movb    ROW, MM_EROW(bp)
        !          61906:        jmp     scrollup
        !          61907: 
        !          61908: ////////
        !          61909: /
        !          61910: / mm_new - save cursor position
        !          61911: /
        !          61912: ////////
        !          61913: 
        !          61914: mm_new:        movb    MM_SCOL(bp), COL
        !          61915:        movb    MM_SROW(bp), ROW
        !          61916:        jmp     eval
        !          61917: 
        !          61918: ////////
        !          61919: /
        !          61920: / mm_old - restore old cursor position
        !          61921: /
        !          61922: ////////
        !          61923: 
        !          61924: mm_old:        movb    COL, MM_SCOL(bp)
        !          61925:        movb    ROW, MM_SROW(bp)
        !          61926:        jmp     repos
        !          61927: 
        !          61928: ////////
        !          61929: /
        !          61930: / mm_ri - reverse index
        !          61931: /
        !          61932: /      Moves the active position to the same horizontal position on the
        !          61933: /      preceding line.  Scrolling occurs if above scrolling region.
        !          61934: /
        !          61935: ////////
        !          61936: 
        !          61937: mm_ri: decb    ROW
        !          61938:        cmpb    ROW, MM_BROW(bp)
        !          61939:        jge     0f
        !          61940:        movb    ROW, MM_BROW(bp)
        !          61941:        jmp     scrolldown
        !          61942: 0:     jmp     repos
        !          61943: 
        !          61944: ////////
        !          61945: /
        !          61946: / mm_scr - select cursor rendition
        !          61947: /
        !          61948: /      Invokes the cursor rendition specified by the parameter.
        !          61949: /
        !          61950: /      Recognized renditions are:      0 - cursor visible
        !          61951: /                                      1 - cursor invisible
        !          61952: ////////
        !          61953: 
        !          61954: mm_scr:        decb    MM_N1(bp)
        !          61955:        je      0f
        !          61956:        jg      1f
        !          61957:        mov     MM_VIS(bp), $-1
        !          61958:        jmp     eval
        !          61959: 
        !          61960: 0:     mov     MM_VIS(bp), $0
        !          61961: 1:     jmp     eval
        !          61962: 
        !          61963: ////////
        !          61964: /
        !          61965: / mm_sgr - select graphic rendition
        !          61966: /
        !          61967: /      Invokes the graphic rendition specified by the parameter.
        !          61968: /      All following characters in the data stream are rendered
        !          61969: /      according to the parameters until the next occurrence of
        !          61970: /      SGR in the data stream.
        !          61971: /
        !          61972: /      Recognized renditions are:      1 - high intensity
        !          61973: /                                      4 - underline
        !          61974: /                                      7 - reverse video
        !          61975: /
        !          61976: ////////
        !          61977: 
        !          61978: mm_sgr:        movb    al, MM_N1(bp)
        !          61979:        cmpb    al, $0
        !          61980:        jne     0f
        !          61981:        mov     MM_MASK(bp), $0xAAAA
        !          61982:        mov     MM_FLIP(bp), $0
        !          61983:        mov     MM_ULINE(bp), $0
        !          61984:        jmp     1f
        !          61985: 0:     cmpb    al, $1          / bold
        !          61986:        jne     0f
        !          61987:        mov     MM_MASK(bp), $-1
        !          61988:        jmp     1f
        !          61989: 0:     cmpb    al, $4          / underline
        !          61990:        jne     0f
        !          61991:        mov     MM_ULINE(bp), $0xFFFF
        !          61992:        jmp     1f
        !          61993: 0:     cmpb    al, $7          / reverse video
        !          61994:        jne     0f
        !          61995:        mov     MM_FLIP(bp), $-1
        !          61996:        jmp     1f
        !          61997: 0:
        !          61998: 1:     jmp     eval
        !          61999: 
        !          62000: ////////
        !          62001: /
        !          62002: / mm_so - stand out - enter 40 column mode
        !          62003: /
        !          62004: ////////
        !          62005: 
        !          62006: mm_so: cmpb    MM_NCOL(bp), $80
        !          62007:        jne     0f
        !          62008:        movb    MM_NCOL(bp), $40
        !          62009:        incb    COL
        !          62010:        shrb    COL, $1
        !          62011: 0:     mov     MM_CURSE(bp), $0xffff
        !          62012:        jmp     repos
        !          62013: 
        !          62014: ////////
        !          62015: /
        !          62016: / mm_si - stand in - enter 80 column mode
        !          62017: /
        !          62018: ////////
        !          62019: 
        !          62020: mm_si: cmpb    MM_NCOL(bp), $40
        !          62021:        jne     0f
        !          62022:        movb    MM_NCOL(bp), $80
        !          62023:        shlb    COL, $1
        !          62024: 0:     mov     MM_CURSE(bp), $0x00ff
        !          62025:        jmp     repos
        !          62026: 
        !          62027: ////////
        !          62028: /
        !          62029: / mm_ssr - set scrolling region
        !          62030: /
        !          62031: ////////
        !          62032: 
        !          62033: mm_ssr:        movb    al, MM_N1(bp)
        !          62034:        decb    al
        !          62035:        jge     0f
        !          62036:        subb    al, al
        !          62037: 0:     cmpb    al, MM_LROW(bp)
        !          62038:        ja      1f
        !          62039:        movb    bl, MM_N2(bp)
        !          62040:        decb    bl
        !          62041:        jge     0f
        !          62042:        subb    bl, bl
        !          62043: 0:     cmpb    bl, MM_LROW(bp)
        !          62044:        ja      1f
        !          62045:        cmpb    al, bl
        !          62046:        ja      1f
        !          62047:        movb    MM_BROW(bp), al
        !          62048:        movb    MM_EROW(bp), bl
        !          62049:        movb    ROW, al
        !          62050:        subb    COL, COL
        !          62051: 1:     jmp     repos
        !          62052: 
        !          62053: ////////
        !          62054: /
        !          62055: / mm_vpa - vertical position absolute
        !          62056: /
        !          62057: /      Moves the active position to the line specified by the parameter
        !          62058: /      without changing the horizontal position.
        !          62059: /      A parameter value of 0 or 1 moves the active position vertically
        !          62060: /      to the first line.
        !          62061: /
        !          62062: ////////
        !          62063: 
        !          62064: mm_vpa:        movb    ROW, MM_N1(bp)
        !          62065:        decb    ROW
        !          62066:        jg      0f
        !          62067:        subb    ROW, ROW
        !          62068: 0:     cmpb    ROW, MM_LROW(bp)
        !          62069:        jna     0f
        !          62070:        movb    ROW, MM_LROW(bp)
        !          62071: 0:     jmp     repos                   / reposition cursor
        !          62072: 
        !          62073: ////////
        !          62074: /
        !          62075: / mm_vpr - vertical position relative
        !          62076: /
        !          62077: /      Moves the active position downward the number of lines specified
        !          62078: /      by the parameter without changing the horizontal position.
        !          62079: /      A parameter value of zero or one moves the active position
        !          62080: /      one line downward.
        !          62081: /
        !          62082: ////////
        !          62083: 
        !          62084: mm_vpr:        movb    al, MM_N1(bp)
        !          62085:        orb     al, al
        !          62086:        jne     0f
        !          62087:        incb    al
        !          62088: 0:     addb    ROW, al
        !          62089:        cmpb    ROW, MM_LROW(bp)
        !          62090:        jb      0f
        !          62091:        movb    ROW, MM_LROW(bp)
        !          62092: 0:     jmp     repos                   / reposition cursor
        !          62093: 
        !          62094: ////////
        !          62095: /
        !          62096: / asctab - table of functions indexed by ascii characters
        !          62097: /
        !          62098: ////////
        !          62099: 
        !          62100: asctab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          62101:        .word   eval,   eval,   eval,   mmbell  /* EOT  ENQ  ACK  BEL  */
        !          62102:        .word   mm_cub, mm_cht, mm_cnl, mm_ind  /* BS   HT   LF   VT  */
        !          62103:        .word   eval,   mm_cr,  mm_so,  mm_si   /* FF   CR   SO   SI  */
        !          62104:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3 */
        !          62105:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          62106:        .word   eval,   eval,   eval,   mm_esc  /* CAN  EM   SUB  ESC  */
        !          62107:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          62108:        .word   mmputc, mmputc, mmputc, mmputc  /*   ! " # \040 - \043 */
        !          62109:        .word   mmputc, mmputc, mmputc, mmputc  /* $ % & ' \044 - \047 */
        !          62110:        .word   mmputc, mmputc, mmputc, mmputc  /* ( ) * + \050 - \053 */
        !          62111:        .word   mmputc, mmputc, mmputc, mmputc  /* , - . / \054 - \057 */
        !          62112:        .word   mmputc, mmputc, mmputc, mmputc  /* 0 1 2 3 \060 - \063 */
        !          62113:        .word   mmputc, mmputc, mmputc, mmputc  /* 4 5 6 7 \064 - \067 */
        !          62114:        .word   mmputc, mmputc, mmputc, mmputc  /* 8 9 : ; \070 - \073 */
        !          62115:        .word   mmputc, mmputc, mmputc, mmputc  /* < = > ? \074 - \077 */
        !          62116:        .word   mmputc, mmputc, mmputc, mmputc  /* @@ A B C \100 - \103 */
        !          62117:        .word   mmputc, mmputc, mmputc, mmputc  /* D E F G \104 - \107 */
        !          62118:        .word   mmputc, mmputc, mmputc, mmputc  /* H I J K \110 - \113 */
        !          62119:        .word   mmputc, mmputc, mmputc, mmputc  /* L M N O \114 - \117 */
        !          62120:        .word   mmputc, mmputc, mmputc, mmputc  /* P Q R S \120 - \123 */
        !          62121:        .word   mmputc, mmputc, mmputc, mmputc  /* T U V W \124 - \127 */
        !          62122:        .word   mmputc, mmputc, mmputc, mmputc  /* X Y Z [ \130 - \133 */
        !          62123:        .word   mmputc, mmputc, mmputc, mmputc  /* \ ] ^ _ \134 - \137 */
        !          62124:        .word   mmputc, mmputc, mmputc, mmputc  /* ` a b c \140 - \143 */
        !          62125:        .word   mmputc, mmputc, mmputc, mmputc  /* d e f g \144 - \147 */
        !          62126:        .word   mmputc, mmputc, mmputc, mmputc  /* h i j k \150 - \153 */
        !          62127:        .word   mmputc, mmputc, mmputc, mmputc  /* l m n o \154 - \157 */
        !          62128:        .word   mmputc, mmputc, mmputc, mmputc  /* p q r s \160 - \163 */
        !          62129:        .word   mmputc, mmputc, mmputc, mmputc  /* t u v w \164 - \167 */
        !          62130:        .word   mmputc, mmputc, mmputc, mmputc  /* x y z { \170 - \173 */
        !          62131:        .word   mmputc, mmputc, mmputc, mmputc  /* | } ~ ? \174 - \177 */
        !          62132: 
        !          62133: ////////
        !          62134: /
        !          62135: / esctab - table of functions indexed by escape characters.
        !          62136: /
        !          62137: ////////
        !          62138: 
        !          62139: esctab:        .word   mmputc, mmputc, mmputc, mmputc  /* NUL  SOH  STX  ETX  */
        !          62140:        .word   mmputc, mmputc, mmputc, mmputc  /* EOT  ENQ  ACK  BEL  */
        !          62141:        .word   mmputc, mmputc, mmputc, mmputc  /* BS   HT   LF   VT  */
        !          62142:        .word   mmputc, mmputc, mmputc, mmputc  /* FF   CR   SO   SI  */
        !          62143:        .word   mmputc, mmputc, mmputc, mmputc  /* DLE  DC1  DC2  DC3 */
        !          62144:        .word   mmputc, mmputc, mmputc, mmputc  /* DC4  NAK  SYN  ETB  */
        !          62145:        .word   mmputc, mmputc, mmputc, mmputc  /* CAN  EM   SUB  ESC  */
        !          62146:        .word   mmputc, mmputc, mmputc, mmputc  /* FS   GS   RS   US   */
        !          62147:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          62148:        .word   eval,   eval,   eval,   eval    /* $ % & ' \044 - \047 */
        !          62149:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          62150:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          62151:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          62152:        .word   eval,   eval,   eval,   mm_new  /* 4 5 6 7 \064 - \067 */
        !          62153:        .word   mm_old, eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          62154:        .word   eval,   mmspec, mmspec, eval    /* < = > ? \074 - \077 */
        !          62155:        .word   eval,   eval,   eval,   eval    /* @@ A B C \100 - \103 */
        !          62156:        .word   mm_ind, mm_cnl, eval,   eval    /* D E F G \104 - \107 */
        !          62157:        .word   eval,   eval,   eval,   eval    /* H I J K \110 - \113 */
        !          62158:        .word   eval,   mm_ri,  eval,   eval    /* L M N O \114 - \117 */
        !          62159:        .word   eval,   eval,   eval,   eval    /* P Q R S \120 - \123 */
        !          62160:        .word   eval,   eval,   eval,   eval    /* T U V W \124 - \127 */
        !          62161:        .word   eval,   eval,   eval,   csi_n1  /* X Y Z [ \130 - \133 */
        !          62162:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          62163:        .word   mm_dmi, eval,   mm_emi, mminit  /* ` a b c \140 - \143 */
        !          62164:        .word   eval,   eval,   eval,   eval    /* d e f g \144 - \147 */
        !          62165:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          62166:        .word   eval,   eval,   eval,   eval    /* l m n o \154 - \157 */
        !          62167:        .word   eval,   eval,   eval,   eval    /* p q r s \160 - \163 */
        !          62168:        .word   mmspec, mmspec, eval,   eval    /* t u v w \164 - \167 */
        !          62169:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          62170:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          62171: 
        !          62172: ////////
        !          62173: /
        !          62174: / csitab - table of functions indexed by ESC [ characters.
        !          62175: /
        !          62176: ////////
        !          62177: 
        !          62178: csitab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          62179:        .word   eval,   eval,   eval,   eval    /* EOT  ENQ  ACK  BEL  */
        !          62180:        .word   eval,   eval,   eval,   eval    /* BS   HT   LF   VT  */
        !          62181:        .word   eval,   eval,   eval,   eval    /* FF   CR   SO   SI  */
        !          62182:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3 */
        !          62183:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          62184:        .word   eval,   eval,   eval,   eval    /* CAN  EM   SUB  ESC  */
        !          62185:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          62186:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          62187:        .word   eval,   eval,   eval,   eval    /* $ % & ' \044 - \047 */
        !          62188:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          62189:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          62190:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          62191:        .word   eval,   eval,   eval,   eval    /* 4 5 6 7 \064 - \067 */
        !          62192:        .word   eval,   eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          62193:        .word   eval,   eval,   csi_gt, eval    /* < = > ? \074 - \077 */
        !          62194:        .word   eval,   mm_cuu, mm_cud, mm_cuf  /* @@ A B C \100 - \103 */
        !          62195:        .word   mm_cub, mm_cnl, mm_cpl, mm_cha  /* D E F G \104 - \107 */
        !          62196:        .word   mm_cup, mm_cht, mm_ed,  mm_el   /* H I J K \110 - \113 */
        !          62197:        .word   mm_il,  mm_dl,  eval,   mm_ea   /* L M N O \114 - \117 */
        !          62198:        .word   eval,   eval,   eval,   mm_ind  /* P Q R S \120 - \123 */
        !          62199:        .word   mm_ri,  eval,   eval,   eval    /* T U V W \124 - \127 */
        !          62200:        .word   eval,   eval,   mm_cbt, eval    /* X Y Z [ \130 - \133 */
        !          62201:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          62202:        .word   mm_hpa, mm_hpr, eval,   eval    /* ` a b c \140 - \143 */
        !          62203:        .word   mm_vpa, mm_vpr, mm_hvp, mm_cup  /* d e f g \144 - \147 */
        !          62204:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          62205:        .word   eval,   mm_sgr, eval,   eval    /* l m n o \154 - \157 */
        !          62206:        .word   eval,   eval,   mm_ssr, eval    /* p q r s \160 - \163 */
        !          62207:        .word   eval,   eval,   mm_scr, eval    /* t u v w \164 - \167 */
        !          62208:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          62209:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          62210: 
        !          62211: ////////
        !          62212: /
        !          62213: / rowtab - array of offsets to each row
        !          62214: /
        !          62215: ////////
        !          62216: 
        !          62217: rowtab:        .word    0*NRB2,         1*NRB2,         2*NRB2,         3*NRB2
        !          62218:        .word    4*NRB2,         5*NRB2,         6*NRB2,         7*NRB2
        !          62219:        .word    8*NRB2,         9*NRB2,        10*NRB2,        11*NRB2
        !          62220:        .word   12*NRB2,        13*NRB2,        14*NRB2,        15*NRB2
        !          62221:        .word   16*NRB2,        17*NRB2,        18*NRB2,        19*NRB2
        !          62222:        .word   20*NRB2,        21*NRB2,        22*NRB2,        23*NRB2
        !          62223:        .word   24*NRB2,        25*NRB2,        26*NRB2,        27*NRB2
        !          62224:        .word   28*NRB2,        29*NRB2,        30*NRB2,        31*NRB2
        !          62225:        .word   32*NRB2,        33*NRB2,        34*NRB2,        35*NRB2
        !          62226:        .word   36*NRB2,        37*NRB2,        38*NRB2,        39*NRB2
        !          62227:        .word   40*NRB2,        41*NRB2,        42*NRB2,        43*NRB2
        !          62228:        .word   44*NRB2,        45*NRB2,        46*NRB2,        47*NRB2
        !          62229:        .word   48*NRB2,        49*NRB2,        50*NRB2,        51*NRB2
        !          62230: 
        !          62231: ////////
        !          62232: /
        !          62233: / grread( dev, iop ) - read graphics display memory
        !          62234: /
        !          62235: ////////
        !          62236: 
        !          62237: grread_:
        !          62238:        push    si
        !          62239:        push    di
        !          62240:        push    bp
        !          62241:        mov     bp, sp
        !          62242:        mov     bp, 10(bp)
        !          62243:        push    ds
        !          62244:        push    es
        !          62245:        cmp     IO_SEG(bp), $IOSYS
        !          62246:        je      0f
        !          62247:        mov     ax, uds_
        !          62248:        mov     es, ax
        !          62249: 0:     mov     di, IO_BASE(bp)
        !          62250:        mov     ax, $VSEG
        !          62251:        mov     ds, ax
        !          62252: 
        !          62253: #ifndef TECMAR
        !          62254:        mov     ax, IO_SEEK(bp)
        !          62255:        add     ax, IO_IOC(bp)
        !          62256:        cmp     ax, $BANKSZ*2
        !          62257:        ja      done
        !          62258: #endif
        !          62259: 
        !          62260:        mov     ax, IO_SEEK(bp)
        !          62261:        sub     dx, dx
        !          62262:        mov     cx, $NHB
        !          62263:        div     cx
        !          62264:        mov     si, dx
        !          62265:        mov     bx, ax
        !          62266:        shr     ax, $1
        !          62267:        mul     cx
        !          62268:        mov     dx, si
        !          62269:        add     si, ax
        !          62270:        testb   bl, $1
        !          62271:        jne     read2
        !          62272: 
        !          62273: read1: mov     cx, $NHB
        !          62274:        sub     cx, dx
        !          62275:        cmp     cx, IO_IOC(bp)
        !          62276:        jle     0f
        !          62277:        mov     cx, IO_IOC(bp)
        !          62278:        jcxz    done
        !          62279: 0:     sub     IO_IOC(bp), cx
        !          62280:        add     IO_BASE(bp), cx
        !          62281:        push    si
        !          62282:        rep
        !          62283:        movsb
        !          62284:        pop     si
        !          62285: read2: add     si, $BANKSZ
        !          62286:        mov     cx, $NHB
        !          62287:        sub     cx, dx
        !          62288:        cmp     cx, IO_IOC(bp)
        !          62289:        jle     0f
        !          62290:        mov     cx, IO_IOC(bp)
        !          62291:        jcxz    done
        !          62292: 0:     sub     IO_IOC(bp), cx
        !          62293:        add     IO_BASE(bp), cx
        !          62294:        rep
        !          62295:        movsb
        !          62296:        sub     si, $BANKSZ
        !          62297:        sub     dx, dx
        !          62298:        jmp     read1
        !          62299: 
        !          62300: done:  pop     es
        !          62301:        pop     ds
        !          62302:        pop     bp
        !          62303:        pop     di
        !          62304:        pop     si
        !          62305:        ret
        !          62306: 
        !          62307: ////////
        !          62308: /
        !          62309: / grwrite( dev, iop ) - write graphics display memory
        !          62310: /
        !          62311: ////////
        !          62312: 
        !          62313: grwrite_:
        !          62314:        push    si
        !          62315:        push    di
        !          62316:        push    bp
        !          62317:        mov     bp, sp
        !          62318:        mov     bp, 10(bp)
        !          62319:        push    ds
        !          62320:        push    es
        !          62321:        cmp     IO_SEG(bp), $IOSYS
        !          62322:        je      0f
        !          62323:        mov     ax, uds_
        !          62324:        mov     ds, ax
        !          62325: 0:     mov     si, IO_BASE(bp)
        !          62326:        mov     ax, $VSEG
        !          62327:        mov     es, ax
        !          62328: 
        !          62329: #ifndef TECMAR
        !          62330:        mov     ax, IO_SEEK(bp)
        !          62331:        add     ax, IO_IOC(bp)
        !          62332:        cmp     ax, $BANKSZ*2
        !          62333:        ja      done
        !          62334: #endif
        !          62335: 
        !          62336:        mov     ax, IO_SEEK(bp)
        !          62337:        sub     dx, dx
        !          62338:        mov     cx, $NHB
        !          62339:        div     cx
        !          62340:        mov     di, dx
        !          62341:        mov     bx, ax
        !          62342:        shr     ax, $1
        !          62343:        mul     cx
        !          62344:        mov     dx, di
        !          62345:        add     di, ax
        !          62346:        testb   bl, $1
        !          62347:        jne     page2
        !          62348: 
        !          62349: page1: mov     cx, $NHB
        !          62350:        sub     cx, dx
        !          62351:        cmp     cx, IO_IOC(bp)
        !          62352:        jle     0f
        !          62353:        mov     cx, IO_IOC(bp)
        !          62354:        jcxz    done
        !          62355: 0:     sub     IO_IOC(bp), cx
        !          62356:        add     IO_BASE(bp), cx
        !          62357:        push    di
        !          62358:        rep
        !          62359:        movsb
        !          62360:        pop     di
        !          62361: page2: add     di, $BANKSZ
        !          62362:        mov     cx, $NHB
        !          62363:        sub     cx, dx
        !          62364:        cmp     cx, IO_IOC(bp)
        !          62365:        jle     0f
        !          62366:        mov     cx, IO_IOC(bp)
        !          62367:        jcxz    done
        !          62368: 0:     sub     IO_IOC(bp), cx
        !          62369:        add     IO_BASE(bp), cx
        !          62370:        rep
        !          62371:        movsb
        !          62372:        sub     di, $BANKSZ
        !          62373:        sub     dx, dx
        !          62374:        jmp     page1
        !          62375: 
        !          62376: ////////
        !          62377: /
        !          62378: / mm_voff()    -- Disable video display
        !          62379: /
        !          62380: ////////
        !          62381:        .globl  mm_voff_
        !          62382: mm_voff_:
        !          62383:        mov     dx, $MSR
        !          62384:        movb    al, $0x12
        !          62385:        outb    dx, al
        !          62386:        ret
        !          62387: 
        !          62388: ////////
        !          62389: /
        !          62390: / mm_von()     -- Enable video display
        !          62391: /
        !          62392: ////////
        !          62393:        .globl  mm_von_
        !          62394: mm_von_:
        !          62395:        mov     dx, $MSR                / enable video display
        !          62396:        movb    al, $0x1A
        !          62397:        outb    dx, al
        !          62398:        mov     ss:mmvcnt_, $480        / 480 seconds before video disabled
        !          62399:        ret
        !          62400: @
        !          62401: 0707070064030106701004440000030000030000011777770507310673100006200000035253/newbits/kernel/USRSRC/i8086/drv/RCS/hs.c.debug,vhead     1.1;
        !          62402: branch   ;
        !          62403: access   ;
        !          62404: symbols  ;
        !          62405: locks    bin:1.1; strict;
        !          62406: comment  @@;
        !          62407: 
        !          62408: 
        !          62409: 1.1
        !          62410: date     91.06.10.10.23.00;  author bin;  state Exp;
        !          62411: branches ;
        !          62412: next     ;
        !          62413: 
        !          62414: 
        !          62415: desc
        !          62416: @initial version prov by hal
        !          62417: @
        !          62418: 
        !          62419: 
        !          62420: 
        !          62421: 1.1
        !          62422: log
        !          62423: @Initial revision
        !          62424: @
        !          62425: text
        !          62426: @/* (-lgl
        !          62427:  *     COHERENT Driver Kit Version 1.1.0
        !          62428:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          62429:  *     All rights reserved. May not be copied without permission.
        !          62430:  *
        !          62431:  *     $Header: /usr/src/sys/i8086/drv/RCS/hs.c,v 1.2 91/02/13 15:54:29 root Exp $
        !          62432:  -lgl) */
        !          62433: /*
        !          62434:  * Polled Serial Port Device Driver.
        !          62435:  * - supports version 7 compatible ioctl
        !          62436:  */
        !          62437: 
        !          62438: #include "coherent.h"
        !          62439: #include "ins8250.h"
        !          62440: #include <sys/stat.h>
        !          62441: #include <sys/uproc.h>
        !          62442: #include <sys/proc.h>
        !          62443: #include <sys/tty.h>           /* indirectly includes sgtty.h */
        !          62444: #include <sys/con.h>
        !          62445: #include <errno.h>
        !          62446: #include <sys/timeout.h>       /* TIM */
        !          62447: #include <sched.h>             /* CVTTOUT, IVTTOUT, SVTTOUT */
        !          62448: #include <poll_clk.h>
        !          62449: 
        !          62450: /*
        !          62451:  * Definitions.
        !          62452:  *
        !          62453:  * HSBAUD is the highest baud rate supported by this driver
        !          62454:  * HS_HZ is the polling rate, i.e. the number of times per second
        !          62455:  *   at which all open ports are checked for input, output, and
        !          62456:  *   line status changes
        !          62457:  * MAX_HSNUM is the maximum number of devices that can be polled
        !          62458:  *   using this driver and can be revised up or down
        !          62459:  * PORT is a convenience macro for the base address of a port
        !          62460:  * port_config is the structure of the initial configuration for each
        !          62461:  *   polled port;  note that "speed" is NOT the actual baud rate, but
        !          62462:  *   the value of the symbol for that baud rate as defined in
        !          62463:  *   /usr/include/sgtty.h
        !          62464:  *
        !          62465:  * "PORT" is a macro yielding the 8250 base address, given the "tp" pointer.
        !          62466:  * "PORT_NUM" is a macro yielding the port index (0..MAX_HSNUM-1) given "tp".
        !          62467:  */
        !          62468: #define        HSBAUD  9600
        !          62469: #define        HS_HZ   (HSBAUD/6)
        !          62470: #define MAX_HSNUM      8
        !          62471: #define        PORT            (HS_PORTS[(int)(tp->t_ddp)].addr)
        !          62472: #define        PORT_NUM        ((int)(tp->t_ddp))
        !          62473: #define MSR_DELTAS     (MS_DCTS | MS_DDSR | MS_TERI | MS_DRLSD)
        !          62474: struct port_config {
        !          62475:        int     addr;   /* base address of the 8250-family UART */
        !          62476:        int     speed;  /* B0..B19200 */
        !          62477: };
        !          62478: 
        !          62479: /*
        !          62480:  * Export Variables - these can be patched without recompiling and linking
        !          62481:  *
        !          62482:  * HSNUM is the actual number of polled serial ports, and should be
        !          62483:  *   less than or equal to MAX_HSNUM
        !          62484:  * HS_PORTS is an array of address/speed pairs, one for each port
        !          62485:  */
        !          62486: int    HSNUM = 4;
        !          62487: struct port_config HS_PORTS[MAX_HSNUM] = {
        !          62488:        { 0x3F8, B9600 },
        !          62489:        { 0x2F8, B9600 },
        !          62490:        { 0x3E8, B9600 },
        !          62491:        { 0x2E8, B9600 }
        !          62492: };
        !          62493: 
        !          62494: /*
        !          62495:  * 8250's MSR delta bits are cleared each time the MSR is read.
        !          62496:  * But different parts of the driver look for deltas of different bits.
        !          62497:  * Array msr[] saves delta bits until they are needed.
        !          62498:  */
        !          62499: static char msr[MAX_HSNUM];
        !          62500: /*
        !          62501:  * Export Functions.
        !          62502:  */
        !          62503: int    hsload();
        !          62504: int    hsopen();
        !          62505: int    hsclose();
        !          62506: int    hsread();
        !          62507: int    hswrite();
        !          62508: int    hsioctl();
        !          62509: int    hsunload();
        !          62510: int    hspoll();
        !          62511: 
        !          62512: int    hscycle();
        !          62513: int    hsintr();
        !          62514: int    hsparam();
        !          62515: int    hsstart();
        !          62516: int    hsclk();
        !          62517: int    set_poll_rate();
        !          62518: 
        !          62519: /*
        !          62520:  * Import Functions
        !          62521:  */
        !          62522: int    nulldev();
        !          62523: int    nonedev();
        !          62524: 
        !          62525: /*
        !          62526:  * Configuration table.
        !          62527:  */
        !          62528: CON hscon ={
        !          62529:        DFCHR|DFPOL,                    /* Flags */
        !          62530:        7,                              /* Major index */
        !          62531:        hsopen,                         /* Open */
        !          62532:        hsclose,                        /* Close */
        !          62533:        nulldev,                        /* Block */
        !          62534:        hsread,                         /* Read */
        !          62535:        hswrite,                        /* Write */
        !          62536:        hsioctl,                        /* Ioctl */
        !          62537:        nulldev,                        /* Powerfail */
        !          62538:        nulldev,                        /* Timeout */
        !          62539:        hsload,                         /* Load */
        !          62540:        hsunload,                       /* Unload */
        !          62541:        hspoll                          /* Poll */
        !          62542: };
        !          62543: 
        !          62544: /*
        !          62545:  * Local variables.
        !          62546:  */
        !          62547: static TTY *hstty;
        !          62548: static TTY *hslimtty;
        !          62549: static TIM hstim;
        !          62550: static int poll_divisor;       /* used in hsclk() and set_poll_rate() */
        !          62551: 
        !          62552: /*
        !          62553:  * Time constant table.
        !          62554:  * Indexed by ioctl baud rate.
        !          62555:  */
        !          62556: static
        !          62557: int timeconst[] = {
        !          62558:        0,                              /* 0 */
        !          62559:        2304,                           /* 50 */
        !          62560:        1536,                           /* 75 */
        !          62561:        1047,                           /* 110 */
        !          62562:        857,                            /* 134.5 */
        !          62563:        768,                            /* 150 */
        !          62564:        576,                            /* 200 */
        !          62565:        384,                            /* 300 */
        !          62566:        192,                            /* 600 */
        !          62567:        96,                             /* 1200 */
        !          62568:        64,                             /* 1800 */
        !          62569:        58,                             /* 2000 */
        !          62570:        48,                             /* 2400 */
        !          62571:        32,                             /* 3600 */
        !          62572:        24,                             /* 4800 */
        !          62573:        16,                             /* 7200 */
        !          62574:        12,                             /* 9600 */
        !          62575:        6,                              /* 19200 */
        !          62576:        6,                              /* EXTA */
        !          62577:        6                               /* EXTB */
        !          62578: };
        !          62579: 
        !          62580: /*
        !          62581:  * poll_hz[] is tied to timeconst[] - it gives the minimum polling
        !          62582:  *     rate for the corresponding port speed; it must be a multiple
        !          62583:  *     of 100 (system clock Hz) and >= baud/6
        !          62584:  */
        !          62585: int poll_hz[] ={
        !          62586:        0,                              /* 0 */
        !          62587:        1*HZ,                           /* 50 */
        !          62588:        1*HZ,                           /* 75 */
        !          62589:        1*HZ,                           /* 110 */
        !          62590:        1*HZ,                           /* 134.5 */
        !          62591:        1*HZ,                           /* 150 */
        !          62592:        1*HZ,                           /* 200 */
        !          62593:        1*HZ,                           /* 300 */
        !          62594:        1*HZ,                           /* 600 */
        !          62595:        2*HZ,                           /* 1200 */
        !          62596:        3*HZ,                           /* 1800 */
        !          62597:        4*HZ,                           /* 2000 */
        !          62598:        4*HZ,                           /* 2400 */
        !          62599:        6*HZ,                           /* 3600 */
        !          62600:        8*HZ,                           /* 4800 */
        !          62601:        12*HZ,                          /* 7200 */
        !          62602:        16*HZ,                          /* 9600 */
        !          62603:        0,                              /* 19200 */
        !          62604:        0,                              /* EXTA */
        !          62605:        0                               /* EXTB */
        !          62606: };
        !          62607: 
        !          62608: /*
        !          62609:  * Load Routine.
        !          62610:  */
        !          62611: static hsload()
        !          62612: {
        !          62613:        register TTY * tp;
        !          62614:        register int port;
        !          62615:        int i, b;
        !          62616: 
        !          62617:        if ((hstty = (TTY *)kalloc(HSNUM*sizeof(TTY))) == 0) {
        !          62618:                printf("hsload: can't allocate tty's\n");
        !          62619:                return;
        !          62620:        }
        !          62621:        kclear(hstty, HSNUM*sizeof(TTY));
        !          62622: 
        !          62623:        for (i = 0; i < HSNUM; i++) {
        !          62624:                port = HS_PORTS[i].addr;
        !          62625:                tp = hstty + i;
        !          62626: 
        !          62627:                outb( port+MCR, 0 );
        !          62628:                outb( port+IER, 0 );
        !          62629: 
        !          62630:                if ( inb( port+IER ) )
        !          62631:                        break;
        !          62632: 
        !          62633:                tp->t_cs_sel  = cs_sel();
        !          62634:                tp->t_start   = hsstart;
        !          62635:                tp->t_param   = hsparam;
        !          62636:                tp->t_sgttyb.sg_ospeed = tp->t_sgttyb.sg_ispeed = 
        !          62637:                tp->t_dispeed = tp->t_dospeed = HS_PORTS[i].speed;
        !          62638:                tp->t_ddp     = i;
        !          62639: 
        !          62640:                b = timeconst[ tp->t_sgttyb.sg_ospeed ];
        !          62641:                outb( port+LCR, LC_DLAB );
        !          62642:                outb( port+DLL, b );
        !          62643:                outb( port+DLH, b >> 8);
        !          62644:                outb( port+LCR, LC_CS8);
        !          62645: 
        !          62646:                hslimtty = tp;
        !          62647:        }
        !          62648: }
        !          62649: 
        !          62650: static hsunload()
        !          62651: {
        !          62652:        if (hstty != (TTY *)0)
        !          62653:                kfree(hstty);
        !          62654: }
        !          62655: 
        !          62656: /*
        !          62657:  * Open Routine.
        !          62658:  */
        !          62659: hsopen( dev, mode )
        !          62660: dev_t dev;
        !          62661: {
        !          62662:        register TTY * tp = &hstty[ dev & 15 ];
        !          62663:        int port = PORT;
        !          62664:        int s;
        !          62665:        char msr_ch;
        !          62666: printf("hsopen #%d: enter, count=%d\n", PORT_NUM, tp->t_open);
        !          62667:        /*
        !          62668:         * Verify hardware exists.
        !          62669:         */
        !          62670:        if ( (port == 0) || (inb(port+IER) & ~IE_TxI) ) {
        !          62671:                u.u_error = ENXIO;
        !          62672:                return;
        !          62673:        }
        !          62674:        
        !          62675:        /*
        !          62676:         * Don't allow open if flagged for exclusive use and not super-user.
        !          62677:         */
        !          62678:        if ((tp->t_flags & T_EXCL) && !super()) {
        !          62679:                u.u_error = ENODEV;
        !          62680:                return;
        !          62681:        }
        !          62682: 
        !          62683:        /*
        !          62684:         * Don't open if modem is settling from previous close.
        !          62685:         */
        !          62686:        if (drvl[major(dev)].d_time != 0) {     /* Modem settling */
        !          62687:                u.u_error = EDBUSY;
        !          62688:                return;
        !          62689:        }
        !          62690: 
        !          62691:        /*
        !          62692:         * Can't open if another driver is using polling
        !          62693:         */
        !          62694:        if (poll_owner & ~ POLL_HS) {
        !          62695:                u.u_error = EDBUSY;
        !          62696:                return;
        !          62697:        }
        !          62698: 
        !          62699:        /*
        !          62700:         * Initialize if not already open.
        !          62701:         */
        !          62702:        if ( tp->t_open++ == 0 ) {
        !          62703:                hscycle( tp );
        !          62704:                /*
        !          62705:                 * ttopen() will call hsparam()
        !          62706:                 * hsparam() asserts DTR and RTS and sets polling rate
        !          62707:                 */
        !          62708:                ttopen( tp );
        !          62709: 
        !          62710:                if (dev & 0x80) { /* if modem control... */
        !          62711:                        s = sphi();
        !          62712:                        tp->t_flags |= T_MODC + T_STOP + T_HOPEN;
        !          62713:                        /*
        !          62714:                         * Sleep while waiting for carrier.
        !          62715:                         */
        !          62716:                        while(1) {
        !          62717:                                msr_ch = inb(port + MSR);
        !          62718:                                msr[PORT_NUM] |= msr_ch & MSR_DELTAS; 
        !          62719:                                if (msr_ch & MS_RLSD)
        !          62720:                                        break;
        !          62721:                                sleep((char *)(&tp->t_open), CVTTOUT, IVTTOUT,
        !          62722:                                        SVTTOUT);       /* wait for carrier */
        !          62723:                                if (SELF->p_ssig && nondsig()) {  /* signal? */
        !          62724:                                        outb(port+MCR, 0);  /* kill RTS/DTR */
        !          62725:                                        u.u_error = EINTR;
        !          62726:                                        spl(s);
        !          62727:                                        tp->t_open = 0;
        !          62728:                                        return;
        !          62729:                                }
        !          62730:                        }
        !          62731:                        tp->t_flags &= ~T_HOPEN; /* no longer hanging in open */
        !          62732:                        msr_ch = inb(port + MSR);
        !          62733:                        msr[PORT_NUM] |= msr_ch & MSR_DELTAS; 
        !          62734:                        if (msr_ch & MS_CTS)
        !          62735:                                tp->t_flags &= ~T_STOP;
        !          62736:                        spl( s );
        !          62737:                } else  {
        !          62738:                        tp->t_flags &= ~T_MODC;
        !          62739:                        tp->t_flags |=  T_CARR;
        !          62740:                }
        !          62741:        }
        !          62742:        ttsetgrp( tp, dev );
        !          62743: printf("hsopen #%d: leave, count=%d\n", PORT_NUM, tp->t_open);
        !          62744: }
        !          62745: 
        !          62746: /*
        !          62747:  * Close Routine.
        !          62748:  */
        !          62749: hsclose( dev )
        !          62750: dev_t dev;
        !          62751: {
        !          62752:        register TTY * tp = &hstty[ dev & 15 ];
        !          62753: printf("hsclose #%d: enter, count=%d\n", PORT_NUM, tp->t_open);
        !          62754:        /*
        !          62755:         * Reset if last close.
        !          62756:         */
        !          62757:        if ( tp->t_open == 1 ) {
        !          62758:                int state;
        !          62759:                int holdflags = tp->t_flags;    /* save flags */
        !          62760:                int port = PORT;
        !          62761: 
        !          62762:                ttclose( tp );                  /* clears flags */
        !          62763: 
        !          62764:                if (holdflags & T_HOPEN) {  /* if waiting for RLSD... */
        !          62765:                        /*
        !          62766:                         * Flags for first open
        !          62767:                         * (clear T_HPCL)
        !          62768:                         */
        !          62769:                        tp->t_flags = T_MODC | T_HOPEN;
        !          62770:                }
        !          62771: 
        !          62772:                /*
        !          62773:                 * If hupcls
        !          62774:                 */
        !          62775:                if (holdflags & T_HPCL) {
        !          62776:                        int maj;
        !          62777:                        /*
        !          62778:                         * Hangup port
        !          62779:                         */
        !          62780:                        outb(port+MCR, 0);
        !          62781:                        /*
        !          62782:                         * Hold dtr low for timeout
        !          62783:                         */
        !          62784:                        maj = major(dev);
        !          62785:                        drvl[maj].d_time = 1;
        !          62786:                        sleep((char *)&drvl[maj].d_time, CVTTOUT, IVTTOUT, SVTTOUT);
        !          62787:                        drvl[maj].d_time = 0;
        !          62788:                }
        !          62789:                
        !          62790:                /*
        !          62791:                 * ttclose() only emptied the output queue tp->t_oq;
        !          62792:                 * now wait 0.1 sec for the silo tp->rawout to empty
        !          62793:                 * and allow a delay for the UART on-chip xmit buffer to empty
        !          62794:                 *
        !          62795:                 * state 2: waiting for silo to empty
        !          62796:                 * state 1: stalling so UART can empty xmit buffer
        !          62797:                 * state 0: done!
        !          62798:                 */
        !          62799:                state = 2;
        !          62800:                while (state) {
        !          62801:                        timeout(&hstim, 10, wakeup, (int)&hstim);
        !          62802:                        sleep((char *)&hstim, CVTTOUT, IVTTOUT, SVTTOUT);
        !          62803:                        if (tp->t_rawout.si_ix == tp->t_rawout.si_ox  && state)
        !          62804:                                state--;
        !          62805:                }
        !          62806:        }
        !          62807: 
        !          62808:        --tp->t_open;
        !          62809:        set_poll_rate();
        !          62810: printf("hsclose #%d: leave, count=%d\n", PORT_NUM, tp->t_open);
        !          62811: }
        !          62812: 
        !          62813: /*
        !          62814:  * Read Routine.
        !          62815:  */
        !          62816: hsread( dev, iop )
        !          62817: dev_t dev;
        !          62818: register IO * iop;
        !          62819: {
        !          62820:        ttread( &hstty[ dev & 15 ], iop, 0 );
        !          62821: }
        !          62822: 
        !          62823: /*
        !          62824:  * Write Routine.
        !          62825:  */
        !          62826: hswrite( dev, iop )
        !          62827: dev_t dev;
        !          62828: register IO * iop;
        !          62829: {
        !          62830:        ttwrite( &hstty[ dev & 15 ], iop, 0 );
        !          62831: }
        !          62832: 
        !          62833: /*
        !          62834:  * Ioctl Routine.
        !          62835:  */
        !          62836: hsioctl( dev, com, vec )
        !          62837: dev_t dev;
        !          62838: int com;
        !          62839: struct sgttyb * vec;
        !          62840: {
        !          62841:        ttioctl( &hstty[ dev & 15 ], com, vec );
        !          62842: }
        !          62843: 
        !          62844: /*
        !          62845:  * Polling Routine.
        !          62846:  */
        !          62847: hspoll( dev, ev, msec )
        !          62848: dev_t dev;
        !          62849: int ev;
        !          62850: int msec;
        !          62851: {
        !          62852:        return ttpoll( &hstty[ dev & 15 ], ev, msec );
        !          62853: }
        !          62854: 
        !          62855: /*
        !          62856:  * Cyclic routine - invoked every clock tick to perform raw input/output.
        !          62857:  *
        !          62858:  *     Notes:  Invoked 10 times per second.
        !          62859:  */
        !          62860: hscycle( tp )
        !          62861: register TTY * tp;
        !          62862: {
        !          62863:        register int resid;
        !          62864:        register int c;
        !          62865:        int msr_ch;
        !          62866: 
        !          62867:        /*
        !          62868:         * Check modem status every clock tick.
        !          62869:         */
        !          62870:        if ( tp->t_flags & T_MODC ) {
        !          62871:                /*
        !          62872:                 * Get status
        !          62873:                 */
        !          62874:                msr_ch = inb(PORT + MSR);
        !          62875:                msr[PORT_NUM] |= msr_ch & MSR_DELTAS; 
        !          62876: 
        !          62877:                /*
        !          62878:                 * Carrier changed.
        !          62879:                 */
        !          62880:                if ( msr[PORT_NUM] & MS_DRLSD ) {
        !          62881:                        if (msr_ch & MS_RLSD)
        !          62882:                                tp->t_flags |= T_CARR;  /* carrier on */
        !          62883:                        else
        !          62884:                                tp->t_flags &= ~T_CARR; /* no carrier */
        !          62885: 
        !          62886:                        msr[PORT_NUM] &= ~MS_DRLSD;
        !          62887:                        /*
        !          62888:                         * wakeup open
        !          62889:                         */
        !          62890:                        if ( tp->t_open == 0 ) {
        !          62891:                                wakeup((char *)(&tp->t_open));
        !          62892:                        }
        !          62893: 
        !          62894:                        /*
        !          62895:                         * carrier off?
        !          62896:                         */
        !          62897:                        else if ( (msr_ch & MS_RLSD) == 0 ) {
        !          62898:                                /*
        !          62899:                                 * clear carrier flag; send hangup signal
        !          62900:                                 */
        !          62901:                                tp->t_rawin.si_ox = tp->t_rawin.si_ix;
        !          62902:                                tthup( tp );
        !          62903:                        }
        !          62904:                }
        !          62905:        }
        !          62906: 
        !          62907:        /*
        !          62908:         * Process rawin buf.
        !          62909:         */
        !          62910:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          62911: 
        !          62912:                ttin( tp, tp->t_rawin.si_buf[ tp->t_rawin.si_ox ] );
        !          62913: 
        !          62914:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          62915:                        tp->t_rawin.si_ox = 0;
        !          62916:                else
        !          62917:                        tp->t_rawin.si_ox++;
        !          62918:        }
        !          62919: 
        !          62920:        /*
        !          62921:         * Calculate free output slot count.
        !          62922:         */
        !          62923:        resid  = sizeof(tp->t_rawout.si_buf) - 1;
        !          62924:        resid += tp->t_rawout.si_ox - tp->t_rawout.si_ix;
        !          62925:        resid %= sizeof(tp->t_rawout.si_buf);
        !          62926: 
        !          62927:        /*
        !          62928:         * Fill raw output buffer.
        !          62929:         */
        !          62930:        while ( (--resid >= 0) && ((c = ttout(tp)) >= 0) ) {
        !          62931: 
        !          62932:                tp->t_rawout.si_buf[ tp->t_rawout.si_ix ] = c;
        !          62933: 
        !          62934:                if ( tp->t_rawout.si_ix >= sizeof(tp->t_rawout.si_buf) - 1 )
        !          62935:                        tp->t_rawout.si_ix = 0;
        !          62936:                else
        !          62937:                        tp->t_rawout.si_ix++;
        !          62938:        }
        !          62939: 
        !          62940:        /*
        !          62941:         * (Re)start output, waking processes waiting to output, etc.
        !          62942:         */
        !          62943:        ttstart( tp );
        !          62944: 
        !          62945:        /*
        !          62946:         * Schedule next cycle.
        !          62947:         */
        !          62948:        if ( tp->t_open != 0 )
        !          62949:                timeout( &tp->t_rawtim, HZ/10, hscycle, tp );
        !          62950: }
        !          62951: 
        !          62952: /*
        !          62953:  * Clock Interrupt driven Polling routine.
        !          62954:  */
        !          62955: hsintr()
        !          62956: {
        !          62957:        register TTY * tp = &hstty[0];
        !          62958:        register int b;
        !          62959:        char msr_ch;
        !          62960: 
        !          62961:        do {
        !          62962:                int port = PORT, port_num = PORT_NUM;   /* for speed */
        !          62963: 
        !          62964:                if ( tp->t_open == 0 )
        !          62965:                        continue;
        !          62966: 
        !          62967:                /*
        !          62968:                 * Check modem status if modem control is enabled.
        !          62969:                 */
        !          62970:                if ( tp->t_flags & T_MODC ) {
        !          62971: 
        !          62972:                        msr_ch = inb(port + MSR);
        !          62973:                        msr[port_num] |= msr_ch & MSR_DELTAS; 
        !          62974: 
        !          62975:                        if ( msr[port_num] & MS_DCTS ) {
        !          62976:                                msr[port_num] &= ~MS_DCTS;
        !          62977:                                if ( msr_ch & MS_CTS )
        !          62978:                                        tp->t_flags &= ~T_STOP;
        !          62979:                                else
        !          62980:                                        tp->t_flags |=  T_STOP;
        !          62981:                        }
        !          62982:                }
        !          62983: 
        !          62984:                b = inb( port+LSR );
        !          62985: 
        !          62986:                if ( (b & LS_BREAK) && (tp->t_flags & T_CARR) )
        !          62987:                        ttsignal( tp, SIGINT );
        !          62988: 
        !          62989:                /*
        !          62990:                 * Receive ready.
        !          62991:                 */
        !          62992:                if ( b & LS_RxRDY ) {
        !          62993: 
        !          62994:                        tp->t_rawin.si_buf[tp->t_rawin.si_ix] = inb(port+DREG);
        !          62995: 
        !          62996:                        if ( tp->t_flags & T_CARR ) {
        !          62997: 
        !          62998:                                if ( ++(tp->t_rawin.si_ix) >=
        !          62999:                                                sizeof(tp->t_rawin.si_buf) )
        !          63000:                                        tp->t_rawin.si_ix = 0;
        !          63001:                        }
        !          63002:                }
        !          63003: 
        !          63004:                /*
        !          63005:                 * Transmit ready and raw output data exists.
        !          63006:                 */
        !          63007:                if ( (b & LS_TxRDY) && ((tp->t_flags & T_STOP) == 0)
        !          63008:                  && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          63009: 
        !          63010:                        outb(port+DREG,
        !          63011:                                tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          63012: 
        !          63013:                        if ( ++(tp->t_rawout.si_ox) >=
        !          63014:                                        sizeof(tp->t_rawout.si_buf) )
        !          63015:                                tp->t_rawout.si_ox = 0;
        !          63016:                }
        !          63017: 
        !          63018:        } while ( ++tp <= hslimtty );
        !          63019: }
        !          63020: 
        !          63021: /*
        !          63022:  * Set hardware parameters.
        !          63023:  */
        !          63024: hsparam( tp )
        !          63025: register TTY * tp;
        !          63026: {
        !          63027:        register int b;
        !          63028:        int s;
        !          63029: 
        !          63030:        s = sphi();
        !          63031:        /*
        !          63032:         * Assert required modem control lines (DTR, RTS).
        !          63033:         */
        !          63034:        b = 0;
        !          63035:        if ( tp->t_sgttyb.sg_ospeed != B0 )
        !          63036:                b |=  MC_DTR | MC_RTS;
        !          63037:        outb( PORT+MCR, b );
        !          63038: 
        !          63039:        /*
        !          63040:         * Program baud rate.
        !          63041:         */
        !          63042:        if (b = timeconst[ tp->t_sgttyb.sg_ospeed ]) {
        !          63043:                outb( PORT+LCR, LC_DLAB );
        !          63044:                outb( PORT+DLL, b );
        !          63045:                outb( PORT+DLH, b >> 8 );
        !          63046:        }
        !          63047: 
        !          63048:        /*
        !          63049:         * Program character size, parity.
        !          63050:         */
        !          63051:        switch ( tp->t_sgttyb.sg_flags & (EVENP|ODDP|RAW) ) {
        !          63052:        case ODDP:              b = LC_CS7|LC_PARENB;            break;
        !          63053:        case EVENP:             b = LC_CS7|LC_PARENB|LC_PAREVEN; break;
        !          63054:        default:                b = LC_CS8;                      break;
        !          63055:        }
        !          63056:        outb( PORT+LCR, b );
        !          63057: 
        !          63058:        /*
        !          63059:         * Enable Transmit Buffer Empty Interrupts.
        !          63060:         */
        !          63061:        outb( PORT+IER, IE_TxI );
        !          63062: 
        !          63063:        spl(s);
        !          63064:        set_poll_rate();
        !          63065: }
        !          63066: 
        !          63067: /*
        !          63068:  * Start Routine.
        !          63069:  */
        !          63070: hsstart( tp )
        !          63071: register TTY * tp;
        !          63072: {
        !          63073:        register int s;
        !          63074: 
        !          63075:        /*
        !          63076:         * Transmit buffer is empty, and raw output buffer is not.
        !          63077:         */
        !          63078:        s = sphi();
        !          63079:        if ( (inb( PORT+LSR ) & LS_TxRDY)
        !          63080:          && (tp->t_rawout.si_ix != tp->t_rawout.si_ox) ) {
        !          63081: 
        !          63082:                /*
        !          63083:                 * Send next char from raw output buffer.
        !          63084:                 */
        !          63085:                outb( PORT+DREG, tp->t_rawout.si_buf[ tp->t_rawout.si_ox ] );
        !          63086: 
        !          63087:                if ( ++tp->t_rawout.si_ox >= sizeof(tp->t_rawout.si_buf) )
        !          63088:                        tp->t_rawout.si_ox = 0;
        !          63089:        }
        !          63090:        spl( s );
        !          63091: }
        !          63092: 
        !          63093: /*
        !          63094:  * hsclk will be called every time T0 interrupts - if it returns 0,
        !          63095:  * the usual system timer interrupt stuff is done
        !          63096:  */
        !          63097: static int hsclk()
        !          63098: {
        !          63099:   static int count;
        !          63100: 
        !          63101:   hsintr();
        !          63102:   count++;
        !          63103:   if (count >= poll_divisor)
        !          63104:     count = 0;
        !          63105:   return count;
        !          63106: }
        !          63107: 
        !          63108: /*
        !          63109:  * set_poll_rate is called when a port is opened or closed or changes speed
        !          63110:  * it sets the polling rate only as fast as needed, and shuts off polling
        !          63111:  * whenever possible
        !          63112:  */
        !          63113: static set_poll_rate()
        !          63114: {
        !          63115:        int port_num, max_rate, port_rate;
        !          63116: printf("set_poll_rate()\n");
        !          63117: 
        !          63118:        /*
        !          63119:         * If another driver has the polling clock, do nothing.
        !          63120:         */
        !          63121:        if (poll_owner & ~ POLL_HS)
        !          63122:                return;
        !          63123: 
        !          63124:        /*
        !          63125:         * find highest valid polling rate in units of HZ/10
        !          63126:         */
        !          63127:        max_rate = 0;
        !          63128:        for (port_num = 0; port_num < HSNUM; port_num++) {
        !          63129:                if (hstty[port_num].t_open) {
        !          63130:                  port_rate = poll_hz[hstty[port_num].t_sgttyb.sg_ispeed];
        !          63131: printf("port %d  rate=%d\n", port_num, port_rate);               
        !          63132:                  if (max_rate < port_rate)
        !          63133:                        max_rate = port_rate;
        !          63134:                }
        !          63135:        }
        !          63136:        /*
        !          63137:         * if max_rate is not current rate, adjust the system clock
        !          63138:         */
        !          63139:        if (max_rate != poll_rate) {
        !          63140:                poll_rate = max_rate;
        !          63141:                poll_divisor = poll_rate/HZ;  /* used in hsclk() */
        !          63142:                altclk_out();           /* stop previous polling */
        !          63143: printf("altclk_out()\n");              
        !          63144:                poll_owner &= ~POLL_HS;
        !          63145:                if (max_rate) { /* resume polling at new rate if needed */
        !          63146:                        altclk_in(poll_rate, hsclk);
        !          63147: printf("altclk_in(%d, hsclk)\n", poll_rate);                   
        !          63148:                        poll_owner |= POLL_HS;
        !          63149:                }
        !          63150:        }
        !          63151: }
        !          63152: @
        !          63153: 0707070064030104271004440000030000030000011777770507310673500005500000004443/newbits/kernel/USRSRC/i8086/drv/RCS/ipc.c,vhead     1.4;
        !          63154: branch   ;
        !          63155: access   ;
        !          63156: symbols  ;
        !          63157: locks    bin:1.4; strict;
        !          63158: comment  @ * @;
        !          63159: 
        !          63160: 
        !          63161: 1.4
        !          63162: date     91.06.20.14.50.14;  author bin;  state Exp;
        !          63163: branches ;
        !          63164: next     1.3;
        !          63165: 
        !          63166: 1.3
        !          63167: date     91.06.18.08.12.14;  author bin;  state Exp;
        !          63168: branches ;
        !          63169: next     1.2;
        !          63170: 
        !          63171: 1.2
        !          63172: date     91.06.17.12.31.52;  author bin;  state Exp;
        !          63173: branches ;
        !          63174: next     1.1;
        !          63175: 
        !          63176: 1.1
        !          63177: date     91.06.10.10.23.12;  author bin;  state Exp;
        !          63178: branches ;
        !          63179: next     ;
        !          63180: 
        !          63181: 
        !          63182: desc
        !          63183: @initial version prov by hal
        !          63184: @
        !          63185: 
        !          63186: 
        !          63187: 1.4
        !          63188: log
        !          63189: @update provided by hal
        !          63190: @
        !          63191: text
        !          63192: @/* $Header: /usr/src/sys/i8086/drv/RCS/ipc.c,v 2.1 88/09/03 13:06:15 src Exp $
        !          63193:  *
        !          63194:  *     The  information  contained herein  is a trade secret  of INETCO
        !          63195:  *     Systems, and is confidential information.   It is provided under
        !          63196:  *     a license agreement,  and may be copied or disclosed  only under
        !          63197:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          63198:  *     this  material  without  the express  written  authorization  of
        !          63199:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          63200:  *
        !          63201:  *     Copyright (c) 1985
        !          63202:  *     An unpublished work by INETCO Systems, Ltd.
        !          63203:  *     All rights reserved.
        !          63204:  */
        !          63205: 
        !          63206: /*
        !          63207:  * Inter-Process Communication.
        !          63208:  *
        !          63209:  * $Log:       /usr/src/sys/i8086/drv/RCS/ipc.c,v $
        !          63210:  * Revision 2.1        88/09/03  13:06:15      src
        !          63211:  * *** empty log message ***
        !          63212:  * 
        !          63213:  * Revision 1.1        88/03/24  17:05:02      src
        !          63214:  * Initial revision
        !          63215:  * 
        !          63216:  */
        !          63217: #include <coherent.h>
        !          63218: #include <sys/ipc.h>
        !          63219: #include <sys/uproc.h>
        !          63220: 
        !          63221: /*
        !          63222:  * Determine Inter-Process Communication Access Permissions.
        !          63223:  *
        !          63224:  *     Input:  p = pointer to inter-process communication permission struct.
        !          63225:  *
        !          63226:  *     Action: If super user, permissions are 0600.
        !          63227:  *             If uid is that of the creator or owner of the message id,
        !          63228:  *                     use user permissions.
        !          63229:  *             If gid is that of the creator or owner of the message id,
        !          63230:  *                     use group permissions.
        !          63231:  *             Otherwise, use others permissions.
        !          63232:  *
        !          63233:  *     Output: 0600 = Read/Alter permission.
        !          63234:  *             0400 = Read permission.
        !          63235:  *             0200 = Alter permission.
        !          63236:  *                0 = No permission.
        !          63237:  */
        !          63238: 
        !          63239: ipcaccess( p )
        !          63240: 
        !          63241: register struct ipc_perm * p;
        !          63242: 
        !          63243: {
        !          63244:        if ( u.u_uid == 0 )
        !          63245:                return 0600;
        !          63246: 
        !          63247:        if ((u.u_uid == p->uid) || (u.u_uid == p->cuid))
        !          63248:                return p->mode & 0600;
        !          63249: 
        !          63250:        if ((u.u_gid == p->gid) || (u.u_gid == p->cgid))
        !          63251:                return (p->mode << 3) & 0600;
        !          63252: 
        !          63253:        return (p->mode << 6) & 0600;
        !          63254: }
        !          63255: @
        !          63256: 
        !          63257: 
        !          63258: 1.3
        !          63259: log
        !          63260: @update provided by hal
        !          63261: @
        !          63262: text
        !          63263: @@
        !          63264: 
        !          63265: 
        !          63266: 1.2
        !          63267: log
        !          63268: @new version provided y hal for v321
        !          63269: @
        !          63270: text
        !          63271: @@
        !          63272: 
        !          63273: 
        !          63274: 1.1
        !          63275: log
        !          63276: @Initial revision
        !          63277: @
        !          63278: text
        !          63279: @@
        !          63280: 0707070064030106671004440000030000030000011777770507310673500005700000010524/newbits/kernel/USRSRC/i8086/drv/RCS/ipcas.s,vhead     1.2;
        !          63281: branch   ;
        !          63282: access   ;
        !          63283: symbols  ;
        !          63284: locks    bin:1.2; strict;
        !          63285: comment  @@;
        !          63286: 
        !          63287: 
        !          63288: 1.2
        !          63289: date     91.06.20.14.50.17;  author bin;  state Exp;
        !          63290: branches ;
        !          63291: next     1.1;
        !          63292: 
        !          63293: 1.1
        !          63294: date     91.06.10.10.23.14;  author bin;  state Exp;
        !          63295: branches ;
        !          63296: next     ;
        !          63297: 
        !          63298: 
        !          63299: desc
        !          63300: @initial version prov by hal
        !          63301: @
        !          63302: 
        !          63303: 
        !          63304: 1.2
        !          63305: log
        !          63306: @update provided by hal
        !          63307: @
        !          63308: text
        !          63309: @/ $Header: /usr/src/sys/i8086/drv/RCS/ipcas.s,v 2.1 88/09/03 13:06:24 src Exp $
        !          63310: /
        !          63311: /      The  information  contained herein  is a trade secret  of INETCO
        !          63312: /      Systems, and is confidential information.   It is provided under
        !          63313: /      a license agreement,  and may be copied or disclosed  only under
        !          63314: /      the terms of that agreement.   Any reproduction or disclosure of
        !          63315: /      this  material  without  the express  written  authorization  of
        !          63316: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          63317: /
        !          63318: /      Copyright (c) 1985, 1984
        !          63319: /      An unpublished work by INETCO Systems, Ltd.
        !          63320: /      All rights reserved.
        !          63321: /
        !          63322: 
        !          63323: ////////
        !          63324: /
        !          63325: / System V Compatible Inter-Process Communication - Assembler Support
        !          63326: /
        !          63327: / ufcopy( base, off, sel, n ) -- copy n bytes from user base to sel:off.
        !          63328: / fucopy( off, sel, base, n ) -- copy n bytes from sel:off to user base.
        !          63329: /
        !          63330: / $Log:        /usr/src/sys/i8086/drv/RCS/ipcas.s,v $
        !          63331: / Revision 2.1 88/09/03  13:06:24      src
        !          63332: / *** empty log message ***
        !          63333: / 
        !          63334: / Revision 1.1 88/03/24  17:05:05      src
        !          63335: / Initial revision
        !          63336: / 
        !          63337: /
        !          63338: / 85/07/19     Allan Cornish
        !          63339: / Inserted code to check user address for validity.
        !          63340: / Functions ufcopy and fucopy now return 0 if user address is invalid.
        !          63341: / Replaced 'jnc .+2;movsb' with 'rcl cx,$1;rep movsb' to improve pipelining.
        !          63342: /
        !          63343: / 85/07/03     Allan Cornish
        !          63344: / Functions renamed: uoscopy --> ufcopy, osucopy --> fucopy (f = far).
        !          63345: / Module moved from msgas.s to ipcas.s, to reflect its shared use.
        !          63346: /
        !          63347: ////////
        !          63348: 
        !          63349:        .globl  ufcopy_
        !          63350:        .globl  fucopy_
        !          63351: 
        !          63352: ////////
        !          63353: /
        !          63354: / ufcopy( base, off, sel, n )  -- copy n bytes from user base to sel:off.
        !          63355: /
        !          63356: /      Input:  base = offset in user memory to copy from
        !          63357: /              off  = offset in the destination segment
        !          63358: /              sel  = selector to access the destination segment
        !          63359: /              n    = number of bytes to copy
        !          63360: /
        !          63361: /      Action: Copy 'n' bytes of data from offset 'base' in user memory
        !          63362: /              to offset 'off' in the segment accessed by selector 'sel'.
        !          63363: /
        !          63364: /      Return: Number of bytes copied, or 0 if invalid user address.
        !          63365: /
        !          63366: ////////
        !          63367: 
        !          63368: ufcopy_:                       / ufcopy( base, off, sel, n )
        !          63369:        push    si              /
        !          63370:        push    di              / unsigned base;
        !          63371:        push    bp              / unsigned off;
        !          63372:        mov     bp, sp          / saddr_t sel;
        !          63373:        push    ds              / unsigned n;
        !          63374:        push    es              /
        !          63375:                                / {
        !          63376:        mov     ax, 8(bp)       /       Validate user address.
        !          63377:        dec     ax              /
        !          63378:        add     ax, 14(bp)      /       Wrap-around error?
        !          63379:        jc      fuerr           /
        !          63380:        cmp     ax, udl_        /       Address out of bounds error?
        !          63381:        ja      fuerr           /
        !          63382:                                /
        !          63383:        mov     bx, uds_        /       Map DS:SI into user (source) addr
        !          63384:        mov     ds, bx          /
        !          63385:        mov     si, 8(bp)       /
        !          63386:        les     di, 10(bp)      /       Map ES:DI into segment (dest) addr
        !          63387:        mov     cx, 14(bp)      /       Transfer count
        !          63388:                                /
        !          63389:        cld                     /       Auto Increment
        !          63390:        clc                     /
        !          63391:        rcr     cx, $1          /       Change byte count into word count
        !          63392:        rep                     /       Transfer data words
        !          63393:        movsw                   /
        !          63394:        rcl     cx, $1          /       If residual byte count
        !          63395:        rep                     /               Transfer last data byte.
        !          63396:        movsb                   /
        !          63397:                                /
        !          63398:        mov     ax, 14(bp)      /       Return transfer count.
        !          63399:        pop     es              / }
        !          63400:        pop     ds
        !          63401:        pop     bp
        !          63402:        pop     di
        !          63403:        pop     si
        !          63404:        ret
        !          63405: 
        !          63406: fuerr: sub     ax, ax
        !          63407:        pop     es
        !          63408:        pop     ds
        !          63409:        pop     bp
        !          63410:        pop     di
        !          63411:        pop     si
        !          63412:        ret
        !          63413: 
        !          63414: ////////
        !          63415: /
        !          63416: / fucopy( off, sel, base, n )  -- copy n bytes from sel:off to user base.
        !          63417: /
        !          63418: /      Input:  off  = offset is the source segment
        !          63419: /              sel  = selector to access the source segment
        !          63420: /              base = offset in user memory to copy to
        !          63421: /              n    = number of bytes to copy
        !          63422: /
        !          63423: /      Action: Copy 'n' bytes of data from offset 'off' in the segment
        !          63424: /              accessed by selector 'sel' to offset 'base' in user memory.
        !          63425: /
        !          63426: /      Return: Number of bytes copied, or 0 if invalid user address.
        !          63427: /
        !          63428: ////////
        !          63429: 
        !          63430: fucopy_:                       / fucopy( off, sel, base, n )
        !          63431:        push    si              /
        !          63432:        push    di              / unsigned off;
        !          63433:        push    bp              / saddr_t  sel;
        !          63434:        mov     bp, sp          / unsigned base;
        !          63435:        push    ds              / unsigned n;
        !          63436:        push    es              /
        !          63437:                                / {
        !          63438:        mov     ax, 12(bp)      /       Validate user address.
        !          63439:        dec     ax              /
        !          63440:        add     ax, 14(bp)      /       Wrap-around error?
        !          63441:        jc      fuerr           /
        !          63442:        cmp     ax, udl_        /       Address out of bounds error?
        !          63443:        ja      fuerr           /
        !          63444:                                /
        !          63445:        mov     es, uds_        /       Map ES:DI into user (dest) address
        !          63446:        mov     di, 12(bp)      /
        !          63447:        lds     si, 8(bp)       /       Map DS:SI into segment (source) addr
        !          63448:        mov     cx, 14(bp)      /       Transfer count
        !          63449:                                /
        !          63450:        cld                     /       Auto Increment
        !          63451:        clc                     /
        !          63452:        rcr     cx, $1          /       Change byte count into word count
        !          63453:        rep                     /
        !          63454:        movsw                   /       Transfer data words
        !          63455:        rcl     cx, $1          /       If residual byte count
        !          63456:        rep                     /               Transfer last data byte.
        !          63457:        movsb                   /
        !          63458:                                /
        !          63459:        mov     ax, 14(bp)      /       Return transfer count.
        !          63460:        pop     es              / }
        !          63461:        pop     ds
        !          63462:        pop     bp
        !          63463:        pop     di
        !          63464:        pop     si
        !          63465:        ret
        !          63466: @
        !          63467: 
        !          63468: 
        !          63469: 1.1
        !          63470: log
        !          63471: @Initial revision
        !          63472: @
        !          63473: text
        !          63474: @@
        !          63475: 0707070064030054731004440000000000000000011777770507310673700005400000044213/newbits/kernel/USRSRC/i8086/drv/RCS/kb.c,vhead     1.2;
        !          63476: branch   ;
        !          63477: access   ;
        !          63478: symbols  ;
        !          63479: locks    bin:1.2; strict;
        !          63480: comment  @ * @;
        !          63481: 
        !          63482: 
        !          63483: 1.2
        !          63484: date     91.07.03.13.18.48;  author bin;  state Exp;
        !          63485: branches ;
        !          63486: next     1.1;
        !          63487: 
        !          63488: 1.1
        !          63489: date     91.06.10.10.23.18;  author bin;  state Exp;
        !          63490: branches ;
        !          63491: next     ;
        !          63492: 
        !          63493: 
        !          63494: desc
        !          63495: @initial version prov by hal
        !          63496: @
        !          63497: 
        !          63498: 
        !          63499: 1.2
        !          63500: log
        !          63501: @update provided by hal
        !          63502: @
        !          63503: text
        !          63504: @/* (-lgl
        !          63505:  *     COHERENT Driver Kit Version 1.1.0
        !          63506:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          63507:  *     All rights reserved. May not be copied without permission.
        !          63508:  -lgl) */
        !          63509: /*
        !          63510:  * Keyboard/display driver.
        !          63511:  * Coherent, IBM PC/XT/AT.
        !          63512:  */
        !          63513: #include <sys/coherent.h>
        !          63514: #include <sys/i8086.h>
        !          63515: #include <sys/con.h>
        !          63516: #include <errno.h>
        !          63517: #include <sys/stat.h>
        !          63518: #include <sys/tty.h>
        !          63519: #include <sys/uproc.h>
        !          63520: #include <signal.h>
        !          63521: #include <sys/sched.h>
        !          63522: 
        !          63523: #define        ISMAJ   2                       /* Keyboard major device */
        !          63524: 
        !          63525: #define        SPC     0376                    /* Special encoding */
        !          63526: #define XXX    0377                    /* Non-character */
        !          63527: #define        KBDATA  0x60                    /* Keyboard data */
        !          63528: #define        KBCTRL  0x61                    /* Keyboard control */
        !          63529: #define        KBFLAG  0x80                    /* Keyboard reset flag */
        !          63530: #define        LEDCMD  0xED                    /* status indicator command */
        !          63531: #define        KBACK   0xFA                    /* status indicator acknowledge */
        !          63532: #define        EXTENDED1 0xE1                  /* extended key seq initiator */
        !          63533: 
        !          63534: #define        KEYUP   0x80                    /* Key up change */
        !          63535: #define        KEYSC   0x7F                    /* Key scan code mask */
        !          63536: #define        LSHIFT  0x2A-1                  /* Left shift key */
        !          63537: #define LSHIFTA 0x2B-1                 /* Alternate left-shift key */
        !          63538: #define        RSHIFT  0x36-1                  /* Right shift key */
        !          63539: #define        CTRL    0x1D-1                  /* Control key */
        !          63540: /*-- #define   CAPLOCK 0x1D-1  --*/            /* Control key */
        !          63541: #define        ALT     0x38-1                  /* Alt key */
        !          63542: #define        CAPLOCK 0x3A-1                  /* Caps lock key */
        !          63543: /*-- #define   CTRL    0x3A-1  --*/            /* Caps lock key */
        !          63544: #define        NUMLOCK 0x45-1                  /* Numeric lock key */
        !          63545: #define        DELETE  0x53-1                  /* Del, as in CTRL-ALT-DEL */
        !          63546: #define BACKSP 0x0E-1                  /* Back space */
        !          63547: #define SCRLOCK        0x46-1                  /* Scroll lock */
        !          63548: 
        !          63549: /* Shift flags */
        !          63550: #define        SRS     0x01                    /* Right shift key on */
        !          63551: #define        SLS     0x02                    /* Left shift key on */
        !          63552: #define CTS    0x04                    /* Ctrl key on */
        !          63553: #define ALS    0x08                    /* Alt key on */
        !          63554: #define CPLS   0x10                    /* Caps lock on */
        !          63555: #define NMLS   0x20                    /* Num lock on */
        !          63556: #define AKPS   0x40                    /* Alternate keypad shift */
        !          63557: #define SHFT   0x80                    /* Shift key flag */
        !          63558: 
        !          63559: /* Function key information */
        !          63560: #define        NFKEY   20                      /* Number of settable functions */
        !          63561: #define        NFCHAR  150                     /* Number of characters settable */
        !          63562: #define        NFBUF   (NFKEY*2+NFCHAR+1)      /* Size of buffer */
        !          63563: 
        !          63564: /*
        !          63565:  * Functions.
        !          63566:  */
        !          63567: int    isrint();
        !          63568: int    istime();
        !          63569: void   isbatch();
        !          63570: int    mmstart();
        !          63571: int    isopen();
        !          63572: int    isclose();
        !          63573: int    isread();
        !          63574: int    mmwrite();
        !          63575: int    isioctl();
        !          63576: void   mmwatch();
        !          63577: int    isload();
        !          63578: int    isuload();
        !          63579: int    ispoll();
        !          63580: int    nulldev();
        !          63581: int    nonedev();
        !          63582: 
        !          63583: /*
        !          63584:  * Configuration table.
        !          63585:  */
        !          63586: CON iscon ={
        !          63587:        DFCHR|DFPOL,                    /* Flags */
        !          63588:        ISMAJ,                          /* Major index */
        !          63589:        isopen,                         /* Open */
        !          63590:        isclose,                        /* Close */
        !          63591:        nulldev,                        /* Block */
        !          63592:        isread,                         /* Read */
        !          63593:        mmwrite,                        /* Write */
        !          63594:        isioctl,                        /* Ioctl */
        !          63595:        nulldev,                        /* Powerfail */
        !          63596:        mmwatch,                        /* Timeout */
        !          63597:        isload,                         /* Load */
        !          63598:        isuload,                        /* Unload */
        !          63599:        ispoll                          /* Poll */
        !          63600: };
        !          63601: 
        !          63602: /*
        !          63603:  * Flag indicating turbo machine.
        !          63604:  */
        !          63605: int isturbo = 0;
        !          63606: 
        !          63607: /*
        !          63608:  * Terminal structure.
        !          63609:  */
        !          63610: TTY    istty = {
        !          63611:        {0}, {0}, 0, mmstart, NULL, 0, 0
        !          63612: };
        !          63613: 
        !          63614: /*
        !          63615:  * State variables.
        !          63616:  */
        !          63617: int            islock;                 /* Keyboard locked flag */
        !          63618: int            isbusy;                 /* Raw input conversion busy */
        !          63619: static char    shift;                  /* Overall shift state */
        !          63620: static char    scroll;                 /* Scroll lock state */
        !          63621: static  char   lshift = LSHIFT;        /* Left shift alternate state */
        !          63622: static char    isfbuf[NFBUF];          /* Function key values */
        !          63623: static char    *isfval[NFKEY];         /* Function key string pointers */
        !          63624: static int     ledcmd;                 /* LED update command flag */
        !          63625: static int     extended;               /* extended key scan count */
        !          63626: 
        !          63627: /*
        !          63628:  * Tables for converting key code to ASCII.
        !          63629:  * lmaptab specifies unshifted conversion,
        !          63630:  * umaptab specifies shifted conversion,
        !          63631:  * smaptab specifies the shift states which are active.
        !          63632:  * An entry of XXX says the key is dead.
        !          63633:  * An entry of SPC requires further processing.
        !          63634:  *
        !          63635:  * Key codes:
        !          63636:  *     ESC .. <- == 1 .. 14
        !          63637:  *     -> .. \n == 15 .. 28
        !          63638:  *     CTRL .. ` == 29 .. 41
        !          63639:  *     ^Shift .. PrtSc == 42 .. 55
        !          63640:  *     ALT .. CapsLock == 56 .. 58
        !          63641:  *     F1 .. F10 == 59 .. 68
        !          63642:  *     NumLock .. Del == 69 .. 83
        !          63643:  */
        !          63644: static unsigned char lmaptab[] ={
        !          63645:             '\33',  '1',  '2',  '3',  '4',  '5',  '6',         /* 1 - 7 */
        !          63646:         '7',  '8',  '9',  '0',  '-',  '=', '\b', '\t',         /* 8 - 15 */
        !          63647:         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',         /* 16 - 23 */
        !          63648:         'o',  'p',  '[',  ']', '\r',  XXX,  'a',  's',         /* 24 - 31 */
        !          63649:         'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',         /* 32 - 39 */
        !          63650:         '\'', '`',  XXX,  '\\',  'z',  'x',  'c',  'v',        /* 40 - 47 */
        !          63651:         'b',  'n',  'm',  ',',  '.',  '/',  XXX,  '*',         /* 48 - 55 */
        !          63652:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
        !          63653:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
        !          63654:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
        !          63655:         SPC,  SPC,  SPC,  SPC                                  /* 80 - 83 */
        !          63656: };
        !          63657: 
        !          63658: static unsigned char umaptab[] ={
        !          63659:             '\33',  '!',  '@@',  '#',  '$',  '%',  '^',                /* 1 - 7 */
        !          63660:         '&',  '*',  '(',  ')',  '_',  '+', '\b', SPC,          /* 8 - 15 */
        !          63661:         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',         /* 16 - 23 */
        !          63662:         'O',  'P',  '{',  '}', '\r',  XXX,  'A',  'S',         /* 24 - 31 */
        !          63663:         'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',         /* 32 - 39 */
        !          63664:         '"',  '~',  XXX,  '|',  'Z',  'X',  'C',  'V',         /* 40 - 47 */
        !          63665:         'B',  'N',  'M',  '<',  '>',  '?',  XXX,  '*',         /* 48 - 55 */
        !          63666:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
        !          63667:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
        !          63668:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
        !          63669:         SPC,  SPC,  SPC,  SPC                                  /* 80 - 83 */
        !          63670: };
        !          63671: 
        !          63672: #define SS0    0                       /* No shift */
        !          63673: #define SS1    (SLS|SRS|CTS)           /* Shift, Ctrl */
        !          63674: #define SES    (SLS|SRS)               /* Shift */
        !          63675: #define LET    (SLS|SRS|CPLS|CTS)      /* Shift, Caps, Ctrl */
        !          63676: #define KEY    (SLS|SRS|NMLS|AKPS)     /* Shift, Num, Alt keypad */
        !          63677: 
        !          63678: static unsigned char smaptab[] ={
        !          63679:               SS0,  SES,  SS1,  SES,  SES,  SES,  SS1,         /* 1 - 7 */
        !          63680:         SES,  SES,  SES,  SES,  SS1,  SES,  CTS,  SES,         /* 8 - 15 */
        !          63681:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  LET,         /* 16 - 23 */
        !          63682:         LET,  LET,  SS1,  SS1,  CTS, SHFT,  LET,  LET,         /* 24 - 31 */
        !          63683:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  SES,         /* 32 - 39 */
        !          63684:         SES,  SS1, SHFT,  SS1,  LET,  LET,  LET,  LET,         /* 40 - 47 */
        !          63685:         LET,  LET,  LET,  SES,  SES,  SES, SHFT,  SES,         /* 48 - 55 */
        !          63686:        SHFT,  SS1, SHFT,  SS0,  SS0,  SS0,  SS0,  SS0,         /* 56 - 63 */
        !          63687:         SS0,  SS0,  SS0,  SS0,  SS0, SHFT,  KEY,  KEY,         /* 64 - 71 */
        !          63688:         KEY,  KEY,  SS0,  KEY,  KEY,  KEY,  SS0,  KEY,         /* 72 - 79 */
        !          63689:         KEY,  KEY,  KEY,  KEY                                  /* 80 - 83 */
        !          63690: };
        !          63691: 
        !          63692: /*
        !          63693:  * Load entry point.
        !          63694:  *  Do reset the keyboard because it gets terribly munged
        !          63695:  *  if you type during the boot.
        !          63696:  */
        !          63697: isload()
        !          63698: {
        !          63699:        register int i;
        !          63700: 
        !          63701:        /*
        !          63702:         * Reset keyboard if NOT an XT turbo.
        !          63703:         */
        !          63704:        if ( ! isturbo ) {
        !          63705:                outb(KBCTRL, 0x0C);             /* Clock low */
        !          63706:                for (i = 10582; --i >= 0; );    /* For 20ms */
        !          63707:                outb(KBCTRL, 0xCC);             /* Clock high */
        !          63708:                for (i = 0; --i != 0; )
        !          63709:                        ;
        !          63710:                i = inb(KBDATA);
        !          63711:                outb(KBCTRL, 0xCC);                     /* Clear keyboard */
        !          63712:                outb(KBCTRL, 0x4D);                     /* Enable keyboard */
        !          63713:        }
        !          63714: 
        !          63715:        /*
        !          63716:         * Enable mmwatch() invocation every second.
        !          63717:         */
        !          63718:        drvl[ISMAJ].d_time = 1;
        !          63719: 
        !          63720:        /*
        !          63721:         * Seize keyboard interrupt.
        !          63722:         */
        !          63723:        setivec(1, isrint);
        !          63724: 
        !          63725:        /*
        !          63726:         * Initiailize video display.
        !          63727:         */
        !          63728:        mmstart( &istty );
        !          63729: }
        !          63730: 
        !          63731: /*
        !          63732:  * Unload entry point.
        !          63733:  */
        !          63734: isuload()
        !          63735: {
        !          63736:        clrivec(1);
        !          63737: }
        !          63738: 
        !          63739: /*
        !          63740:  * Default function key strings (terminated by -1 [\377])
        !          63741:  */
        !          63742: static char *deffuncs[] = {
        !          63743:        "\33[1x\377",   /* F1 */
        !          63744:        "\33[2x\377",   /* F2 */
        !          63745:        "\33[3x\377",   /* F3 */
        !          63746:        "\33[4x\377",   /* F4 */
        !          63747:        "\33[5x\377",   /* F5 */
        !          63748:        "\33[6x\377",   /* F6 */
        !          63749:        "\33[7x\377",   /* F7 */
        !          63750:        "\33[8x\377",   /* F8 */
        !          63751:        "\33[9x\377",   /* F9 */
        !          63752:        "\33[0x\377",   /* F10 - historical value */
        !          63753:        "\33[1y\377",   /* F11 */
        !          63754:        "\33[2y\377",   /* F12 */
        !          63755:        "\33[3y\377",   /* F13 */
        !          63756:        "\33[4y\377",   /* F14 */
        !          63757:        "\33[5y\377",   /* F15 */
        !          63758:        "\33[6y\377",   /* F16 */
        !          63759:        "\33[7y\377",   /* F17 */
        !          63760:        "\33[8y\377",   /* F18 */
        !          63761:        "\33[9y\377",   /* F19 */
        !          63762:        "\33[0y\377"    /* F20 */
        !          63763: };
        !          63764: 
        !          63765: /*
        !          63766:  * Open routine.
        !          63767:  */
        !          63768: isopen(dev)
        !          63769: dev_t dev;
        !          63770: {
        !          63771:        register int s;
        !          63772: 
        !          63773:        if (minor(dev) != 0) {
        !          63774:                u.u_error = ENXIO;
        !          63775:                return;
        !          63776:        }
        !          63777:        if ((istty.t_flags&T_EXCL)!=0 && super()==0) {
        !          63778:                u.u_error = ENODEV;
        !          63779:                return;
        !          63780:        }
        !          63781:        ttsetgrp(&istty, dev);
        !          63782: 
        !          63783:        s = sphi();
        !          63784:        if (istty.t_open++ == 0)
        !          63785:        {  initkeys();   /* init function keys */
        !          63786:           istty.t_flags = T_CARR;  /* indicate "carrier" */
        !          63787:           ttopen(&istty);
        !          63788:        }
        !          63789:        spl(s);
        !          63790:        updleds();                      /* update keyboard status LEDS */
        !          63791: }
        !          63792: 
        !          63793: /* Init function keys */
        !          63794: initkeys()
        !          63795: {      register int i;
        !          63796:        register char *cp1, *cp2;
        !          63797: 
        !          63798:        for (i=0; i<NFKEY; i++)
        !          63799:            isfval[i] = 0;          /* clear function key buffer */
        !          63800:        cp2 = isfbuf;               /* pointer to key buffer */   
        !          63801:        for (i=0; i<NFKEY; i++)
        !          63802:        {  isfval[i] = cp2;         /* save pointer to key string */
        !          63803:           cp1 = deffuncs[i];       /* get init string pointer */
        !          63804:           while ((*cp2++ = *cp1++) != -1)  /* copy key data */
        !          63805:             if (cp2 >= &isfbuf[NFBUF-3])   /* overflow? */
        !          63806:                return;
        !          63807:        }
        !          63808: }
        !          63809: 
        !          63810: /*
        !          63811:  * Close a tty.
        !          63812:  */
        !          63813: isclose(dev)
        !          63814: {
        !          63815:        register int s;
        !          63816: 
        !          63817:        s = sphi();
        !          63818:        if (--istty.t_open == 0)
        !          63819:        {       s = sphi();
        !          63820:                ttclose(&istty);
        !          63821:                spl(s);
        !          63822:        }
        !          63823: }
        !          63824: 
        !          63825: /*
        !          63826:  * Read routine.
        !          63827:  */
        !          63828: isread(dev, iop)
        !          63829: dev_t dev;
        !          63830: IO *iop;
        !          63831: {
        !          63832:        ttread(&istty, iop, 0);
        !          63833:        if (istty.t_oq.cq_cc)
        !          63834:                mmtime(&istty);
        !          63835: }
        !          63836: 
        !          63837: /*
        !          63838:  * Ioctl routine.
        !          63839:  */
        !          63840: isioctl(dev, com, vec)
        !          63841: dev_t dev;
        !          63842: struct sgttyb *vec;
        !          63843: {
        !          63844:        register int s;
        !          63845: 
        !          63846:        switch(com) {
        !          63847:        case TIOCSETF:
        !          63848:        case TIOCGETF:
        !          63849:                isfunction(com, (char *)vec);
        !          63850:                return;
        !          63851:        case TIOCSHIFT:   /* switch left-SHIFT and "\" */
        !          63852:                lshift = LSHIFTA;    /* alternate values */
        !          63853:                lmaptab[41] = '\\';
        !          63854:                lmaptab[42] = XXX;
        !          63855:                umaptab[41] = '|';
        !          63856:                umaptab[42] = XXX;
        !          63857:                smaptab[41] = SS1;
        !          63858:                smaptab[42] = SHFT;
        !          63859:                return;
        !          63860:        case TIOCCSHIFT:  /* normal (default) left-SHIFT and "\" */
        !          63861:                lshift = LSHIFT;     /* normal values */
        !          63862:                lmaptab[41] = XXX;
        !          63863:                lmaptab[42] = '\\';
        !          63864:                umaptab[41] = XXX;
        !          63865:                umaptab[42] = '|';
        !          63866:                smaptab[41] = SHFT;
        !          63867:                smaptab[42] = SS1;
        !          63868:                return;
        !          63869:        }
        !          63870:        s = sphi();
        !          63871:        ttioctl(&istty, com, vec);
        !          63872:        spl(s);
        !          63873: }
        !          63874: 
        !          63875: /*
        !          63876:  * Set and receive the function keys.
        !          63877:  */
        !          63878: isfunction(c, v)
        !          63879: int c;
        !          63880: char *v;
        !          63881: {
        !          63882:        register char *cp;
        !          63883:        register int i;
        !          63884: 
        !          63885:        if (c == TIOCGETF) {
        !          63886:                for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++)
        !          63887:                    putubd(v++, *cp);
        !          63888:        } else {
        !          63889:                for (i=0; i<NFKEY; i++)         /* zap current settings */
        !          63890:                        isfval[i] = 0;
        !          63891:                cp = isfbuf;                    /* pointer to key buffer */
        !          63892:                for (i=0; i<NFKEY; i++) {
        !          63893:                        isfval[i] = cp;         /* save pointer to key string */
        !          63894:                        while ((*cp++ = getubd(v++)) != -1)  /* copy key data */
        !          63895:                                if (cp >= &isfbuf[NFBUF-3])  /* overflow? */
        !          63896:                                        return;
        !          63897:                }
        !          63898:        }
        !          63899: }
        !          63900: 
        !          63901: 
        !          63902: /*
        !          63903:  * Poll routine.
        !          63904:  */
        !          63905: ispoll( dev, ev, msec )
        !          63906: dev_t dev;
        !          63907: int ev;
        !          63908: int msec;
        !          63909: {
        !          63910:        /*
        !          63911:         * Priority polls not supported.
        !          63912:         */
        !          63913:        ev &= ~POLLPRI;
        !          63914: 
        !          63915:        /*
        !          63916:         * Input poll failure.
        !          63917:         */
        !          63918:        if ( (ev & POLLIN) && (istty.t_iq.cq_cc == 0) ) {
        !          63919: 
        !          63920:                if ( msec != 0 )
        !          63921:                        pollopen( &istty.t_ipolls );
        !          63922: 
        !          63923:                /*
        !          63924:                 * Second look AFTER enabling monitor, avoiding interrupt race.
        !          63925:                 */
        !          63926:                if ( istty.t_iq.cq_cc == 0 )
        !          63927:                        ev &= ~POLLIN;
        !          63928:        }
        !          63929: 
        !          63930:        return ev;
        !          63931: }
        !          63932: 
        !          63933: /*
        !          63934:  * Receive interrupt.
        !          63935:  */
        !          63936: isrint()
        !          63937: {
        !          63938:        register int    c;
        !          63939:        register int    s;
        !          63940:        register int    r;
        !          63941:        int     savests;
        !          63942:        int     update_leds = 0;
        !          63943: 
        !          63944:        /*
        !          63945:         * Schedule raw input handler if not already active.
        !          63946:         */
        !          63947:        if ( isbusy == 0 ) {
        !          63948:                defer( isbatch, &istty );
        !          63949:                isbusy = 1;
        !          63950:        }
        !          63951: 
        !          63952:        /*
        !          63953:         * Pull character from the data
        !          63954:         * port. Pulse the KBFLAG in the control
        !          63955:         * port to reset the data buffer.
        !          63956:         */
        !          63957:        r = inb(KBDATA) & 0xFF;
        !          63958:        c = inb(KBCTRL);
        !          63959:        outb(KBCTRL, c|KBFLAG);
        !          63960:        outb(KBCTRL, c);
        !          63961: #if    KBDEBUG
        !          63962:        printf("kbd: %d\n", r);                 /* print scan code/direction */
        !          63963: #endif
        !          63964:        if (ledcmd) {
        !          63965:                ledcmd = 0;
        !          63966:                if (r == KBACK) {               /* output to status LEDS */
        !          63967:                        c = scroll & 1;
        !          63968:                        if (shift & NMLS)
        !          63969:                                c |= 2;
        !          63970:                        if (shift & CPLS)
        !          63971:                                c |= 4;
        !          63972:                        outb(KBDATA, c);
        !          63973:                }
        !          63974:                return;
        !          63975:        }
        !          63976:        if (extended > 0) {                     /* if multi-character seq, */
        !          63977:                --extended;                     /* ... ignore this char */
        !          63978:                return;
        !          63979:        }
        !          63980:        if (r == EXTENDED1) {                   /* ignore extended sequences */
        !          63981:                extended = 5;
        !          63982:                return;
        !          63983:        }
        !          63984:        if (r == 0xFF)
        !          63985:                return; /* Overrun */
        !          63986:        c = (r & KEYSC) - 1;
        !          63987:        /*
        !          63988:         * Check for reset.
        !          63989:         */
        !          63990:        if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS))
        !          63991:                boot();
        !          63992: 
        !          63993:        /*
        !          63994:         * Track "shift" keys.
        !          63995:         */
        !          63996:        s = smaptab[c];
        !          63997:        if (s&SHFT) {
        !          63998:                if (r&KEYUP) {                  /* "shift" released */
        !          63999:                        if (c == RSHIFT)
        !          64000:                                shift &= ~SRS;
        !          64001:                        else if (c == lshift)
        !          64002:                                shift &= ~SLS;
        !          64003:                        else if (c == CTRL)
        !          64004:                                shift &= ~CTS;
        !          64005:                        else if (c == ALT)
        !          64006:                                shift &= ~ALS;
        !          64007:                } else {                        /* "shift" pressed */
        !          64008:                        if (c == lshift)
        !          64009:                                shift |= SLS;
        !          64010:                        else if (c == RSHIFT)
        !          64011:                                shift |= SRS;
        !          64012:                        else if (c == CTRL)
        !          64013:                                shift |= CTS;
        !          64014:                        else if (c == ALT)
        !          64015:                                shift |= ALS;
        !          64016:                        else if (c == CAPLOCK) {
        !          64017:                                shift ^= CPLS;  /* toggle cap lock */
        !          64018:                                updleds();
        !          64019:                        } else if (c == NUMLOCK) {
        !          64020:                                shift ^= NMLS;  /* toggle num lock */
        !          64021:                                updleds();
        !          64022:                        }
        !          64023:                }
        !          64024:                return;
        !          64025:        }
        !          64026: 
        !          64027:        /*
        !          64028:         * No other key up codes of interest.
        !          64029:         */
        !          64030:        if (r&KEYUP)
        !          64031:                return;
        !          64032: 
        !          64033:        /*
        !          64034:         * If the tty is not open the character is
        !          64035:         * just tossed away.
        !          64036:         */
        !          64037:        if (istty.t_open == 0)
        !          64038:                return;
        !          64039: 
        !          64040:        /*
        !          64041:         * Map character, based on the
        !          64042:         * current state of the shift, control,
        !          64043:         * meta and lock flags.
        !          64044:         */
        !          64045:        if (shift & CTS) {
        !          64046:                if (s == CTS)                   /* Map Ctrl (BS | NL) */
        !          64047:                        c = (c == BACKSP) ? 0x7F : 0x0A;  
        !          64048:                else if (s==SS1 || s==LET)      /* Normal Ctrl map */
        !          64049:                        c = umaptab[c]&0x1F;    /* Clear bits 5-6 */
        !          64050:                else                            
        !          64051:                        return;                 /* Ignore this char */
        !          64052:        } else if (s &= shift) {
        !          64053:                if (shift & SES) {               /* if shift on */
        !          64054:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
        !          64055:                                c = lmaptab[c];  /* use unshifted */
        !          64056:                        else
        !          64057:                                c = umaptab[c];  /* use shifted */
        !          64058:                } else {                         /* if shift not on */
        !          64059:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
        !          64060:                                c = umaptab[c];  /* use shifted */
        !          64061:                        else
        !          64062:                                c = lmaptab[c];  /* use unshifted */
        !          64063:                }
        !          64064:        } else                                   
        !          64065:                c = lmaptab[c];                  /* use unshifted */
        !          64066: 
        !          64067:        /*
        !          64068:         * Act on character.
        !          64069:         */
        !          64070:        if (c == XXX)                           
        !          64071:                return;                          /* char to ignore */
        !          64072: 
        !          64073:        if (c != SPC) {                  /* not special char? */
        !          64074:                if (shift & ALS)         /* ALT (meta bit)? */
        !          64075:                        c |= 0x80;       /* set meta */
        !          64076:                isin(c);                 /* send the char */
        !          64077:        } else
        !          64078:                update_leds += isspecial(r);     /* special chars */
        !          64079:        if (update_leds) {
        !          64080:                savests = sphi();
        !          64081:                outb(KBDATA, LEDCMD);
        !          64082:                ledcmd = 1;
        !          64083:                spl(savests);
        !          64084:        }
        !          64085: }
        !          64086: 
        !          64087: /*
        !          64088:  * Handle special input sequences.
        !          64089:  * The character passed is the key number.
        !          64090:  *
        !          64091:  * The keypad is translated by the following table,
        !          64092:  * the first entry is the normal sequence, the second the shifted,
        !          64093:  * and the third the alternate keypad sequence.
        !          64094:  */
        !          64095: static char *keypad[][3] = {
        !          64096:        { "\33[H",  "7", "\33?w" },     /* 71 */
        !          64097:        { "\33[A",  "8", "\33?x" },     /* 72 */
        !          64098:        { "\33[V",  "9", "\33?y" },     /* 73 */
        !          64099:        { "\33[D",  "4", "\33?t" },     /* 75 */
        !          64100:        { "\0337",  "5", "\33?u" },     /* 76 */
        !          64101:        { "\33[C",  "6", "\33?v" },     /* 77 */
        !          64102:        { "\33[24H","1", "\33?q" },     /* 79 */
        !          64103:        { "\33[B",  "2", "\33?r" },     /* 80 */
        !          64104:        { "\33[U",  "3", "\33?s" },     /* 81 */
        !          64105:        { "\33[@@",  "0", "\33?p" },    /* 82 */
        !          64106:        { "\33[P", ".",  "\33?n" }      /* 83 */
        !          64107: };
        !          64108: 
        !          64109: isspecial(c)
        !          64110: int c;
        !          64111: {
        !          64112:        register char *cp;
        !          64113:        register int s;
        !          64114:        int     update_leds = 0;
        !          64115: 
        !          64116:        cp = 0;
        !          64117: 
        !          64118:        switch (c) {
        !          64119:        case 15:                                        /* cursor back tab */
        !          64120:                cp = "\033[Z";
        !          64121:                break;
        !          64122:        case 59: case 60: case 61: case 62: case 63:    /* Function keys */
        !          64123:        case 64: case 65: case 66: case 67: case 68:
        !          64124:                /* offset to function string */
        !          64125:                if ( shift & ALS )
        !          64126:                        cp = isfval[c-49];
        !          64127:                else
        !          64128:                        cp = isfval[c-59];
        !          64129:                break;
        !          64130: 
        !          64131:        case 70:                /* Scroll Lock -- stop/start output */
        !          64132:        {
        !          64133:                static char cbuf[2];
        !          64134: 
        !          64135:                cp = &cbuf[0];  /* working buffer */
        !          64136:                if (!(istty.t_sgttyb.sg_flags&RAWIN)) { /* not if in RAW mode */
        !          64137:                        ++update_leds;
        !          64138:                        if (istty.t_flags & T_STOP) {   /* output stopped? */
        !          64139:                           cbuf[0] = istty.t_tchars.t_startc;  /* start it */
        !          64140:                           scroll = 0;
        !          64141:                        } else {
        !          64142:                           cbuf[0] = istty.t_tchars.t_stopc;   /* stop output */
        !          64143:                           scroll = 1;
        !          64144:                        }
        !          64145:                }
        !          64146:                break;
        !          64147:        }
        !          64148: 
        !          64149:        case 79:                /* 1/End */
        !          64150:        case 80:                /* 2/DOWN */
        !          64151:        case 81:                /* 3/PgDn */
        !          64152:        case 82:                /* 0/Ins */
        !          64153:        case 83:                /* ./Del */
        !          64154:                --c;            /* adjust code */
        !          64155:        case 75:                /* 4/LEFT */
        !          64156:        case 76:                /* 5 */
        !          64157:        case 77:                /* 6/RIGHT */
        !          64158:                --c;            /* adjust code */
        !          64159:        case 71:                /* 7/Home/Clear */
        !          64160:        case 72:                /* 8/UP */
        !          64161:        case 73:                /* 9/PgUp */
        !          64162:                s = 0;                  /* start off with normal keypad */
        !          64163:                if (shift&NMLS)         /* num lock? */
        !          64164:                        s = 1;          /* set shift pad */
        !          64165:                if (shift&SES)          /* shift? */
        !          64166:                        s ^= 1;         /* toggle shift pad */
        !          64167:                if (shift&AKPS)         /* alternate pad? */
        !          64168:                        s = 2;          /* set alternate pad */         
        !          64169:                cp = keypad[c-71][s];   /* get keypad value */
        !          64170:                break;
        !          64171:        }
        !          64172:        if (cp)                                 /* send string */
        !          64173:                while ((*cp != 0) && (*cp != -1))
        !          64174:                        isin( *cp++ & 0377 );
        !          64175:        return update_leds;
        !          64176: }
        !          64177: 
        !          64178: /**
        !          64179:  *
        !          64180:  * void
        !          64181:  * ismmfunc( c )       -- process keyboard related output escape sequences
        !          64182:  * char c;
        !          64183:  */
        !          64184: void
        !          64185: ismmfunc(c)
        !          64186: register int c;
        !          64187: {
        !          64188:        switch (c) {
        !          64189:        case 't':       /* Enter numlock */
        !          64190:                shift |= NMLS;
        !          64191:                updleds();                      /* update LED status */
        !          64192:                break;
        !          64193:        case 'u':       /* Leave numlock */
        !          64194:                shift &= ~NMLS;
        !          64195:                updleds();                      /* update LED status */
        !          64196:                break;
        !          64197:        case '=':       /* Enter alternate keypad */
        !          64198:                shift |= AKPS;
        !          64199:                break;
        !          64200:        case '>':       /* Exit alternate keypad */
        !          64201:                shift &= ~AKPS;
        !          64202:                break;
        !          64203:        case 'c':       /* Reset terminal */
        !          64204:                islock = 0;
        !          64205:                shift  = 0;
        !          64206:                initkeys();
        !          64207:                updleds();                      /* update LED status */
        !          64208:                break;
        !          64209:        }
        !          64210: }
        !          64211: 
        !          64212: /**
        !          64213:  *
        !          64214:  * void
        !          64215:  * isin( c )   -- append character to raw input silo
        !          64216:  * char c;
        !          64217:  */
        !          64218: static
        !          64219: isin( c )
        !          64220: register int c;
        !          64221: {
        !          64222:        /*
        !          64223:         * Cache received character.
        !          64224:         */
        !          64225:        istty.t_rawin.si_buf[ istty.t_rawin.si_ix ] = c;
        !          64226: 
        !          64227:        if ( ++istty.t_rawin.si_ix >= sizeof(istty.t_rawin.si_buf) )
        !          64228:                istty.t_rawin.si_ix = 0;
        !          64229: }
        !          64230: 
        !          64231: /**
        !          64232:  *
        !          64233:  * void
        !          64234:  * isbatch()   -- raw input conversion routine
        !          64235:  *
        !          64236:  *     Action: Enable the video display.
        !          64237:  *             Canonize the raw input silo.
        !          64238:  *
        !          64239:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
        !          64240:  */
        !          64241: static void
        !          64242: isbatch( tp )
        !          64243: register TTY * tp;
        !          64244: {
        !          64245:        register int c;
        !          64246:        static int lastc;
        !          64247: 
        !          64248:        /*
        !          64249:         * Ensure video display is enabled.
        !          64250:         */
        !          64251:        mm_von();
        !          64252: 
        !          64253:        isbusy = 0;
        !          64254: 
        !          64255:        /*
        !          64256:         * Process all cached characters.
        !          64257:         */
        !          64258:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          64259: 
        !          64260:                /*
        !          64261:                 * Get next cached char.
        !          64262:                 */
        !          64263:                c = tp->t_rawin.si_buf[ tp->t_rawin.si_ox ];
        !          64264: 
        !          64265:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          64266:                        tp->t_rawin.si_ox = 0;
        !          64267:                else
        !          64268:                        tp->t_rawin.si_ox++;
        !          64269: 
        !          64270:                if ( (islock == 0) || ISINTR || ISQUIT ) {
        !          64271:                        ttin( tp, c );
        !          64272:                }
        !          64273: 
        !          64274:                else if ( (c == 'b') && (lastc == '\033') ) {
        !          64275:                        islock = 0;
        !          64276:                        ttin( tp, lastc );
        !          64277:                        ttin( tp, c );
        !          64278:                }
        !          64279: 
        !          64280:                else if ( (c == 'c') && (lastc == '\033') ) {
        !          64281:                        ttin( tp, lastc );
        !          64282:                        ttin( tp, c );
        !          64283:                }
        !          64284: 
        !          64285:                else
        !          64286:                        putchar('\007');
        !          64287: 
        !          64288:                lastc = c;
        !          64289:        }
        !          64290: }
        !          64291: 
        !          64292: /*
        !          64293:  * update the keyboard status LEDS
        !          64294:  */
        !          64295: updleds()
        !          64296: {
        !          64297:        int     s;
        !          64298: 
        !          64299:        s = sphi();
        !          64300:        outb(KBDATA, LEDCMD);
        !          64301:        ledcmd = 1;
        !          64302:        spl(s);
        !          64303: }
        !          64304: 
        !          64305: /*
        !          64306:  * unlock the scroll in case an interrupt character is received
        !          64307:  */
        !          64308: kbunscroll()
        !          64309: {
        !          64310:        scroll = 0;
        !          64311:        updleds();
        !          64312: }
        !          64313: @
        !          64314: 
        !          64315: 
        !          64316: 1.1
        !          64317: log
        !          64318: @Initial revision
        !          64319: @
        !          64320: text
        !          64321: @d10 3
        !          64322: a12 3
        !          64323: #include <coherent.h>
        !          64324: #include <i8086.h>
        !          64325: #include <con.h>
        !          64326: d14 3
        !          64327: a16 3
        !          64328: #include <stat.h>
        !          64329: #include <tty.h>
        !          64330: #include <uproc.h>
        !          64331: d18 1
        !          64332: a18 2
        !          64333: #include <sys/timeout.h>
        !          64334: #include <sched.h>
        !          64335: @
        !          64336: 0707070064030106641004440000030000030000011777770507310674400005500000000647/newbits/kernel/USRSRC/i8086/drv/RCS/lgl.h,vhead     1.1;
        !          64337: branch   ;
        !          64338: access   ;
        !          64339: symbols  ;
        !          64340: locks    bin:1.1; strict;
        !          64341: comment  @ * @;
        !          64342: 
        !          64343: 
        !          64344: 1.1
        !          64345: date     91.06.10.10.23.24;  author bin;  state Exp;
        !          64346: branches ;
        !          64347: next     ;
        !          64348: 
        !          64349: 
        !          64350: desc
        !          64351: @initial version prov by hal
        !          64352: @
        !          64353: 
        !          64354: 
        !          64355: 
        !          64356: 1.1
        !          64357: log
        !          64358: @Initial revision
        !          64359: @
        !          64360: text
        !          64361: @/* (-lgl
        !          64362:  *     COHERENT Driver Kit Version (Beta)
        !          64363:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          64364:  *     All rights reserved. May not be copied without permission.
        !          64365:  -lgl) */
        !          64366: @
        !          64367: 0707070064030104261004440000030000030000011777770507310674400005400000006622/newbits/kernel/USRSRC/i8086/drv/RCS/mm.c,vhead     1.2;
        !          64368: branch   ;
        !          64369: access   ;
        !          64370: symbols  ;
        !          64371: locks    bin:1.2; strict;
        !          64372: comment  @ * @;
        !          64373: 
        !          64374: 
        !          64375: 1.2
        !          64376: date     91.06.20.14.50.47;  author bin;  state Exp;
        !          64377: branches ;
        !          64378: next     1.1;
        !          64379: 
        !          64380: 1.1
        !          64381: date     91.06.10.10.23.33;  author bin;  state Exp;
        !          64382: branches ;
        !          64383: next     ;
        !          64384: 
        !          64385: 
        !          64386: desc
        !          64387: @initial version prov by hal
        !          64388: @
        !          64389: 
        !          64390: 
        !          64391: 1.2
        !          64392: log
        !          64393: @update provided by hal
        !          64394: @
        !          64395: text
        !          64396: @/* (-lgl
        !          64397:  *     COHERENT Driver Kit Version 1.1.0
        !          64398:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          64399:  *     All rights reserved. May not be copied without permission.
        !          64400:  -lgl) */
        !          64401: /*
        !          64402:  * Memory Mapped Video
        !          64403:  * High level output routines.
        !          64404:  */
        !          64405: #include <sys/coherent.h>
        !          64406: #include <sys/sched.h>
        !          64407: #include <errno.h>
        !          64408: #include <sys/stat.h>
        !          64409: #include <sys/io.h>
        !          64410: #include <sys/tty.h>
        !          64411: #include <sys/uproc.h>
        !          64412: #include <sys/timeout.h>
        !          64413: 
        !          64414: /* For beeper */
        !          64415: #define        TIMCTL  0x43                    /* Timer control port */
        !          64416: #define        TIMCNT  0x42                    /* Counter timer port */
        !          64417: #define        PORTB   0x61                    /* Port containing speaker enable */
        !          64418: #define        FREQ    ((int)(1193181L/440))   /* Counter for 440 Hz. tone */
        !          64419: 
        !          64420: int mmtime();
        !          64421: 
        !          64422: char mmbeeps;          /* number of ticks remaining on bell */
        !          64423: char mmesc;            /* last unserviced escape character */
        !          64424: int  mmcrtsav = 1;     /* crt saver enabled */
        !          64425: int  mmvcnt   = 900;   /* seconds remaining before crt saver is activated */
        !          64426: 
        !          64427: extern TTY istty;
        !          64428: 
        !          64429: /*
        !          64430:  * Start the output stream.
        !          64431:  * Called from `ttwrite' and `isrint' routines.
        !          64432:  */
        !          64433: TIM mmtim;
        !          64434: 
        !          64435: mmstart(tp)
        !          64436: register TTY *tp;
        !          64437: {
        !          64438:        int c;
        !          64439:        IO iob;
        !          64440:        static int mmbegun;
        !          64441: 
        !          64442:        while ((tp->t_flags&T_STOP) == 0) {
        !          64443:                if ((c = ttout(tp)) < 0)
        !          64444:                        break;
        !          64445:                iob.io_seg  = IOSYS;
        !          64446:                iob.io_ioc  = 1;
        !          64447:                iob.io_base = &c;
        !          64448:                iob.io_flag = 0;
        !          64449:                mmwrite( makedev(2,0), &iob );
        !          64450:        }
        !          64451: 
        !          64452:        if (mmbegun == 0) {
        !          64453:                ++mmbegun;
        !          64454:                timeout(&mmtim, HZ/10, mmtime, (char *)tp);
        !          64455:        }
        !          64456: }
        !          64457: 
        !          64458: mmtime(xp)
        !          64459: char *xp;
        !          64460: {
        !          64461:        register int s;
        !          64462: 
        !          64463:        s = sphi();
        !          64464:        if (mmbeeps < 0) {
        !          64465:                mmbeeps = 2;
        !          64466:                outb(TIMCTL, 0xB6);     /* Timer 2, lsb, msb, binary */
        !          64467:                outb(TIMCNT, FREQ&0xFF);
        !          64468:                outb(TIMCNT, FREQ>>8);
        !          64469:                outb(PORTB, inb(PORTB) | 03);   /* Turn speaker on */
        !          64470:        }
        !          64471:        else if ((mmbeeps > 0) && (--mmbeeps == 0))
        !          64472:                outb( PORTB, inb(PORTB) & ~03 );
        !          64473: 
        !          64474:        if (mmesc) {
        !          64475:                ismmfunc(mmesc);
        !          64476:                mmesc = 0;
        !          64477:        }
        !          64478:        spl(s);
        !          64479: 
        !          64480:        ttstart( (TTY *) xp );
        !          64481: 
        !          64482:        timeout(&mmtim, HZ/10, mmtime, xp);
        !          64483: }
        !          64484: 
        !          64485: /**
        !          64486:  *
        !          64487:  * void
        !          64488:  * mmwatch()   -- turn video display off after 15 minutes inactivity.
        !          64489:  */
        !          64490: void
        !          64491: mmwatch()
        !          64492: {
        !          64493:        if ( (mmcrtsav > 0) && (mmvcnt > 0) && (--mmvcnt == 0) )
        !          64494:                mm_voff();
        !          64495: }
        !          64496: 
        !          64497: mmwrite( dev, iop )
        !          64498: dev_t dev;
        !          64499: register IO *iop;
        !          64500: {
        !          64501:        int ioc;
        !          64502:        int s;
        !          64503: 
        !          64504:        ioc = iop->io_ioc;
        !          64505: 
        !          64506:        /*
        !          64507:         * Kernel writes.
        !          64508:         */
        !          64509:        if (iop->io_seg == IOSYS) {
        !          64510:                while (mmgo(iop))
        !          64511:                        ;
        !          64512:        }
        !          64513: 
        !          64514:        /*
        !          64515:         * Blocking user writes.
        !          64516:         */
        !          64517:        else if ( (iop->io_flag & IONDLY) == 0 ) {
        !          64518:                do {
        !          64519:                        while (istty.t_flags & T_STOP) {
        !          64520:                                s = sphi();
        !          64521:                                istty.t_flags |= T_HILIM;
        !          64522:                                sleep((char*) &istty.t_oq,
        !          64523:                                        CVTTOUT, IVTTOUT, SVTTOUT);
        !          64524:                                spl( s );
        !          64525:                        }
        !          64526:                        /*
        !          64527:                         * Signal received.
        !          64528:                         */
        !          64529:                        if ( SELF->p_ssig && nondsig() ) {
        !          64530:                                kbunscroll();   /* update kbd LEDS */
        !          64531:                                /*
        !          64532:                                 * No data transferred yet.
        !          64533:                                 */
        !          64534:                                if ( ioc == iop->io_ioc )
        !          64535:                                        u.u_error = EINTR;
        !          64536:                                /*
        !          64537:                                 * Transfer remaining data
        !          64538:                                 * without pausing after scrolling.
        !          64539:                                 */
        !          64540:                                else while ( mmgo(iop) )
        !          64541:                                        ;
        !          64542: 
        !          64543:                                return;
        !          64544:                        }
        !          64545:                        mmgo(iop);
        !          64546:                } while ( iop->io_ioc );
        !          64547:        }
        !          64548: 
        !          64549:        /*
        !          64550:         * Non-blocking user writes with output stopped.
        !          64551:         */
        !          64552:        else if ( istty.t_flags & T_STOP ) {
        !          64553:                u.u_error = EAGAIN;
        !          64554:                return;
        !          64555:        }
        !          64556: 
        !          64557:        /*
        !          64558:         * Non-blocking user writes do not pause after scrolling.
        !          64559:         */
        !          64560:        else {
        !          64561:                while ( mmgo(iop) )
        !          64562:                        ;
        !          64563:        }
        !          64564: }
        !          64565: @
        !          64566: 
        !          64567: 
        !          64568: 1.1
        !          64569: log
        !          64570: @Initial revision
        !          64571: @
        !          64572: text
        !          64573: @d10 1
        !          64574: a10 1
        !          64575: #include <coherent.h>
        !          64576: @
        !          64577: 0707070064030106621004440000030000030000011777770507310674500005600000075145/newbits/kernel/USRSRC/i8086/drv/RCS/mmas.s,vhead     1.2;
        !          64578: branch   ;
        !          64579: access   ;
        !          64580: symbols  ;
        !          64581: locks    bin:1.2; strict;
        !          64582: comment  @@;
        !          64583: 
        !          64584: 
        !          64585: 1.2
        !          64586: date     91.06.10.14.33.03;  author bin;  state Exp;
        !          64587: branches ;
        !          64588: next     1.1;
        !          64589: 
        !          64590: 1.1
        !          64591: date     91.06.10.10.23.35;  author bin;  state Exp;
        !          64592: branches ;
        !          64593: next     ;
        !          64594: 
        !          64595: 
        !          64596: desc
        !          64597: @initial version prov by hal
        !          64598: @
        !          64599: 
        !          64600: 
        !          64601: 1.2
        !          64602: log
        !          64603: @update prov by hal
        !          64604: @
        !          64605: text
        !          64606: @////////
        !          64607: /
        !          64608: /      Memory mapped video driver assembler assist.
        !          64609: /
        !          64610: ////////
        !          64611: /
        !          64612: / State driven code
        !          64613: /
        !          64614: /      Input:  DS:SI - input string
        !          64615: /              ES:DI - current screen location
        !          64616: /              SS:BP - terminal information
        !          64617: /              CX    - input count
        !          64618: /              BP    - references terminal information
        !          64619: /              AH    - character attributes
        !          64620: /              AL    - character
        !          64621: /              BH    - (usually) kept zeroed for efficiency
        !          64622: /              DH    - current row
        !          64623: /              DL    - current column
        !          64624: /
        !          64625: ////////
        !          64626: 
        !          64627:        NCOL    = 80            / number of columns
        !          64628:        NCB     = 2             / number of horizontal bytes per char
        !          64629:        NCR     = 1             / number of horizontal lines per char
        !          64630:        NHB     = 160           / number of horizontal bytes per line
        !          64631:        NRB     = NCR*NHB       / number of bytes per character row
        !          64632: 
        !          64633:        ATTR    = ah            / attribute byte
        !          64634:        ZERO    = bh            / (almost) always zero
        !          64635:        ROW     = dh            / currently active vertical position
        !          64636:        COL     = dl            / currently active horizontal position
        !          64637:        POS     = di            / currently active display address
        !          64638: 
        !          64639:        INTENSE = 0x08          / high intensity attribute bit
        !          64640:        BLINK   = 0x80          / blinking attribute bit
        !          64641:        REVERSE = 0x70          / reverse video
        !          64642: 
        !          64643: ////////
        !          64644: /
        !          64645: / Magic constants from <sys/io.h>
        !          64646: /
        !          64647: ////////
        !          64648: 
        !          64649:        IO_SEG  = 0
        !          64650:        IO_IOC  = 2
        !          64651:        IO_BASE = 8
        !          64652: 
        !          64653:        IOSYS   = 0
        !          64654:        IOUSR   = 1
        !          64655: 
        !          64656: ////////
        !          64657: /
        !          64658: / Data
        !          64659: /
        !          64660: ////////
        !          64661: 
        !          64662: MM_FUNC                = 0             / current state
        !          64663: MM_PORT                = 2             / adapter base i/o port
        !          64664: MM_BASE                = 4             / adapter base memory address
        !          64665: MM_ROW         = 6             / screen row
        !          64666: MM_COL         = 7             / screen column
        !          64667: MM_POS         = 8             / screen position
        !          64668: MM_ATTR                = 10            / attributes
        !          64669: MM_N1          = 11            / numeric argument 1
        !          64670: MM_N2          = 12            / numeric argument 2
        !          64671: MM_BROW                = 13            / base row
        !          64672: MM_EROW                = 14            / end row
        !          64673: MM_LROW                = 15            / legal row limit
        !          64674: MM_SROW                = 16            / saved cursor row
        !          64675: MM_SCOL                = 17            / saved cursor column
        !          64676: MM_IBROW       = 18            / initial base row
        !          64677: MM_IEROW       = 19            / initial end row
        !          64678: MM_INVIS       = 20            / cursor invisible mask
        !          64679: MM_SLOW                = 22            / slow [no flicker] video update
        !          64680: MM_WRAP                = 23            / wrap to start of next line
        !          64681: 
        !          64682:        .globl  VIDSLOW_        / Patchable kernel variable.
        !          64683:        .prvd
        !          64684: mmdata:        .word   mminit
        !          64685:        .word   0x03B4
        !          64686:        .word   0xB000
        !          64687:        .byte   0, 0
        !          64688:        .word   0
        !          64689:        .byte   0x7, 0, 0, 0, 23, 24, 0, 0, 0, 23
        !          64690:        .word   0
        !          64691: VIDSLOW_:.byte 0
        !          64692:        .byte   1
        !          64693:        .shri
        !          64694: 
        !          64695: ////////
        !          64696: /
        !          64697: / mmgo( iop )
        !          64698: / IO *iop;
        !          64699: /
        !          64700: ////////
        !          64701: 
        !          64702:        .globl  mmgo_
        !          64703: 
        !          64704: mmgo_:
        !          64705:        push    si
        !          64706:        push    di
        !          64707:        push    bp
        !          64708:        mov     bp, sp
        !          64709:        push    ds
        !          64710:        push    es
        !          64711:        cld
        !          64712:        mov     bx, 8(bp)               / iop
        !          64713:        mov     si, IO_BASE(bx)         / iop->io_base
        !          64714:        mov     cx, IO_IOC(bx)          / iop->io_ioc
        !          64715: 
        !          64716:        cmp     IO_SEG(bx), $IOSYS      / user address space
        !          64717:        je      0f
        !          64718:        mov     bx, uds_
        !          64719:        mov     ds, bx
        !          64720: 0:
        !          64721:        mov     bp, $mmdata
        !          64722:        mov     dx, MM_PORT(bp)         / turn video off if color board
        !          64723:        cmp     dx, $0x3B4
        !          64724:        je      3f
        !          64725:        cmpb    MM_SLOW(bp), $0         / check for slow [flicker-free]
        !          64726:        je      2f
        !          64727: 
        !          64728:        mov     dx, $0x3DA
        !          64729: 1:     inb     al, dx                  / wait for vertical retrace
        !          64730:        testb   al, $8
        !          64731:        je      1b
        !          64732: 2:
        !          64733:        mov     dx, $0x3D8              / disable video
        !          64734:        movb    al, $0x25
        !          64735:        outb    dx, al
        !          64736: 3:
        !          64737:        movb    ROW, MM_ROW(bp)
        !          64738:        movb    COL, MM_COL(bp)
        !          64739:        mov     es,  MM_BASE(bp)
        !          64740:        mov     POS, MM_POS(bp)
        !          64741:        sub     bx, bx
        !          64742:        movb    ATTR, MM_ATTR(bp)
        !          64743:        ijmp    MM_FUNC(bp)
        !          64744: 
        !          64745: exit:  pop     bx
        !          64746:        pop     es
        !          64747:        pop     ds
        !          64748:        movb    MM_ATTR(bp), ATTR
        !          64749:        mov     MM_FUNC(bp), bx
        !          64750:        movb    MM_ROW(bp), ROW         / save row,column
        !          64751:        movb    MM_COL(bp), COL
        !          64752:        mov     MM_POS(bp), POS         / save position
        !          64753: 
        !          64754:        mov     dx, MM_PORT(bp)         / adjust cursor location
        !          64755:        mov     bx, POS
        !          64756:        or      bx, MM_INVIS(bp)
        !          64757:        shr     bx, $1
        !          64758: 
        !          64759:        movb    al, $14
        !          64760:        outb    dx, al
        !          64761:        inc     dx
        !          64762:        movb    al, bh
        !          64763:        outb    dx, al
        !          64764:        dec     dx
        !          64765:        movb    al, $15
        !          64766:        outb    dx, al
        !          64767:        inc     dx
        !          64768:        movb    al, bl
        !          64769:        outb    dx, al
        !          64770: 
        !          64771:        mov     dx, MM_PORT(bp)         / turn video on
        !          64772:        add     dx, $4
        !          64773:        movb    al, $0x29
        !          64774:        outb    dx, al
        !          64775:        mov     mmvcnt_, $600           / 600 seconds before video disabled
        !          64776: 
        !          64777:        mov     bp, sp
        !          64778:        mov     bx, 8(bp)
        !          64779:        mov     ax, cx
        !          64780:        xchg    cx, IO_IOC(bx)
        !          64781:        sub     cx, IO_IOC(bx)
        !          64782:        add     IO_BASE(bx), cx
        !          64783:        pop     bp
        !          64784:        pop     di
        !          64785:        pop     si
        !          64786:        ret
        !          64787: 
        !          64788: 
        !          64789: ////////
        !          64790: /
        !          64791: / mminit - initialize screen
        !          64792: /
        !          64793: ////////
        !          64794: 
        !          64795: mminit:        movb    ss:mmesc_, $'c          / schedule keyboard initialization
        !          64796:        call    int11_                  / read equipment status
        !          64797:        and     ax, $0x30               / isolate video bits
        !          64798:        cmp     ax, $0x30               / if not monochrome
        !          64799:        je      0f
        !          64800:        mov     MM_PORT(bp), $0x3D4     /       set color port
        !          64801:        mov     MM_BASE(bp), $0xB800    /       set color base
        !          64802:        mov     es, MM_BASE(bp)         /
        !          64803: 0:                                     /
        !          64804:        mov     dx, MM_PORT(bp)         / turn video off
        !          64805:        add     dx, $4
        !          64806:        movb    al, $0x21
        !          64807:        outb    dx, al
        !          64808: 
        !          64809:        mov     dx, MM_PORT(bp)         / zero display offset
        !          64810:        movb    al, $12
        !          64811:        outb    dx, al
        !          64812:        inc     dx
        !          64813:        subb    al, al
        !          64814:        outb    dx, al
        !          64815:        dec     dx
        !          64816:        movb    al, $13
        !          64817:        outb    dx, al
        !          64818:        inc     dx
        !          64819:        subb    al, al
        !          64820:        outb    dx, al
        !          64821: 
        !          64822:        mov     dx, MM_PORT(bp)         / reset border to black
        !          64823:        add     dx, $5
        !          64824:        subb    al, al
        !          64825:        outb    dx, al
        !          64826: 
        !          64827:        inc     dx                      / reset TECMAR XMSR register
        !          64828:        outb    dx, al
        !          64829: 
        !          64830:        mov     MM_INVIS(bp), $0
        !          64831:        movb    ATTR, $0x07
        !          64832:        movb    MM_ATTR(bp), ATTR
        !          64833:        movb    MM_WRAP(bp), $1
        !          64834:        movb    ROW, MM_IBROW(bp)
        !          64835:        movb    MM_BROW(bp), ROW
        !          64836:        movb    bl, MM_IEROW(bp)
        !          64837:        movb    MM_EROW(bp), bl
        !          64838:        sub     bx, bx
        !          64839:        movb    MM_N1(bp), $2
        !          64840:        jmp     mm_ed
        !          64841: 
        !          64842: ////////
        !          64843: /
        !          64844: / mmspec - schedule special keyboard function
        !          64845: /
        !          64846: ////////
        !          64847: 
        !          64848: mmspec:        movb    ss:mmesc_, al
        !          64849:        jmp     eval
        !          64850: 
        !          64851: ////////
        !          64852: /
        !          64853: / mmbell - schedule beep
        !          64854: /
        !          64855: ////////
        !          64856: 
        !          64857: mmbell:        movb    ss:mmbeeps_, $-1
        !          64858:        jmp     eval
        !          64859: 
        !          64860: ////////
        !          64861: /
        !          64862: / mm_cnl - cursor next line
        !          64863: /
        !          64864: /      Moves the active position to the first column of the next display line.
        !          64865: /      Scrolls the active display if necessary.
        !          64866: /
        !          64867: ////////
        !          64868: 
        !          64869: mm_cnl:        subb    COL, COL
        !          64870:        incb    ROW
        !          64871:        cmpb    ROW, MM_EROW(bp)
        !          64872:        jna     repos
        !          64873:        movb    ROW, MM_EROW(bp)
        !          64874: /      jmp     scrollup
        !          64875: 
        !          64876: ////////
        !          64877: /
        !          64878: / scrollup - scroll display upwards
        !          64879: /
        !          64880: ////////
        !          64881: 
        !          64882: scrollup:
        !          64883:        push    ds
        !          64884:        push    si
        !          64885:        push    cx
        !          64886:        mov     ds, MM_BASE(bp)
        !          64887:        movb    bl, MM_BROW(bp)
        !          64888:        shlb    bl, $1
        !          64889:        mov     di, cs:rowtab(bx)
        !          64890:        mov     si, cs:rowtab+2(bx)
        !          64891:        movb    bl, ROW
        !          64892:        shlb    bl, $1
        !          64893:        mov     cx, cs:rowtab(bx)
        !          64894:        push    cx
        !          64895:        sub     cx, di
        !          64896:        shr     cx, $1
        !          64897:        cld
        !          64898:        rep
        !          64899:        movsw
        !          64900:        movb    al, $' 
        !          64901:        pop     di
        !          64902:        mov     cx, $NCOL
        !          64903:        rep
        !          64904:        stosw
        !          64905:        pop     cx
        !          64906:        pop     si
        !          64907:        pop     ds
        !          64908:        movb    bl, COL                 / reposition to ROW and COL
        !          64909:        shlb    bl, $1
        !          64910:        mov     POS, cs:coltab(bx)
        !          64911:        movb    bl, ROW
        !          64912:        shlb    bl, $1
        !          64913:        add     POS, cs:rowtab(bx)
        !          64914:        call    exit
        !          64915:        jmp     eval
        !          64916: 
        !          64917: ////////
        !          64918: /
        !          64919: / repos - reposition cursor
        !          64920: /
        !          64921: ////////
        !          64922: 
        !          64923: repos: movb    bl, COL                 / reposition to ROW and COL
        !          64924:        shlb    bl, $1
        !          64925:        mov     POS, cs:coltab(bx)
        !          64926:        movb    bl, ROW
        !          64927:        shlb    bl, $1
        !          64928:        add     POS, cs:rowtab(bx)
        !          64929: /      jmp     eval
        !          64930: 
        !          64931: ////////
        !          64932: /
        !          64933: / eval - evaluate input character
        !          64934: /
        !          64935: ////////
        !          64936: 
        !          64937: eval:  jcxz    ewait
        !          64938:        dec     cx                              / evaluate next char
        !          64939:        lodsb
        !          64940:        movb    bl, al
        !          64941:        shlb    bl, $1
        !          64942:        jc      mmputc
        !          64943:        ijmp    cs:asctab(bx)
        !          64944: 
        !          64945: ////////
        !          64946: /
        !          64947: / mmputc - put character on screen
        !          64948: /
        !          64949: ////////
        !          64950: 
        !          64951: mmputc:        stosw                           / Update display memory.
        !          64952:        incb    COL
        !          64953:        cmpb    COL, $NCOL              / Past end of line?
        !          64954:        jge     0f
        !          64955:        jcxz    ewait                   / Not past, evaluate next character.
        !          64956:        dec     cx
        !          64957:        lodsb
        !          64958:        movb    bl, al
        !          64959:        shlb    bl, $1
        !          64960:        jc      mmputc
        !          64961:        ijmp    cs:asctab(bx)
        !          64962: 
        !          64963: 0:     cmpb    MM_WRAP(bp), $0         / Yes past, Wrap around?
        !          64964:        jne     0f
        !          64965:        sub     di, $2                  / No wrap, adjust back to end of line.
        !          64966:        decb    COL
        !          64967:        jcxz    ewait                   / Not past, evaluate next character.
        !          64968:        dec     cx
        !          64969:        lodsb
        !          64970:        movb    bl, al
        !          64971:        shlb    bl, $1
        !          64972:        jc      mmputc
        !          64973:        ijmp    cs:asctab(bx)
        !          64974: 
        !          64975: 0:     subb    COL, COL                / Wrap to next line.
        !          64976:        incb    ROW
        !          64977:        cmpb    ROW, MM_EROW(bp)        / Past scrolling region?
        !          64978:        jg      0f
        !          64979:        jcxz    ewait                   / Not past, evaluate next character.
        !          64980:        dec     cx
        !          64981:        lodsb
        !          64982:        movb    bl, al
        !          64983:        shlb    bl, $1
        !          64984:        jc      mmputc
        !          64985:        ijmp    cs:asctab(bx)
        !          64986: 
        !          64987: 0:     movb    ROW, MM_EROW(bp)        / Yes past, scroll up 1 line.
        !          64988:        jmp     scrollup
        !          64989: 
        !          64990: ////////
        !          64991: /
        !          64992: / Ewait - wait for next input char to evaluate
        !          64993: /
        !          64994: ////////
        !          64995: 
        !          64996: ewait: call    exit
        !          64997:        jcxz    ewait
        !          64998:        dec     cx
        !          64999:        lodsb
        !          65000:        movb    bl, al
        !          65001:        shlb    bl, $1
        !          65002:        jc      mmputc
        !          65003:        ijmp    cs:asctab(bx)
        !          65004: 
        !          65005: ////////
        !          65006: /
        !          65007: / mm_cr - carriage return
        !          65008: /
        !          65009: /      Moves the active position to first position of current display line.
        !          65010: /
        !          65011: ////////
        !          65012: 
        !          65013: mm_cr: subb    COL, COL
        !          65014:        movb    bl, ROW
        !          65015:        shlb    bl, $1
        !          65016:        mov     POS, cs:rowtab(bx)
        !          65017:        jcxz    ewait
        !          65018:        dec     cx
        !          65019:        lodsb
        !          65020:        movb    bl, al
        !          65021:        shlb    bl, $1
        !          65022:        jc      mmputc
        !          65023:        ijmp    cs:asctab(bx)
        !          65024: 
        !          65025: ////////
        !          65026: /
        !          65027: / mm_cub - cursor backwards
        !          65028: /
        !          65029: ////////
        !          65030: 
        !          65031: mm_cub:        sub     POS, $2
        !          65032:        decb    COL
        !          65033:        jge     0f
        !          65034:        movb    COL, $NCOL-1
        !          65035:        decb    ROW
        !          65036:        cmpb    ROW, MM_BROW(bp)
        !          65037:        jge     0f
        !          65038:        subb    COL, COL
        !          65039:        movb    ROW, MM_BROW(bp)
        !          65040:        movb    bl, ROW
        !          65041:        shlb    bl, $1
        !          65042:        mov     POS, cs:rowtab(bx)
        !          65043: 0:     jcxz    ewait
        !          65044:        dec     cx
        !          65045:        lodsb
        !          65046:        movb    bl, al
        !          65047:        shlb    bl, $1
        !          65048:        jc      mmputc
        !          65049:        ijmp    cs:asctab(bx)
        !          65050: 
        !          65051: ////////
        !          65052: /
        !          65053: / Esc state - entered when last char was ESC - transient state.
        !          65054: /
        !          65055: ////////
        !          65056: 
        !          65057: 0:     call    exit
        !          65058: mm_esc:        jcxz    0b
        !          65059:        dec     cx
        !          65060:        lodsb
        !          65061:        movb    MM_N1(bp), ZERO
        !          65062:        movb    MM_N2(bp), ZERO
        !          65063:        movb    bl, al
        !          65064:        shlb    bl, $1
        !          65065:        jc      mmputc
        !          65066:        ijmp    cs:esctab(bx)
        !          65067: 
        !          65068: ////////
        !          65069: /
        !          65070: / Csi_n1 state - entered when last two chars were ESC [
        !          65071: /
        !          65072: /      Action: Evaluates numeric chars as numeric parameter 1.
        !          65073: /
        !          65074: ////////
        !          65075: 
        !          65076: 0:     call    exit
        !          65077: csi_n1:        jcxz    0b
        !          65078:        dec     cx
        !          65079:        lodsb
        !          65080:        cmpb    al, $';
        !          65081:        je      csi_n2
        !          65082:        movb    bl, al
        !          65083:        subb    bl, $'0
        !          65084:        cmpb    bl, $9
        !          65085:        ja      csival
        !          65086:        shlb    MM_N1(bp), $1   / n1 * 2
        !          65087:        movb    al, MM_N1(bp)   / n1 * 2
        !          65088:        shlb    al, $1          / n1 * 4
        !          65089:        shlb    al, $1          / n1 * 8
        !          65090:        addb    al, MM_N1(bp)   / n1 * 10
        !          65091:        addb    al, bl          / n1 * 10 + digit
        !          65092:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          65093:        jmp     csi_n1
        !          65094: 
        !          65095: ////////
        !          65096: /
        !          65097: / Csi_n2 state - entered after input sequence ESC [ n ;
        !          65098: /
        !          65099: ////////
        !          65100: 
        !          65101: 0:     call    exit
        !          65102: csi_n2:        jcxz    0b
        !          65103:        dec     cx
        !          65104:        lodsb
        !          65105:        movb    bl, al
        !          65106:        subb    bl, $'0
        !          65107:        cmpb    bl, $9
        !          65108:        ja      csival
        !          65109:        shlb    MM_N2(bp), $1   / n2 * 2
        !          65110:        movb    al, MM_N2(bp)   / n2 * 2
        !          65111:        shlb    al, $1          / n2 * 4
        !          65112:        shlb    al, $1          / n2 * 8
        !          65113:        addb    al, MM_N2(bp)   / n2 * 10
        !          65114:        addb    al, bl          / n2 * 10 + digit
        !          65115:        movb    MM_N2(bp), al   / n2 = (n2 * 10) + digit
        !          65116:        jmp     csi_n2
        !          65117: 
        !          65118: csival:        movb    bl, al
        !          65119:        shlb    bl, $1
        !          65120:        jc      mmputc
        !          65121:        ijmp    cs:csitab(bx)
        !          65122: 
        !          65123: ////////
        !          65124: /
        !          65125: / Csi_gt state - entered after input sequence ESC [ >
        !          65126: /      
        !          65127: ////////
        !          65128: 
        !          65129: 0:     call    exit
        !          65130: csi_gt:        jcxz    0b
        !          65131:        dec     cx
        !          65132:        lodsb
        !          65133:        movb    bl, al
        !          65134:        subb    bl, $'0
        !          65135:        cmpb    bl, $9
        !          65136:        ja      0f
        !          65137:        shlb    MM_N1(bp), $1   / n1 * 2
        !          65138:        movb    al, MM_N1(bp)   / n1 * 2
        !          65139:        shlb    al, $1          / n1 * 4
        !          65140:        shlb    al, $1          / n1 * 8
        !          65141:        addb    al, MM_N1(bp)   / n1 * 10
        !          65142:        addb    al, bl          / n1 * 10 + digit
        !          65143:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          65144:        jmp     csi_gt
        !          65145: 
        !          65146: 0:     cmpb    al, $'h
        !          65147:        je      mm_cgh
        !          65148:        cmpb    al, $'l
        !          65149:        je      mm_cgl
        !          65150:        jmp     eval
        !          65151: 
        !          65152: ////////
        !          65153: /
        !          65154: / Csi_q state - entered after input sequence ESC [ ?
        !          65155: /      
        !          65156: ////////
        !          65157: 
        !          65158: 0:     call    exit
        !          65159: csi_q: jcxz    0b
        !          65160:        dec     cx
        !          65161:        lodsb
        !          65162:        movb    bl, al
        !          65163:        subb    bl, $'0
        !          65164:        cmpb    bl, $9
        !          65165:        ja      0f
        !          65166:        shlb    MM_N1(bp), $1   / n1 * 2
        !          65167:        movb    al, MM_N1(bp)   / n1 * 2
        !          65168:        shlb    al, $1          / n1 * 4
        !          65169:        shlb    al, $1          / n1 * 8
        !          65170:        addb    al, MM_N1(bp)   / n1 * 10
        !          65171:        addb    al, bl          / n1 * 10 + digit
        !          65172:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          65173:        jmp     csi_q
        !          65174: 
        !          65175: 0:     cmpb    al, $'h
        !          65176:        je      mm_cqh
        !          65177:        cmpb    al, $'l
        !          65178:        je      mm_cql
        !          65179:        jmp     eval
        !          65180: 
        !          65181: ////////
        !          65182: /
        !          65183: / mm_cbt - cursor backward tabulation
        !          65184: /
        !          65185: /      Moves the active position horizontally in the backward direction
        !          65186: /      to the preceding in a series of predetermined positions.
        !          65187: /
        !          65188: ////////
        !          65189: 
        !          65190: mm_cbt:        orb     COL, $7                 / calculate next tab stop
        !          65191:        incb    COL
        !          65192:        subb    COL, $16                / step back two tab positions
        !          65193:        jg      0f
        !          65194:        subb    COL, COL                / can't step past column 0
        !          65195: 0:     jmp     repos                   / reposition cursor
        !          65196: 
        !          65197: ////////
        !          65198: /
        !          65199: / mm_cgh - process 'ESC [ > N1 h' escape sequence
        !          65200: /
        !          65201: /      Recognized sequences:   ESC [ > 13 h    -- Set CRT saver enabled.
        !          65202: /
        !          65203: ////////
        !          65204: 
        !          65205: mm_cgh:        cmpb    MM_N1(bp), $13
        !          65206:        jne     0f
        !          65207:        mov     ss:mmcrtsav_, $1
        !          65208: 0:     jmp     eval
        !          65209: 
        !          65210: ////////
        !          65211: /
        !          65212: / mm_cgl - process 'ESC [ > N1 l' escape sequence
        !          65213: /
        !          65214: /      Recognized sequences:   ESC [ > 13 l    -- Reset CRT saver.
        !          65215: /
        !          65216: ////////
        !          65217: 
        !          65218: mm_cgl:        cmpb    MM_N1(bp), $13
        !          65219:        jne     0f
        !          65220:        mov     ss:mmcrtsav_, $0
        !          65221: 0:     jmp     eval
        !          65222: 
        !          65223: ////////
        !          65224: /
        !          65225: / mm_cha - cursor horizontal absolute
        !          65226: /
        !          65227: /      Advances the active position forward or backward along the active line
        !          65228: /      to the character position specified by the parameter.
        !          65229: /      A parameter value of zero or one moves the active position to the
        !          65230: /      first character position of the active line.
        !          65231: /      A parameter value of N moves the active position to character position
        !          65232: /      N of the active line.
        !          65233: /
        !          65234: ////////
        !          65235: 
        !          65236: mm_cha:        movb    COL, MM_N1(bp)
        !          65237:        decb    COL
        !          65238:        jge     0f
        !          65239:        subb    COL, COL
        !          65240: 0:     cmpb    COL, $NCOL
        !          65241:        jb      0f
        !          65242:        movb    COL, $NCOL-1
        !          65243: 0:     jmp     repos                   / reposition cursor
        !          65244: 
        !          65245: 
        !          65246: ////////
        !          65247: /
        !          65248: / mm_cht - cursor horizontal tabulation
        !          65249: /
        !          65250: /      Advances the active position horizontally to the next or following
        !          65251: /      in a series of predetermined positions.
        !          65252: /
        !          65253: ////////
        !          65254: 
        !          65255: mm_cht:        push    cx
        !          65256:        sub     cx, cx
        !          65257:        movb    cl, COL
        !          65258:        orb     cl, $7
        !          65259:        incb    cl
        !          65260:        subb    cl, COL
        !          65261:        addb    COL, cl
        !          65262:        movb    al, $' 
        !          65263:        rep
        !          65264:        stosw
        !          65265:        pop     cx
        !          65266:        cmpb    COL, $NCOL
        !          65267:        jb      0f
        !          65268:        subb    COL, $NCOL
        !          65269:        incb    ROW
        !          65270:        cmpb    ROW, MM_EROW(bp)
        !          65271:        jna     0f
        !          65272:        movb    ROW, MM_EROW(bp)
        !          65273:        jmp     scrollup
        !          65274: 0:     jmp     eval
        !          65275: 
        !          65276: ////////
        !          65277: /
        !          65278: / mm_cpl - cursor preceding line
        !          65279: /
        !          65280: /      Moves the active position to the first position of the preceding
        !          65281: /      display line.
        !          65282: /
        !          65283: ////////
        !          65284: 
        !          65285: mm_cpl:        subb    COL, COL
        !          65286:        decb    ROW
        !          65287:        cmpb    ROW, MM_BROW(bp)
        !          65288:        jnb     0f
        !          65289:        movb    ROW, MM_BROW(bp)
        !          65290:        jmp     scrolldown
        !          65291: 0:     jmp     repos                   / reposition cursor
        !          65292: 
        !          65293: ////////
        !          65294: /
        !          65295: / mm_cqh - process 'ESC [ ? N1 h' escape sequence
        !          65296: /
        !          65297: /      Recognized sequences:   ESC [ ? 4 h     -- Set smooth scroll.
        !          65298: /                              ESC [ ? 7 h     -- Set wraparound.
        !          65299: /
        !          65300: ////////
        !          65301: 
        !          65302: mm_cqh:        cmpb    MM_N1(bp), $4           / Smooth scroll.
        !          65303:        jne     0f
        !          65304:        movb    MM_SLOW(bp), $1
        !          65305: 0:     cmpb    MM_N1(bp), $7           / Wraparound.
        !          65306:        jne     0f
        !          65307:        movb    MM_WRAP(bp), $1
        !          65308: 0:     jmp     eval
        !          65309: 
        !          65310: ////////
        !          65311: /
        !          65312: / mm_cql - process 'ESC [ ? N1 l' escape sequence
        !          65313: /
        !          65314: /      Recognized sequences:   ESC [ ? 4 l     -- Set jump scroll.
        !          65315: /                              ESC [ ? 7 l     -- Reset wraparound.
        !          65316: /
        !          65317: ////////
        !          65318: 
        !          65319: mm_cql:        cmpb    MM_N1(bp), $4           / Jump scroll.
        !          65320:        jne     0f
        !          65321:        movb    MM_SLOW(bp), $0
        !          65322: 0:     cmpb    MM_N1(bp), $7           / No wraparound.
        !          65323:        jne     0f
        !          65324:        movb    MM_WRAP(bp), $0
        !          65325: 0:     jmp     eval
        !          65326: 
        !          65327: ////////
        !          65328: /
        !          65329: / mm_cud - cursor down
        !          65330: /
        !          65331: /      Moves the active position downward without altering the
        !          65332: /      horizontal position.
        !          65333: /
        !          65334: ////////
        !          65335: 
        !          65336: mm_cud:        incb    ROW
        !          65337:        cmpb    ROW, MM_EROW(bp)
        !          65338:        jna     0f
        !          65339:        movb    ROW, MM_EROW(bp)
        !          65340: 0:     jmp     repos                   / reposition cursor
        !          65341: 
        !          65342: ////////
        !          65343: /
        !          65344: / mm_cuf - cursor forward
        !          65345: /
        !          65346: /      Moves the active position in the forward direction.
        !          65347: /
        !          65348: ////////
        !          65349: 
        !          65350: mm_cuf:        incb    COL
        !          65351:        cmpb    COL, $NCOL
        !          65352:        jb      0f
        !          65353:        subb    COL, $NCOL
        !          65354:        incb    ROW
        !          65355:        cmpb    ROW, MM_EROW(bp)
        !          65356:        jna     0f
        !          65357:        movb    ROW, MM_EROW(bp)
        !          65358:        movb    COL, $NCOL-1
        !          65359: 0:     jmp     repos
        !          65360: 
        !          65361: ////////
        !          65362: /
        !          65363: / mm_cup - cursor position
        !          65364: /
        !          65365: /      Moves the active position to the position specified by two parameters.
        !          65366: /      The first parameter (mm_n1) specifies the vertical position (MM_ROW(bp)).
        !          65367: /      The second parameter (mm_n2) specifies the horizontal position (MM_COL(bp)).
        !          65368: /      A parameter value of 0 or 1 for the first or second parameter
        !          65369: /      moves the active position to the first line or column in the
        !          65370: /      display respectively.
        !          65371: /
        !          65372: ////////
        !          65373: 
        !          65374: mm_cup:        movb    ROW, MM_N1(bp)
        !          65375:        decb    ROW
        !          65376:        jg      0f
        !          65377:        subb    ROW, ROW
        !          65378: 0:     addb    ROW, MM_BROW(bp)
        !          65379:        cmpb    ROW, MM_EROW(bp)
        !          65380:        jb      0f
        !          65381:        movb    ROW, MM_EROW(bp)
        !          65382: 0:     movb    COL, MM_N2(bp)
        !          65383:        decb    COL
        !          65384:        jg      0f
        !          65385:        subb    COL, COL
        !          65386: 0:     cmpb    COL, $NCOL
        !          65387:        jb      0f
        !          65388:        movb    COL, $NCOL-1
        !          65389: 0:     jmp     repos                   / reposition cursor
        !          65390: 
        !          65391: ////////
        !          65392: /
        !          65393: / mm_cuu - cursor up
        !          65394: /
        !          65395: /      Moves the active position upward without altering the horizontal
        !          65396: /      position.
        !          65397: /
        !          65398: ////////
        !          65399: 
        !          65400: mm_cuu:        decb    ROW
        !          65401:        cmpb    ROW, MM_BROW(bp)
        !          65402:        jge     0f
        !          65403:        movb    ROW, MM_BROW(bp)
        !          65404: 0:     jmp     repos                   / reposition cursor
        !          65405: 
        !          65406: ////////
        !          65407: /
        !          65408: / mm_dl - delete line
        !          65409: /
        !          65410: /      Removes the contents of the active line.
        !          65411: /      The contents of all following lines are shifted in a block
        !          65412: /      toward the active line.
        !          65413: /
        !          65414: ////////
        !          65415: 
        !          65416: mm_dl: push    ds
        !          65417:        push    si
        !          65418:        push    cx
        !          65419:        mov     ds, MM_BASE(bp)
        !          65420:        movb    bl, ROW
        !          65421:        shlb    bl, $1
        !          65422:        mov     di, cs:rowtab(bx)
        !          65423:        mov     si, cs:rowtab+2(bx)
        !          65424:        movb    bl, MM_EROW(bp)
        !          65425:        shlb    bl, $1
        !          65426:        mov     cx, cs:rowtab(bx)
        !          65427:        sub     cx, di
        !          65428:        jle     0f
        !          65429:        shr     cx, $1
        !          65430:        rep
        !          65431:        movsw
        !          65432:        mov     di, cs:rowtab(bx)
        !          65433:        mov     cx, $NCOL
        !          65434:        movb    al, $' 
        !          65435:        rep
        !          65436:        stosw
        !          65437:        subb    COL, COL
        !          65438:        movb    bl, ROW
        !          65439:        shlb    bl, $1
        !          65440:        mov     di, cs:rowtab(bx)
        !          65441: 0:     pop     cx
        !          65442:        pop     si
        !          65443:        pop     ds
        !          65444:        call    exit
        !          65445:        jmp     eval
        !          65446: 
        !          65447: ////////
        !          65448: /
        !          65449: / mm_dmi - disable manual input
        !          65450: /
        !          65451: /      Set flag preventing keyboard input, and causing cursor to vanish.
        !          65452: /
        !          65453: ////////
        !          65454: 
        !          65455: mm_dmi:
        !          65456:        mov     ss:islock_, $1
        !          65457:        jmp     eval
        !          65458: 
        !          65459: ////////
        !          65460: /
        !          65461: / mm_ea - erase in area
        !          65462: /
        !          65463: /      Erase some or all of the characters in the currently active area
        !          65464: /      according to the parameter:
        !          65465: /              0 - erase from active position to end inclusive (default)
        !          65466: /              1 - erase from start to active position inclusive
        !          65467: /              2 - erase all of active area
        !          65468: /
        !          65469: ////////
        !          65470: 
        !          65471: mm_ea: movb    al, MM_N1(bp)
        !          65472:        cmpb    al, $0
        !          65473:        jne     0f
        !          65474:        movb    bl, MM_EROW(bp)
        !          65475:        jmp     mm_e0
        !          65476: 0:     cmpb    al, $1
        !          65477:        jne     0f
        !          65478:        movb    bl, MM_BROW(bp)
        !          65479:        jmp     mm_e1
        !          65480: 0:     subb    COL, COL
        !          65481:        movb    ROW, MM_BROW(bp)
        !          65482:        movb    bl, ROW
        !          65483:        shlb    bl, $1
        !          65484:        mov     POS, cs:rowtab(bx)
        !          65485:        movb    bl, MM_EROW(bp)
        !          65486:        subb    bl, ROW
        !          65487:        jmp     mm_e2
        !          65488: 
        !          65489: 
        !          65490: ////////
        !          65491: /
        !          65492: / mm_ed - erase in display
        !          65493: /
        !          65494: /      Erase some or all of the characters in the display according to the
        !          65495: /      parameter
        !          65496: /              0 - erase from active position to end inclusive (default)
        !          65497: /              1 - erase from start to active position inclusive
        !          65498: /              2 - erase all of display
        !          65499: /
        !          65500: ////////
        !          65501: 
        !          65502: mm_ed: movb    al, MM_N1(bp)
        !          65503:        cmpb    al, $0
        !          65504:        jne     0f
        !          65505:        movb    bl, MM_LROW(bp)
        !          65506:        jmp     mm_e0
        !          65507: 0:     cmpb    al, $1
        !          65508:        jne     0f
        !          65509:        subb    bl, bl
        !          65510:        jmp     mm_e1
        !          65511: 0:     subb    COL, COL
        !          65512:        movb    ROW, MM_BROW(bp)
        !          65513:        sub     POS, POS
        !          65514:        movb    bl, MM_LROW(bp)
        !          65515:        jmp     mm_e2
        !          65516: 
        !          65517: ////////
        !          65518: /
        !          65519: / mm_el - erase in line
        !          65520: /
        !          65521: /      Erase some or all of the characters in the line according to the
        !          65522: /      parameter:
        !          65523: /              0 - erase from active position to end inclusive (default)
        !          65524: /              1 - erase from start to active position inclusive
        !          65525: /              2 - erase entire line
        !          65526: /
        !          65527: ////////
        !          65528: 
        !          65529: mm_el: movb    al, MM_N1(bp)
        !          65530:        movb    bl, ROW
        !          65531:        cmpb    al, $0
        !          65532:        je      mm_e0
        !          65533:        cmpb    al, $1
        !          65534:        je      mm_e1
        !          65535:        shlb    bl, $1
        !          65536:        mov     POS, cs:rowtab(bx)
        !          65537:        subb    COL, COL
        !          65538:        subb    bl, bl
        !          65539: /      jmp     mm_e2
        !          65540: 
        !          65541: mm_e2: push    cx
        !          65542:        movb    al, $' 
        !          65543: 0:     mov     cx, $NCOL
        !          65544:        rep
        !          65545:        stosw
        !          65546:        decb    bl
        !          65547:        jge     0b
        !          65548:        pop     cx
        !          65549:        jmp     repos
        !          65550: 
        !          65551: mm_e1: push    cx
        !          65552:        mov     cx, POS
        !          65553:        shlb    bl, $1
        !          65554:        mov     POS, cs:rowtab(bx)
        !          65555:        sub     cx, POS
        !          65556:        jl      0f
        !          65557:        movb    al, $' 
        !          65558:        shr     cx, $1
        !          65559:        rep
        !          65560:        stosw
        !          65561: 0:     pop     cx
        !          65562:        jmp     repos
        !          65563: 
        !          65564: mm_e0: push    cx
        !          65565:        shlb    bl, $1
        !          65566:        mov     cx, cs:rowtab+2(bx)
        !          65567:        sub     cx, POS
        !          65568:        jl      0f
        !          65569:        movb    al, $' 
        !          65570:        shr     cx, $1
        !          65571:        rep
        !          65572:        stosw
        !          65573: 0:     pop     cx
        !          65574:        jmp     repos
        !          65575: 
        !          65576: ////////
        !          65577: /
        !          65578: / mm_emi - enable manual input
        !          65579: /
        !          65580: /      Clear flag preventing keyboard input.
        !          65581: /
        !          65582: ////////
        !          65583: 
        !          65584: mm_emi:
        !          65585:        mov     ss:islock_, $0
        !          65586:        jmp     eval
        !          65587: 
        !          65588: ////////
        !          65589: /
        !          65590: / mm_il - insert line
        !          65591: /
        !          65592: /      Insert a erased line at the active line by shifting the contents
        !          65593: /      of the active line and all following lines away from the active line.
        !          65594: /      The contents of the last line in the scrolling region are removed.
        !          65595: /
        !          65596: ////////
        !          65597: 
        !          65598: scrolldown:
        !          65599: mm_il: push    ds
        !          65600:        push    si
        !          65601:        push    cx
        !          65602:        mov     ds, MM_BASE(bp)
        !          65603:        movb    bl, MM_EROW(bp)
        !          65604:        shlb    bl, $1
        !          65605:        mov     si, cs:rowtab(bx)
        !          65606:        mov     cx, si
        !          65607:        sub     si, $2
        !          65608:        mov     di, cs:rowtab+2(bx)
        !          65609:        sub     di, $2
        !          65610:        movb    bl, ROW
        !          65611:        shlb    bl, $1
        !          65612:        sub     cx, cs:rowtab(bx)
        !          65613:        jle     0f
        !          65614:        shr     cx, $1
        !          65615:        std
        !          65616:        rep
        !          65617:        movsw
        !          65618:        mov     di, cs:rowtab(bx)
        !          65619:        mov     cx, $NCOL
        !          65620:        movb    al, $' 
        !          65621:        cld
        !          65622:        rep
        !          65623:        stosw
        !          65624:        subb    COL, COL
        !          65625:        movb    bl, ROW
        !          65626:        shlb    bl, $1
        !          65627:        mov     di, cs:rowtab(bx)
        !          65628: 0:     pop     cx
        !          65629:        pop     si
        !          65630:        pop     ds
        !          65631:        call    exit
        !          65632:        jmp     eval
        !          65633: 
        !          65634: ////////
        !          65635: /
        !          65636: / mm_hpa - horizontal position absolute
        !          65637: /
        !          65638: /      Moves the active position within the active line to the position
        !          65639: /      specified by the parameter.  A parameter value of zero or one
        !          65640: /      moves the active position to the first position of the active line.
        !          65641: /
        !          65642: ////////
        !          65643: 
        !          65644: mm_hpa:        movb    COL, MM_N1(bp)
        !          65645:        decb    COL
        !          65646:        jg      0f
        !          65647:        subb    COL, COL
        !          65648: 0:     cmpb    COL, $NCOL
        !          65649:        jb      0f
        !          65650:        movb    COL, $NCOL-1
        !          65651: 0:     jmp     repos                   / reposition cursor
        !          65652: 
        !          65653: ////////
        !          65654: /
        !          65655: / mm_hpr - horizontal position relative
        !          65656: /
        !          65657: /      Moves the active position forward the number of positions specified
        !          65658: /      by the parameter.  A parameter value of zero or one indicates a
        !          65659: /      single-position move.
        !          65660: /
        !          65661: ////////
        !          65662: 
        !          65663: mm_hpr:        movb    al, MM_N1(bp)
        !          65664:        orb     al, al
        !          65665:        jne     0f
        !          65666:        incb    al
        !          65667: 0:     addb    COL, al
        !          65668:        cmpb    COL, $NCOL
        !          65669:        jb      0f
        !          65670:        movb    COL, $NCOL-1
        !          65671: 0:     jmp     repos                   / reposition cursor
        !          65672: 
        !          65673: ////////
        !          65674: /
        !          65675: / mm_hvp - horizontal and vertical position
        !          65676: /
        !          65677: /      Moves the active position to the position specified by two parameters.
        !          65678: /      The first parameter specifies the vertical position (MM_ROW(bp)).
        !          65679: /      The second parameter specifies the horizontal position (MM_COL(bp)).
        !          65680: /      A parameter value of zero or one moves the active position to the
        !          65681: /      first line or column in the display.
        !          65682: /
        !          65683: ////////
        !          65684: 
        !          65685: mm_hvp:        movb    ROW, MM_N1(bp)
        !          65686:        decb    ROW
        !          65687:        jg      0f
        !          65688:        subb    ROW, ROW
        !          65689: 0:     cmpb    ROW, MM_LROW(bp)
        !          65690:        jna     0f
        !          65691:        movb    ROW, MM_LROW(bp)
        !          65692: 0:     movb    COL, MM_N2(bp)
        !          65693:        decb    COL
        !          65694:        jg      0f
        !          65695:        subb    COL, COL
        !          65696: 0:     cmpb    COL, $NCOL
        !          65697:        jb      0f
        !          65698:        movb    COL, $NCOL-1
        !          65699: 0:     jmp     repos                   / reposition cursor
        !          65700: 
        !          65701: ////////
        !          65702: /
        !          65703: / mm_ind - index
        !          65704: /
        !          65705: /      Causes the active position to move downward one line without changing
        !          65706: /      the horizontal position.  Scrolling occurs if below scrolling region.
        !          65707: /
        !          65708: ////////
        !          65709: 
        !          65710: mm_ind:        incb    ROW
        !          65711:        cmpb    ROW, MM_EROW(bp)
        !          65712:        jg      0f
        !          65713:        jmp     repos
        !          65714: 0:     movb    ROW, MM_EROW(bp)
        !          65715:        jmp     scrollup
        !          65716: 
        !          65717: ////////
        !          65718: /
        !          65719: / mm_new - save cursor position
        !          65720: /
        !          65721: ////////
        !          65722: 
        !          65723: mm_new:        movb    MM_SCOL(bp), COL
        !          65724:        movb    MM_SROW(bp), ROW
        !          65725:        jmp     eval
        !          65726: 
        !          65727: ////////
        !          65728: /
        !          65729: / mm_old - restore old cursor position
        !          65730: /
        !          65731: ////////
        !          65732: 
        !          65733: mm_old:        movb    COL, MM_SCOL(bp)
        !          65734:        movb    ROW, MM_SROW(bp)
        !          65735:        jmp     repos
        !          65736: 
        !          65737: ////////
        !          65738: /
        !          65739: / mm_ri - reverse index
        !          65740: /
        !          65741: /      Moves the active position to the same horizontal position on the
        !          65742: /      preceding line.  Scrolling occurs if above scrolling region.
        !          65743: /
        !          65744: ////////
        !          65745: 
        !          65746: mm_ri: decb    ROW
        !          65747:        cmpb    ROW, MM_BROW(bp)
        !          65748:        jge     0f
        !          65749:        movb    ROW, MM_BROW(bp)
        !          65750:        jmp     scrolldown
        !          65751: 0:     jmp     repos
        !          65752: 
        !          65753: ////////
        !          65754: /
        !          65755: / mm_scr - select cursor rendition
        !          65756: /
        !          65757: /      Invokes the cursor rendition specified by the parameter.
        !          65758: /
        !          65759: /      Recognized renditions are:      0 - cursor visible
        !          65760: /                                      1 - cursor invisible
        !          65761: ////////
        !          65762: 
        !          65763: mm_scr:        decb     MM_N1(bp)
        !          65764:        je      0f
        !          65765:        jg      1f
        !          65766:        mov     MM_INVIS(bp), $0
        !          65767:        jmp     eval
        !          65768: 
        !          65769: 0:     mov     MM_INVIS(bp), $-1
        !          65770: 1:     jmp     eval
        !          65771: 
        !          65772: ////////
        !          65773: /
        !          65774: / mm_sgr - select graphic rendition
        !          65775: /
        !          65776: /      Invokes the graphic rendition specified by the parameter.
        !          65777: /      All following characters in the data stream are rendered
        !          65778: /      according to the parameters until the next occurrence of
        !          65779: /      SGR in the data stream.
        !          65780: /
        !          65781: /      Recognized renditions are:      1 - high intensity
        !          65782: /                                      4 - underline
        !          65783: /                                      5 - slow blink
        !          65784: /                                      7 - reverse video
        !          65785: /                                      8 - concealed on
        !          65786: /                                      30-37 - foreground color
        !          65787: /                                      40-47 - background color
        !          65788: /                                      50-57 - border color
        !          65789: /
        !          65790: ////////
        !          65791: 
        !          65792: mm_sgr:        movb    al, MM_N1(bp)
        !          65793: 
        !          65794:        cmpb    al, $0                  / reset all = 0
        !          65795:        jne     0f
        !          65796:        movb    ATTR, $0x07
        !          65797: 1:     jmp     eval
        !          65798: 
        !          65799: 0:     cmpb    al, $1                  / bold = 1
        !          65800:        jne     0f
        !          65801:        orb     ATTR, $INTENSE
        !          65802:        jmp     1b
        !          65803: 
        !          65804: 0:     cmpb    al, $4                  / underline = 4
        !          65805:        jne     0f
        !          65806:        cmp     MM_PORT(bp), $0x03D4    / color card?
        !          65807:        je      1b                      / yes, ignore underline
        !          65808:        andb    ATTR, $~0x77
        !          65809:        orb     ATTR, $0x01
        !          65810:        jmp     1b
        !          65811: 
        !          65812: 0:     cmpb    al, $5                  / blinking = 5
        !          65813:        jne     0f
        !          65814:        orb     ATTR, $BLINK
        !          65815:        jmp     1b
        !          65816: 
        !          65817: 0:     cmpb    al, $7                  / reverse video = 7
        !          65818:        jne     0f
        !          65819:        movb    al, $0x70
        !          65820:        cmp     MM_PORT(bp), $0x3D4     / color card?
        !          65821:        jne     2f
        !          65822:        movb    al, ATTR                / yes, exchange foreground/background
        !          65823:        andb    al, $0x77
        !          65824:        rolb    al, $1
        !          65825:        rolb    al, $1
        !          65826:        rolb    al, $1
        !          65827:        rolb    al, $1
        !          65828: 2:     andb    ATTR, $~0x77
        !          65829:        orb     ATTR, al
        !          65830:        jmp     1b
        !          65831: 
        !          65832: 0:     cmpb    al, $8                  / concealed on = 8
        !          65833:        jne     0f
        !          65834:        cmp     MM_PORT(bp), $0x3D4     / color card?
        !          65835:        jne     2f
        !          65836: 
        !          65837:        andb    ATTR, $0x70             / Yes,  Set foreground color
        !          65838:        movb    al, ATTR                /       to background color.
        !          65839:        rorb    al, $1
        !          65840:        rorb    al, $1
        !          65841:        rorb    al, $1
        !          65842:        rorb    al, $1
        !          65843:        orb     ATTR, al
        !          65844:        jmp     1b
        !          65845: 
        !          65846: 2:     andb    ATTR, $0x80             / No, set attributes to non-display.
        !          65847:        jmp     1b                      /       retain blink attribute.
        !          65848: 
        !          65849: 0:     cmp     MM_PORT(bp), $0x03D4    / color card?
        !          65850:        jne     1b                      / no, ignore remaining options
        !          65851: 0:     subb    al, $30                 / foreground color
        !          65852:        jl      1f
        !          65853:        cmpb    al, $7
        !          65854:        jg      0f
        !          65855:        movb    bl, al
        !          65856:        andb    ATTR, $~0x07
        !          65857:        orb     ATTR, cs:fcolor(bx)
        !          65858:        jmp     1f
        !          65859: 0:     subb    al, $10
        !          65860:        jl      1f
        !          65861:        cmpb    al, $7
        !          65862:        jg      0f
        !          65863:        movb    bl, al
        !          65864:        andb    ATTR, $~0x70
        !          65865:        orb     ATTR, cs:bcolor(bx)
        !          65866:        jmp     1f
        !          65867: 0:     subb    al, $10
        !          65868:        jl      1f
        !          65869:        cmpb    al, $7
        !          65870:        jg      0f
        !          65871:        movb    bl, al
        !          65872:        movb    al, cs:fcolor(bx)
        !          65873:        push    dx
        !          65874:        mov     dx, MM_PORT(bp)
        !          65875:        add     dx, $5
        !          65876:        outb    dx, al
        !          65877:        pop     dx
        !          65878: /      jmp     1f
        !          65879: 0:
        !          65880: 1:     jmp     eval
        !          65881: 
        !          65882: ////////
        !          65883: /
        !          65884: / mm_ssr - set scrolling region
        !          65885: /
        !          65886: ////////
        !          65887: 
        !          65888: mm_ssr:        movb    al, MM_N1(bp)
        !          65889:        decb    al
        !          65890:        jge     0f
        !          65891:        subb    al, al
        !          65892: 0:     cmpb    al, MM_LROW(bp)
        !          65893:        ja      1f
        !          65894:        movb    bl, MM_N2(bp)
        !          65895:        decb    bl
        !          65896:        jge     0f
        !          65897:        subb    bl, bl
        !          65898: 0:     cmpb    bl, MM_LROW(bp)
        !          65899:        ja      1f
        !          65900:        cmpb    al, bl
        !          65901:        ja      1f
        !          65902:        movb    MM_BROW(bp), al
        !          65903:        movb    MM_EROW(bp), bl
        !          65904:        movb    ROW, al
        !          65905:        subb    COL, COL
        !          65906: 1:     jmp     repos
        !          65907: 
        !          65908: ////////
        !          65909: /
        !          65910: / mm_vpa - vertical position absolute
        !          65911: /
        !          65912: /      Moves the active position to the line specified by the parameter
        !          65913: /      without changing the horizontal position.
        !          65914: /      A parameter value of 0 or 1 moves the active position vertically
        !          65915: /      to the first line.
        !          65916: /
        !          65917: ////////
        !          65918: 
        !          65919: mm_vpa:        movb    ROW, MM_N1(bp)
        !          65920:        decb    ROW
        !          65921:        jg      0f
        !          65922:        subb    ROW, ROW
        !          65923: 0:     cmpb    ROW, MM_LROW(bp)
        !          65924:        jna     0f
        !          65925:        movb    ROW, MM_LROW(bp)
        !          65926: 0:     jmp     repos                   / reposition cursor
        !          65927: 
        !          65928: ////////
        !          65929: /
        !          65930: / mm_vpr - vertical position relative
        !          65931: /
        !          65932: /      Moves the active position downward the number of lines specified
        !          65933: /      by the parameter without changing the horizontal position.
        !          65934: /      A parameter value of zero or one moves the active position
        !          65935: /      one line downward.
        !          65936: /
        !          65937: ////////
        !          65938: 
        !          65939: mm_vpr:        movb    al, MM_N1(bp)
        !          65940:        orb     al, al
        !          65941:        jne     0f
        !          65942:        incb    al
        !          65943: 0:     addb    ROW, al
        !          65944:        cmpb    ROW, MM_LROW(bp)
        !          65945:        jb      0f
        !          65946:        movb    ROW, MM_LROW(bp)
        !          65947: 0:     jmp     repos                   / reposition cursor
        !          65948: 
        !          65949: ////////
        !          65950: /
        !          65951: / asctab - table of functions indexed by ascii characters
        !          65952: /
        !          65953: ////////
        !          65954: 
        !          65955: asctab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          65956:        .word   eval,   eval,   eval,   mmbell  /* EOT  ENQ  ACK  BEL  */
        !          65957:        .word   mm_cub, mm_cht, mm_cnl, mm_ind  /* BS   HT   LF   VT   */
        !          65958:        .word   eval,   mm_cr,  eval,   eval    /* FF   CR   SO   SI   */
        !          65959:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3  */
        !          65960:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          65961:        .word   eval,   eval,   eval,   mm_esc  /* CAN  EM   SUB  ESC  */
        !          65962:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          65963:        .word   mmputc, mmputc, mmputc, mmputc  /*   ! " # \040 - \043 */
        !          65964:        .word   mmputc, mmputc, mmputc, mmputc  /* $ % & ' \044 - \047 */
        !          65965:        .word   mmputc, mmputc, mmputc, mmputc  /* ( ) * + \050 - \053 */
        !          65966:        .word   mmputc, mmputc, mmputc, mmputc  /* , - . / \054 - \057 */
        !          65967:        .word   mmputc, mmputc, mmputc, mmputc  /* 0 1 2 3 \060 - \063 */
        !          65968:        .word   mmputc, mmputc, mmputc, mmputc  /* 4 5 6 7 \064 - \067 */
        !          65969:        .word   mmputc, mmputc, mmputc, mmputc  /* 8 9 : ; \070 - \073 */
        !          65970:        .word   mmputc, mmputc, mmputc, mmputc  /* < = > ? \074 - \077 */
        !          65971:        .word   mmputc, mmputc, mmputc, mmputc  /* @@ A B C \100 - \103 */
        !          65972:        .word   mmputc, mmputc, mmputc, mmputc  /* D E F G \104 - \107 */
        !          65973:        .word   mmputc, mmputc, mmputc, mmputc  /* H I J K \110 - \113 */
        !          65974:        .word   mmputc, mmputc, mmputc, mmputc  /* L M N O \114 - \117 */
        !          65975:        .word   mmputc, mmputc, mmputc, mmputc  /* P Q R S \120 - \123 */
        !          65976:        .word   mmputc, mmputc, mmputc, mmputc  /* T U V W \124 - \127 */
        !          65977:        .word   mmputc, mmputc, mmputc, mmputc  /* X Y Z [ \130 - \133 */
        !          65978:        .word   mmputc, mmputc, mmputc, mmputc  /* \ ] ^ _ \134 - \137 */
        !          65979:        .word   mmputc, mmputc, mmputc, mmputc  /* ` a b c \140 - \143 */
        !          65980:        .word   mmputc, mmputc, mmputc, mmputc  /* d e f g \144 - \147 */
        !          65981:        .word   mmputc, mmputc, mmputc, mmputc  /* h i j k \150 - \153 */
        !          65982:        .word   mmputc, mmputc, mmputc, mmputc  /* l m n o \154 - \157 */
        !          65983:        .word   mmputc, mmputc, mmputc, mmputc  /* p q r s \160 - \163 */
        !          65984:        .word   mmputc, mmputc, mmputc, mmputc  /* t u v w \164 - \167 */
        !          65985:        .word   mmputc, mmputc, mmputc, mmputc  /* x y z { \170 - \173 */
        !          65986:        .word   mmputc, mmputc, mmputc, mmputc  /* | } ~ ? \174 - \177 */
        !          65987: 
        !          65988: ////////
        !          65989: /
        !          65990: / esctab - table of functions indexed by ESC characters.
        !          65991: /
        !          65992: ////////
        !          65993: 
        !          65994: esctab:        .word   mmputc, mmputc, mmputc, mmputc  /* NUL  SOH  STX  ETX  */
        !          65995:        .word   mmputc, mmputc, mmputc, mmputc  /* EOT  ENQ  ACK  BEL  */
        !          65996:        .word   mmputc, mmputc, mmputc, mmputc  /* BS   HT   LF   VT   */
        !          65997:        .word   mmputc, mmputc, mmputc, mmputc  /* FF   CR   SO   SI   */
        !          65998:        .word   mmputc, mmputc, mmputc, mmputc  /* DLE  DC1  DC2  DC3  */
        !          65999:        .word   mmputc, mmputc, mmputc, mmputc  /* DC4  NAK  SYN  ETB  */
        !          66000:        .word   mmputc, mmputc, mmputc, mmputc  /* CAN  EM   SUB  ESC  */
        !          66001:        .word   mmputc, mmputc, mmputc, mmputc  /* FS   GS   RS   US   */
        !          66002:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          66003:        .word   eval,   eval,   eval,   eval    /* $ % & ' \044 - \047 */
        !          66004:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          66005:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          66006:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          66007:        .word   eval,   eval,   eval,   mm_new  /* 4 5 6 7 \064 - \067 */
        !          66008:        .word   mm_old, eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          66009:        .word   eval,   mmspec, mmspec, eval    /* < = > ? \074 - \077 */
        !          66010:        .word   eval,   eval,   eval,   eval    /* @@ A B C \100 - \103 */
        !          66011:        .word   mm_ind, mm_cnl, eval,   eval    /* D E F G \104 - \107 */
        !          66012:        .word   eval,   eval,   eval,   eval    /* H I J K \110 - \113 */
        !          66013:        .word   eval,   mm_ri,  eval,   eval    /* L M N O \114 - \117 */
        !          66014:        .word   eval,   eval,   eval,   eval    /* P Q R S \120 - \123 */
        !          66015:        .word   eval,   eval,   eval,   eval    /* T U V W \124 - \127 */
        !          66016:        .word   eval,   eval,   eval,   csi_n1  /* X Y Z [ \130 - \133 */
        !          66017:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          66018:        .word   mm_dmi, eval,   mm_emi, mminit  /* ` a b c \140 - \143 */
        !          66019:        .word   eval,   eval,   eval,   eval    /* d e f g \144 - \147 */
        !          66020:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          66021:        .word   eval,   eval,   eval,   eval    /* l m n o \154 - \157 */
        !          66022:        .word   eval,   eval,   eval,   eval    /* p q r s \160 - \163 */
        !          66023:        .word   mmspec, mmspec, eval,   eval    /* t u v w \164 - \167 */
        !          66024:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          66025:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          66026: 
        !          66027: 
        !          66028: ////////
        !          66029: /
        !          66030: / csitab - table of functions indexed by ESC [ characters.
        !          66031: /
        !          66032: ////////
        !          66033: 
        !          66034: csitab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          66035:        .word   eval,   eval,   eval,   eval    /* EOT  ENQ  ACK  BEL  */
        !          66036:        .word   eval,   eval,   eval,   eval    /* BS   HT   LF   VT   */
        !          66037:        .word   eval,   eval,   eval,   eval    /* FF   CR   SO   SI   */
        !          66038:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3  */
        !          66039:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          66040:        .word   eval,   eval,   eval,   eval    /* CAN  EM   SUB  ESC  */
        !          66041:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          66042:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          66043:        .word   eval,   eval,   eval,   eval    /* $ % & ' \044 - \047 */
        !          66044:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          66045:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          66046:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          66047:        .word   eval,   eval,   eval,   eval    /* 4 5 6 7 \064 - \067 */
        !          66048:        .word   eval,   eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          66049:        .word   eval,   eval,   csi_gt, csi_q   /* < = > ? \074 - \077 */
        !          66050:        .word   eval,   mm_cuu, mm_cud, mm_cuf  /* @@ A B C \100 - \103 */
        !          66051:        .word   mm_cub, mm_cnl, mm_cpl, mm_cha  /* D E F G \104 - \107 */
        !          66052:        .word   mm_cup, mm_cht, mm_ed,  mm_el   /* H I J K \110 - \113 */
        !          66053:        .word   mm_il,  mm_dl,  eval,   mm_ea   /* L M N O \114 - \117 */
        !          66054:        .word   eval,   eval,   eval,   mm_ind  /* P Q R S \120 - \123 */
        !          66055:        .word   mm_ri,  eval,   eval,   eval    /* T U V W \124 - \127 */
        !          66056:        .word   eval,   eval,   mm_cbt, eval    /* X Y Z [ \130 - \133 */
        !          66057:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          66058:        .word   mm_hpa, mm_hpr, eval,   eval    /* ` a b c \140 - \143 */
        !          66059:        .word   mm_vpa, mm_vpr, mm_hvp, mm_cup  /* d e f g \144 - \147 */
        !          66060:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          66061:        .word   eval,   mm_sgr, eval,   eval    /* l m n o \154 - \157 */
        !          66062:        .word   eval,   eval,   mm_ssr, eval    /* p q r s \160 - \163 */
        !          66063:        .word   eval,   eval,   mm_scr, eval    /* t u v w \164 - \167 */
        !          66064:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          66065:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          66066: 
        !          66067: ////////
        !          66068: /
        !          66069: / coltab - integer array of offsets to each column
        !          66070: /
        !          66071: ////////
        !          66072: 
        !          66073: coltab:        .word    0*NCB,  1*NCB,  2*NCB,  3*NCB
        !          66074:        .word    4*NCB,  5*NCB,  6*NCB,  7*NCB
        !          66075:        .word    8*NCB,  9*NCB, 10*NCB, 11*NCB
        !          66076:        .word   12*NCB, 13*NCB, 14*NCB, 15*NCB
        !          66077:        .word   16*NCB, 17*NCB, 18*NCB, 19*NCB
        !          66078:        .word   20*NCB, 21*NCB, 22*NCB, 23*NCB
        !          66079:        .word   24*NCB, 25*NCB, 26*NCB, 27*NCB
        !          66080:        .word   28*NCB, 29*NCB, 30*NCB, 31*NCB
        !          66081:        .word   32*NCB, 33*NCB, 34*NCB, 35*NCB
        !          66082:        .word   36*NCB, 37*NCB, 38*NCB, 39*NCB
        !          66083:        .word   40*NCB, 41*NCB, 42*NCB, 43*NCB
        !          66084:        .word   44*NCB, 45*NCB, 46*NCB, 47*NCB
        !          66085:        .word   48*NCB, 49*NCB, 50*NCB, 51*NCB
        !          66086:        .word   52*NCB, 53*NCB, 54*NCB, 55*NCB
        !          66087:        .word   56*NCB, 57*NCB, 58*NCB, 59*NCB
        !          66088:        .word   60*NCB, 61*NCB, 62*NCB, 63*NCB
        !          66089:        .word   64*NCB, 65*NCB, 66*NCB, 67*NCB
        !          66090:        .word   68*NCB, 69*NCB, 70*NCB, 71*NCB
        !          66091:        .word   72*NCB, 73*NCB, 74*NCB, 75*NCB
        !          66092:        .word   76*NCB, 77*NCB, 78*NCB, 79*NCB
        !          66093: 
        !          66094: ////////
        !          66095: /
        !          66096: / rowtab - array of offsets to each row
        !          66097: /
        !          66098: ////////
        !          66099: 
        !          66100: rowtab:        .word    0*NRB,  1*NRB,  2*NRB,  3*NRB
        !          66101:        .word    4*NRB,  5*NRB,  6*NRB,  7*NRB
        !          66102:        .word    8*NRB,  9*NRB, 10*NRB, 11*NRB
        !          66103:        .word   12*NRB, 13*NRB, 14*NRB, 15*NRB
        !          66104:        .word   16*NRB, 17*NRB, 18*NRB, 19*NRB
        !          66105:        .word   20*NRB, 21*NRB, 22*NRB, 23*NRB
        !          66106:        .word   24*NRB, 25*NRB, 26*NRB, 27*NRB
        !          66107:        .word   28*NRB, 29*NRB, 30*NRB, 31*NRB
        !          66108: 
        !          66109: ////////
        !          66110: /
        !          66111: / fcolor - foreground color
        !          66112: / bcolor - background color
        !          66113: /
        !          66114: /      indexed by ansi color (black,red,green,brown,blue,magenta,cyan,white)
        !          66115: /      yields graphics color (black,blue,green,cyan,red,magenta,brown,white)
        !          66116: /              which is properly shifted for installation in attribute byte.
        !          66117: /
        !          66118: ////////
        !          66119: 
        !          66120: fcolor:        .byte   0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07
        !          66121: bcolor:        .byte   0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70
        !          66122: 
        !          66123: ////////
        !          66124: /
        !          66125: / mm_voff()    -- turn video display off
        !          66126: /
        !          66127: ////////
        !          66128:        .globl  mm_voff_
        !          66129: mm_voff_:
        !          66130:        mov     dx, mmdata+MM_PORT
        !          66131:        add     dx, $4
        !          66132:        movb    al, $0x21
        !          66133:        outb    dx, al
        !          66134:        ret
        !          66135: 
        !          66136: ////////
        !          66137: /
        !          66138: / mm_von()     -- turn video display on
        !          66139: /
        !          66140: ////////
        !          66141:        .globl  mm_von_
        !          66142: mm_von_:
        !          66143:        mov     dx, mmdata+MM_PORT      / enable video display
        !          66144:        add     dx, $4
        !          66145:        movb    al, $0x29
        !          66146:        outb    dx, al
        !          66147:        mov     mmvcnt_, $900           / 900 seconds before video disabled
        !          66148:        ret
        !          66149: @
        !          66150: 
        !          66151: 
        !          66152: 1.1
        !          66153: log
        !          66154: @Initial revision
        !          66155: @
        !          66156: text
        !          66157: @a0 5
        !          66158: / (lgl-
        !          66159: /      COHERENT Driver Kit Version 1.1.0
        !          66160: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          66161: /      All rights reserved. May not be copied without permission.
        !          66162: / -lgl)
        !          66163: d337 1
        !          66164: d355 1
        !          66165: d367 1
        !          66166: d379 1
        !          66167: d397 1
        !          66168: d417 1
        !          66169: d443 1
        !          66170: d515 1
        !          66171: @
        !          66172: 0707070064030106631004440000030000030000011777770507310675400005400000021265/newbits/kernel/USRSRC/i8086/drv/RCS/ms.c,vhead     1.3;
        !          66173: branch   ;
        !          66174: access   ;
        !          66175: symbols  ;
        !          66176: locks    bin:1.3; strict;
        !          66177: comment  @ * @;
        !          66178: 
        !          66179: 
        !          66180: 1.3
        !          66181: date     91.06.20.14.51.08;  author bin;  state Exp;
        !          66182: branches ;
        !          66183: next     1.2;
        !          66184: 
        !          66185: 1.2
        !          66186: date     91.06.17.12.33.02;  author bin;  state Exp;
        !          66187: branches ;
        !          66188: next     1.1;
        !          66189: 
        !          66190: 1.1
        !          66191: date     91.06.10.10.23.45;  author bin;  state Exp;
        !          66192: branches ;
        !          66193: next     ;
        !          66194: 
        !          66195: 
        !          66196: desc
        !          66197: @initial version prov by hal
        !          66198: @
        !          66199: 
        !          66200: 
        !          66201: 1.3
        !          66202: log
        !          66203: @update provided by hal
        !          66204: @
        !          66205: text
        !          66206: @/* (-lgl
        !          66207:  *     COHERENT Driver Kit Version 1.1.0
        !          66208:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          66209:  *     All rights reserved. May not be copied without permission.
        !          66210:  -lgl) */
        !          66211: /*
        !          66212:  *     Microsoft bus mouse (rodent) driver.
        !          66213:  */
        !          66214: 
        !          66215: #include <sys/coherent.h>
        !          66216: #include <sys/uproc.h>
        !          66217: #include <sys/con.h>
        !          66218: #include <sys/ms.h>
        !          66219: #include <errno.h>
        !          66220: 
        !          66221: #define Help(fmt, p)           printf(fmt, p)
        !          66222: #define Help2(fmt, p, q)       printf(fmt, p, q)
        !          66223: #define Diag(fmt, p)           /* Help(fmt, p) */
        !          66224: #define Diag2(fmt, p, q)       /* Help2(fmt, p, q) */
        !          66225: #define        MSMAJOR         10      /* major device # */
        !          66226: 
        !          66227: /*
        !          66228:  *     global patchable definitions
        !          66229:  */
        !          66230: unsigned MSPORT  = 0x23C;      /* mouse 8255A registers: */
        !          66231:                                /* modified mouse is 0x23C */
        !          66232:                                /* Geac modified mouse is 0x230 */
        !          66233: unsigned MSIRQ   = 2;          /* mouse interrupt # */
        !          66234: 
        !          66235: /*
        !          66236:  *     driver function definitions
        !          66237:  */
        !          66238: int    msload();
        !          66239: int    msunload();
        !          66240: int    msopen();
        !          66241: int    msclose();
        !          66242: int    msioctl();
        !          66243: int    mspoll();
        !          66244: int    msintr();
        !          66245: int    nulldev();
        !          66246: int    nonedev();
        !          66247: 
        !          66248: /*
        !          66249:  *     configuration table
        !          66250:  */
        !          66251: CON mscon = {
        !          66252:        DFCHR|DFPOL,                    /* flags        */
        !          66253:        MSMAJOR,                        /* major index  */
        !          66254:        msopen,                         /* open         */
        !          66255:        msclose,                        /* close        */
        !          66256:        nonedev,                        /* block        */
        !          66257:        nonedev,                        /* read         */
        !          66258:        nonedev,                        /* write        */
        !          66259:        msioctl,                        /* ioctl        */
        !          66260:        nulldev,                        /* power fail   */
        !          66261:        nulldev,                        /* timeout      */
        !          66262:        msload,                         /* load         */
        !          66263:        msunload,                       /* unload       */
        !          66264:        mspoll                          /* poll         */
        !          66265: };
        !          66266: 
        !          66267: /*
        !          66268:  *     ioctl function definitions
        !          66269:  */
        !          66270: 
        !          66271: int    ms_setup();
        !          66272: int    ms_setcrs();
        !          66273: int    ms_readcrs();
        !          66274: int    ms_setmick();
        !          66275: int    ms_readmick();
        !          66276: int    ms_readbtns();
        !          66277: int    ms_readstat();
        !          66278: int    ms_wait();
        !          66279: 
        !          66280: int (*ioctls[])() = {
        !          66281:   /*      0         1           2           3            4             */
        !          66282:        ms_setup, ms_setcrs, ms_readcrs, ms_setmick, ms_readmick,
        !          66283: 
        !          66284:   /*        5           6         7                                    */
        !          66285:        ms_readbtns, ms_readstat, ms_wait
        !          66286: };
        !          66287: 
        !          66288: /*
        !          66289:  *     hardware constants
        !          66290:  */
        !          66291: static int     porta;                  /*      port A (read/write) */
        !          66292: static int     portb;                  /*      port B (read/write) */
        !          66293: static int     portc;                  /*      port C (read/write) */
        !          66294: static int     portcm;                 /*      control port (write only) */
        !          66295: 
        !          66296: static int     u_stts  =  0;           /* changed-status flags */
        !          66297: static int     u_mask  =  0;           /* user condition mask */
        !          66298: 
        !          66299: static event_t ipolls;
        !          66300: 
        !          66301: static struct msparms parms, initparm = {
        !          66302:        2, -16, 655, -16, 215, 8, 16
        !          66303: };
        !          66304: 
        !          66305: static struct mspos crsr, csav, initcrsr = { 320, 100 };
        !          66306: 
        !          66307: static struct msmick mick, initmick = { 0, 0 };
        !          66308: 
        !          66309: static struct msbuts buttons, initbuttons = {
        !          66310:        0,
        !          66311:        {       {0, {320, 100}},
        !          66312:                {0, {320, 100}},
        !          66313:                {0, {320, 100}},
        !          66314:                {0, {320, 100}}
        !          66315:        }
        !          66316: };
        !          66317: 
        !          66318: static int     ms_inuse = 0;           /* is mouse in use ? */
        !          66319: 
        !          66320: msload()
        !          66321: {
        !          66322:        int s;
        !          66323: 
        !          66324:        porta  = MSPORT;
        !          66325:        portb  = MSPORT + 1;
        !          66326:        portc  = MSPORT + 2;
        !          66327:        portcm = MSPORT + 3;
        !          66328: 
        !          66329:        s = sphi();
        !          66330:        outb( portcm, 0x91 );           /* set 8255A mode 9 */
        !          66331:        outb( portc,  0x10 );           /* disable interrupt */
        !          66332:        setivec( MSIRQ, msintr );       /* set up irq vector */
        !          66333:        spl(s);
        !          66334: 
        !          66335:        return 0;
        !          66336: }
        !          66337: 
        !          66338: /*
        !          66339:  * Unload function.
        !          66340:  */
        !          66341: msunload()
        !          66342: {
        !          66343:        clrivec( MSIRQ );               /* release irq vector */
        !          66344:        outb( portcm, 0x91 );           /* set 8255A mode 9 */
        !          66345:        outb( portc,  0x10 );           /* disable interrupt */
        !          66346: }
        !          66347: 
        !          66348: msopen(dev, mode)
        !          66349: dev_t  dev;
        !          66350: {
        !          66351:        int     s;
        !          66352: 
        !          66353:        s = sphi(s);
        !          66354:        if (ms_inuse) {
        !          66355:                u.u_error = EDBUSY;
        !          66356:                spl(s);
        !          66357:                return( -1 );
        !          66358:        }
        !          66359: 
        !          66360:        outb( portcm, 0x91 );                   /* set 8255A mode 9 */
        !          66361:        outb( portb,  0x5a );
        !          66362: 
        !          66363:        if( inb( portb ) != 0x5a) {             /* hardware installed? */
        !          66364:                u.u_error = ENXIO;
        !          66365:                spl(s);
        !          66366:                return( -1 );
        !          66367:        }
        !          66368: 
        !          66369:        outb( portc, 0x90 );
        !          66370:        inb( porta );
        !          66371:        outb( portc, 0xb0 );
        !          66372:        inb( porta );
        !          66373:        outb( portc, 0xd0 );
        !          66374:        inb( porta );
        !          66375:        outb( portc, 0xf0 );
        !          66376:        inb( porta );
        !          66377:        outb( portc, 0 );               /* clear all mouse registers */
        !          66378: 
        !          66379: /* set things */
        !          66380:        parms = initparm;
        !          66381:        crsr = csav = initcrsr;
        !          66382:        mick = initmick;
        !          66383:        buttons = initbuttons;
        !          66384:        u_stts = u.u_error = 0;
        !          66385:        ms_inuse = 1;
        !          66386:        spl(s);
        !          66387: 
        !          66388:        return( 0 );
        !          66389: }
        !          66390: 
        !          66391: msclose()
        !          66392: {
        !          66393:        int s;
        !          66394: 
        !          66395:        s = sphi();
        !          66396:        outb( portc, 0x10 );                    /* disable interrupt */
        !          66397:        ms_inuse = u.u_error = 0;
        !          66398:        spl(s);
        !          66399:        return( 0 );
        !          66400: }
        !          66401: 
        !          66402: msioctl( dev, com, vec )
        !          66403: dev_t  dev;
        !          66404: int    com;
        !          66405: char   *vec;
        !          66406: {
        !          66407:        int s;
        !          66408: 
        !          66409:        s = sphi();
        !          66410:        if (com >= 0 && com < sizeof(ioctls)/sizeof(ioctls[0])) {
        !          66411:                (*ioctls[com])(vec);    /* indirect func call */
        !          66412:                u.u_error = 0;
        !          66413:        } else
        !          66414:                u.u_error = EINVAL;
        !          66415:        spl(s);
        !          66416:        if (u.u_error)
        !          66417:                return( -1 );
        !          66418: 
        !          66419:        return( 0 );
        !          66420: }
        !          66421: 
        !          66422: /*
        !          66423:  * Polling routine.
        !          66424:  * [System V.3 Compatible].
        !          66425:  */
        !          66426: mspoll( dev, ev, msec )
        !          66427: dev_t dev;
        !          66428: int ev;
        !          66429: int msec;
        !          66430: {
        !          66431:        ev &= ~POLLPRI;
        !          66432:        ev &= ~POLLOUT;
        !          66433: 
        !          66434:        /*
        !          66435:         * No input.
        !          66436:         */
        !          66437:        if ( (u_stts & u_mask) == 0 ) {
        !          66438:                /*
        !          66439:                 * Enable monitor if blocking poll.
        !          66440:                 */
        !          66441:                if ( msec != 0 ) 
        !          66442:                        pollopen( &ipolls );
        !          66443:                /*
        !          66444:                 * Look again to avoid interrupt race.
        !          66445:                 */
        !          66446:                if ( (u_stts & u_mask) == 0 )
        !          66447:                        ev &= ~POLLIN;
        !          66448:        }
        !          66449: 
        !          66450:        return ev;
        !          66451: }
        !          66452: 
        !          66453: /*
        !          66454:  *     write setup structure
        !          66455:  */
        !          66456: ms_setup( newparm )
        !          66457: struct msparms *newparm;
        !          66458: {
        !          66459:        ukcopy(newparm, &parms, sizeof(struct msparms));
        !          66460:        if (parms.h_mpr == 0)
        !          66461:                parms.h_mpr = 1;
        !          66462:        if (parms.v_mpr == 0)
        !          66463:                parms.v_mpr = 1;
        !          66464: }
        !          66465: 
        !          66466: /*
        !          66467:  *     write cursor position
        !          66468:  */
        !          66469: ms_setcrs( pos )
        !          66470: struct mspos *pos;
        !          66471: {
        !          66472:        ukcopy(pos, &crsr, sizeof(struct mspos));
        !          66473:        u_stts &= ~MS_S_MOVE;           /* clear u_stts pos bit */
        !          66474: }
        !          66475: 
        !          66476: /*
        !          66477:  *     read cursor postion
        !          66478:  */
        !          66479: ms_readcrs( pos )
        !          66480: struct mspos *pos;
        !          66481: {
        !          66482:        kucopy(&crsr, pos, sizeof(struct mspos));
        !          66483:        u_stts &= ~MS_S_MOVE;           /* clear u_stts pos bit */
        !          66484: }
        !          66485: 
        !          66486: /*
        !          66487:  *     write mickey postion
        !          66488:  */
        !          66489: ms_setmick( pos )
        !          66490: struct msmick *pos;
        !          66491: {
        !          66492:        ukcopy(pos, &mick, sizeof(struct msmick));
        !          66493: }
        !          66494: 
        !          66495: /*
        !          66496:  *     read mickey postion
        !          66497:  */
        !          66498: ms_readmick( pos )
        !          66499: struct msmick *pos;
        !          66500: {
        !          66501:        kucopy(&mick, pos, sizeof(struct msmick));
        !          66502: }
        !          66503: 
        !          66504: /*
        !          66505:  *     read button status
        !          66506:  */
        !          66507: ms_readbtns( btns )
        !          66508: struct msbuts *btns;
        !          66509: {
        !          66510:        kucopy(&buttons, btns, sizeof(struct msbuts));
        !          66511:        u_stts &= ~MS_S_BUTTONS;                /* clear u_stts button bits */
        !          66512: }
        !          66513: 
        !          66514: /*
        !          66515:  *     read "changed status" mask
        !          66516:  */
        !          66517: ms_readstat( stat )
        !          66518: int *stat;
        !          66519: {
        !          66520:        kucopy(&u_stts, stat, sizeof(int));
        !          66521: }
        !          66522: 
        !          66523: /*
        !          66524:  *     wait on "changed status" mask
        !          66525:  */
        !          66526: ms_wait( flag )
        !          66527: int *flag;
        !          66528: {
        !          66529:        ukcopy(flag, &u_mask, sizeof(int));
        !          66530:        while ((u_mask & u_stts) == 0)  /* wait until any bit is on */
        !          66531:                sleep(&u_stts, 0x7fff, 0x7fff, 0);
        !          66532:        u_mask = 0;
        !          66533: }
        !          66534: 
        !          66535: /*
        !          66536:  *     mouse interrupt service routine
        !          66537:  */
        !          66538: msintr()
        !          66539: {
        !          66540:        static  int h_fpix =  0;                        /* fractional pixel */
        !          66541:        static  int v_fpix = 0;                         /* ditto */
        !          66542:        int     s, n_l, n_h, h_diff, v_diff, tmp, left, right;
        !          66543: 
        !          66544:        if (!ms_inuse)                  /* dev not open - ignore interrupts */
        !          66545:                return;
        !          66546:        
        !          66547:        s = sphi();
        !          66548:        outb( portc, 0x90 );            /* get horizontal change */
        !          66549:        n_l = inb( porta );
        !          66550:        outb( portc, 0xb0 );
        !          66551:        n_h = inb( porta );
        !          66552:        h_diff = (char) ((n_l & 0x0f) | (n_h << 4));
        !          66553: 
        !          66554:        outb( portc, 0xd0 );            /* get vertical change */
        !          66555:        n_l = inb( porta );
        !          66556:        outb( portc, 0xf0 );
        !          66557:        n_h = inb( porta );
        !          66558:        v_diff = (char) ((n_l & 0x0f) | (n_h << 4));
        !          66559: 
        !          66560:        outb( portc, 0 );
        !          66561:        left = right = 0;                               /* set button status */
        !          66562:        if (!(n_h & 0x80)) left = MS_L_DOWN;            /* left button.. */
        !          66563:        if ((buttons.bbstat & MS_L_DOWN) ^ left) {
        !          66564:                if (left)
        !          66565:                        button(MS_B_L_PRESS,   MS_S_L_PRESS);
        !          66566:                else
        !          66567:                        button(MS_B_L_RELEASE, MS_S_L_RELEASE);
        !          66568:        }
        !          66569:        if (!(n_h & 0x20))                              /* right button.. */
        !          66570:                right = MS_R_DOWN;
        !          66571:        if ((buttons.bbstat & MS_R_DOWN) ^ right) {
        !          66572:                if (right)
        !          66573:                        button(MS_B_R_PRESS,   MS_S_R_PRESS);
        !          66574:                else
        !          66575:                        button(MS_B_R_RELEASE, MS_S_R_RELEASE);
        !          66576:        }
        !          66577: 
        !          66578:        buttons.bbstat = left | right;          /* set new button status */
        !          66579: 
        !          66580:        if (h_diff || v_diff) {                 /* any motion? */
        !          66581:                mick.h_mick += h_diff;          /* yes - update positions */
        !          66582:                mick.v_mick += v_diff;
        !          66583:                if ((abs(h_diff) > parms.accel_t) || (abs(v_diff) > parms.accel_t)) {
        !          66584:                        h_diff *= 2;
        !          66585:                        v_diff *= 2;
        !          66586:                }
        !          66587: 
        !          66588:                if (h_diff) {                   /* horizontal change */
        !          66589:                        tmp   = h_fpix + 8 * h_diff;
        !          66590:                        h_fpix = tmp % parms.h_mpr;
        !          66591:                        tmp    = crsr.h_crsr + tmp / parms.h_mpr;
        !          66592:                        crsr.h_crsr = c_range(tmp, parms.h_cmin, parms.h_cmax);
        !          66593:                }
        !          66594: 
        !          66595:                if (v_diff) {                   /* vertical change */                                                                                                                                                                                           
        !          66596:                        tmp   = v_fpix + 8 * v_diff;
        !          66597:                        v_fpix = tmp % parms.v_mpr;
        !          66598:                        tmp    = crsr.v_crsr + tmp / parms.v_mpr;
        !          66599:                        crsr.v_crsr = c_range(tmp, parms.v_cmin, parms.v_cmax);
        !          66600:                }
        !          66601: 
        !          66602:                if ((crsr.h_crsr != csav.h_crsr) || (crsr.v_crsr != csav.v_crsr)) {
        !          66603:                        u_stts |= MS_S_MOVE;
        !          66604:                        csav = crsr;
        !          66605:                }
        !          66606:        }
        !          66607: 
        !          66608:        if (u_stts & u_mask) {
        !          66609:                wakeup(&u_stts);
        !          66610:                if ( ipolls.e_procp )
        !          66611:                        pollwake( &ipolls );
        !          66612:        }
        !          66613: 
        !          66614:        spl(s);
        !          66615: }
        !          66616: 
        !          66617: /*
        !          66618:  *     update button-press/release data
        !          66619:  */
        !          66620: button( bp, sbit )
        !          66621: int bp;
        !          66622: unsigned sbit;
        !          66623: {
        !          66624:        ++buttons.buts[bp].cnt;
        !          66625:        buttons.buts[bp].bpos = crsr;
        !          66626:        u_stts |= sbit;
        !          66627: }
        !          66628: 
        !          66629: /*
        !          66630:  *     force return value to be within specified range
        !          66631:  */
        !          66632: c_range(c, cmin, cmax)
        !          66633: int    c, cmin, cmax;
        !          66634: {
        !          66635:        if( c < cmin )
        !          66636:                c = cmin;
        !          66637:        else if( c > cmax )
        !          66638:                c = cmax;
        !          66639:        return( c );
        !          66640: }
        !          66641: 
        !          66642: abs(i)
        !          66643: int i;
        !          66644: {
        !          66645:        if (i < 0)
        !          66646:                return (-i);
        !          66647:        return i;
        !          66648: }
        !          66649: @
        !          66650: 
        !          66651: 
        !          66652: 1.2
        !          66653: log
        !          66654: @new version provided y hal for v321
        !          66655: @
        !          66656: text
        !          66657: @d10 1
        !          66658: a10 1
        !          66659: #include <coherent.h>
        !          66660: @
        !          66661: 
        !          66662: 
        !          66663: 1.1
        !          66664: log
        !          66665: @Initial revision
        !          66666: @
        !          66667: text
        !          66668: @d10 1
        !          66669: a10 1
        !          66670: #include <sys/coherent.h>
        !          66671: @
        !          66672: 0707070064030106611004440000030000030000011777770507310675600005500000045247/newbits/kernel/USRSRC/i8086/drv/RCS/msg.c,vhead     1.4;
        !          66673: branch   ;
        !          66674: access   ;
        !          66675: symbols  ;
        !          66676: locks    bin:1.4; strict;
        !          66677: comment  @ * @;
        !          66678: 
        !          66679: 
        !          66680: 1.4
        !          66681: date     91.06.20.14.51.17;  author bin;  state Exp;
        !          66682: branches ;
        !          66683: next     1.3;
        !          66684: 
        !          66685: 1.3
        !          66686: date     91.06.18.08.12.53;  author bin;  state Exp;
        !          66687: branches ;
        !          66688: next     1.2;
        !          66689: 
        !          66690: 1.2
        !          66691: date     91.06.17.12.33.12;  author bin;  state Exp;
        !          66692: branches ;
        !          66693: next     1.1;
        !          66694: 
        !          66695: 1.1
        !          66696: date     91.06.10.10.23.53;  author bin;  state Exp;
        !          66697: branches ;
        !          66698: next     ;
        !          66699: 
        !          66700: 
        !          66701: desc
        !          66702: @initial version prov by hal
        !          66703: @
        !          66704: 
        !          66705: 
        !          66706: 1.4
        !          66707: log
        !          66708: @update provided by hal
        !          66709: @
        !          66710: text
        !          66711: @/* $Header: /usr/src/sys/i8086/drv/RCS/msg.c,v 2.1 88/09/03 13:09:07 src Exp $
        !          66712:  *
        !          66713:  *     The  information  contained herein  is a trade secret  of INETCO
        !          66714:  *     Systems, and is confidential information.   It is provided under
        !          66715:  *     a license agreement,  and may be copied or disclosed  only under
        !          66716:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          66717:  *     this  material  without  the express  written  authorization  of
        !          66718:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          66719:  *
        !          66720:  *     Copyright (c) 1987, 1986, 1985, 1984.
        !          66721:  *     An unpublished work by INETCO Systems, Ltd.
        !          66722:  *     All rights reserved.
        !          66723:  */
        !          66724: 
        !          66725: /*
        !          66726:  * System V Compatible Messaging
        !          66727:  *
        !          66728:  *     This module provides System V compatible messaging operations.
        !          66729:  *
        !          66730:  *                     Author: Allan Cornish, INETCO Systems Ltd., Oct 1984
        !          66731:  *
        !          66732:  * $Log:       /usr/src/sys/i8086/drv/RCS/msg.c,v $
        !          66733:  * Revision 2.1        88/09/03  13:09:07      src
        !          66734:  * *** empty log message ***
        !          66735:  * 
        !          66736:  * Revision 1.2        88/08/02  16:49:52      src
        !          66737:  * Bug:        msgget with IPC_CREAT could fail if message queue already
        !          66738:  *     existed, and queue permissions were not an exact match
        !          66739:  *     for requested permissions.
        !          66740:  * Fix:        Permission checking made more rigorous.
        !          66741:  * 
        !          66742:  * Revision 1.1        88/03/24  17:05:44      src
        !          66743:  * Initial revision
        !          66744:  * 
        !          66745:  * 87/04/24    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          66746:  * Msgctl() IPC_STAT check of polled devices modified.
        !          66747:  *
        !          66748:  * 87/04/01    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          66749:  * Msgctl() now correctly reports polling events on an IPC_STAT operation.
        !          66750:  *
        !          66751:  * 87/03/20    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          66752:  * Msgpoll() now correctly reports POLLOUT events.
        !          66753:  *
        !          66754:  * 87/01/20    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          66755:  * msginit() is now more paranoid about validating NMSC, NMSG, NMSQID.
        !          66756:  *
        !          66757:  * 87/01/05    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          66758:  * msginit() now allocates message buffers in high memory.
        !          66759:  *
        !          66760:  * 86/12/12    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          66761:  * Added 3rd argument to msgpoll() to support non-blocking polls.
        !          66762:  *
        !          66763:  * 86/11/21    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          66764:  * Added support for System V.3 compatible polls.
        !          66765:  * Added msgpoll() routine and xmsqid_ds structure.
        !          66766:  *
        !          66767:  * 85/08/06    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          66768:  * Msg.c split into configuration (msgcon.c) and implementation (msg.c).
        !          66769:  *
        !          66770:  * 85/07/22    Allan Cornish           /usr/src/sys/i8086/drv/msg.c
        !          66771:  * Msgget, msgctl, msgsnd, msgrcv now return immediately if u.u_error is set.
        !          66772:  *
        !          66773:  * 85/07/19    Allan Cornish
        !          66774:  * Msgrcv() now reports E2BIG if message is larger than size requested.
        !          66775:  * Msgfree() integrated into msginit() and msgrcv() functions.
        !          66776:  * Msgsnd() now checks for queue removal after waking from sleep.
        !          66777:  * Msgsnd() and msgrcv() now detect address faults and report EFAULT.
        !          66778:  *
        !          66779:  * 85/07/03    Allan Cornish
        !          66780:  * Replaced use of EDOM with EIDRM.
        !          66781:  * Replaced msgaccess() by calls to ipcaccess(), increasing shared ipc code.
        !          66782:  * Eliminated many calls to sphi() and spl().  They are not really required,
        !          66783:  * since system calls are synchronous unless they sleep or are interrupted.
        !          66784:  * Sleeps cause no problem, and interrupts do not affect messaging state.
        !          66785:  *
        !          66786:  * 85/06/19    Allan Cornish
        !          66787:  * Added code to msgctl to allow the owner of a queue to reduce msg_qbytes.
        !          66788:  * Previously only the super-user could modify msg_qbytes.
        !          66789:  *
        !          66790:  * 85/06/18    Allan Cornish
        !          66791:  * Added code to msgsnd to check for full queue (msg_cbytes >= msg_qbytes).
        !          66792:  * Integrated msgalloc function into msgsnd, since only called from there.
        !          66793:  * Fixed bug in msgrcv when msgtyp < 0, to treat msg_type as mesg priority.
        !          66794:  *
        !          66795:  * 85/05/10    Allan Cornish
        !          66796:  * C compiler bug in msginit caused 'mp->msg_spot = (wanted -= NMSC)' to fail.
        !          66797:  * For NMSG=10, NMSC=640, msg_spot always set to 0x1900 or 0xE980.
        !          66798:  * Code changed to 'wanted -= NMSC; mp->msg_spot = wanted'.
        !          66799:  *
        !          66800:  * 85/04/01    Allan Cornish
        !          66801:  * fixed qp->msg_last bug in msgrcv().
        !          66802:  */
        !          66803: 
        !          66804: #include <coherent.h>
        !          66805: #include <sched.h>
        !          66806: #include <types.h>
        !          66807: #include <uproc.h>
        !          66808: #include <errno.h>
        !          66809: #include <stat.h>
        !          66810: #include <con.h>
        !          66811: #include <seg.h>
        !          66812: #include <msg.h>
        !          66813: 
        !          66814: #ifndef        EIDRM
        !          66815: #define        EIDRM   EDOM
        !          66816: #endif
        !          66817: 
        !          66818: /*
        !          66819:  * Extended message queue id data structure.
        !          66820:  *     - extended to support System V.3 compatible polls.
        !          66821:  */
        !          66822: struct xmsqid_ds {
        !          66823:        struct msqid_ds msq;
        !          66824:        struct event    ipolls;
        !          66825:        struct event    opolls;
        !          66826: };
        !          66827: 
        !          66828: /*
        !          66829:  *     Message Information
        !          66830:  */
        !          66831: 
        !          66832: struct xmsqid_ds *msqs = 0;    /* Pointer to array of message queues */
        !          66833:                                /* (first queue contains free message list) */
        !          66834: 
        !          66835: struct msg * msgs = 0;         /* Pointer to array of message headers */
        !          66836: 
        !          66837: static SEG * msgsp;            /* Segment containing messages */
        !          66838: #define        msgsel FP_SEL(msgsp->s_faddr)
        !          66839: 
        !          66840: /*
        !          66841:  *     Global Message Parameters
        !          66842:  */
        !          66843: 
        !          66844: unsigned NMSQID = 9;   /* allocated number of message queues */
        !          66845: unsigned NMSQB  = 2048;        /* default maximum queue size in bytes */
        !          66846: unsigned NMSG = 10;    /* allocated messages: (NMSG * NMSC) < 2^16 */
        !          66847: unsigned NMSC = 640;   /* maximum message text size */
        !          66848: 
        !          66849: /*
        !          66850:  * Message Device Initialization.
        !          66851:  *
        !          66852:  *     Initialize message ids.
        !          66853:  */
        !          66854: 
        !          66855: msginit()
        !          66856: {
        !          66857:        register struct xmsqid_ds *qp;
        !          66858:        register struct msg *mp;
        !          66859:        long wanted;
        !          66860:        int i;
        !          66861: 
        !          66862:        if ( NMSG == 0 )
        !          66863:                NMSQID = 0;
        !          66864:        if ( NMSC == 0 )
        !          66865:                NMSQID = 0;
        !          66866:        if ( NMSQID == 0 )
        !          66867:                return 0;
        !          66868: 
        !          66869:        if ( NMSQID > 128 )
        !          66870:                NMSQID = 128;
        !          66871: 
        !          66872:        /*
        !          66873:         * Allocate message queues and message headers.
        !          66874:         */
        !          66875:        wanted = (NMSQID * (long) sizeof(struct xmsqid_ds)) +
        !          66876:                (NMSG * (long) sizeof(struct msg));
        !          66877:        if (wanted > 16384) {
        !          66878:                printf("invalid NMSQID or NMSG kernel variable\n");
        !          66879:                NMSQID=0;
        !          66880:                return;
        !          66881:        }
        !          66882: 
        !          66883:        if ( msqs = kalloc( (unsigned) wanted) ) {
        !          66884: 
        !          66885:                /*
        !          66886:                 * Ensure allocated space is cleared.
        !          66887:                 */
        !          66888:                memset( msqs, 0, (unsigned) wanted );
        !          66889: 
        !          66890:                /*
        !          66891:                 * Message headers are contiguous to message queues.
        !          66892:                 */
        !          66893:                msgs = (struct msg *) (&msqs[NMSQID]);
        !          66894: 
        !          66895:                /*
        !          66896:                 * Allocate message buffers.
        !          66897:                 */
        !          66898:                wanted = (long) NMSG * NMSC;
        !          66899:                if ( wanted > 0xFFFFL ) {
        !          66900:                        printf("invalid NMSG or NMSC kernel variable\n");
        !          66901:                        kfree( msqs );
        !          66902:                        NMSQID = 0;
        !          66903:                        msqs   = 0;
        !          66904:                        return;
        !          66905:                }
        !          66906: 
        !          66907:                msgsp = salloc( (size_t) wanted, SFHIGH|SFNSWP|SFNCLR );
        !          66908: 
        !          66909:                if ( msgsp == 0 ) {
        !          66910:                        printf("could not salloc %u messages\n", NMSG);
        !          66911:                        kfree( msqs );
        !          66912:                        NMSQID = 0;
        !          66913:                        msqs   = 0;
        !          66914:                        return;
        !          66915:                }
        !          66916: 
        !          66917:                /*
        !          66918:                 * Initialize message queues.
        !          66919:                 */
        !          66920:                for ( qp = msqs, i = 0; i < NMSQID; i++, qp++ ) {
        !          66921: 
        !          66922:                        qp->msq.msg_perm.seq  = i * 256;
        !          66923: 
        !          66924:                        qp->ipolls.e_dnext =
        !          66925:                        qp->ipolls.e_dlast = &qp->ipolls;
        !          66926: 
        !          66927:                        qp->opolls.e_dnext =
        !          66928:                        qp->opolls.e_dlast = &qp->opolls;
        !          66929:                }
        !          66930: 
        !          66931:                /*
        !          66932:                 * Initialize message headers, place on free queue.
        !          66933:                 */
        !          66934:                for ( qp = msqs, mp = &msgs[NMSG]; --mp >= msgs; ) {
        !          66935:                        wanted -= NMSC;
        !          66936:                        mp->msg_spot  = wanted;
        !          66937:                        mp->msg_next  = qp->msq.msg_first;
        !          66938:                        qp->msq.msg_first = mp;
        !          66939:                }
        !          66940:        }
        !          66941:        else {
        !          66942:                printf("could not kalloc %u message ids\n", NMSQID);
        !          66943:                NMSQID = 0;
        !          66944:        }
        !          66945: }
        !          66946: 
        !          66947: 
        !          66948: /*
        !          66949:  * Msgctl - Message Control Operations.
        !          66950:  */
        !          66951: 
        !          66952: umsgctl( qid, cmd, buf )
        !          66953: 
        !          66954: int qid;
        !          66955: int cmd;
        !          66956: struct msqid_ds *buf;
        !          66957: 
        !          66958: {
        !          66959:        register struct xmsqid_ds *qp;
        !          66960:        register struct msg *mp;
        !          66961:        unsigned n;
        !          66962: 
        !          66963:        /*
        !          66964:         * Validate queue identifier.
        !          66965:         */
        !          66966:        if ( (qid <= 0) || (qid/256 >= NMSQID) || (msqs == 0) ) {
        !          66967:                u.u_error = EINVAL;
        !          66968:                return -1;
        !          66969:        }
        !          66970: 
        !          66971:        qp = &msqs[ qid / 256 ];
        !          66972: 
        !          66973:        /*
        !          66974:         * Validate queue existence.
        !          66975:         */
        !          66976:        if ( (qp == 0) || ((qp->msq.msg_perm.mode & IPC_ALLOC) == 0) ) {
        !          66977:                u.u_error = EINVAL;
        !          66978:                return -1;
        !          66979:        }
        !          66980: 
        !          66981:        /*
        !          66982:         * Validate qid for all commands except for IPC_STAT.
        !          66983:         */
        !          66984:        if ( (cmd != IPC_STAT) && (qp->msq.msg_perm.seq != qid) ) {
        !          66985:                u.u_error = EINVAL;
        !          66986:                return -1;
        !          66987:        }
        !          66988: 
        !          66989:        switch ( cmd ) {
        !          66990: 
        !          66991:        case IPC_STAT:
        !          66992:                /*
        !          66993:                 * Validate access authority.
        !          66994:                 */
        !          66995:                if ( (ipcaccess(&qp->msq.msg_perm) & MSG_R) == 0 ) {
        !          66996:                        u.u_error = EACCES;
        !          66997:                        break;
        !          66998:                }
        !          66999: 
        !          67000:                /*
        !          67001:                 * Copy queue info to user.
        !          67002:                 */
        !          67003:                kucopy( qp, buf, sizeof(struct msqid_ds) );
        !          67004: 
        !          67005:                /*
        !          67006:                 * Include input polls in receive waiting.
        !          67007:                 */
        !          67008:                if ( (qp->ipolls.e_dnext != NULL)
        !          67009:                  && (qp->ipolls.e_dnext != &qp->ipolls) ) {
        !          67010:                        putuwd( &buf->msg_perm.mode,
        !          67011:                                getuwd( &buf->msg_perm.mode ) | MSG_RWAIT );
        !          67012:                }
        !          67013: 
        !          67014:                /*
        !          67015:                 * Include output polls in write waiting.
        !          67016:                 */
        !          67017:                if ( (qp->opolls.e_dnext != NULL)
        !          67018:                  && (qp->opolls.e_dnext != &qp->opolls) ) {
        !          67019:                        putuwd( &buf->msg_perm.mode,
        !          67020:                                getuwd( &buf->msg_perm.mode ) | MSG_WWAIT );
        !          67021:                }
        !          67022: 
        !          67023:                /*
        !          67024:                 * Validate qid.
        !          67025:                 * Doing it now lets user get info on message queue.
        !          67026:                 */
        !          67027:                if ( qp->msq.msg_perm.seq != qid )
        !          67028:                        u.u_error = EINVAL;
        !          67029:                break;
        !          67030: 
        !          67031:        case IPC_SET:
        !          67032:                /*
        !          67033:                 * Validate modify authority.
        !          67034:                 */
        !          67035:                if ( (u.u_uid != 0) && (u.u_uid != qp->msq.msg_perm.uid) ) {
        !          67036:                        u.u_error = EPERM;
        !          67037:                        break;
        !          67038:                }
        !          67039: 
        !          67040:                /*
        !          67041:                 * Get desired queue size.
        !          67042:                 */
        !          67043:                n = getuwd( &(buf->msg_qbytes) );
        !          67044:                if (u.u_error)
        !          67045:                        break;
        !          67046: 
        !          67047:                /*
        !          67048:                 * Only super-user can increase queue size.
        !          67049:                 */
        !          67050:                if ( (u.u_uid != 0) && (n > qp->msq.msg_qbytes) ) {
        !          67051:                        u.u_error = EPERM;
        !          67052:                        break;
        !          67053:                }
        !          67054: 
        !          67055:                /*
        !          67056:                 * Set queue parameters.
        !          67057:                 */
        !          67058:                qp->msq.msg_perm.uid   = getuwd( &(buf->msg_perm.uid ) );
        !          67059:                qp->msq.msg_perm.gid   = getuwd( &(buf->msg_perm.gid ) );
        !          67060:                qp->msq.msg_perm.mode &= ~0777;
        !          67061:                qp->msq.msg_perm.mode |= getuwd( &(buf->msg_perm.mode) ) & 0777;
        !          67062:                qp->msq.msg_qbytes     = n;
        !          67063:                break;
        !          67064: 
        !          67065:        case IPC_RMID:
        !          67066:                /*
        !          67067:                 * Validate removal authority.
        !          67068:                 */
        !          67069:                if ( (u.u_uid != 0) && (u.u_uid != qp->msq.msg_perm.uid) ) {
        !          67070:                        u.u_error = EPERM;
        !          67071:                        break;
        !          67072:                }
        !          67073: 
        !          67074:                /*
        !          67075:                 * Free all messages on the queue being removed.
        !          67076:                 */
        !          67077:                while ( mp = qp->msq.msg_first ) {
        !          67078:                        qp->msq.msg_first   = mp->msg_next;
        !          67079:                        mp->msg_next        = msqs->msq.msg_first;
        !          67080:                        msqs->msq.msg_first = mp;
        !          67081:                }
        !          67082: 
        !          67083:                /*
        !          67084:                 * Wakeup processes waiting for free message buffers.
        !          67085:                 */
        !          67086:                if ( msqs->msq.msg_perm.mode & MSG_RWAIT ) {
        !          67087:                        msqs->msq.msg_perm.mode &= ~MSG_RWAIT;
        !          67088:                        wakeup( msqs );
        !          67089:                }
        !          67090:                if ( msqs->ipolls.e_procp )
        !          67091:                        pollwake( &msqs->ipolls );
        !          67092: 
        !          67093:                /*
        !          67094:                 * Initialize queue parameters.
        !          67095:                 */
        !          67096:                qp->msq.msg_last   = 0;
        !          67097:                qp->msq.msg_qnum   = 0;
        !          67098:                qp->msq.msg_cbytes = 0;
        !          67099:                if ( (qp->msq.msg_perm.seq & 0x00FF) == 0x00FF )
        !          67100:                        qp->msq.msg_perm.seq &= 0x7F00;
        !          67101:                qp->msq.msg_perm.seq++;
        !          67102: 
        !          67103:                /*
        !          67104:                 * Wakeup processes sleeping on the removed message queue.
        !          67105:                 */
        !          67106:                if ( qp->msq.msg_perm.mode & (MSG_RWAIT|MSG_WWAIT) )
        !          67107:                        wakeup( qp );
        !          67108:                if ( qp->ipolls.e_procp )
        !          67109:                        pollwake( &qp->ipolls );
        !          67110:                if ( qp->opolls.e_procp )
        !          67111:                        pollwake( &qp->opolls );
        !          67112: 
        !          67113:                qp->msq.msg_perm.mode = 0;
        !          67114:                break;
        !          67115: 
        !          67116:        default:
        !          67117:                u.u_error = EINVAL;
        !          67118:        }
        !          67119: 
        !          67120:        if ( u.u_error )
        !          67121:                return -1;
        !          67122: 
        !          67123:        return 0;
        !          67124: }
        !          67125: 
        !          67126: /*
        !          67127:  * Msgget - Get set of messages
        !          67128:  */
        !          67129: 
        !          67130: umsgget( mykey, msgflg )
        !          67131: 
        !          67132: key_t mykey;
        !          67133: int msgflg;
        !          67134: 
        !          67135: {
        !          67136:        register struct xmsqid_ds *qp;
        !          67137:        register struct xmsqid_ds *freeidp = 0;
        !          67138:        int rwmode;
        !          67139:        
        !          67140:        if ( msqs == 0 ) {
        !          67141: 
        !          67142:                msginit();
        !          67143: 
        !          67144:                if ( msqs == 0 ) {
        !          67145:                        u.u_error = ENOMEM;
        !          67146:                        return;
        !          67147:                }
        !          67148:        }
        !          67149: 
        !          67150:        /*
        !          67151:         * Extract desired access mode from flags.
        !          67152:         */
        !          67153:        rwmode = msgflg & 0777;
        !          67154: 
        !          67155:        /*
        !          67156:         * Search for desired message queue [also for first free queue].
        !          67157:         */
        !          67158:        for ( qp = &msqs[NMSQID]; --qp > msqs; ) {
        !          67159: 
        !          67160:                if ( (qp->msq.msg_perm.mode & IPC_ALLOC) == 0 ) {
        !          67161: 
        !          67162:                        if ((freeidp == 0) ||
        !          67163:                            (freeidp->msq.msg_ctime > qp->msq.msg_ctime))
        !          67164:                                freeidp = qp;
        !          67165:                        continue;
        !          67166:                }
        !          67167: 
        !          67168:                if (mykey == IPC_PRIVATE)
        !          67169:                        continue;
        !          67170: 
        !          67171:                if ( mykey == qp->msq.msg_perm.key ) {          /* found! */
        !          67172: 
        !          67173:                        if ( (msgflg & IPC_CREAT) && (msgflg & IPC_EXCL) ) {
        !          67174:                                u.u_error = EEXIST;
        !          67175:                                return -1;
        !          67176:                        }
        !          67177: 
        !          67178:                        if ( (qp->msq.msg_perm.mode & rwmode) != rwmode ) {
        !          67179:                                u.u_error = EACCES;
        !          67180:                                return -1;
        !          67181:                        }
        !          67182: 
        !          67183:                        return qp->msq.msg_perm.seq;
        !          67184:                }
        !          67185:        }
        !          67186: 
        !          67187:        if ( ! (msgflg & IPC_CREAT) ) {
        !          67188:                u.u_error = ENOENT;
        !          67189:                return -1;
        !          67190:        }
        !          67191: 
        !          67192:        if ( (qp = freeidp) == 0 ) {
        !          67193:                u.u_error = ENOSPC;
        !          67194:                return -1;
        !          67195:        }
        !          67196: 
        !          67197:        qp->msq.msg_first  = 0;
        !          67198:        qp->msq.msg_last   = 0;
        !          67199:        qp->msq.msg_cbytes = 0;
        !          67200:        qp->msq.msg_qnum   = 0;
        !          67201:        qp->msq.msg_qbytes = NMSQB;
        !          67202:        qp->msq.msg_lspid  = 0;
        !          67203:        qp->msq.msg_lrpid  = 0;
        !          67204:        qp->msq.msg_stime  = 0;
        !          67205:        qp->msq.msg_rtime  = 0;
        !          67206:        qp->msq.msg_ctime  = timer.t_time;
        !          67207: 
        !          67208:        qp->msq.msg_perm.cuid = qp->msq.msg_perm.uid = u.u_uid;
        !          67209:        qp->msq.msg_perm.cgid = qp->msq.msg_perm.gid = u.u_gid;
        !          67210:        qp->msq.msg_perm.mode = rwmode | IPC_ALLOC;
        !          67211:        qp->msq.msg_perm.key  = mykey;
        !          67212: 
        !          67213:        return qp->msq.msg_perm.seq;
        !          67214: }
        !          67215: 
        !          67216: /*
        !          67217:  * Send a Message
        !          67218:  */
        !          67219: 
        !          67220: umsgsnd( qid, bufp, msgsz, msgflg )
        !          67221: 
        !          67222: int qid;
        !          67223: struct msgbuf *bufp;
        !          67224: unsigned msgsz, msgflg;
        !          67225: 
        !          67226: {
        !          67227:        register struct xmsqid_ds * qp;
        !          67228:        register struct msg      * mp;
        !          67229: 
        !          67230:        /*
        !          67231:         * Validate queue identifier.
        !          67232:         */
        !          67233:        if ((qid <= 0) || (qid/256 >= NMSQID) || (msgsz > NMSC) || (msqs==0)) {
        !          67234:                u.u_error = EINVAL;
        !          67235:                return -1;
        !          67236:        }
        !          67237: 
        !          67238:        qp = &msqs[ qid / 256 ];
        !          67239: 
        !          67240:        /*
        !          67241:         * Validate queue existence.
        !          67242:         */
        !          67243:        if ( (qp->msq.msg_perm.seq != qid)
        !          67244:          || ((qp->msq.msg_perm.mode & IPC_ALLOC) == 0) ) {
        !          67245:                u.u_error = EINVAL;
        !          67246:                return -1;
        !          67247:        }
        !          67248: 
        !          67249:        if ((ipcaccess(&qp->msq.msg_perm) & MSG_W) == 0){ /* can't send mesg */
        !          67250:                u.u_error = EACCES;
        !          67251:                return -1;
        !          67252:        }
        !          67253: 
        !          67254:        /*
        !          67255:         * Wait for a free message buffer
        !          67256:         */
        !          67257:        while ( (msqs->msq.msg_first == 0)
        !          67258:             || (qp->msq.msg_qbytes <= qp->msq.msg_cbytes)) {
        !          67259: 
        !          67260:                if ( msgflg & IPC_NOWAIT ) {
        !          67261:                        u.u_error = EAGAIN;
        !          67262:                        return -1;
        !          67263:                }
        !          67264: 
        !          67265:                if (qp->msq.msg_qbytes <= qp->msq.msg_cbytes) {
        !          67266:                        qp->msq.msg_perm.mode |= MSG_WWAIT;
        !          67267:                        sleep( qp, CVTTOUT, IVTTOUT, SVTTOUT );
        !          67268:                }
        !          67269:                else {
        !          67270:                        msqs->msq.msg_perm.mode |= MSG_RWAIT;
        !          67271:                        sleep( msqs, CVTTOUT, IVTTOUT, SVTTOUT );
        !          67272:                }
        !          67273: 
        !          67274:                /*
        !          67275:                 * Abort if a signal was received
        !          67276:                 */
        !          67277:                if (SELF->p_ssig && nondsig() ) {
        !          67278:                        u.u_error = EINTR;
        !          67279:                        return -1;
        !          67280:                }
        !          67281: 
        !          67282:                /*
        !          67283:                 * Abort if the message queue was removed.
        !          67284:                 */
        !          67285:                if ( qid != qp->msq.msg_perm.seq ) {
        !          67286:                        u.u_error = EIDRM;
        !          67287:                        return -1;
        !          67288:                }
        !          67289:        }
        !          67290: 
        !          67291:        /*
        !          67292:         * Use first message on free message queue
        !          67293:         */
        !          67294:        mp = msqs->msq.msg_first;
        !          67295:        mp->msg_ts = msgsz;
        !          67296: 
        !          67297:        /*
        !          67298:         * Transfer the message type and text.
        !          67299:         */
        !          67300:        ukcopy( &(bufp->mtype), &(mp->msg_type), sizeof(mp->msg_type) );
        !          67301:        if ( ufcopy( &bufp->mtext[0], mp->msg_spot, msgsel, msgsz ) != msgsz )
        !          67302:                        u.u_error = EFAULT;
        !          67303: 
        !          67304:        /*
        !          67305:         * Abort if address fault occured during transfer.
        !          67306:         */
        !          67307:        if ( u.u_error )
        !          67308:                return -1;
        !          67309: 
        !          67310:        /*
        !          67311:         * Move the message to the desired queue.
        !          67312:         */
        !          67313:        msqs->msq.msg_first = mp->msg_next;
        !          67314:        mp->msg_next = 0;
        !          67315: 
        !          67316:        if ( qp->msq.msg_last )
        !          67317:                qp->msq.msg_last->msg_next = mp;
        !          67318:        else
        !          67319:                qp->msq.msg_first = mp;
        !          67320:        qp->msq.msg_last = mp;
        !          67321: 
        !          67322:        /*
        !          67323:         * Update queue statistics.
        !          67324:         */
        !          67325:        qp->msq.msg_cbytes += msgsz;
        !          67326:        qp->msq.msg_qnum++;
        !          67327:        qp->msq.msg_lspid = SELF->p_pid;
        !          67328:        qp->msq.msg_stime = timer.t_time;
        !          67329: 
        !          67330:        /*
        !          67331:         * Wake processes waiting to receive.
        !          67332:         */
        !          67333:        if ( qp->msq.msg_perm.mode & MSG_RWAIT ) {
        !          67334:                qp->msq.msg_perm.mode &= ~MSG_RWAIT;
        !          67335:                wakeup( qp );
        !          67336:        }
        !          67337:        if ( qp->ipolls.e_procp )
        !          67338:                pollwake( &qp->ipolls );
        !          67339: 
        !          67340:        return 0;
        !          67341: }
        !          67342: 
        !          67343: /*
        !          67344:  * Receive A Message
        !          67345:  */
        !          67346: 
        !          67347: umsgrcv( qid, bufp, msgsz, msgtyp, msgflg )
        !          67348: 
        !          67349: int qid;
        !          67350: struct msgbuf *bufp;
        !          67351: unsigned msgsz;
        !          67352: long msgtyp;
        !          67353: unsigned msgflg;
        !          67354: 
        !          67355: {
        !          67356:        register struct xmsqid_ds *qp;
        !          67357:        register struct msg *mp;
        !          67358:        register struct msg *prev;
        !          67359: 
        !          67360:        /*
        !          67361:         * Validate queue identifier.
        !          67362:         */
        !          67363:        if ( (qid <= 0) || (qid/256 >= NMSQID) || (msqs == 0) ) {
        !          67364:                u.u_error = EINVAL;
        !          67365:                return -1;
        !          67366:        }
        !          67367: 
        !          67368:        qp = &msqs[ qid / 256 ];
        !          67369: 
        !          67370:        /*
        !          67371:         * Validate queue existence.
        !          67372:         */
        !          67373:        if ( (qp->msq.msg_perm.seq != qid)
        !          67374:          || ((qp->msq.msg_perm.mode & IPC_ALLOC) == 0) ) {
        !          67375:                u.u_error = EINVAL;
        !          67376:                return -1;
        !          67377:        }
        !          67378: 
        !          67379:        /*
        !          67380:         * Permission denied
        !          67381:         */
        !          67382:        if ( (ipcaccess(&qp->msq.msg_perm) & MSG_R) == 0 ) {
        !          67383:                u.u_error = EACCES;
        !          67384:                return -1;
        !          67385:        }
        !          67386: 
        !          67387:        /*
        !          67388:         * Wait for message
        !          67389:         */
        !          67390:        for (;;) {
        !          67391: 
        !          67392:                mp   = qp->msq.msg_first;
        !          67393:                prev = 0;
        !          67394: 
        !          67395:                /*
        !          67396:                 * Find mesg of type <= abs(msgtyp)
        !          67397:                 */
        !          67398:                if ( msgtyp < 0 ) {
        !          67399: 
        !          67400:                        struct msg *xp, *xprev;
        !          67401:                        
        !          67402:                        xp     = 0;
        !          67403:                        xprev  = 0;
        !          67404:                        msgtyp = -msgtyp;
        !          67405: 
        !          67406:                        for ( ; mp != 0 ; prev = mp, mp = mp->msg_next ) {
        !          67407: 
        !          67408:                                if (mp->msg_type > msgtyp)
        !          67409:                                        continue;
        !          67410: 
        !          67411:                                if ((xp==0) || (mp->msg_type < xp->msg_type)) {
        !          67412:                                        xp    = mp;
        !          67413:                                        xprev = prev;
        !          67414:                                }
        !          67415:                        }
        !          67416:                        mp     = xp;
        !          67417:                        prev   = xprev;
        !          67418:                        msgtyp = -msgtyp;
        !          67419:                }
        !          67420: 
        !          67421:                /*
        !          67422:                 * Find message of type == msgtyp
        !          67423:                 */
        !          67424:                else if ( msgtyp > 0 ) {
        !          67425: 
        !          67426:                        while ( (mp != 0) && (mp->msg_type != msgtyp) ) {
        !          67427:                                prev = mp;
        !          67428:                                mp = mp->msg_next;
        !          67429:                        }
        !          67430:                }
        !          67431: 
        !          67432:                /*
        !          67433:                 * Else take first message
        !          67434:                 */
        !          67435: 
        !          67436:                if ( mp )
        !          67437:                        break;
        !          67438: 
        !          67439:                /*
        !          67440:                 * Can't wait to receive mesg
        !          67441:                 */
        !          67442:                if ( msgflg & IPC_NOWAIT ) {
        !          67443:                        u.u_error = EAGAIN;
        !          67444:                        return -1;
        !          67445:                }
        !          67446: 
        !          67447:                qp->msq.msg_perm.mode |= MSG_RWAIT;
        !          67448:                sleep( qp, CVTTOUT, IVTTOUT, SVTTOUT );
        !          67449: 
        !          67450:                /*
        !          67451:                 * Signal received
        !          67452:                 */
        !          67453:                if ( SELF->p_ssig && nondsig() ) {
        !          67454:                        u.u_error = EINTR;
        !          67455:                        return -1;
        !          67456:                }
        !          67457: 
        !          67458:                /*
        !          67459:                 * Not same q anymore
        !          67460:                 */
        !          67461:                if ( qid != qp->msq.msg_perm.seq ) {
        !          67462:                        u.u_error = EIDRM;
        !          67463:                        return -1;
        !          67464:                }
        !          67465:        }
        !          67466: 
        !          67467:        /*
        !          67468:         * Ensure entire message can be transferred, or MSG_NOERROR asserted.
        !          67469:         */
        !          67470:        if ( (msgsz < mp->msg_ts) && ((msgflg & MSG_NOERROR) == 0) ) {
        !          67471:                u.u_error = E2BIG;
        !          67472:                return -1;
        !          67473:        }
        !          67474: 
        !          67475:        /*
        !          67476:         * Transfer message data
        !          67477:         */
        !          67478:        if ( msgsz > mp->msg_ts )
        !          67479:                msgsz = mp->msg_ts;
        !          67480: 
        !          67481:        kucopy( &(mp->msg_type), &(bufp->mtype), sizeof(mp->msg_type) );
        !          67482:        if (fucopy( mp->msg_spot, msgsel, &(bufp->mtext[0]), msgsz ) != msgsz)
        !          67483:                u.u_error = EFAULT;
        !          67484: 
        !          67485:        /*
        !          67486:         * Abort if address fault occurred during transfer.
        !          67487:         */
        !          67488:        if ( u.u_error )
        !          67489:                return -1;
        !          67490: 
        !          67491:        /*
        !          67492:         * Remove message from queue
        !          67493:         */
        !          67494:        if ( prev )
        !          67495:                prev->msg_next = mp->msg_next;
        !          67496:        else
        !          67497:                qp->msq.msg_first = mp->msg_next;
        !          67498: 
        !          67499:        if ( qp->msq.msg_last == mp )
        !          67500:                qp->msq.msg_last = prev;
        !          67501: 
        !          67502:        /*
        !          67503:         * Update queue statistics
        !          67504:         */
        !          67505:        qp->msq.msg_cbytes -= mp->msg_ts;
        !          67506:        qp->msq.msg_qnum--;
        !          67507:        qp->msq.msg_lrpid = SELF->p_pid;
        !          67508:        qp->msq.msg_rtime = timer.t_time;
        !          67509: 
        !          67510:        /*
        !          67511:         * Wakeup processes waiting to send.
        !          67512:         */
        !          67513:        if (qp->msq.msg_perm.mode & MSG_WWAIT) {
        !          67514:                qp->msq.msg_perm.mode &= ~MSG_WWAIT;
        !          67515:                wakeup( qp );
        !          67516:        }
        !          67517:        if ( qp->opolls.e_procp )
        !          67518:                pollwake( &qp->opolls );
        !          67519: 
        !          67520:        /*
        !          67521:         * Place message buffer on free message queue
        !          67522:         */
        !          67523:        qp = msqs;
        !          67524:        mp->msg_next = qp->msq.msg_first;
        !          67525:        qp->msq.msg_first = mp;
        !          67526: 
        !          67527:        /*
        !          67528:         * Wakeup processes waiting for empty message buffer
        !          67529:         */
        !          67530:        if ( qp->msq.msg_perm.mode & MSG_RWAIT ) {
        !          67531:                qp->msq.msg_perm.mode &= ~MSG_RWAIT;
        !          67532:                wakeup( qp );
        !          67533:        }
        !          67534:        if ( msqs->ipolls.e_procp )
        !          67535:                pollwake( &msqs->ipolls );
        !          67536: 
        !          67537:        return msgsz;
        !          67538: }
        !          67539: 
        !          67540: /*
        !          67541:  * Msgpoll - Message Queue Polling.
        !          67542:  */
        !          67543: msgpoll( qid, ev, msec )
        !          67544: int qid;
        !          67545: int ev;
        !          67546: int msec;
        !          67547: {
        !          67548:        register struct xmsqid_ds * qp;
        !          67549: 
        !          67550:        /*
        !          67551:         * Validate queue identifier.
        !          67552:         */
        !          67553:        if ( (qid <= 0) || (qid/256 >= NMSQID) || (msqs == 0) )
        !          67554:                return POLLNVAL;
        !          67555: 
        !          67556:        qp = &msqs[ qid / 256 ];
        !          67557: 
        !          67558:        /*
        !          67559:         * Validate queue existence.
        !          67560:         */
        !          67561:        if ( ((qp->msq.msg_perm.mode & IPC_ALLOC) == 0)
        !          67562:          || (qp->msq.msg_perm.seq != qid) )
        !          67563:                return POLLHUP;
        !          67564: 
        !          67565:        /*
        !          67566:         * Priority polls not supported.
        !          67567:         */
        !          67568:        ev &= ~POLLPRI;
        !          67569: 
        !          67570:        /*
        !          67571:         * Input poll.
        !          67572:         */
        !          67573:        if ( ev & POLLIN ) {
        !          67574: 
        !          67575:                /*
        !          67576:                 * No messages on queue.
        !          67577:                 */
        !          67578:                if ( qp->msq.msg_qnum == 0 ) {
        !          67579:                        /*
        !          67580:                         * Enable input monitor.
        !          67581:                         */
        !          67582:                        if ( msec != 0 )
        !          67583:                                pollopen( &qp->ipolls );
        !          67584:                        ev &= ~POLLIN;
        !          67585:                }
        !          67586: 
        !          67587:                /*
        !          67588:                 * Prevent output monitor.
        !          67589:                 */
        !          67590:                else
        !          67591:                        msec = 0;
        !          67592:        }
        !          67593: 
        !          67594:        /*
        !          67595:         * Output poll.
        !          67596:         */
        !          67597:        if ( ev & POLLOUT ) {
        !          67598: 
        !          67599:                /*
        !          67600:                 * Queue full.
        !          67601:                 */
        !          67602:                if ( qp->msq.msg_cbytes >= qp->msq.msg_qbytes ) {
        !          67603:                        if ( msec != 0 )
        !          67604:                                pollopen( &qp->opolls );
        !          67605:                        ev &= ~POLLOUT;
        !          67606:                }
        !          67607: 
        !          67608:                /*
        !          67609:                 * No free message buffers.
        !          67610:                 */
        !          67611:                else if ( msqs->msq.msg_first == NULL ) {
        !          67612:                        if ( msec != 0 )
        !          67613:                                pollopen( &msqs->ipolls );
        !          67614:                        ev &= ~POLLOUT;
        !          67615:                }
        !          67616:        }
        !          67617: 
        !          67618:        return ev;
        !          67619: }
        !          67620: @
        !          67621: 
        !          67622: 
        !          67623: 1.3
        !          67624: log
        !          67625: @update provided by hal
        !          67626: @
        !          67627: text
        !          67628: @@
        !          67629: 
        !          67630: 
        !          67631: 1.2
        !          67632: log
        !          67633: @new version provided y hal for v321
        !          67634: @
        !          67635: text
        !          67636: @@
        !          67637: 
        !          67638: 
        !          67639: 1.1
        !          67640: log
        !          67641: @Initial revision
        !          67642: @
        !          67643: text
        !          67644: @@
        !          67645: 0707070064030106601004440000030000030000011777770507310676200006000000007307/newbits/kernel/USRSRC/i8086/drv/RCS/msgcon.c,vhead     1.4;
        !          67646: branch   ;
        !          67647: access   ;
        !          67648: symbols  ;
        !          67649: locks    bin:1.4; strict;
        !          67650: comment  @ * @;
        !          67651: 
        !          67652: 
        !          67653: 1.4
        !          67654: date     91.06.20.14.51.35;  author bin;  state Exp;
        !          67655: branches ;
        !          67656: next     1.3;
        !          67657: 
        !          67658: 1.3
        !          67659: date     91.06.18.08.13.14;  author bin;  state Exp;
        !          67660: branches ;
        !          67661: next     1.2;
        !          67662: 
        !          67663: 1.2
        !          67664: date     91.06.17.12.33.34;  author bin;  state Exp;
        !          67665: branches ;
        !          67666: next     1.1;
        !          67667: 
        !          67668: 1.1
        !          67669: date     91.06.10.10.23.59;  author bin;  state Exp;
        !          67670: branches ;
        !          67671: next     ;
        !          67672: 
        !          67673: 
        !          67674: desc
        !          67675: @initial version prov by hal
        !          67676: @
        !          67677: 
        !          67678: 
        !          67679: 1.4
        !          67680: log
        !          67681: @update provided by hal
        !          67682: @
        !          67683: text
        !          67684: @/* $Header: /usr/src/sys/i8086/drv/RCS/msgcon.c,v 2.1 88/09/03 13:09:32 src Exp $
        !          67685:  *
        !          67686:  *     The  information  contained herein  is a trade secret  of INETCO
        !          67687:  *     Systems, and is confidential information.   It is provided under
        !          67688:  *     a license agreement,  and may be copied or disclosed  only under
        !          67689:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          67690:  *     this  material  without  the express  written  authorization  of
        !          67691:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          67692:  *
        !          67693:  *     Copyright (c) 1987, 1985, 1984.
        !          67694:  *     An unpublished work by INETCO Systems, Ltd.
        !          67695:  *     All rights reserved.
        !          67696:  */
        !          67697: 
        !          67698: /*
        !          67699:  * System V Compatible Message Device Driver
        !          67700:  *
        !          67701:  *     This device driver provides System V compatible messaging operations.
        !          67702:  *     Operations are performed through the message device (/dev/msg).
        !          67703:  *     and are implemented as ioctl calls from msgctl, msgget, msgsnd, msgrcv
        !          67704:  *     utilities.
        !          67705:  *
        !          67706:  *                     Author: Allan Cornish, INETCO Systems Ltd., Oct 1984
        !          67707:  *
        !          67708:  * $Log:       /usr/src/sys/i8086/drv/RCS/msgcon.c,v $
        !          67709:  * Revision 2.1        88/09/03  13:09:32      src
        !          67710:  * *** empty log message ***
        !          67711:  * 
        !          67712:  * Revision 1.1        88/03/24  17:05:49      src
        !          67713:  * Initial revision
        !          67714:  * 
        !          67715:  * 87/03/02    Allan Cornish           /usr/src/sys/i8086/drv/msgcon.c
        !          67716:  * Msgioctl() now supports long key [was short] on MSGGET operations.
        !          67717:  * This allows compatability with System V.
        !          67718:  *
        !          67719:  * 85/08/06    Allan Cornish
        !          67720:  * Msg.c split into configuration (msgcon.c) and implementation (msg.c).
        !          67721:  *
        !          67722:  * 85/07/03    Allan Cornish
        !          67723:  * Simplified msgopen by ignoring minor device, which previously had to be 0.
        !          67724:  *
        !          67725:  * 84/01/30    Allan Cornish
        !          67726:  * Initial revision.
        !          67727:  */
        !          67728: 
        !          67729: #include <coherent.h>
        !          67730: #include <types.h>
        !          67731: #include <uproc.h>
        !          67732: #include <errno.h>
        !          67733: #include <con.h>
        !          67734: #include <msg.h>
        !          67735: 
        !          67736: /*
        !          67737:  * Functions.
        !          67738:  */
        !          67739: 
        !          67740: int msgopen();
        !          67741: int msgioctl();
        !          67742: int nulldev();
        !          67743: int nonedev();
        !          67744: 
        !          67745: /*
        !          67746:  * Device Configuration.
        !          67747:  */
        !          67748: 
        !          67749: CON msgcon = {
        !          67750:        DFCHR,                  /* Flags                        */
        !          67751:        25,                     /* Major Index                  */
        !          67752:        msgopen,                /* Open                         */
        !          67753:        nulldev,                /* Close                        */
        !          67754:        nonedev,                /* Block                        */
        !          67755:        nonedev,                /* Read                         */
        !          67756:        nonedev,                /* Write                        */
        !          67757:        msgioctl,               /* Ioctl                        */
        !          67758:        nulldev,                /* Power fail                   */
        !          67759:        nulldev,                /* Timeout                      */
        !          67760:        nulldev,                /* Load                         */
        !          67761:        nulldev                 /* Unload                       */
        !          67762: };
        !          67763: 
        !          67764: /*
        !          67765:  * Message Device Open.
        !          67766:  */
        !          67767: 
        !          67768: static
        !          67769: msgopen( dev, mode )
        !          67770: 
        !          67771: dev_t dev;
        !          67772: int mode;
        !          67773: 
        !          67774: {
        !          67775:        extern struct msqid_ds * msqs; /* Pointer to array of message queues */
        !          67776: 
        !          67777:        if ( ! msqs )                   /* message queues not initialized */
        !          67778:                msginit();
        !          67779: 
        !          67780:        if ( ! msqs )                   /* no message queues */
        !          67781:                u.u_error = ENODEV;
        !          67782: }
        !          67783: 
        !          67784: /*
        !          67785:  * Message Device Ioctl.
        !          67786:  */
        !          67787: 
        !          67788: static
        !          67789: msgioctl( dev, com, vec )
        !          67790: 
        !          67791: dev_t dev;
        !          67792: int com;
        !          67793: register int *vec;
        !          67794: 
        !          67795: {
        !          67796:        switch ( com ) {
        !          67797: 
        !          67798:        case MSGCTL:
        !          67799:                putuwd( vec+0,
        !          67800:                        umsgctl(getuwd( vec+1 ),
        !          67801:                                getuwd( vec+2 ),
        !          67802:                                getuwd( vec+3 ) ));
        !          67803:                return;
        !          67804: 
        !          67805:        case MSGGET:
        !          67806:                putuwd( vec+0,
        !          67807:                        umsgget(getuwd( vec+1 ),
        !          67808:                                getuwd( vec+2 ),
        !          67809:                                getuwd( vec+3 ) ));
        !          67810:                return;
        !          67811: 
        !          67812:        case MSGSND:
        !          67813:                putuwd( vec+0,
        !          67814:                        umsgsnd(getuwd( vec+1 ),
        !          67815:                                getuwd( vec+2 ),
        !          67816:                                getuwd( vec+3 ),
        !          67817:                                getuwd( vec+4 ) ));
        !          67818:                return;
        !          67819: 
        !          67820:        case MSGRCV:
        !          67821:                putuwd( vec+0,
        !          67822:                        umsgrcv(getuwd( vec+1 ),
        !          67823:                                getuwd( vec+2 ),
        !          67824:                                getuwd( vec+3 ),
        !          67825:                                getuwd( vec+4 ),
        !          67826:                                getuwd( vec+5 ),
        !          67827:                                getuwd( vec+6 ) ));
        !          67828:                return;
        !          67829: 
        !          67830:        default:
        !          67831:                u.u_error = EINVAL;
        !          67832:                return;
        !          67833:        }
        !          67834: }
        !          67835: @
        !          67836: 
        !          67837: 
        !          67838: 1.3
        !          67839: log
        !          67840: @update provided by hal
        !          67841: @
        !          67842: text
        !          67843: @@
        !          67844: 
        !          67845: 
        !          67846: 1.2
        !          67847: log
        !          67848: @new version provided y hal for v321
        !          67849: @
        !          67850: text
        !          67851: @@
        !          67852: 
        !          67853: 
        !          67854: 1.1
        !          67855: log
        !          67856: @Initial revision
        !          67857: @
        !          67858: text
        !          67859: @@
        !          67860: 0707070064030106561004440000030000030000011777770507310676300006100000003343/newbits/kernel/USRSRC/i8086/drv/RCS/msgstub.c,vhead     1.1;
        !          67861: branch   ;
        !          67862: access   ;
        !          67863: symbols  ;
        !          67864: locks    bin:1.1; strict;
        !          67865: comment  @ * @;
        !          67866: 
        !          67867: 
        !          67868: 1.1
        !          67869: date     91.06.10.10.24.23;  author bin;  state Exp;
        !          67870: branches ;
        !          67871: next     ;
        !          67872: 
        !          67873: 
        !          67874: desc
        !          67875: @initial version prov by hal
        !          67876: @
        !          67877: 
        !          67878: 
        !          67879: 
        !          67880: 1.1
        !          67881: log
        !          67882: @Initial revision
        !          67883: @
        !          67884: text
        !          67885: @/* $Header: /usr/src/sys/i8086/drv/RCS/msgstub.c,v 2.1 88/09/03 13:09:42 src Exp $
        !          67886:  *
        !          67887:  *     The  information  contained herein  is a trade secret  of INETCO
        !          67888:  *     Systems, and is confidential information.   It is provided under
        !          67889:  *     a license agreement,  and may be copied or disclosed  only under
        !          67890:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          67891:  *     this  material  without  the express  written  authorization  of
        !          67892:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          67893:  *
        !          67894:  *     Copyright (c) 1985
        !          67895:  *     An unpublished work by INETCO Systems, Ltd.
        !          67896:  *     All rights reserved.
        !          67897:  */
        !          67898: 
        !          67899: /*
        !          67900:  * Message Device Driver Stub.
        !          67901:  *
        !          67902:  *     This module provides stubs for messaging routines accessed by the
        !          67903:  *     operating system, and is linked in when messaging is not specified.
        !          67904:  *
        !          67905:  *                     Author: Allan Cornish, INETCO Systems Ltd., Nov 1986.
        !          67906:  *
        !          67907:  * $Log:       /usr/src/sys/i8086/drv/RCS/msgstub.c,v $
        !          67908:  * Revision 2.1        88/09/03  13:09:42      src
        !          67909:  * *** empty log message ***
        !          67910:  * 
        !          67911:  * Revision 1.1        88/03/24  17:05:52      src
        !          67912:  * Initial revision
        !          67913:  * 
        !          67914:  * 86/12/12    Allan Cornish           /usr/src/sys/i8086/drv/msgstub.c
        !          67915:  * Added 3rd argument to msgpoll() to support non-blocking polls.
        !          67916:  *
        !          67917:  * 85/11/21    Allan Cornish           /usr/src/sys/i8086/drv/msgstub.c
        !          67918:  * Initial Revision.
        !          67919:  */
        !          67920: 
        !          67921: #include <coherent.h>
        !          67922: #include <errno.h>
        !          67923: #include <sys/uproc.h>
        !          67924: 
        !          67925: msgpoll( qid, ev, msec )
        !          67926: int qid;
        !          67927: int ev;
        !          67928: int msec;
        !          67929: {
        !          67930:        return POLLNVAL;
        !          67931: }
        !          67932: 
        !          67933: umsgget()
        !          67934: {
        !          67935:        u.u_error = ENXIO;
        !          67936: }
        !          67937: 
        !          67938: umsgrcv()
        !          67939: {
        !          67940:        u.u_error = ENXIO;
        !          67941: }
        !          67942: 
        !          67943: umsgsnd()
        !          67944: {
        !          67945:        u.u_error = ENXIO;
        !          67946: }
        !          67947: 
        !          67948: umsgctl()
        !          67949: {
        !          67950:        u.u_error = ENXIO;
        !          67951: }
        !          67952: @
        !          67953: 0707070064030106551005550000030000030000011777770507310676300005500000016405/newbits/kernel/USRSRC/i8086/drv/RCS/parms,vhead     1.1;
        !          67954: branch   ;
        !          67955: access   ;
        !          67956: symbols  ;
        !          67957: locks    bin:1.1; strict;
        !          67958: comment  @# @;
        !          67959: 
        !          67960: 
        !          67961: 1.1
        !          67962: date     91.06.10.10.24.26;  author bin;  state Exp;
        !          67963: branches ;
        !          67964: next     ;
        !          67965: 
        !          67966: 
        !          67967: desc
        !          67968: @initial version prov by hal
        !          67969: @
        !          67970: 
        !          67971: 
        !          67972: 
        !          67973: 1.1
        !          67974: log
        !          67975: @Initial revision
        !          67976: @
        !          67977: text
        !          67978: @&� �&�����F� �P�́�VWU���U�&;v}=����^
        !          67979: �?�=t,��=-t=ct�DG��F��;F|�6����^
        !          67980: ��"��F��5+�P�X��]_^�VWU���"j� t]_^�VWU��~P�&��]_^�VWU��P�BP�6"�*&���>Ru�6"��P����+�P�6 �����}�6 ��P���� P�"P�T+�RP�e����P�:���F��~�}G�~���犅**�P�~���犅0*�P�~���犅$*�P�~������"�v���P��&���F�볋�]_^�VWU��+�P�v
        !          67981: �v�6�����v�v�6����;Ft
        !          67982: �"&P���]_^�VWU��z&P�|���FP�;&P��&P�&���>&P��&P�&���&P��
        !          67983: ��]_^�VWU���J+��v
        !          67984: ����<t+��D�DG���@@&P�v�����F��u�'&P�&P�,P�F�P����F��~�&t���~�&t���F���F��~�4�F������ȋ���F��F������ȋ���w��w�����^��GډW��ËFڋV�F�V�F�V�F�V�F�V�,���F��V�+�PR�v��v��5���F��V��F��V���n��^��~�x[u�~�tS�tO�v��&P�P�F�P�J���ȋ�=&u1�v
        !          67985: ����<t��P�F�PV����u�FΉD�FЉDOu���v��    ����]_^�VWU��FP�z&P�j��]_^�VWU��F
        !          67986: P�v�T��]_^�VWU����F�P��P�v�����F
        !          67987: P�F�P�)���N�}�F��F�P+�P�V����      �~��F����]_^�VWU���^�F
        !          67988: �F��^���F�F��^��F����=%t/�u���^�O}
�GSW�W
        !          67989: ���ԋ^���F��^��Lj���F� �F����F����^��F������-u�F�&�^��F������F���0u�F�0�^��F������*u'�^��F���F��}
        !          67990: �F�&�؉F�^��F�����0�F���0|&��9!�F�.�.  �ȋ��-0�F�^��F�����Ճ�.uY�^��F������*u�^��F���F�^��F�����0�F���0|&��9!�F�.�.   �ȋ��-0�F�^��F�����Ճ�lu&�^��F������dt��ot
        !          67991: ��ut��xu��%�����F��F����F�&�ǻl�CC.;��t��.�gDOUXcdefgorsux�I-N��SSS��i���^��F���F�~�}�؉F��F�-�
        !          67992: P�v�V� �������
        !          67993: P�^��F��7������^���W�F�V�F��~�y���؃��F�V��F�-�
        !          67994: P�v��v�V�?��뤸
        !          67995: P�^��w�7V�*�����F�������V�v��v�W�p �����F��j�F��^���F��u�F��F��F��F�����F�?t�~�|��+F�;F�~�N�-�F���F�F��^��F���^����^��7�v������F��F�F�+ƉF��}�F��~�uz�~�tG�~�0uA�^��?-u9�^�O}�GS�^��F���P�^�W
        !          67996: ����^���F��^��F����^���F��N��t#�^�O} �GS�v��ŋ^���F��^��F���;v�v;�^�O}�GS�^��F���P�^�W
        !          67997: ���ڋ^���F��^��F����^�����~�u�*��F��N��u���^�O}�GS�v��W
        !          67998: ���܋^���F��^��F���ȋ�]_^�VWU����v
        !          67999: �F��F��N��^����+��v���t �N��F��F��+��v�ڊ���^������N��^������^��?t�F�F�F��F����^���F��]_^�VWU����v�~�n��N�^���ǙRP�v�v
        !          68000: �
        !          68001: ���F�V��t4�N�F�F�ǙRP�v�v
        !          68002: �*
        !          68003: ���؊���^��F�V�F
        !          68004: �V��N�F�F�F
        !          68005: �؊���^��^�?t
��F�F��F���Ƌ�]_^�
        !          68006: VWU��B&��j&s(�<t�<�E&u���P�4�v
        !          68007: �v�4&��������+�]_^�VWU����v�~�F�f
        !          68008: �F��Et��F�F�W�U���^���N��}u�Eu1�~�tV�E~�MW�U������*�F�=��t5��F��N����v�V�E
�P����F��~)F���~�u�M��M�F�f
        !          68009: +F�+��v
        !          68010: ��]_^�VWU��v�~&u�Dt�n
        !          68011: &�^V���=��u����B�v�v�v
        !          68012: �D
�P�@@���؋ʉ^
        !          68013: �N���u���tӃ|t�F
        !          68014: %�&D��D�d�+�]_^�VWU����v�~�F�&�F��F��^
        !          68015: �F
        !          68016: ��F��F�r�~�rt���F��F�w�^
        !          68017: ���F�
        !          68018: �t�~�bt�~�+t�F��:F�t���F��}�~�u�v��v������}:�~�u�~�t.��&P�v�h�����|�~�&tW�Q���v��v�U�����|p�~�t�P+�PPW�6���u�P������u     W����>�D&+��D��D�D�Dp�D
        !          68019: ��LjD
����~�wu�F����~�au�F���+���]_^�VWU��v�|u:�Du(�D
�P������t��z&u�P�����D�u�D�D
        !          68020: ��A�Du�t��z&u�D�
�D
        !          68021: �D��D�
�D
        !          68022: ~�D
�P���D��D�D]_^�VWU����&P+�PP�v�-���؋ʉ^��N����u  ���u+���F�+�.�6��‹�]_^�VWU��vV�$���V�T��]_^�VWU��v�~
        !          68023: W����WV�U
        !          68024: ��]_^�VWU��h&��B&r�<t�4�$������]_^�VWU������v�A��]_^�VWU��v�D&u����/V�/�����D
�P�\���|t�Du  �t����D��]_^�VWU��v�D��D�uI�+D���~W�t�D
�P�"����;�t�>u�|�D;u�D����D+���L����]_^�VWU��vV�����t����i�>�&u
        !          68025: �z&P�o�����D+DP�t�D
�P����؉D=&u�>t�L��D믃|u�L@@룋D�D)D�<��*�]_^�VWU��P�v�>�&u
        !          68026: �z&P������D��&P�F�P�D
�P�(��=��t�t�F�*���>t
        !          68027: �L���L@@�����]_^�VWU��v�~
        !          68028: W����t�����E+EH�E����*�*�]_^�VWU��P�v�~
        !          68029: �ƈF��E��Eu4W�:���u)�&P�F�P�E
�P���=&u��*���>t�M�����]_^�VWU��v�DtV�T���D;w        V������8�&P�<+|�ǙRP�D
�P����؋ʃ��u
        !          68030: ���u������D�D+�]_^�VWU����F�P�AP�v�����|�&�+���]_^�VWU���N�t�v
        !          68031: �~���u
        !          68032: ����wB�&J��]_^�VWU�츚&P��&P�����&P��&P�q���&P�����]_^�VWU����>�&t+���F%��F�;Fs�F�F���&��&�v���&����=��u��&&�~�&v}�n�&�~�s��F��҃>�&u��&�ƉF���&��&�/;6�&u���F��D�F���&���&-���E�F��u��&�F�-
&���F���&-����F��E�&��]_^�VWU����~u+����F%���F�;Fr�+��6�&��&�F��F��N��t$��N���&uC+��~�t
        !          68033: �F�%�����D����;6�&t�P��&P�P�8&�����v������u���t���F�%��&��F���&�F�;F�s��뜋F�)F��F�=s�%���F����F���&��F����F���&�F���&���&�D��]_^�VWU��~tE�FHH���<��s�P�P�P����'�&�ρ������;�&t
        !          68034: ��&�&u�6�&]_^�VWU��̀��]_^�VWU��+�P�[�����~t$��F��;�v�����V�6���>u��]_^�͆��͈��Ͷ��͓��ͅ��̓��̈́�̋܋W�G�͑�̋Ë܋_��Ë܍_VWU��P�V
        !          68035: �F+�+�� ��������;wrw;?r+?w@@��[��]_^��Ë܋_��Ë܍_VWU��P�v
        !          68036: �~+�+�� ��������;Wrw;r+W��[��]_^�VWU��v�~
        !          68037: �E�E;uW������u���ƈ*�=
        !          68038: uW������t������*�]_^�VWU��v�F��D�D��F
        !          68039: �؉D�|&�}�D��D
        !          68040: ���D
        !          68041: ���]_^�VWU��v
        !          68042: �D���]_^�VWU��v
        !          68043: �D��<��F�*�]_^�VWU��v�D���]_^�{NULL}0123456789ABCDEFatparm_/coherent/dev/kmemUsage: parms [-][c kernel_file]Bad namelist file %sCannot open %sHard drive parameters as stored in "at" driver:
        !          68044: drive %d  cyl=%4d  hd=%2d  spt=%2d  ctrl=%02x
        !          68045: Kernel memory read error%r
        !          68046: rj&z&�&p�&p�&&p�You must compile with the -f flag to include printf() floating point.
        !          68047: Bad pointer in malloc.
        !          68048: Bad pointer in free.
        !          68049: ahigh     
        !          68050: ahigh      
        !          68051: free_�bhigh  bhigh     main_ __a_first_�&errno___a_count_�&_fgetb_�
_fgetc__fpinit_�_dtefg_�Count     _stropen_dnlist_�&write_|initialise_}sbrk_$open_texecute_�_stderr_�&_fp_B&kfd__fopen_f
        !          68052: malloc_�fprintf_]exit_�fclose_�_canl_�_fgeteof_�brk_�_fputb_~_fputc_�_stdin_j&environ_ fread_D        _stdout_z&atparm_"vldiv�sprintf_svlrem�strncmp_�kread_g&fflush_*
String1        String2     
        !          68053: kfile_ panic_�&vrdiv�vrrem�fseek_�   nfile_"creat_h_fputt___a_scanp_�&printf_Falow    alow     lseek_pblow blow     usage_�close_dabort_fopen_      _exit_finit_�nl_Bioctl_lread_x_fpseek_isatty_x_finish_�_fginit_p@
        !          68054: 0707070064030106541004440000030000030000011777770507310676500005700000005110/newbits/kernel/USRSRC/i8086/drv/RCS/parms.c,vhead     1.1;
        !          68055: branch   ;
        !          68056: access   ;
        !          68057: symbols  ;
        !          68058: locks    bin:1.1; strict;
        !          68059: comment  @ * @;
        !          68060: 
        !          68061: 
        !          68062: 1.1
        !          68063: date     91.06.10.10.24.29;  author bin;  state Exp;
        !          68064: branches ;
        !          68065: next     ;
        !          68066: 
        !          68067: 
        !          68068: desc
        !          68069: @initial version prov by hal
        !          68070: @
        !          68071: 
        !          68072: 
        !          68073: 
        !          68074: 1.1
        !          68075: log
        !          68076: @Initial revision
        !          68077: @
        !          68078: text
        !          68079: @/* parms.c - display hard drive parameters per "atparm" in kernel */
        !          68080: 
        !          68081: #include <stdio.h>
        !          68082: #include <l.out.h>
        !          68083: 
        !          68084: /*
        !          68085:  * For easy referencing.
        !          68086:  */
        !          68087: #define        at_table                nl[0].n_value
        !          68088: #define        plowner         nl[1].n_value
        !          68089: #define NDRIVE         2
        !          68090: 
        !          68091: struct dparm_s {
        !          68092:        unsigned short  d_ncyl;         /* number of cylinders */
        !          68093:        unsigned char   d_nhead;        /* number of heads */
        !          68094:        unsigned short  d_rwcc;         /* reduced write current cyl */
        !          68095:        unsigned short  d_wpcc;         /* write pre-compensation cyl */
        !          68096:        unsigned char   d_eccl;         /* max ecc data length */
        !          68097:        unsigned char   d_ctrl;         /* control byte */
        !          68098:        unsigned char   d_fill2[3];
        !          68099:        unsigned short  d_landc;        /* landing zone cylinder */
        !          68100:        unsigned char   d_nspt;         /* number of sectors per track */
        !          68101:        unsigned char   d_fill3;
        !          68102: 
        !          68103: }      atparm[ NDRIVE ] = {
        !          68104:        0                               /* Initialized to allow patching */
        !          68105: };
        !          68106: 
        !          68107: /*
        !          68108:  * Table for namelist.
        !          68109:  */
        !          68110: struct nlist nl[] ={
        !          68111:        "atparm_",              0,      0,
        !          68112:        ""
        !          68113: };
        !          68114: 
        !          68115: /*
        !          68116:  * Symbols.
        !          68117:  */
        !          68118: char    *kfile;                        /* Kernel data memory file */
        !          68119: char    *nfile;                        /* Namelist file */
        !          68120: int     kfd;                           /* Kernel memory file descriptor */
        !          68121: 
        !          68122: main(argc, argv)
        !          68123: char *argv[];
        !          68124: {
        !          68125:        register int i;
        !          68126:        register char *cp;
        !          68127: 
        !          68128:        initialise();
        !          68129:        for (i=1; i<argc; i++) {
        !          68130:                for (cp=&argv[i][0]; *cp; cp++) {
        !          68131:                        switch (*cp) {
        !          68132:                        case '-':
        !          68133:                                continue;
        !          68134:                        case 'c':
        !          68135:                                if (++i >= argc)
        !          68136:                                        usage();
        !          68137:                                nfile = argv[i];
        !          68138:                                continue;
        !          68139:                        default:
        !          68140:                                usage();
        !          68141:                        }
        !          68142:                }
        !          68143:        }
        !          68144:        execute();
        !          68145:        exit(0);
        !          68146: }
        !          68147: 
        !          68148: /*
        !          68149:  * Initialise.
        !          68150:  */
        !          68151: initialise()
        !          68152: {
        !          68153:        nfile = "/coherent";
        !          68154:        kfile = "/dev/kmem";
        !          68155: }
        !          68156: 
        !          68157: /*
        !          68158:  * Print out usage.
        !          68159:  */
        !          68160: usage()
        !          68161: {
        !          68162:        panic("Usage: parms [-][c kernel_file]");
        !          68163: }
        !          68164: 
        !          68165: /*
        !          68166:  * Display parameters
        !          68167:  */
        !          68168: execute()
        !          68169: {
        !          68170:        int dr;
        !          68171: 
        !          68172:        nlist(nfile, nl);
        !          68173:        if (nl[0].n_type == 0)
        !          68174:                panic("Bad namelist file %s", nfile);
        !          68175:        if ((kfd = open(kfile, 0)) < 0)
        !          68176:                panic("Cannot open %s", kfile);
        !          68177: 
        !          68178:        kread((long)at_table, atparm, sizeof(atparm));
        !          68179:        printf("Hard drive parameters as stored in \"at\" driver:\n");
        !          68180:        for (dr = 0;  dr < NDRIVE;  dr++) {
        !          68181:                printf("drive %d  cyl=%4d  hd=%2d  spt=%2d  ctrl=%02x\n",
        !          68182:                        dr, atparm[dr].d_ncyl, atparm[dr].d_nhead,
        !          68183:                        atparm[dr].d_nspt, atparm[dr].d_ctrl);
        !          68184:        }
        !          68185: }
        !          68186: 
        !          68187: /*
        !          68188:  * Read `n' bytes into the buffer `bp' from kernel memory
        !          68189:  * starting at seek position `s'.
        !          68190:  */
        !          68191: kread(s, bp, n)
        !          68192: long s;
        !          68193: {
        !          68194:        lseek(kfd, (long)s, 0);
        !          68195:        if (read(kfd, bp, n) != n)
        !          68196:                panic("Kernel memory read error");
        !          68197: }
        !          68198: 
        !          68199: /*
        !          68200:  * Print out an error message and exit.
        !          68201:  */
        !          68202: panic(a1)
        !          68203: char *a1;
        !          68204: {
        !          68205:        fflush(stdout);
        !          68206:        fprintf(stderr, "%r", &a1);
        !          68207:        fprintf(stderr, "\n");
        !          68208:        exit(1);
        !          68209: }
        !          68210: @
        !          68211: 0707070064030106261004440000030000030000011777770507310676600005700000005737/newbits/kernel/USRSRC/i8086/drv/RCS/pccon.c,vhead     1.4;
        !          68212: branch   ;
        !          68213: access   ;
        !          68214: symbols  ;
        !          68215: locks    bin:1.4; strict;
        !          68216: comment  @ * @;
        !          68217: 
        !          68218: 
        !          68219: 1.4
        !          68220: date     91.06.20.14.52.01;  author bin;  state Exp;
        !          68221: branches ;
        !          68222: next     1.3;
        !          68223: 
        !          68224: 1.3
        !          68225: date     91.06.18.08.13.40;  author bin;  state Exp;
        !          68226: branches ;
        !          68227: next     1.2;
        !          68228: 
        !          68229: 1.2
        !          68230: date     91.06.17.12.34.31;  author bin;  state Exp;
        !          68231: branches ;
        !          68232: next     1.1;
        !          68233: 
        !          68234: 1.1
        !          68235: date     91.06.10.10.24.31;  author bin;  state Exp;
        !          68236: branches ;
        !          68237: next     ;
        !          68238: 
        !          68239: 
        !          68240: desc
        !          68241: @initial version prov by hal
        !          68242: @
        !          68243: 
        !          68244: 
        !          68245: 1.4
        !          68246: log
        !          68247: @update provided by hal
        !          68248: @
        !          68249: text
        !          68250: @/* $Header: /usr/src/sys/i8086/drv/RCS/pccon.c,v 2.1 88/09/03 13:09:51 src Exp $ */
        !          68251: /* (lgl-
        !          68252:  *     The information contained herein is a trade secret of Mark Williams
        !          68253:  *     Company, and  is confidential information.  It is provided  under a
        !          68254:  *     license agreement,  and may be  copied or disclosed  only under the
        !          68255:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          68256:  *     material without the express written authorization of Mark Williams
        !          68257:  *     Company or persuant to the license agreement is unlawful.
        !          68258:  *
        !          68259:  *     COHERENT Version 2.3.37
        !          68260:  *     Copyright (c) 1982, 1983, 1984.
        !          68261:  *     An unpublished work by Mark Williams Company, Chicago.
        !          68262:  *     All rights reserved.
        !          68263:  -lgl) */
        !          68264: /*
        !          68265:  * Configuration table.
        !          68266:  * 8088 Coherent, IBM PC.
        !          68267:  * Minimal system.
        !          68268:  *
        !          68269:  * $Log:       /usr/src/sys/i8086/drv/RCS/pccon.c,v $
        !          68270:  * Revision 2.1        88/09/03  13:09:51      src
        !          68271:  * *** empty log message ***
        !          68272:  * 
        !          68273:  * Revision 1.1        88/03/24  17:05:55      src
        !          68274:  * Initial revision
        !          68275:  * 
        !          68276:  */
        !          68277: #include <sys/coherent.h>
        !          68278: #include <sys/con.h>
        !          68279: #include <mtype.h>
        !          68280: #include <sys/stat.h>
        !          68281: 
        !          68282: extern CON     nlcon[];                /* Null device */
        !          68283: extern CON     ctcon[];                /* Console terminal */
        !          68284: 
        !          68285: /*
        !          68286:  * Device table.
        !          68287:  */
        !          68288: DRV    drvl[NDRV] = {
        !          68289:        {nlcon},        {ctcon},        {NULL },        {NULL },  /*  0 -  3 */
        !          68290:        {NULL },        {NULL },        {NULL },        {NULL },  /*  4 -  7 */
        !          68291:        {NULL },        {NULL },        {NULL },        {NULL },  /*  8 - 11 */
        !          68292:        {NULL },        {NULL },        {NULL },        {NULL },  /* 12 - 15 */
        !          68293:        {NULL },        {NULL },        {NULL },        {NULL },  /* 16 - 19 */
        !          68294:        {NULL },        {NULL },        {NULL },        {NULL },  /* 20 - 23 */
        !          68295:        {NULL },        {NULL },        {NULL },        {NULL },  /* 24 - 27 */
        !          68296:        {NULL },        {NULL },        {NULL },        {NULL }   /* 28 - 31 */
        !          68297: };
        !          68298: 
        !          68299: /*
        !          68300:  * Time.
        !          68301:  */
        !          68302: TIME timer ={
        !          68303:        0,                              /* Initial time */
        !          68304:        0,                              /* Ticks */
        !          68305:        8*60,                           /* Pacific */
        !          68306:        1                               /* Daylight saving time */
        !          68307: };
        !          68308: 
        !          68309: /*
        !          68310:  * Devices and sizes.
        !          68311:  */
        !          68312: dev_t  rootdev = makedev(4, 4);        /* Root device */
        !          68313: dev_t  pipedev = makedev(4, 4);        /* Pipe device */
        !          68314: dev_t  swapdev = makedev(0, 0);        /* Swap device */
        !          68315: daddr_t        swapbot = 0;                    /* Swap base */
        !          68316: daddr_t        swaptop = 0;                    /* Swap end */
        !          68317: int    ronflag = 0;                    /* Not read only root device */
        !          68318: int    drvn    = NDRV;                 /* Maximum number of devices */
        !          68319: int    mactype = M_8086;               /* Machine type */
        !          68320: 
        !          68321: /*
        !          68322:  * Flexible param's
        !          68323:  */
        !          68324: int    NCLIST  = 8;            /* 8 clists per installed tty, never run out */
        !          68325: int    ALLSIZE = 7*1024;       /* 7K has been reasonable */
        !          68326: int    NINODE  = 64;           /* More than enough so far */
        !          68327: int    NBUF    = 16;           /* Stingy */
        !          68328: @
        !          68329: 
        !          68330: 
        !          68331: 1.3
        !          68332: log
        !          68333: @update provided by hal
        !          68334: @
        !          68335: text
        !          68336: @d28 2
        !          68337: a29 2
        !          68338: #include <coherent.h>
        !          68339: #include <con.h>
        !          68340: d31 1
        !          68341: a31 1
        !          68342: #include <stat.h>
        !          68343: @
        !          68344: 
        !          68345: 
        !          68346: 1.2
        !          68347: log
        !          68348: @new version provided y hal for v321
        !          68349: @
        !          68350: text
        !          68351: @@
        !          68352: 
        !          68353: 
        !          68354: 1.1
        !          68355: log
        !          68356: @Initial revision
        !          68357: @
        !          68358: text
        !          68359: @@
        !          68360: 0707070064030106521004440000030000030000011777770507310676700005700000004047/newbits/kernel/USRSRC/i8086/drv/RCS/prate.c,vhead     1.1;
        !          68361: branch   ;
        !          68362: access   ;
        !          68363: symbols  ;
        !          68364: locks    bin:1.1; strict;
        !          68365: comment  @ * @;
        !          68366: 
        !          68367: 
        !          68368: 1.1
        !          68369: date     91.06.10.10.24.36;  author bin;  state Exp;
        !          68370: branches ;
        !          68371: next     ;
        !          68372: 
        !          68373: 
        !          68374: desc
        !          68375: @initial version prov by hal
        !          68376: @
        !          68377: 
        !          68378: 
        !          68379: 
        !          68380: 1.1
        !          68381: log
        !          68382: @Initial revision
        !          68383: @
        !          68384: text
        !          68385: @/* prate.c - display polling rate of com[1-4] drivers */
        !          68386: 
        !          68387: #include <stdio.h>
        !          68388: #include <l.out.h>
        !          68389: #include <poll_clk.h>
        !          68390: 
        !          68391: /*
        !          68392:  * For easy referencing.
        !          68393:  */
        !          68394: #define        plrate          nl[0].n_value
        !          68395: #define        plowner         nl[1].n_value
        !          68396: 
        !          68397: /*
        !          68398:  * Table for namelist.
        !          68399:  */
        !          68400: struct nlist nl[] ={
        !          68401:        "poll_rate_",           0,      0,
        !          68402:        "poll_owner_",          0,      0,
        !          68403:        ""
        !          68404: };
        !          68405: 
        !          68406: /*
        !          68407:  * Symbols.
        !          68408:  */
        !          68409: char    *kfile;                        /* Kernel data memory file */
        !          68410: char    *nfile;                        /* Namelist file */
        !          68411: int     kfd;                           /* Kernel memory file descriptor */
        !          68412: 
        !          68413: main(argc, argv)
        !          68414: char *argv[];
        !          68415: {
        !          68416:        register int i;
        !          68417:        register char *cp;
        !          68418: 
        !          68419:        initialise();
        !          68420:        for (i=1; i<argc; i++) {
        !          68421:                for (cp=&argv[i][0]; *cp; cp++) {
        !          68422:                        switch (*cp) {
        !          68423:                        case '-':
        !          68424:                                continue;
        !          68425:                        case 'c':
        !          68426:                                if (++i >= argc)
        !          68427:                                        usage();
        !          68428:                                nfile = argv[i];
        !          68429:                                continue;
        !          68430:                        default:
        !          68431:                                usage();
        !          68432:                        }
        !          68433:                }
        !          68434:        }
        !          68435:        execute();
        !          68436:        exit(0);
        !          68437: }
        !          68438: 
        !          68439: /*
        !          68440:  * Initialise.
        !          68441:  */
        !          68442: initialise()
        !          68443: {
        !          68444:        nfile = "/coherent";
        !          68445:        kfile = "/dev/kmem";
        !          68446: }
        !          68447: 
        !          68448: /*
        !          68449:  * Print out usage.
        !          68450:  */
        !          68451: usage()
        !          68452: {
        !          68453:        panic("Usage: prate [-][c kernel_file]");
        !          68454: }
        !          68455: 
        !          68456: /*
        !          68457:  * Display polling rate
        !          68458:  */
        !          68459: execute()
        !          68460: {
        !          68461:        int rate, owner;
        !          68462: 
        !          68463:        nlist(nfile, nl);
        !          68464:        if (nl[0].n_type == 0)
        !          68465:                panic("Bad namelist file %s", nfile);
        !          68466:        if ((kfd = open(kfile, 0)) < 0)
        !          68467:                panic("Cannot open %s", kfile);
        !          68468: 
        !          68469:        kread((long)plrate, &rate, sizeof(int));
        !          68470:        kread((long)plowner, &owner, sizeof(int));
        !          68471:        if (rate) {
        !          68472:                if (owner & POLL_AL)
        !          68473:                        printf("al driver is ");
        !          68474:                else if (owner & POLL_HS)
        !          68475:                        printf("hs driver is ");
        !          68476:                printf("polling at %d Hz\n", rate);
        !          68477:        } else
        !          68478:                printf("polling is OFF\n");
        !          68479: }
        !          68480: 
        !          68481: /*
        !          68482:  * Read `n' bytes into the buffer `bp' from kernel memory
        !          68483:  * starting at seek position `s'.
        !          68484:  */
        !          68485: kread(s, bp, n)
        !          68486: long s;
        !          68487: {
        !          68488:        lseek(kfd, (long)s, 0);
        !          68489:        if (read(kfd, bp, n) != n)
        !          68490:                panic("Kernel memory read error");
        !          68491: }
        !          68492: 
        !          68493: /*
        !          68494:  * Print out an error message and exit.
        !          68495:  */
        !          68496: panic(a1)
        !          68497: char *a1;
        !          68498: {
        !          68499:        fflush(stdout);
        !          68500:        fprintf(stderr, "%r", &a1);
        !          68501:        fprintf(stderr, "\n");
        !          68502:        exit(1);
        !          68503: }
        !          68504: @
        !          68505: 0707070064030106511004440000030000030000011777770507310676700005400000012610/newbits/kernel/USRSRC/i8086/drv/RCS/qq.c,vhead     1.1;
        !          68506: branch   ;
        !          68507: access   ;
        !          68508: symbols  ;
        !          68509: locks    bin:1.1; strict;
        !          68510: comment  @ * @;
        !          68511: 
        !          68512: 
        !          68513: 1.1
        !          68514: date     91.06.10.10.24.41;  author bin;  state Exp;
        !          68515: branches ;
        !          68516: next     ;
        !          68517: 
        !          68518: 
        !          68519: desc
        !          68520: @initial version prov by hal
        !          68521: @
        !          68522: 
        !          68523: 
        !          68524: 
        !          68525: 1.1
        !          68526: log
        !          68527: @Initial revision
        !          68528: @
        !          68529: text
        !          68530: @/*
        !          68531:  * qq - sample device driver using absolute memory addressing
        !          68532:  *
        !          68533:  * All this device does is read/write video ram.
        !          68534:  * It assumes that there is a monochrome adapter in use, so that video
        !          68535:  * ram starts at segment B000;  if color, this should be changed to B800.
        !          68536:  *
        !          68537:  * This driver does not do anything useful;  it is intended to serve as
        !          68538:  * an example.
        !          68539:  *
        !          68540:  * Here is how to make the driver and test it (you will need a COHERENT
        !          68541:  * Driver Kit installed on your system):
        !          68542:  * 1.  put this file, "qq.c", in /usr/src/sys/i8086/drv/qq.c
        !          68543:  * 2.  cut out the make file and store it in /usr/src/sys/i8086/drv/Mf.qq
        !          68544:  * 3.  cut out the config file and store it at /usr/sys/confdrv/qq
        !          68545:  * 4.  execute the following commands
        !          68546:  *             cd /usr/src/sys/i8086/drv
        !          68547:  *             make -f Mf.qq
        !          68548:  *             cd /usr/sys
        !          68549:  *             ldconfig qq
        !          68550:  *             drvld ldrv/qq
        !          68551:  * 5.  the driver should now be loaded - try "date > /dev/qq" or
        !          68552:  *     "cat < /dev/qq" (you will have to use Ctrl-C to stop the "cat"
        !          68553:  *     command)
        !          68554:  * 6.  to unload the driver, do "ps -d" to get the PID number for the driver;
        !          68555:  *     then do "kill kill nnn" where nnn is the process number for "<qq>"
        !          68556:  */
        !          68557: /****
        !          68558: Here is the makefile for the "qq" driver (cut it out of this file):
        !          68559: --------------- cut here -----------------
        !          68560: # Make file for a loadable driver
        !          68561: 
        !          68562: AS=exec /bin/as
        !          68563: CC=exec /bin/cc
        !          68564: CPP=exec /lib/cpp
        !          68565: CFLAGS=-I.. -I../sys -I../.. -I../../sys \
        !          68566:        -I/usr/include/sys
        !          68567: AFLAGS=-gx
        !          68568: 
        !          68569: # Include directories
        !          68570: USRINC=/usr/include
        !          68571: SYSINC=/usr/include/sys
        !          68572: KERINC=/usr/src/sys/sys
        !          68573: DRVINC=/usr/src/sys/i8086/sys
        !          68574: USRSYS=/usr/sys
        !          68575: 
        !          68576: DRVOBJ=        objects/qq.o
        !          68577: 
        !          68578: qq: objects/qq.o
        !          68579:        rm -f $(USRSYS)/lib/qq.a
        !          68580:        ar rc $(USRSYS)/lib/qq.a objects/qq.o
        !          68581: 
        !          68582: objects/qq.o:                          \
        !          68583:                $(KERINC)/coherent.h    $(SYSINC)/types.h \
        !          68584:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          68585:                                        $(SYSINC)/fun.h \
        !          68586:                $(SYSINC)/con.h         \
        !          68587:                $(USRINC)/errno.h       \
        !          68588:                $(SYSINC)/sched.h       \
        !          68589:                $(SYSINC)/seg.h         \
        !          68590:                $(SYSINC)/stat.h        \
        !          68591:                $(SYSINC)/types.h       \
        !          68592:                $(SYSINC)/uproc.h       \
        !          68593:                qq.c
        !          68594:        $(CC) $(CFLAGS) -c -o $@@ qq.c
        !          68595: --------------- cut here -----------------
        !          68596: 
        !          68597: Here is the configuration file for the "qq" driver.
        !          68598: Cut it out of this file and copy it to "/usr/sys/confdrv/qq".
        !          68599: When "ldconfig" is run, it will create a node for /dev/qq.
        !          68600: --------------- cut here -----------------
        !          68601: :
        !          68602: : 'Dummy driver for write to absolute RAM area'
        !          68603: :
        !          68604: UNDEF="${UNDEF} -u qqcon_ lib/qq.a"
        !          68605: PATCH="${PATCH} drvl_+70=qqcon_"
        !          68606: :
        !          68607: : devices
        !          68608: :
        !          68609: umask 0111
        !          68610: /etc/mknod -f ${DEV-/dev}/qq c 7  0 || exit 1
        !          68611: --------------- cut here -----------------
        !          68612: ****/
        !          68613: #include "coherent.h"
        !          68614: #include "ins8250.h"
        !          68615: #include <sys/stat.h>
        !          68616: #include <sys/uproc.h>
        !          68617: #include <sys/proc.h>
        !          68618: #include <sys/con.h>
        !          68619: #include <errno.h>
        !          68620: #include <sys/types.h>
        !          68621: #include <sys/mmu.h>
        !          68622: 
        !          68623: /*
        !          68624:  * Definitions.
        !          68625:  *
        !          68626:  */
        !          68627: #define        MONOVIDEO       0xB000          /* monochrome text RAM segment */
        !          68628: #define        VIDLENGTH       (2048*2)        /* screen locations (2 bytes each) */
        !          68629: 
        !          68630: /*
        !          68631:  * Export Functions.
        !          68632:  */
        !          68633: int    qqload();
        !          68634: int    qqopen();
        !          68635: int    qqclose();
        !          68636: int    qqread();
        !          68637: int    qqwrite();
        !          68638: int    qqunload();
        !          68639: 
        !          68640: /*
        !          68641:  * Import Functions
        !          68642:  */
        !          68643: int    nulldev();
        !          68644: int    nonedev();
        !          68645: 
        !          68646: /*
        !          68647:  * Configuration table.
        !          68648:  */
        !          68649: CON qqcon ={
        !          68650:        DFCHR,                          /* Flags */
        !          68651:        7,                              /* Major index */
        !          68652:        qqopen,                         /* Open */
        !          68653:        qqclose,                        /* Close */
        !          68654:        nulldev,                        /* Block */
        !          68655:        qqread,                         /* Read */
        !          68656:        qqwrite,                        /* Write */
        !          68657:        nulldev,                        /* Ioctl */
        !          68658:        nulldev,                        /* Powerfail */
        !          68659:        nulldev,                        /* Timeout */
        !          68660:        qqload,                         /* Load */
        !          68661:        qqunload,                       /* Unload */
        !          68662:        nulldev                         /* Poll */
        !          68663: };
        !          68664: 
        !          68665: /*
        !          68666:  * Local variables.
        !          68667:  */
        !          68668: static faddr_t screen_fp;              /* (far *) to access screen */
        !          68669: static paddr_t screen_base;            /* physical address of screen base */
        !          68670: 
        !          68671: /*
        !          68672:  * Load Routine.
        !          68673:  */
        !          68674: static qqload()
        !          68675: {
        !          68676:        /*
        !          68677:         * Allocate a selector to map onto the video RAM.  ptov() will
        !          68678:         * return the first available selector of the 8,192 possible.
        !          68679:         * This is time consuming, so we only want to do this as part
        !          68680:         * of our initialization code and not on every access.
        !          68681:         *
        !          68682:         * Since we are operating in 286 protected mode (ugh), the
        !          68683:         * second argument to ptov() must not exceed 0x10000L.
        !          68684:         */
        !          68685:        screen_base = (paddr_t)((long)(unsigned)MONOVIDEO << 4);
        !          68686:        screen_fp = ptov(screen_base, (fsize_t)VIDLENGTH);
        !          68687: }
        !          68688: 
        !          68689: static qqunload()
        !          68690: {
        !          68691:        /*
        !          68692:         * We have to free up the selector now that we're done using it.
        !          68693:         */
        !          68694:        vrelse(screen_fp);
        !          68695: }
        !          68696: 
        !          68697: /*
        !          68698:  * Open Routine.
        !          68699:  */
        !          68700: qqopen( dev, mode )
        !          68701: dev_t dev;
        !          68702: {
        !          68703: }
        !          68704: 
        !          68705: /*
        !          68706:  * Close Routine.
        !          68707:  */
        !          68708: qqclose( dev )
        !          68709: dev_t dev;
        !          68710: {
        !          68711: }
        !          68712: 
        !          68713: /*
        !          68714:  * Read Routine.
        !          68715:  */
        !          68716: qqread( dev, iop )
        !          68717: dev_t dev;
        !          68718: register IO * iop;
        !          68719: {
        !          68720:        static int offset;
        !          68721:        int c;
        !          68722:        /*
        !          68723:         * Read a character code from video RAM
        !          68724:         * Start reading RAM just after where previous read ended
        !          68725:         *
        !          68726:         * Note that "offset" is the value of the displacement into
        !          68727:         * the screen RAM. Any expression which results in a value
        !          68728:         * which is less than VIDLENGTH is OK here.
        !          68729:         */
        !          68730:        while(iop->io_ioc) {
        !          68731:                c = ffbyte(screen_fp + offset); /* fetch a "far" byte */
        !          68732:                if(ioputc(c, iop) == -1)
        !          68733:                        break;
        !          68734:                offset += 2;
        !          68735:                offset %= VIDLENGTH;
        !          68736:        }
        !          68737: }
        !          68738: 
        !          68739: /*
        !          68740:  * Write Routine.
        !          68741:  */
        !          68742: qqwrite( dev, iop )
        !          68743: dev_t dev;
        !          68744: register IO * iop;
        !          68745: {
        !          68746:        int offset = 0;
        !          68747:        int c;
        !          68748: 
        !          68749:        /*
        !          68750:         * Write a character into the screen RAM
        !          68751:         * Note that "offset" is the value of the displacement into
        !          68752:         * the screen RAM. Any expression which results in a value
        !          68753:         * which is less than VIDLENGTH is OK here.
        !          68754:         */
        !          68755:        while ((c = iogetc(iop)) >= 0 && offset < VIDLENGTH) {
        !          68756:                sfbyte(screen_fp + offset, c);     /* store a "far" byte */
        !          68757:                offset += 2;    /* skip attribute byte */
        !          68758:        }
        !          68759: }
        !          68760: @
        !          68761: 0707070064030106501004440000030000030000011777770507310677100005400000015475/newbits/kernel/USRSRC/i8086/drv/RCS/rp.c,vhead     1.1;
        !          68762: branch   ;
        !          68763: access   ;
        !          68764: symbols  ;
        !          68765: locks    bin:1.1; strict;
        !          68766: comment  @ * @;
        !          68767: 
        !          68768: 
        !          68769: 1.1
        !          68770: date     91.06.10.10.24.49;  author bin;  state Exp;
        !          68771: branches ;
        !          68772: next     ;
        !          68773: 
        !          68774: 
        !          68775: desc
        !          68776: @initial version prov by hal
        !          68777: @
        !          68778: 
        !          68779: 
        !          68780: 
        !          68781: 1.1
        !          68782: log
        !          68783: @Initial revision
        !          68784: @
        !          68785: text
        !          68786: @/*
        !          68787:  *     Ram Pipe Device Driver
        !          68788:  */
        !          68789: 
        !          68790: #include <coherent.h>
        !          68791: #include <con.h>
        !          68792: #include <seg.h>
        !          68793: #include <stat.h>
        !          68794: #include <sched.h>
        !          68795: #include <termio.h>
        !          68796: #include <v7sgtty.h>
        !          68797: #include <uproc.h>
        !          68798: #include <errno.h>
        !          68799: 
        !          68800: #define        MAXNRP  30              /* Maximum number of ram pipes (must be < 32) */
        !          68801: #define        NCPQ    2048            /* Size of pipe in bytes */
        !          68802: #define        RPMAJOR 22              /* Major device for ram pipes  */
        !          68803: 
        !          68804: /*
        !          68805:  *     function definitions
        !          68806:  */
        !          68807: int    rpopen();
        !          68808: int    rpread();
        !          68809: int    rpwrite();
        !          68810: int    rpioctl();
        !          68811: int    rppoll();
        !          68812: void   rpuload();
        !          68813: int    nulldev();
        !          68814: int    nonedev();
        !          68815: 
        !          68816: 
        !          68817: /*
        !          68818:  *     configuration table
        !          68819:  */
        !          68820: CON rpcon = {
        !          68821:        DFCHR|DFPOL,                    /* flags        */
        !          68822:        RPMAJOR,                        /* major index  */
        !          68823:        rpopen,                         /* open         */
        !          68824:        nulldev,                        /* close        */
        !          68825:        nonedev,                        /* block        */
        !          68826:        rpread,                         /* read         */
        !          68827:        rpwrite,                        /* write        */
        !          68828:        rpioctl,                        /* ioctl        */
        !          68829:        nulldev,                        /* power fail   */
        !          68830:        nulldev,                        /* timeout      */
        !          68831:        nulldev,                        /* load         */
        !          68832:        rpuload,                        /* unload       */
        !          68833:        rppoll                          /* poll         */
        !          68834: };
        !          68835: 
        !          68836: /*
        !          68837:  *     Ram Pipe Headers
        !          68838:  */
        !          68839: static
        !          68840: struct ring {
        !          68841:        unsigned short  q_size;         /* Number of characters in queue    */
        !          68842:        unsigned short  q_mask;         /* Ring buffer Mask: NCPQ-1         */
        !          68843:        faddr_t         q_ifaddr;       /* Input virtual address            */
        !          68844:        faddr_t         q_ofaddr;       /* Output virtual address           */
        !          68845:        GATE            q_igate;        /* Read lock                        */
        !          68846:        GATE            q_ogate;        /* Write lock                       */
        !          68847:        event_t         q_ipoll;        /* Input polls                      */
        !          68848:        event_t         q_opoll;        /* Output polls                     */
        !          68849: 
        !          68850: } rpq[MAXNRP];
        !          68851: 
        !          68852: static SEG * rpsegp;
        !          68853: unsigned NRP = MAXNRP;
        !          68854: 
        !          68855: /*
        !          68856:  * Initialization Routine
        !          68857:  */
        !          68858: static
        !          68859: rpinit()
        !          68860: {
        !          68861:        register struct ring *rp;
        !          68862:        faddr_t faddr;
        !          68863:        paddr_t paddr;
        !          68864: 
        !          68865:        /*
        !          68866:         * Ensure valid number of ram pipes
        !          68867:         */
        !          68868:        if ( NRP > MAXNRP )
        !          68869:                NRP = MAXNRP;
        !          68870:                
        !          68871:        /*
        !          68872:         * Allocate ram pipe segment, initialize ram pipe queues
        !          68873:         */
        !          68874:         if ( NRP != 0 ) {
        !          68875:                rpsegp = salloc((fsize_t)NRP*NCPQ, SFSYST|SFHIGH|SFNSWP|SFNCLR);
        !          68876: 
        !          68877:                if ( rpsegp == NULL )
        !          68878:                        return -1;
        !          68879: 
        !          68880:                paddr = rpsegp->s_paddr;
        !          68881: 
        !          68882:                for ( rp = &rpq[0]; rp < &rpq[NRP]; rp++, paddr += NCPQ ) {
        !          68883: 
        !          68884:                        faddr = ptov( paddr, (fsize_t)NCPQ );
        !          68885:                        rp->q_size = 0;
        !          68886:                        rp->q_mask = NCPQ - 1;
        !          68887: 
        !          68888:                        rp->q_ifaddr = faddr;
        !          68889:                        rp->q_ofaddr = faddr;
        !          68890:                }
        !          68891:        }
        !          68892:        return 0;
        !          68893: }
        !          68894: 
        !          68895: /*
        !          68896:  * Unload Routine.
        !          68897:  */
        !          68898: static void
        !          68899: rpuload()
        !          68900: {
        !          68901:        register struct ring *rp;
        !          68902: 
        !          68903:        /*
        !          68904:         * Release virtual address mappers.
        !          68905:         */
        !          68906:        for ( rp = &rpq[0]; rp < &rpq[NRP]; rp++ ) {
        !          68907:                if ( rp->q_ifaddr )
        !          68908:                        vrelse( rp->q_ifaddr );
        !          68909:        }
        !          68910: 
        !          68911:        /*
        !          68912:         * Release ring buffer storage.
        !          68913:         */
        !          68914:        if ( rpsegp != NULL ) {
        !          68915:                sfree( rpsegp );
        !          68916:                rpsegp = NULL;
        !          68917:        }
        !          68918: 
        !          68919:        /*
        !          68920:         * Erase private data.
        !          68921:         */
        !          68922:        memset( &rpq[0], 0, sizeof(rpq) );
        !          68923: }
        !          68924: 
        !          68925: /*
        !          68926:  * Open Routine
        !          68927:  */
        !          68928: static
        !          68929: rpopen( dev, mode )
        !          68930: dev_t dev;
        !          68931: {
        !          68932:        int s;
        !          68933: 
        !          68934:        s = sphi();
        !          68935:        if ( rpq[0].q_mask == 0 )
        !          68936:                if ( rpinit() < 0 )
        !          68937:                        u.u_error = ENOSPC;
        !          68938:        spl( s );
        !          68939:        if ( minor(dev) >= NRP )
        !          68940:                u.u_error = ENXIO;
        !          68941: }
        !          68942: 
        !          68943: /*
        !          68944:  * Ioctl Routine
        !          68945:  */
        !          68946: static
        !          68947: rpioctl( dev, com, vec )
        !          68948: dev_t dev;
        !          68949: {
        !          68950:        switch ( com ) {
        !          68951: 
        !          68952:        case TIOCQUERY:
        !          68953:                putuwd( vec, rpq[ minor(dev) ].q_size );
        !          68954:                return;
        !          68955: 
        !          68956:        case TIOCOUTQ:
        !          68957:                putuwd( vec, rpq[ minor(dev) ].q_size );
        !          68958:                return;
        !          68959: 
        !          68960:        case TIOCFLUSH:
        !          68961:        case TCFLSH:
        !          68962:                rpflush( &rpq[minor(dev)] );
        !          68963:                return;
        !          68964: 
        !          68965:        default:
        !          68966:                u.u_error = EINVAL;
        !          68967:                return;
        !          68968:        }
        !          68969: }
        !          68970: 
        !          68971: /*
        !          68972:  * Read Routine
        !          68973:  */
        !          68974: static
        !          68975: rpread( dev, iop )
        !          68976: dev_t dev;
        !          68977: register IO *iop;
        !          68978: {
        !          68979:        register struct ring *rp;
        !          68980:        unsigned n;
        !          68981:        int s;
        !          68982: 
        !          68983:        rp = &rpq[ minor(dev) ];
        !          68984:        s  = sphi();
        !          68985: 
        !          68986:        /*
        !          68987:         * Wait until read is unlocked, and there is data to read
        !          68988:         */
        !          68989:        while ( (rp->q_igate[0] != 0) || ((n = rp->q_size) == 0) ) {
        !          68990: 
        !          68991:                /*
        !          68992:                 * Non-blocking reads.
        !          68993:                 */
        !          68994:                if ( iop->io_flag & IONDLY ) {
        !          68995:                        u.u_error = EAGAIN;
        !          68996:                        return;
        !          68997:                }
        !          68998: 
        !          68999:                ++rp->q_igate[1];
        !          69000:                sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
        !          69001:                --rp->q_igate[1];
        !          69002: 
        !          69003:                if ( SELF->p_ssig && nondsig() ) {      /* signal received */
        !          69004: 
        !          69005:                        spl( s );
        !          69006:                        u.u_error = EINTR;
        !          69007:                        return;
        !          69008:                }
        !          69009:        }
        !          69010:        rp->q_igate[0] = 1;                     /* lock read gate           */
        !          69011:        spl( s );
        !          69012: 
        !          69013:        if ( n > iop->io_ioc )                  /* more data than requested */
        !          69014:                n = iop->io_ioc;
        !          69015: 
        !          69016:        rucopy( rp, iop->io_base, n );          /* copy data to user space  */
        !          69017:        iop->io_base += n;
        !          69018:        iop->io_ioc  -= n;
        !          69019: 
        !          69020:        if ( rp->q_ogate[1] != 0 )              /* someone waiting to write */
        !          69021:                wakeup( rp->q_ogate );
        !          69022:        if ( rp->q_opoll.e_procp )              /* someone polling to write */
        !          69023:                pollwake( &rp->q_opoll );
        !          69024: 
        !          69025:        rp->q_igate[0] = 0;                     /* unlock read gate         */
        !          69026: 
        !          69027:        if ( rp->q_igate[1] != 0 )              /* others waiting to read   */
        !          69028:                wakeup( rp->q_igate );
        !          69029: }
        !          69030: 
        !          69031: /*
        !          69032:  * Write Routine
        !          69033:  */
        !          69034: static
        !          69035: rpwrite( dev, iop )
        !          69036: dev_t dev;
        !          69037: register IO *iop;
        !          69038: {
        !          69039:        register struct ring *rp;
        !          69040:        unsigned n;
        !          69041:        int s;
        !          69042: 
        !          69043:        rp = &rpq[ minor(dev) ];
        !          69044: 
        !          69045:        do {
        !          69046:                s  = sphi();
        !          69047:                /*
        !          69048:                 * Wait until write is unlocked and 512 free slots exist
        !          69049:                 */
        !          69050: 
        !          69051:                while ((rp->q_ogate[0] != 0) || ((n = NCPQ-rp->q_size) < 512)) {
        !          69052: 
        !          69053:                        /*
        !          69054:                         * Non-blocking writes.
        !          69055:                         */
        !          69056:                        if ( iop->io_flag & IONDLY ) {
        !          69057:                                u.u_error = EAGAIN;
        !          69058:                                return;
        !          69059:                        }
        !          69060: 
        !          69061:                        ++rp->q_ogate[1];
        !          69062:                        sleep( rp->q_ogate, CVTTOUT, IVTTOUT, SVTTOUT );
        !          69063:                        --rp->q_ogate[1];
        !          69064: 
        !          69065:                        if (SELF->p_ssig && nondsig()) { /* received signal */
        !          69066: 
        !          69067:                                spl( s );
        !          69068:                                u.u_error = EINTR;
        !          69069:                                return;
        !          69070:                        }
        !          69071:                }
        !          69072:                rp->q_ogate[0] = 1;             /* lock write gate           */
        !          69073:                spl( s );
        !          69074: 
        !          69075:                if ( n > iop->io_ioc )
        !          69076:                        n = iop->io_ioc;
        !          69077: 
        !          69078:                urcopy( iop->io_base, rp, n );  /* copy data from user space */
        !          69079:                iop->io_base += n;
        !          69080:                iop->io_ioc  -= n;
        !          69081: 
        !          69082:                rp->q_ogate[0] = 0;             /* unlock write gate         */
        !          69083: 
        !          69084:                if ( rp->q_igate[1] != 0 )      /* someone waiting to read   */
        !          69085:                        wakeup( rp->q_igate );
        !          69086: 
        !          69087:                if ( rp->q_ipoll.e_procp )      /* someone polling to read */
        !          69088:                        pollwake( &rp->q_ipoll );
        !          69089: 
        !          69090:        } while ( iop->io_ioc != 0 );           /* until all data copied     */
        !          69091: 
        !          69092:        if (rp->q_ogate[1] != 0)                /* someone waiting to write  */
        !          69093:                wakeup( rp->q_ogate );
        !          69094: }
        !          69095: 
        !          69096: /*
        !          69097:  * Poll.
        !          69098:  */
        !          69099: rppoll( dev, ev, msec )
        !          69100: dev_t dev;
        !          69101: int ev;
        !          69102: int msec;
        !          69103: {
        !          69104:        register struct ring *rp = &rpq[ minor(dev) ];
        !          69105: 
        !          69106:        ev &= ~POLLPRI;
        !          69107: 
        !          69108:        /*
        !          69109:         * Input poll.
        !          69110:         */
        !          69111:        if ( ev & POLLIN ) {
        !          69112: 
        !          69113:                /*
        !          69114:                 * Pipe empty.
        !          69115:                 */
        !          69116:                if ( FP_OFF(rp->q_ifaddr) == FP_OFF(rp->q_ofaddr) ) {
        !          69117:                        if ( msec != 0 )
        !          69118:                                pollopen( &rp->q_ipoll );
        !          69119:                        ev &= ~POLLIN;
        !          69120:                }
        !          69121:        }
        !          69122: 
        !          69123:        /*
        !          69124:         * Output poll.
        !          69125:         */
        !          69126:        if ( ev & POLLOUT ) {
        !          69127: 
        !          69128:                /*
        !          69129:                 * Pipe not empty.
        !          69130:                 */
        !          69131:                if ( FP_OFF(rp->q_ifaddr) != FP_OFF(rp->q_ofaddr) ) {
        !          69132:                        if ( msec != 0 )
        !          69133:                                pollopen( &rp->q_opoll );
        !          69134:                        ev &= ~POLLOUT;
        !          69135:                }
        !          69136:        }
        !          69137: 
        !          69138:        return ev;
        !          69139: }
        !          69140: 
        !          69141: /*
        !          69142:  * Flush queue
        !          69143:  */
        !          69144: static
        !          69145: rpflush( rp )
        !          69146: register struct ring *rp;
        !          69147: {
        !          69148:        register int s;
        !          69149: 
        !          69150:        s = sphi();
        !          69151: 
        !          69152:        /*
        !          69153:         * Wait until read is unlocked, or nothing in queue
        !          69154:         */
        !          69155: 
        !          69156:        while ((rp->q_size != 0) && (rp->q_igate[0] != 0) ) {
        !          69157: 
        !          69158:                ++rp->q_igate[1];
        !          69159:                sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
        !          69160:                --rp->q_igate[1];
        !          69161: 
        !          69162:                if (SELF->p_ssig && nondsig()) { /* received signal        */
        !          69163: 
        !          69164:                        spl( s );
        !          69165:                        u.u_error = EINTR;
        !          69166:                        return;
        !          69167:                }
        !          69168:        }
        !          69169: 
        !          69170:        if (rp->q_size != 0) {                  /* flush ram pipe          */
        !          69171: 
        !          69172:                rp->q_ofaddr = rp->q_ifaddr;
        !          69173:                rp->q_size = 0;
        !          69174:        }
        !          69175:        spl( s );
        !          69176: 
        !          69177:        if (rp->q_ogate[1] != 0)                /* someone waiting to write */
        !          69178:                wakeup( rp->q_ogate );
        !          69179: 
        !          69180:        if ( rp->q_opoll.e_procp )              /* someone polling to write */
        !          69181:                pollwake( &rp->q_opoll );
        !          69182: }
        !          69183: @
        !          69184: 0707070064030106471004440000030000030000011777770507310677300005600000005556/newbits/kernel/USRSRC/i8086/drv/RCS/rpas.s,vhead     1.1;
        !          69185: branch   ;
        !          69186: access   ;
        !          69187: symbols  ;
        !          69188: locks    bin:1.1; strict;
        !          69189: comment  @@;
        !          69190: 
        !          69191: 
        !          69192: 1.1
        !          69193: date     91.06.10.10.24.52;  author bin;  state Exp;
        !          69194: branches ;
        !          69195: next     ;
        !          69196: 
        !          69197: 
        !          69198: desc
        !          69199: @initial version prov by hal
        !          69200: @
        !          69201: 
        !          69202: 
        !          69203: 
        !          69204: 1.1
        !          69205: log
        !          69206: @Initial revision
        !          69207: @
        !          69208: text
        !          69209: @////////
        !          69210: /
        !          69211: / Ram Pipe Device Driver Assembler Support
        !          69212: /
        !          69213: /      urcopy( up, np, n )     -- copy user data to pipe
        !          69214: /      rucopy( np, up, n )     -- copy pipe data to user
        !          69215: /
        !          69216: ////////
        !          69217: 
        !          69218:        .globl  urcopy_
        !          69219:        .globl  rucopy_
        !          69220: 
        !          69221: ////////
        !          69222: /
        !          69223: / Offsets of fields within the ram pipe structure
        !          69224: /
        !          69225: ////////
        !          69226: 
        !          69227:        Q_SIZE  = 0
        !          69228:        Q_MASK  = 2
        !          69229:        Q_IX    = 4
        !          69230:        Q_ISEG  = 6
        !          69231:        Q_OX    = 8
        !          69232:        Q_OSEG  = 10
        !          69233:        Q_IGATE = 12
        !          69234:        Q_OGATE = 14
        !          69235: 
        !          69236: ////////
        !          69237: /
        !          69238: / Urcopy ( up, rp, cnt )
        !          69239: / char * up;
        !          69240: / struct ring * rp;
        !          69241: / unsigned cnt;
        !          69242: /
        !          69243: /      Input:  up  = pointer to user data to copy.
        !          69244: /              rp  = pointer to ring structure to copy data to.
        !          69245: /              cnt = number of data bytes to copy.
        !          69246: /
        !          69247: /      Action: Copy CNT bytes from UP to RP->Q_IX.
        !          69248: /
        !          69249: /      Return: Number of bytes transferred.
        !          69250: /
        !          69251: ////////
        !          69252: 
        !          69253: urcopy_:                               / urcopy ( up, rp, cnt )
        !          69254:        push    si                      / register char *up;            /* SI */
        !          69255:        push    di                      / register struct ring *rp;     /* BX */
        !          69256:        push    bp                      / unsigned cnt;
        !          69257:        mov     bp, sp                  / {
        !          69258:        pushf                           /       register char *cp;      /* DI */
        !          69259:        push    ds                      /       register unsigned ret;  /* AX */
        !          69260:        push    es                      /       register unsigned n;    /* CX */
        !          69261:                                        /       register unsigned m;    /* DX */
        !          69262:        mov     si, 8(bp)               /
        !          69263:        mov     bx, 10(bp)              /
        !          69264:        mov     cx, 12(bp)              /       n  = cnt;
        !          69265:        mov     dx, Q_MASK(bx)          /       m  = rp->q_mask;
        !          69266:        les     di, Q_IX(bx)            /       cp = rp->q_ix;
        !          69267:        mov     ds, uds_                /
        !          69268:                                        /
        !          69269:        cld                             /
        !          69270: 0:     movsb                           /       do {    *cp++ = *up++;
        !          69271:        and     di, dx                  /               wrap(cp);
        !          69272:        loop    0b                      /       } while (--n != 0);
        !          69273:                                        /
        !          69274:        pop     es                      /
        !          69275:        pop     ds                      /
        !          69276:        mov     ax, 12(bp)              /       ret = cnt;
        !          69277:        cli                             /       s   = sphi();
        !          69278:        mov     Q_IX(bx), di            /       rp->q_ix = cp;
        !          69279:        add     Q_SIZE(bx), ax          /       rp->q_size += ret;
        !          69280:        popf                            /       spl( s );
        !          69281:        pop     bp                      /
        !          69282:        pop     di                      /       return ret;
        !          69283:        pop     si                      /
        !          69284:        ret                             / }
        !          69285: 
        !          69286: ////////
        !          69287: /
        !          69288: / Rucopy ( rp, up, cnt )
        !          69289: / struct ring * rp;
        !          69290: / char * up;
        !          69291: / unsigned cnt;
        !          69292: /
        !          69293: /      Input:  rp  = pointer to ring structure to copy data from.
        !          69294: /              up  = pointer to user data.
        !          69295: /              cnt = number of data bytes to copy.
        !          69296: /
        !          69297: /      Action: Copy CNT bytes from RP->Q_OX to UP.
        !          69298: /
        !          69299: /      Return: None.
        !          69300: /
        !          69301: ////////
        !          69302: 
        !          69303: rucopy_:                               / rucopy ( rp, up, cnt )
        !          69304:        push    si                      / register struct ring *rp;     /* BX */
        !          69305:        push    di                      / register char * up;           /* DI */
        !          69306:        push    bp                      / unsigned cnt;
        !          69307:        mov     bp, sp                  / {
        !          69308:        pushf                           /       register char *cp;      /* SI */
        !          69309:        push    ds                      /       register unsigned ret;  /* AX */
        !          69310:        push    es                      /       register unsigned n;    /* CX */
        !          69311:                                        /       register unsigned m;    /* DX */
        !          69312:        mov     bx, 8(bp)               /
        !          69313:        mov     di, 10(bp)              /
        !          69314:        mov     cx, 12(bp)              /
        !          69315:        mov     dx, Q_MASK(bx)          /       m = rp->q_mask;
        !          69316:        mov     es, uds_                /
        !          69317:        lds     si, Q_OX(bx)            /       cp = rp->q_ox;
        !          69318:                                        /
        !          69319:        cld                             /
        !          69320: 0:     movsb                           /       do {    *up++ = *cp++;
        !          69321:        and     si, dx                  /               wrap(cp);
        !          69322:        loop    0b                      /       } while (--cnt != 0);
        !          69323:                                        /
        !          69324:        pop     es                      /
        !          69325:        pop     ds                      /
        !          69326:        mov     ax, 12(bp)              /       ret = cnt;
        !          69327:        cli                             /       s   = sphi();
        !          69328:        mov     Q_OX(bx), si            /       rp->q_ox = cp;
        !          69329:        sub     Q_SIZE(bx), ax          /       rp->q_size -= ret;
        !          69330:        popf                            /       spl( s );
        !          69331:        pop     bp                      /
        !          69332:        pop     di                      /       return ret;
        !          69333:        pop     si                      /
        !          69334:        ret                             / }
        !          69335: @
        !          69336: 0707070064030104241004440000030000030000011777770507310677300005400000051350/newbits/kernel/USRSRC/i8086/drv/RCS/rs.c,vhead     1.2;
        !          69337: branch   ;
        !          69338: access   ;
        !          69339: symbols  ;
        !          69340: locks    bin:1.2; strict;
        !          69341: comment  @ * @;
        !          69342: 
        !          69343: 
        !          69344: 1.2
        !          69345: date     91.06.20.14.52.27;  author bin;  state Exp;
        !          69346: branches ;
        !          69347: next     1.1;
        !          69348: 
        !          69349: 1.1
        !          69350: date     91.06.10.10.24.54;  author bin;  state Exp;
        !          69351: branches ;
        !          69352: next     ;
        !          69353: 
        !          69354: 
        !          69355: desc
        !          69356: @initial version prov by hal
        !          69357: @
        !          69358: 
        !          69359: 
        !          69360: 1.2
        !          69361: log
        !          69362: @update provided by hal
        !          69363: @
        !          69364: text
        !          69365: @/* (-lgl
        !          69366:  *     COHERENT Driver Kit Version 1.1.0
        !          69367:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          69368:  *     All rights reserved. May not be copied without permission.
        !          69369:  -lgl) */
        !          69370: /*
        !          69371:  * Raw Serial Device Driver.
        !          69372:  *
        !          69373:  *     Provides fast, efficiently buffered serial i/o to COM1 & COM2.
        !          69374:  *     Supports an extreme subset of System V (termio) parameters.
        !          69375:  *             c_iflag: ISTRIP, IXON, IXANY, IGNBRK, INPCK, PARMRK, IGNPAR.
        !          69376:  *             c_oflag: OPOST, ONLCR, ONLRET, TAB3.
        !          69377:  *             c_cflag: *.
        !          69378:  *
        !          69379:  */
        !          69380: 
        !          69381: #include <sys/coherent.h>
        !          69382: #include <sys/ins8250.h>
        !          69383: #include <sys/proc.h>
        !          69384: #include <sys/uproc.h>
        !          69385: #include <sys/con.h>
        !          69386: #include <sys/sched.h>
        !          69387: #include <sys/stat.h>
        !          69388: #include <termio.h>
        !          69389: #include <errno.h>
        !          69390: 
        !          69391: #define        COM1VEC         4               /* interrupt vector for COM1    */
        !          69392: #define        COM2VEC         3               /* interrupt vector for COM2    */
        !          69393: 
        !          69394: #define        COM1PORT        0x3F8           /* i/o port address for COM1    */
        !          69395: #define        COM2PORT        0x2F8           /* i/o port address for COM2    */
        !          69396: 
        !          69397: #ifdef RS1
        !          69398: #      define  CFLAG   RS1CFLAG
        !          69399: #      define  MAJ     6               /* major device for /dev/rs1    */
        !          69400: #      define  rscon   rs1con          /* configuration table for "    */
        !          69401: #      define  rstty   rs1tty
        !          69402: #      define  IVEC    COM2VEC         /* interrupt vector for rs1     */
        !          69403: #      define  PORT    COM2PORT        /* i/o port address for rs1     */
        !          69404: #else
        !          69405: #      define  CFLAG   RS0CFLAG
        !          69406: #      define  MAJ     5               /* major device for /dev/rs0    */
        !          69407: #      define  rscon   rs0con          /* configuration table for "    */
        !          69408: #      define  rstty   rs0tty
        !          69409: #      define  IVEC    COM1VEC         /* interrupt vector for rs0     */
        !          69410: #      define  PORT    COM1PORT        /* i/o port address for rs0     */
        !          69411: #endif
        !          69412: 
        !          69413: #define        CTRLS   '\023'
        !          69414: #define        CTRLQ   '\021'
        !          69415: 
        !          69416: /*
        !          69417:  * Functions.
        !          69418:  */
        !          69419: 
        !          69420: int    rsload();
        !          69421: int    rsunload();
        !          69422: int    rsopen();
        !          69423: int    rsclose();
        !          69424: int    rsread();
        !          69425: int    rswrite();
        !          69426: int    rsioctl();
        !          69427: int    rspoll();
        !          69428: int    nulldev();
        !          69429: int    nonedev();
        !          69430: 
        !          69431: int    rsintr();
        !          69432: int    rsparam();
        !          69433: 
        !          69434: /*
        !          69435:  * Configuration table.
        !          69436:  */
        !          69437: 
        !          69438: CON rscon ={
        !          69439:        DFCHR|DFPOL,                    /* Flags */
        !          69440:        MAJ,                            /* Major index */
        !          69441:        rsopen,                         /* Open */
        !          69442:        rsclose,                        /* Close */
        !          69443:        nulldev,                        /* Block */
        !          69444:        rsread,                         /* Read */
        !          69445:        rswrite,                        /* Write */
        !          69446:        rsioctl,                        /* Ioctl */
        !          69447:        nulldev,                        /* Powerfail */
        !          69448:        nulldev,                        /* Timeout */
        !          69449:        rsload,                         /* Load */
        !          69450:        rsunload,                       /* Unload */
        !          69451:        rspoll                          /* Poll */
        !          69452: };
        !          69453: 
        !          69454: /*
        !          69455:  * Terminal structure.
        !          69456:  */
        !          69457: 
        !          69458: #define        RAWSZ   (2048-1)
        !          69459: #define        OUTSZ   (2048-1)
        !          69460: 
        !          69461: #define        NRAWC   ((rsrawq.rq_ix - rsrawq.rq_ox) & RAWSZ)
        !          69462: #define        NOUTC   ((rsoutq.rq_ix - rsoutq.rq_ox) & OUTSZ)
        !          69463: 
        !          69464: #define        TTSTOP  00001
        !          69465: #define        TTSBRK  00002
        !          69466: #define        CARRIER 00004
        !          69467: 
        !          69468: typedef
        !          69469: struct rawtty_s {
        !          69470:        unsigned        rt_state;       /* terminal state               */
        !          69471:        int             rt_group;       /* controlling process group    */
        !          69472:        unsigned        rt_ticks;       /* send break 1/10 sec counter  */
        !          69473:        unsigned        rt_iflag;       /* termio input   flags         */
        !          69474:        unsigned        rt_oflag;       /* termio output  flags         */
        !          69475:        unsigned        rt_cflag;       /* termio control flags         */
        !          69476:        unsigned char   rt_col;         /* current output column        */
        !          69477:        unsigned char   rt_refc;        /* # procs accessing the port   */
        !          69478:        unsigned char   rt_irefc;       /* # procs waiting for input    */
        !          69479:        unsigned char   rt_orefc;       /* # procs waitint for output   */
        !          69480:        unsigned char   rt_crefc;       /* # procs waiting for carrier  */
        !          69481:        unsigned char   rt_drefc;       /* # procs waiting for drain    */
        !          69482:        event_t         rt_ipolls;      /* Procs polling on input queue */
        !          69483:        event_t         rt_opolls;      /* Procs polling on output que  */
        !          69484: } RAWTTY;
        !          69485: 
        !          69486: typedef
        !          69487: struct iring_s {
        !          69488:        unsigned short  rq_mask;
        !          69489:        unsigned short  rq_ix;
        !          69490:        unsigned short  rq_ox;
        !          69491:        unsigned char   rq_cc[RAWSZ+1];
        !          69492: } IRING;
        !          69493: 
        !          69494: typedef
        !          69495: struct oring_s {
        !          69496:        unsigned short  rq_mask;
        !          69497:        unsigned short  rq_ix;
        !          69498:        unsigned short  rq_ox;
        !          69499:        unsigned char   rq_cc[OUTSZ+1];
        !          69500: } ORING;
        !          69501: 
        !          69502: /*
        !          69503:  * Local variables.
        !          69504:  */
        !          69505: unsigned CFLAG  = CLOCAL | CREAD | B1200 | CS8 | HUPCL;
        !          69506: RAWTTY rstty;
        !          69507: static ORING   rsoutq;
        !          69508: static IRING   rsrawq;
        !          69509: static TIM     rstim;
        !          69510: 
        !          69511: /*
        !          69512:  * Time constant table.
        !          69513:  * Indexed by ioctl baud rate.
        !          69514:  */
        !          69515: static
        !          69516: int timeconst[] = {
        !          69517:        0,                              /* 0 */
        !          69518:        2304,                           /* 50 */
        !          69519:        1536,                           /* 75 */
        !          69520:        1047,                           /* 110 */
        !          69521:        857,                            /* 134.5 */
        !          69522:        768,                            /* 150 */
        !          69523:        576,                            /* 200 */
        !          69524:        384,                            /* 300 */
        !          69525:        192,                            /* 600 */
        !          69526:        96,                             /* 1200 */
        !          69527:        64,                             /* 1800 */
        !          69528:        48,                             /* 2400 */
        !          69529:        24,                             /* 4800 */
        !          69530:        12,                             /* 9600 */
        !          69531:        6,                              /* 19200/EXTA */
        !          69532:        6                               /* 19200/EXTB */
        !          69533: };
        !          69534: 
        !          69535: /*
        !          69536:  * Rsload() -- Raw Serial Load Routine.
        !          69537:  *
        !          69538:  *     Action: Define terminal parameters.
        !          69539:  *             Initialize terminal hardware.
        !          69540:  *             If serial port exists, seize its interrupt vector.
        !          69541:  *
        !          69542:  *     Return: None.
        !          69543:  */
        !          69544: 
        !          69545: static
        !          69546: rsload()
        !          69547: {
        !          69548:        /*
        !          69549:         * Initialize terminal parameters.
        !          69550:         */
        !          69551:        rsoutq.rq_mask = OUTSZ;
        !          69552:        rsrawq.rq_mask = RAWSZ;
        !          69553: 
        !          69554:        /*
        !          69555:         * Initialize terminal hardware.
        !          69556:         */
        !          69557:        rsparam();
        !          69558: 
        !          69559:        /*
        !          69560:         * If serial port exists, initialize interrupt vector.
        !          69561:         */
        !          69562:        if ( inb(PORT+IER) == 0 ) {
        !          69563:                setivec( IVEC, rsintr);
        !          69564:                rscycle();
        !          69565:        }
        !          69566: }
        !          69567: 
        !          69568: /*
        !          69569:  * Rsunload() -- Raw Serial unload Routine.
        !          69570:  */
        !          69571: 
        !          69572: static
        !          69573: rsunload()
        !          69574: {
        !          69575:        timeout( &rstim, 0, NULL, 0 );  /* cancel timed function */
        !          69576:        clrivec( IVEC );                /* release interrupt vector */
        !          69577:        outb(PORT+IER, 0);              /* disable port interrupts */
        !          69578:        outb(PORT+MCR, MC_OUT2);        /* hangup port */
        !          69579: }
        !          69580: 
        !          69581: /*
        !          69582:  * Rsopen -- Open Routine.
        !          69583:  *
        !          69584:  *     Input:  dev = device to open.
        !          69585:  *             If high bit (0x80) set in minor, modem control is requested.
        !          69586:  *
        !          69587:  *     Action: Validate minor device.
        !          69588:  *             Increment reference count.
        !          69589:  *             If first reference and parameters are not initialized,
        !          69590:  *                     set default parameters and initialize hardware.
        !          69591:  *
        !          69592:  *     Return: None.
        !          69593:  */
        !          69594: 
        !          69595: static
        !          69596: rsopen( dev, mode )
        !          69597: 
        !          69598: dev_t dev;
        !          69599: 
        !          69600: {
        !          69601:        register PROC *pp = SELF;
        !          69602: 
        !          69603:        /*
        !          69604:         * Validate minor device.
        !          69605:         */
        !          69606:        if (minor(dev) & ~0x80) {
        !          69607:                u.u_error = ENODEV;
        !          69608:                return;
        !          69609:        }
        !          69610: 
        !          69611:        /*
        !          69612:         * Validate hardware.
        !          69613:         */
        !          69614:        if (inb(PORT+IER) & ~(IE_RxI|IE_TxI|IE_LSI)) {
        !          69615:                u.u_error = ENXIO;
        !          69616:                return;
        !          69617:        }
        !          69618: 
        !          69619:        /*
        !          69620:         * Ensure controlling terminal and group fields initialized.
        !          69621:         */
        !          69622:        if (pp->p_ttdev == NODEV)
        !          69623:                pp->p_ttdev = dev;
        !          69624:        if (pp->p_group == 0)
        !          69625:                pp->p_group = pp->p_pid;
        !          69626: 
        !          69627:        /*
        !          69628:         * Check for first open.
        !          69629:         */
        !          69630:        if (++rstty.rt_refc == 1) {
        !          69631: 
        !          69632:                if (pp->p_group == pp->p_pid)
        !          69633:                        rstty.rt_group = pp->p_group;
        !          69634: 
        !          69635:                if ((rstty.rt_cflag & CBAUD) == B0) {
        !          69636: 
        !          69637:                        /*
        !          69638:                         * Define terminal parameters.
        !          69639:                         */
        !          69640:                        rstty.rt_state = 0;
        !          69641:                        rstty.rt_col   = 0;
        !          69642:                        rstty.rt_iflag = ISTRIP | IXON;
        !          69643:                        rstty.rt_oflag = OPOST  | ONLCR | TAB3;
        !          69644:                        rstty.rt_cflag = CFLAG;
        !          69645:                        if ( minor(dev) & 0x80 )
        !          69646:                                rstty.rt_cflag &= ~CLOCAL;
        !          69647: 
        !          69648:                        /*
        !          69649:                         * Initialize terminal hardware.
        !          69650:                         */
        !          69651:                        rsparam();
        !          69652:                }
        !          69653: 
        !          69654:                /*
        !          69655:                 * Discard input data.
        !          69656:                 */
        !          69657:                rsrawq.rq_ox = rsrawq.rq_ix;
        !          69658:        }
        !          69659: 
        !          69660:        /*
        !          69661:         * If modem control is requested, check carrier.
        !          69662:         */
        !          69663:        if ( minor(dev) & 0x80 ) {
        !          69664: 
        !          69665:                /*
        !          69666:                 * Delay until carrier is present.
        !          69667:                 */
        !          69668:                while ( (rstty.rt_state & CARRIER) == 0 ) {
        !          69669: 
        !          69670:                        /*
        !          69671:                         * Sleep on carrier.
        !          69672:                         */
        !          69673:                        ++rstty.rt_crefc;
        !          69674:                        sleep( &rstty.rt_crefc,
        !          69675:                                CVTTOUT, IVTTOUT, SVTTOUT);
        !          69676:                        --rstty.rt_crefc;
        !          69677: 
        !          69678:                        /*
        !          69679:                         * Abort if non-ignored signal is received.
        !          69680:                         */
        !          69681:                        if (SELF->p_ssig && nondsig()) {
        !          69682: 
        !          69683:                                if (--rstty.rt_refc == 0) {
        !          69684:                                        rstty.rt_group = 0;
        !          69685:                                        rstty.rt_cflag = 0;
        !          69686:                                        rsparam();
        !          69687:                                }
        !          69688:                                u.u_error = EINTR;
        !          69689:                                return;
        !          69690:                        }
        !          69691:                }
        !          69692:        }
        !          69693: }
        !          69694: 
        !          69695: /*
        !          69696:  * Rsclose -- Close Routine.
        !          69697:  *
        !          69698:  *     Action: Decrement reference count.
        !          69699:  *             If serial port is no longer referenced,
        !          69700:  *             and the hangup on last close bit is set in rt_cflag,
        !          69701:  *             clear terminal parameters, and initialize hardware.
        !          69702:  *
        !          69703:  *     Return: None.
        !          69704:  *
        !          69705:  *     Note:   This routine does not wait for the output queue to empty.
        !          69706:  */
        !          69707: 
        !          69708: static
        !          69709: rsclose( dev )
        !          69710: 
        !          69711: dev_t dev;
        !          69712: 
        !          69713: {
        !          69714:        /*
        !          69715:         * Check for last close and hangup on close.
        !          69716:         */
        !          69717:        if ((rstty.rt_refc == 1) && (rstty.rt_cflag & HUPCL)) {
        !          69718: 
        !          69719:                /*
        !          69720:                 * Wait for output to drain.
        !          69721:                 */
        !          69722:                while ( rsoutq.rq_ox != rsoutq.rq_ix ) {
        !          69723: 
        !          69724:                        ++rstty.rt_drefc;
        !          69725:                        sleep( &rstty.rt_drefc, CVTTOUT, IVTTOUT, SVTTOUT );
        !          69726:                        --rstty.rt_drefc;
        !          69727: 
        !          69728:                        if (rstty.rt_refc != 1) {
        !          69729:                                rstty.rt_refc--;
        !          69730:                                return;
        !          69731:                        }
        !          69732: 
        !          69733:                        if (SELF->p_ssig && nondsig())
        !          69734:                                break;
        !          69735:                }
        !          69736: 
        !          69737:                /*
        !          69738:                 * Initialize terminal hardware.
        !          69739:                 */
        !          69740:                rstty.rt_group = 0;
        !          69741:                rstty.rt_cflag = 0;
        !          69742:                rsparam();
        !          69743: 
        !          69744:                /*
        !          69745:                 * Flush input and output queues.
        !          69746:                 */
        !          69747:                rsrawq.rq_ix =
        !          69748:                rsrawq.rq_ox =
        !          69749:                rsoutq.rq_ox =
        !          69750:                rsoutq.rq_ix = 0;
        !          69751:        }
        !          69752:        --rstty.rt_refc;
        !          69753: }
        !          69754: 
        !          69755: /*
        !          69756:  * Rsread -- Read Routine.
        !          69757:  *
        !          69758:  *     Input:  iop = pointer to structure containing i/o parameters.
        !          69759:  *
        !          69760:  *     Action: Attempt to read data from input buffer until at least
        !          69761:  *             one character has been read, or a signal is received
        !          69762:  *             by the current process.
        !          69763:  *             Update the parameters in the io structure.
        !          69764:  *             If a signal is received, set errno to EINTR.
        !          69765:  *
        !          69766:  *     Return: None.
        !          69767:  */
        !          69768: 
        !          69769: static
        !          69770: rsread( dev, iop )
        !          69771: 
        !          69772: dev_t dev;
        !          69773: register IO *iop;
        !          69774: 
        !          69775: {
        !          69776:        register int sioc;
        !          69777: 
        !          69778:        /*
        !          69779:         * Remember original char count.
        !          69780:         */
        !          69781:        sioc = iop->io_ioc;
        !          69782: 
        !          69783:        do {
        !          69784:                /*
        !          69785:                 * Transfer data until done or input buffer empty.
        !          69786:                 */
        !          69787:                rsin( &rsrawq, iop );
        !          69788: 
        !          69789:                /*
        !          69790:                 * Return if some data was transferred.
        !          69791:                 */
        !          69792:                if (sioc != iop->io_ioc)
        !          69793:                        return;
        !          69794: 
        !          69795:                /*
        !          69796:                 * Non-blocking reads.
        !          69797:                 */
        !          69798:                if ( iop->io_flag & IONDLY ) {
        !          69799:                        u.u_error = EAGAIN;
        !          69800:                        return;
        !          69801:                }
        !          69802: 
        !          69803:                /*
        !          69804:                 * Sleep waiting for a signal or input data.
        !          69805:                 */
        !          69806:                ++rstty.rt_irefc;
        !          69807:                sleep( &rstty.rt_irefc, CVTTOUT, IVTTOUT, SVTTOUT );
        !          69808:                --rstty.rt_irefc;
        !          69809: 
        !          69810:                /*
        !          69811:                 * Abort if a non-ignored signal was received.
        !          69812:                 */
        !          69813:                if (SELF->p_ssig && nondsig()) {
        !          69814:                        u.u_error = EINTR;
        !          69815:                        return;
        !          69816:                }
        !          69817: 
        !          69818:        } while (1);
        !          69819: }
        !          69820: 
        !          69821: /*
        !          69822:  * Rswrite -- Write Routine.
        !          69823:  */
        !          69824: 
        !          69825: static
        !          69826: rswrite( dev, iop )
        !          69827: 
        !          69828: dev_t dev;
        !          69829: register IO *iop;
        !          69830: 
        !          69831: {
        !          69832:        register int n;
        !          69833: 
        !          69834:        /*
        !          69835:         * Non-blocking write.
        !          69836:         */
        !          69837:        if ( iop->io_flag & IONDLY ) {
        !          69838: 
        !          69839:                /*
        !          69840:                 * Calculate free slots.
        !          69841:                 */
        !          69842:                n  = rsoutq.rq_mask - rsoutq.rq_ix + rsoutq.rq_ox;
        !          69843:                n &= rsoutq.rq_mask;
        !          69844: 
        !          69845:                /*
        !          69846:                 * Insufficient space.
        !          69847:                 */
        !          69848:                if ( n <= iop->io_ioc ) {
        !          69849:                        u.u_error = EAGAIN;
        !          69850:                        return;
        !          69851:                }
        !          69852:        }
        !          69853: 
        !          69854:        do {
        !          69855:                /*
        !          69856:                 * Transfer data until done or output queue full.
        !          69857:                 */
        !          69858:                rsout( &rsoutq, iop );
        !          69859: 
        !          69860:                /*
        !          69861:                 * Make sure the transmitter is operating.
        !          69862:                 */
        !          69863:                rsstart();
        !          69864: 
        !          69865:                /*
        !          69866:                 * Return if all data was transferred.
        !          69867:                 */
        !          69868:                if ( iop->io_ioc == 0 )
        !          69869:                        return;
        !          69870: 
        !          69871:                /*
        !          69872:                 * Sleep waiting for a signal or room in the output queue.
        !          69873:                 */
        !          69874:                ++rstty.rt_orefc;
        !          69875:                sleep( &rstty.rt_orefc, CVTTOUT, IVTTOUT, SVTTOUT );
        !          69876:                --rstty.rt_orefc;
        !          69877: 
        !          69878:                /*
        !          69879:                 * Abort if a non-ignored signal was received.
        !          69880:                 */
        !          69881:                if ( SELF->p_ssig && nondsig() ) {
        !          69882:                        u.u_error = EINTR;
        !          69883:                        return;
        !          69884:                }
        !          69885: 
        !          69886:        } while (1);
        !          69887: }
        !          69888: 
        !          69889: /*
        !          69890:  * Rspoll -- Polling Routine.
        !          69891:  */
        !          69892: static int
        !          69893: rspoll( dev, ev, msec )
        !          69894: dev_t dev;
        !          69895: register int ev;
        !          69896: int msec;
        !          69897: {
        !          69898:        /*
        !          69899:         * No priority reports.
        !          69900:         */
        !          69901:        ev &= ~POLLPRI;
        !          69902: 
        !          69903:        /*
        !          69904:         * Input poll with empty input ring.
        !          69905:         */
        !          69906:        if ( (ev & POLLIN) && (rsrawq.rq_ix == rsrawq.rq_ox) ) {
        !          69907: 
        !          69908:                /*
        !          69909:                 * Blocking input poll.
        !          69910:                 */
        !          69911:                if ( msec != 0 )
        !          69912:                        pollopen( &rstty.rt_ipolls );
        !          69913: 
        !          69914:                /*
        !          69915:                 * Second look and clear input report.
        !          69916:                 */
        !          69917:                if ( rsrawq.rq_ix == rsrawq.rq_ox )
        !          69918:                        ev &= ~POLLIN;
        !          69919:        }
        !          69920: 
        !          69921:        /*
        !          69922:         * Output poll with non-empty output ring.
        !          69923:         */
        !          69924:        if ( (ev & POLLOUT) && (rsoutq.rq_ix != rsrawq.rq_ox) ) {
        !          69925: 
        !          69926:                /*
        !          69927:                 * Blocking output poll.
        !          69928:                 */
        !          69929:                if ( msec != 0 )
        !          69930:                        pollopen( &rstty.rt_opolls );
        !          69931: 
        !          69932:                /*
        !          69933:                 * Second look and clear output report.
        !          69934:                 */
        !          69935:                if ( rsoutq.rq_ix != rsoutq.rq_ox )
        !          69936:                        ev &= ~POLLOUT;
        !          69937:        }
        !          69938: 
        !          69939:        return ev;
        !          69940: }
        !          69941: 
        !          69942: /*
        !          69943:  * Cyclic [1 sec] Routine.
        !          69944:  */
        !          69945: static
        !          69946: rscycle()
        !          69947: {
        !          69948:        register PROC *pp;
        !          69949:        register int b;
        !          69950: 
        !          69951:        /*
        !          69952:         * Check for carrier transitions.
        !          69953:         */
        !          69954:        if ( inb( PORT + MSR ) & MS_RLSD ) {
        !          69955: 
        !          69956:                /*
        !          69957:                 * Have carrier.  Wake processes waiting for carrier.
        !          69958:                 */
        !          69959:                rstty.rt_state |= CARRIER;
        !          69960: 
        !          69961:                if ( rstty.rt_crefc )
        !          69962:                        wakeup( &rstty.rt_crefc );
        !          69963:        }
        !          69964:        else if ((rstty.rt_state & CARRIER) && (rstty.rt_cflag&CLOCAL) == 0) {
        !          69965: 
        !          69966:                /*
        !          69967:                 * Lost carrier. Signal attached processes.
        !          69968:                 */
        !          69969:                rstty.rt_state &= ~CARRIER;
        !          69970: 
        !          69971:                if (rstty.rt_refc && (b = rstty.rt_group))
        !          69972:                        for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw)
        !          69973:                                if ( pp->p_group == b )
        !          69974:                                        sendsig( SIGHUP, pp );
        !          69975:        }
        !          69976: 
        !          69977:        /*
        !          69978:         * Wakeup processes waiting to read if input data present.
        !          69979:         */
        !          69980:        if ( rsrawq.rq_ix != rsrawq.rq_ox ) {
        !          69981:                if ( rstty.rt_irefc )
        !          69982:                        wakeup( &rstty.rt_irefc );
        !          69983:                if ( rstty.rt_ipolls.e_procp )
        !          69984:                        pollwake( &rstty.rt_ipolls );
        !          69985:        }
        !          69986: 
        !          69987:        /*
        !          69988:         * Check for break being sent.
        !          69989:         */
        !          69990:        if ( rstty.rt_ticks != 0 ) {
        !          69991: 
        !          69992:                if ( --rstty.rt_ticks == 0 ) {
        !          69993: 
        !          69994:                        b = inb( PORT + LCR );
        !          69995:                        outb( PORT + LCR, b & ~LC_SBRK );
        !          69996:                        rstty.rt_state &= ~TTSBRK;
        !          69997:                }
        !          69998:        }
        !          69999: 
        !          70000:        /*
        !          70001:         * Can check output if not sending break.
        !          70002:         */
        !          70003:        if ( rstty.rt_ticks == 0 ) {
        !          70004: 
        !          70005:                /*
        !          70006:                 * Restart output if necessary.
        !          70007:                 */
        !          70008:                if ( rsoutq.rq_ox != rsoutq.rq_ix )
        !          70009:                        rsstart();
        !          70010: 
        !          70011:                /*
        !          70012:                 * Wakeup processes waiting for drain if output queue empty.
        !          70013:                 */
        !          70014:                if ( rstty.rt_drefc ) {
        !          70015:                        if ( rsoutq.rq_ix == rsoutq.rq_ox )
        !          70016:                                wakeup( &rstty.rt_drefc );
        !          70017:                }
        !          70018: 
        !          70019:                /*
        !          70020:                 * Wakeup processes waiting to write if 512 slots are free.
        !          70021:                 */
        !          70022:                else if ( NOUTC < OUTSZ-512 ) {
        !          70023:                        if ( rstty.rt_orefc )
        !          70024:                                wakeup( &rstty.rt_orefc );
        !          70025:                        if ( rstty.rt_opolls.e_procp )
        !          70026:                                pollwake( &rstty.rt_opolls );
        !          70027:                }
        !          70028:        }
        !          70029: 
        !          70030:        timeout( &rstim, HZ/10, rscycle, 0 );
        !          70031: }
        !          70032: 
        !          70033: /*
        !          70034:  * Rsintr -- Serial Interrupt Handler.
        !          70035:  *
        !          70036:  *     Action: Process all pending interrupt service requests
        !          70037:  *             on the serial port.
        !          70038:  *
        !          70039:  *     Return: None.
        !          70040:  *
        !          70041:  *     Notes:  This routine must loop until all requests are serviced
        !          70042:  *             because of the edge sensitive nature of the programmable
        !          70043:  *             interrupt controller.
        !          70044:  */
        !          70045: 
        !          70046: static
        !          70047: rsintr()
        !          70048: {
        !          70049:        register int b;
        !          70050: 
        !          70051:        /*
        !          70052:         * Service serial port interrupt requests, highest to lowest priority.
        !          70053:         */
        !          70054: rescan:
        !          70055:        b = inb( PORT + IIR );
        !          70056: 
        !          70057:        switch ( b ) {
        !          70058: 
        !          70059:        case LS_INTR:
        !          70060:                /*
        !          70061:                 * Get line status (clear interrupt).
        !          70062:                 */
        !          70063:                b = inb( PORT + LSR );
        !          70064: 
        !          70065:                /*
        !          70066:                 * Check for received break.
        !          70067:                 */
        !          70068:                if (b & LS_BREAK) {
        !          70069: 
        !          70070:                        /*
        !          70071:                         * Read the break char ('\0').
        !          70072:                         */
        !          70073:                        rsrawq.rq_cc[ rsrawq.rq_ix ] = inb( PORT + DREG );
        !          70074: 
        !          70075:                        /*
        !          70076:                         * Clear output stops.
        !          70077:                         */
        !          70078:                        rstty.rt_state &= ~TTSTOP;
        !          70079: 
        !          70080:                        /*
        !          70081:                         * Update input index if not ignoring break.
        !          70082:                         */
        !          70083:                        if ((rstty.rt_iflag & IGNBRK) == 0) {
        !          70084:                                rsrawq.rq_ix ++;
        !          70085:                                rsrawq.rq_ix &= RAWSZ;
        !          70086:                        }
        !          70087:                }
        !          70088: 
        !          70089:                /*
        !          70090:                 * Special handling if frame/parity error and checking enabled.
        !          70091:                 */
        !          70092:                if ((b & (LS_FRAME|LS_PARITY)) && (rstty.rt_iflag & INPCK)) {
        !          70093: 
        !          70094:                        /*
        !          70095:                         * Ignore next input char if IGNPAR set.
        !          70096:                         */
        !          70097:                        if (rstty.rt_iflag & IGNPAR)
        !          70098:                                inb( PORT + DREG );
        !          70099:                        /*
        !          70100:                         * Change next input char into 0377,0,ch if PARMRK set.
        !          70101:                         */
        !          70102:                        else if (rstty.rt_iflag & PARMRK) {
        !          70103: 
        !          70104:                                b = rsrawq.rq_ix;
        !          70105:                                rsrawq.rq_cc[ b++ ] = 0377;
        !          70106:                                b &= RAWSZ;
        !          70107:                                rsrawq.rq_cc[ b++ ] = '\0';
        !          70108:                                b &= RAWSZ;
        !          70109:                                rsrawq.rq_cc[ b++ ] = inb( PORT + DREG );
        !          70110:                                b &= RAWSZ;
        !          70111:                                rsrawq.rq_ix = b;
        !          70112:                        }
        !          70113: 
        !          70114:                        /*
        !          70115:                         * Otherwise change next input char into null.
        !          70116:                         */
        !          70117:                        else {
        !          70118:                                inb( PORT + DREG );
        !          70119:                                rsrawq.rq_cc[ rsrawq.rq_ix++ ] = '\0';
        !          70120:                                rsrawq.rq_ix &= RAWSZ;
        !          70121:                        }
        !          70122:                }
        !          70123:                goto rescan;
        !          70124: 
        !          70125:        case Rx_INTR:
        !          70126:                /*
        !          70127:                 * Read character from receive buffer.
        !          70128:                 */
        !          70129:                b = inb( PORT + DREG );
        !          70130: 
        !          70131:                /*
        !          70132:                 * Discard high bit if ISTRIP set.
        !          70133:                 */
        !          70134:                if ( rstty.rt_iflag & ISTRIP )
        !          70135:                        b &= 0177;
        !          70136: 
        !          70137:                /*
        !          70138:                 * Check for output flow control if IXON set.
        !          70139:                 */
        !          70140:                if ( rstty.rt_iflag & IXON ) {
        !          70141: 
        !          70142:                        /*
        !          70143:                         * Stop output if Ctl-S.
        !          70144:                         */
        !          70145:                        if ( b == CTRLS ) {
        !          70146:                                rstty.rt_state |= TTSTOP;
        !          70147:                                goto rescan;
        !          70148:                        }
        !          70149: 
        !          70150:                        /*
        !          70151:                         * Resume output if Ctl-Q.
        !          70152:                         */
        !          70153:                        if ( b == CTRLQ ) {
        !          70154:                                rstty.rt_state &= ~TTSTOP;
        !          70155:                                goto rescan;
        !          70156:                        }
        !          70157: 
        !          70158:                        /*
        !          70159:                         * Enable output if IXANY set.
        !          70160:                         */
        !          70161:                        if ( rstty.rt_iflag & IXANY )
        !          70162:                                rstty.rt_state &= ~TTSTOP;
        !          70163:                }
        !          70164: 
        !          70165:                /*
        !          70166:                 * Save the character in the input queue.
        !          70167:                 */
        !          70168:                rsrawq.rq_cc[ rsrawq.rq_ix++ ] = b;
        !          70169:                rsrawq.rq_ix &= RAWSZ;
        !          70170: 
        !          70171:                /*
        !          70172:                 * Save again if 0377 and parity marking enabled.
        !          70173:                 */
        !          70174:                if ((b == 0377)
        !          70175:                &&  ((rstty.rt_iflag & (INPCK|PARMRK)) == (INPCK|PARMRK))) {
        !          70176: 
        !          70177:                        rsrawq.rq_cc[ rsrawq.rq_ix++ ] = b;
        !          70178:                        rsrawq.rq_ix &= RAWSZ;
        !          70179:                }
        !          70180: 
        !          70181:                goto rescan;
        !          70182: 
        !          70183:        case Tx_INTR:
        !          70184:                rsstart();
        !          70185:                goto rescan;
        !          70186:        }
        !          70187: }
        !          70188: 
        !          70189: /*
        !          70190:  * Rsstart()
        !          70191:  *
        !          70192:  *     Action: While output data is available, and the transmitter buffer
        !          70193:  *             is empty, transfer one character from the output queue to the
        !          70194:  *             transmit buffer.
        !          70195:  *
        !          70196:  *     Return: None.
        !          70197:  */
        !          70198: 
        !          70199: static
        !          70200: rsstart()
        !          70201: {
        !          70202:        register int b;
        !          70203:        register int s;
        !          70204: 
        !          70205:        /*
        !          70206:         * Can't transmit if output stopped or sending break.
        !          70207:         */
        !          70208:        if ( rstty.rt_state & (TTSTOP|TTSBRK) )
        !          70209:                return;
        !          70210: 
        !          70211:        /*
        !          70212:         * Can't transmit if modem control enabled without CTS present.
        !          70213:         */
        !          70214:        if ( (rstty.rt_cflag & CLOCAL) == 0 )
        !          70215:                if ( (inb(PORT+MSR) & MS_CTS) == 0 )
        !          70216:                        return;
        !          70217: 
        !          70218:        /*
        !          70219:         * Disable interrupts to avoid critical race.
        !          70220:         */
        !          70221:        s = sphi();
        !          70222: 
        !          70223:        /*
        !          70224:         * Can transmit if output data available and transmit buffer empty.
        !          70225:         */
        !          70226:        if ( (rsoutq.rq_ix != rsoutq.rq_ox)
        !          70227:        &&   (inb(PORT+LSR) & LS_TxRDY) ) {
        !          70228: 
        !          70229:                /*
        !          70230:                 * Get next char from output queue.
        !          70231:                 */
        !          70232:                b = rsoutq.rq_cc [ rsoutq.rq_ox ];
        !          70233: 
        !          70234:                if (rstty.rt_oflag & OPOST) {
        !          70235: 
        !          70236:                        /*
        !          70237:                         * Printable characters increment the column.
        !          70238:                         */
        !          70239:                        if (b >= ' ') {
        !          70240:                                rstty.rt_col++;
        !          70241:                        }
        !          70242:                        /*
        !          70243:                         * Carriage return resets the column.
        !          70244:                         */
        !          70245:                        else if (b == '\r') {
        !          70246:                                rstty.rt_col = 0;
        !          70247:                                if (rstty.rt_oflag & OCRNL)
        !          70248:                                        b = '\n';
        !          70249:                        }
        !          70250:                        /*
        !          70251:                         * New-line may also generate a carriage return.
        !          70252:                         */
        !          70253:                        else if (b == '\n') {
        !          70254:                                if (rstty.rt_oflag & ONLCR) {
        !          70255:                                        if (rstty.rt_col) {
        !          70256:                                                rstty.rt_col = 0;
        !          70257:                                                rsoutq.rq_ox--;
        !          70258:                                                b = '\r';
        !          70259:                                        }
        !          70260:                                }
        !          70261:                                else if (rstty.rt_oflag & ONLRET)
        !          70262:                                        rstty.rt_col = 0;
        !          70263:                        }
        !          70264:                        /*
        !          70265:                         * Backspace decrements the column.
        !          70266:                         */
        !          70267:                        else if (b == '\b') {
        !          70268:                                if (rstty.rt_col)
        !          70269:                                        --rstty.rt_col;
        !          70270:                        }
        !          70271:                        /*
        !          70272:                         * Tabs may generate spaces, always move to tab stop.
        !          70273:                         */
        !          70274:                        else if (b == '\t') {
        !          70275:                                if ((rstty.rt_oflag & TABDLY) == TAB3) {
        !          70276:                                        b = ' ';
        !          70277:                                        if (++rstty.rt_col & 7)
        !          70278:                                                rsoutq.rq_ox--;
        !          70279:                                }
        !          70280:                                else {
        !          70281:                                        rstty.rt_col |= 7;
        !          70282:                                        rstty.rt_col++;
        !          70283:                                }
        !          70284:                        }
        !          70285:                }
        !          70286:                rsoutq.rq_ox++;
        !          70287:                rsoutq.rq_ox &= OUTSZ;
        !          70288: 
        !          70289:                /*
        !          70290:                 * Transmit next char.
        !          70291:                 */
        !          70292:                outb( PORT+DREG, b );
        !          70293:        }
        !          70294: 
        !          70295:        spl(s);
        !          70296: }
        !          70297: 
        !          70298: /*
        !          70299:  * Ioctl Routine.
        !          70300:  */
        !          70301: 
        !          70302: static
        !          70303: rsioctl( dev, com, vec )
        !          70304: 
        !          70305: dev_t dev;
        !          70306: int com;
        !          70307: struct termio *vec;
        !          70308: 
        !          70309: {
        !          70310:        register int b;
        !          70311:        struct termio tb;
        !          70312: 
        !          70313:        switch (com) {
        !          70314: 
        !          70315:        case TCSETAW:   /* Set attributes after waiting for output to clear */
        !          70316:        case TCSETAF:   /* ditto, but also flush input queue */
        !          70317:        case TCSBRK:    /* wait for output to clear, send break */
        !          70318: 
        !          70319:                /*
        !          70320:                 * Delay until output queue is empty.
        !          70321:                 */
        !          70322:                while ( rsoutq.rq_ox != rsoutq.rq_ix ) {
        !          70323: 
        !          70324:                        /*
        !          70325:                         * Sleep waiting for empty output queue.
        !          70326:                         */
        !          70327:                        ++rstty.rt_drefc;
        !          70328:                        sleep( &rstty.rt_drefc, CVTTOUT, IVTTOUT, SVTTOUT);
        !          70329:                        --rstty.rt_drefc;
        !          70330: 
        !          70331:                        /*
        !          70332:                         * Abort if a non-ignored signal was received.
        !          70333:                         */
        !          70334:                        if ( SELF->p_ssig && nondsig() ) {
        !          70335:                                u.u_error = EINTR;
        !          70336:                                return;
        !          70337:                        }
        !          70338:                }
        !          70339: 
        !          70340:                if ( com == TCSBRK ) {
        !          70341: 
        !          70342:                        b = inb( PORT + LCR );
        !          70343: 
        !          70344:                        if ( vec == 0 ) {
        !          70345:                                rstty.rt_ticks  = 3;    /* 0.2 to 0.3 sec */
        !          70346:                                rstty.rt_state |= TTSBRK;
        !          70347:                                b |= LC_SBRK;
        !          70348:                        }
        !          70349:                        else {
        !          70350:                                rstty.rt_ticks  = 0;
        !          70351:                                rstty.rt_state &= ~TTSBRK;
        !          70352:                                b &= ~LC_SBRK;
        !          70353:                        }
        !          70354: 
        !          70355:                        outb( PORT + LCR, b );
        !          70356:                        return;
        !          70357:                }
        !          70358:                /* no break */
        !          70359: 
        !          70360:        case TCSETA:
        !          70361:                /*
        !          70362:                 * Get new terminal attributes.
        !          70363:                 */
        !          70364:                ukcopy( vec, &tb, sizeof(tb) );
        !          70365:                if ( u.u_error )
        !          70366:                        return;
        !          70367: 
        !          70368:                /*
        !          70369:                 * Set terminal attributes and hardware.
        !          70370:                 */
        !          70371:                rstty.rt_iflag = tb.c_iflag;
        !          70372:                rstty.rt_oflag = tb.c_oflag;
        !          70373:                if (rstty.rt_cflag != tb.c_cflag) {
        !          70374:                        rstty.rt_cflag = tb.c_cflag;
        !          70375:                        rsparam();
        !          70376:                }
        !          70377: 
        !          70378:                if ((rstty.rt_iflag & IXON) == 0)
        !          70379:                        rstty.rt_state &= ~TTSTOP;
        !          70380: 
        !          70381:                /*
        !          70382:                 * Flush input queue if command was TCSETAF.
        !          70383:                 */
        !          70384:                if ( com == TCSETAF )
        !          70385:                        rsrawq.rq_ox = rsrawq.rq_ix;
        !          70386:                break;
        !          70387: 
        !          70388:        case TCGETA:    /* Get terminal attributes */
        !          70389:                
        !          70390:                memset( &tb, 0, sizeof(tb) );
        !          70391:                tb.c_cflag = rstty.rt_cflag;
        !          70392:                tb.c_iflag = rstty.rt_iflag;
        !          70393:                tb.c_oflag = rstty.rt_oflag;
        !          70394: 
        !          70395:                /*
        !          70396:                 * Transfer terminal attributes to user space.
        !          70397:                 */
        !          70398:                kucopy( &tb, vec, sizeof(tb) );
        !          70399:                break;
        !          70400: 
        !          70401:        case TCFLSH:
        !          70402:                switch ((int) vec) {
        !          70403:                case 0:
        !          70404:                        /* flush input queue */
        !          70405:                        rsrawq.rq_ox = rsrawq.rq_ix;
        !          70406:                        break;
        !          70407:                case 1:
        !          70408:                        /* flush output queue */
        !          70409:                        rsoutq.rq_ox = rsoutq.rq_ix;
        !          70410:                        break;
        !          70411:                case 2:
        !          70412:                        /* flush both input and output queues */
        !          70413:                        rsrawq.rq_ox = rsrawq.rq_ix;
        !          70414:                        rsoutq.rq_ox = rsoutq.rq_ix;
        !          70415:                        break;
        !          70416:                default:
        !          70417:                        u.u_error = EINVAL;
        !          70418:                }
        !          70419:                break;
        !          70420: 
        !          70421:        case TCXONC:
        !          70422:                switch ( (int) vec ) {
        !          70423:                case 0:
        !          70424:                        /* stop output */
        !          70425:                        rstty.rt_state |= TTSTOP;
        !          70426:                        break;
        !          70427:                case 1:
        !          70428:                        /* restart output */
        !          70429:                        rstty.rt_state &= ~TTSTOP;
        !          70430:                        rsstart();
        !          70431:                        break;
        !          70432:                default:
        !          70433:                        u.u_error = EINVAL;
        !          70434:                }
        !          70435:                break;
        !          70436: 
        !          70437:        default:
        !          70438:                u.u_error = EINVAL;
        !          70439:        }
        !          70440: }
        !          70441: 
        !          70442: /*
        !          70443:  * Rsparam -- Setup hardware parameters.
        !          70444:  */
        !          70445: 
        !          70446: static
        !          70447: rsparam()
        !          70448: {
        !          70449:        register int b;
        !          70450:        register int s;
        !          70451: 
        !          70452:        /*
        !          70453:         * Disable interrupts.
        !          70454:         */
        !          70455:        s = sphi();
        !          70456: 
        !          70457:        /*
        !          70458:         * Assert required modem control lines (DTR, RTS).
        !          70459:         */
        !          70460:        if ((rstty.rt_cflag & CBAUD) == B0)
        !          70461:                outb( PORT+MCR, MC_OUT2 );
        !          70462:        else if ((rstty.rt_refc == 0) && (rstty.rt_cflag & HUPCL))
        !          70463:                outb( PORT+MCR, MC_OUT2 );
        !          70464:        else
        !          70465:                outb( PORT+MCR, MC_OUT2+MC_DTR+MC_RTS );
        !          70466: 
        !          70467:        /*
        !          70468:         * Program baud rate.
        !          70469:         */
        !          70470:        if (b = timeconst[ rstty.rt_cflag & CBAUD ]) {
        !          70471:                outb( PORT+LCR, LC_DLAB );
        !          70472:                outb( PORT+DLL, b );
        !          70473:                outb( PORT+DLH, b >> 8 );
        !          70474:        }
        !          70475: 
        !          70476:        /*
        !          70477:         * Program character size, parity, and stop bits.
        !          70478:         */
        !          70479:        switch (rstty.rt_cflag & CSIZE) {
        !          70480:        case CS5:               b = LC_CS5;                     break;
        !          70481:        case CS6:               b = LC_CS6;                     break;
        !          70482:        case CS7:               b = LC_CS7;                     break;
        !          70483:        case CS8:               b = LC_CS8;                     break;
        !          70484:        }
        !          70485: 
        !          70486:        switch (rstty.rt_cflag & (PARENB|PARODD)) {
        !          70487:        case PARENB:            b |= LC_PARENB|LC_PAREVEN;      break;
        !          70488:        case PARENB|PARODD:     b |= LC_PARENB;                 break;
        !          70489:        }
        !          70490: 
        !          70491:        if (rstty.rt_cflag & CSTOPB)
        !          70492:                b |= LC_STOPB;
        !          70493: 
        !          70494:        if (rstty.rt_state & TTSBRK)
        !          70495:                b |= LC_SBRK;
        !          70496: 
        !          70497:        outb( PORT+LCR, b );
        !          70498: 
        !          70499:        /*
        !          70500:         * Enable desired interrupts.
        !          70501:         */
        !          70502:        b = 0;
        !          70503:        if (rstty.rt_cflag & CBAUD) {
        !          70504:                b = IE_TxI | IE_LSI;
        !          70505:                if (rstty.rt_cflag & CREAD)
        !          70506:                        b |= IE_RxI;
        !          70507:        }
        !          70508:        outb( PORT+IER, b );
        !          70509: 
        !          70510:        /*
        !          70511:         * Enable interrupts.
        !          70512:         */
        !          70513:        spl( s );
        !          70514: }
        !          70515: @
        !          70516: 
        !          70517: 
        !          70518: 1.1
        !          70519: log
        !          70520: @Initial revision
        !          70521: @
        !          70522: text
        !          70523: @d17 2
        !          70524: a18 2
        !          70525: #include "coherent.h"
        !          70526: #include "ins8250.h"
        !          70527: @
        !          70528: 0707070064030106451004440000030000030000011777770507310700000005600000004600/newbits/kernel/USRSRC/i8086/drv/RCS/rsas.s,vhead     1.1;
        !          70529: branch   ;
        !          70530: access   ;
        !          70531: symbols  ;
        !          70532: locks    bin:1.1; strict;
        !          70533: comment  @@;
        !          70534: 
        !          70535: 
        !          70536: 1.1
        !          70537: date     91.06.10.10.25.00;  author bin;  state Exp;
        !          70538: branches ;
        !          70539: next     ;
        !          70540: 
        !          70541: 
        !          70542: desc
        !          70543: @initial version prov by hal
        !          70544: @
        !          70545: 
        !          70546: 
        !          70547: 
        !          70548: 1.1
        !          70549: log
        !          70550: @Initial revision
        !          70551: @
        !          70552: text
        !          70553: @/ (lgl-
        !          70554: /      COHERENT Driver Kit Version 1.1.0
        !          70555: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          70556: /      All rights reserved. May not be copied without permission.
        !          70557: / -lgl)
        !          70558: ////////
        !          70559: /
        !          70560: / Raw Serial Device Driver - Assembler Support
        !          70561: /
        !          70562: ////////
        !          70563: 
        !          70564: ////////
        !          70565: /
        !          70566: / Locally defined global symbols
        !          70567: /
        !          70568: ////////
        !          70569: 
        !          70570:        .globl  rsin_
        !          70571:        .globl  rsout_
        !          70572: 
        !          70573: ////////
        !          70574: /
        !          70575: / Offsets to fields in the IRING and ORING data structures.
        !          70576: /
        !          70577: ////////
        !          70578: 
        !          70579:        Q_MASK  = 0
        !          70580:        Q_IX    = 2
        !          70581:        Q_OX    = 4
        !          70582:        Q_CC    = 6
        !          70583: 
        !          70584: ////////
        !          70585: /
        !          70586: / Offsets to fields in the IO data structure.
        !          70587: /
        !          70588: ////////
        !          70589: 
        !          70590:        IO_IOC  = 2
        !          70591:        IO_BASE = 8
        !          70592: 
        !          70593: ////////
        !          70594: /
        !          70595: / Rsin ( rawqp, iop )  -- transfer data from input ring to user
        !          70596: / IRING *rawqp;
        !          70597: / IO *iop;
        !          70598: /
        !          70599: ////////
        !          70600: 
        !          70601: rsin_:
        !          70602:        push    si                              / Save SI, DI, BP, ES
        !          70603:        push    di
        !          70604:        push    bp
        !          70605:        mov     bp, sp
        !          70606:        push    es
        !          70607: 
        !          70608:        mov     bx, 10(bp)                      / User destination --> ES:DI
        !          70609:        mov     di, IO_BASE(bx)
        !          70610:        mov     es, uds_
        !          70611: 
        !          70612:        cld                                     / Auto Increment
        !          70613:        mov     cx, IO_IOC(bx)                  / Byte count --> CX
        !          70614:        jcxz    1f
        !          70615: 
        !          70616:        mov     bx, 8(bp)                       / rawqp --> BX
        !          70617: 
        !          70618:        mov     si, Q_OX(bx)
        !          70619:        cmp     si, Q_IX(bx)                    / Input data available?
        !          70620:        je      1f
        !          70621: 
        !          70622: 0:     movb    al, Q_CC(bx,si)                 / Yes,  read one character
        !          70623:        inc     si                              /       update index
        !          70624:        and     si, Q_MASK(bx)                  /       (wrap if necessary)
        !          70625:        stosb                                   /       write to user space
        !          70626:        cmp     si, Q_IX(bx)                    /       More input data?
        !          70627:        loopne  0b                              /
        !          70628: 
        !          70629:        mov     Q_OX(bx), si                    / Save revised index
        !          70630:        mov     bx, 10(bp)                      / Update io parameters
        !          70631:        mov     IO_BASE(bx), di
        !          70632:        mov     IO_IOC(bx), cx
        !          70633: 
        !          70634: 1:     pop     es                              / Restore ES, BP, DI, SI.
        !          70635:        pop     bp
        !          70636:        pop     di
        !          70637:        pop     si
        !          70638:        ret
        !          70639: 
        !          70640: ////////
        !          70641: /
        !          70642: / Rsout( outqp, iop )  -- transfer data from user to output ring
        !          70643: / ORING *outqp;
        !          70644: / IO *iop;
        !          70645: /
        !          70646: ////////
        !          70647: 
        !          70648: rsout_:
        !          70649:        push    si                              / Save SI, DI, BP, ES
        !          70650:        push    di
        !          70651:        push    bp
        !          70652:        mov     bp, sp
        !          70653:        push    es
        !          70654: 
        !          70655:        mov     bx, 10(bp)                      / User source --> ES:DI
        !          70656:        mov     di, IO_BASE(bx)
        !          70657:        mov     es, uds_
        !          70658: 
        !          70659:        mov     cx, IO_IOC(bx)                  / Byte count --> CX
        !          70660:        jcxz    2f
        !          70661: 
        !          70662:        mov     bx, 8(bp)                       / outqp --> BX
        !          70663:        mov     si, Q_IX(bx)
        !          70664: 
        !          70665: 0:     movb    al, es:(di)
        !          70666:        inc     di
        !          70667:        movb    Q_CC(bx,si), al
        !          70668:        inc     si
        !          70669:        and     si, Q_MASK(bx)
        !          70670:        cmp     si, Q_OX(bx)
        !          70671:        loopne  0b
        !          70672: 
        !          70673:        jne     1f                              / If can't save last char
        !          70674:        dec     di                              /       Undo changes.
        !          70675:        dec     si
        !          70676:        and     si, Q_MASK(bx)
        !          70677:        inc     cx
        !          70678: 
        !          70679: 1:     mov     Q_IX(bx), si                    / Save revised index
        !          70680:        mov     bx, 10(bp)
        !          70681:        mov     IO_BASE(bx), di                 / Update io parameters
        !          70682:        mov     IO_IOC(bx), cx
        !          70683: 
        !          70684: 2:     pop     es                              / Restore ES, BP, DI, SI.
        !          70685:        pop     bp
        !          70686:        pop     di
        !          70687:        pop     si
        !          70688:        ret
        !          70689: @
        !          70690: 0707070064030106441004440000030000030000011777770507310700100005400000000711/newbits/kernel/USRSRC/i8086/drv/RCS/scsi,vhead     1.1;
        !          70691: branch   ;
        !          70692: access   ;
        !          70693: symbols  ;
        !          70694: locks    bin:1.1; strict;
        !          70695: comment  @# @;
        !          70696: 
        !          70697: 
        !          70698: 1.1
        !          70699: date     91.06.10.10.25.02;  author bin;  state Exp;
        !          70700: branches ;
        !          70701: next     ;
        !          70702: 
        !          70703: 
        !          70704: desc
        !          70705: @initial version prov by hal
        !          70706: @
        !          70707: 
        !          70708: 
        !          70709: 
        !          70710: 1.1
        !          70711: log
        !          70712: @Initial revision
        !          70713: @
        !          70714: text
        !          70715: @:
        !          70716: : SCSI Hard Disk Version 0.0
        !          70717: :
        !          70718: MAJOR=13
        !          70719: 
        !          70720: HD_TYPE=sd0
        !          70721: :
        !          70722: :      needed by config
        !          70723: :
        !          70724: UNDEF="${UNDEF} -u sdcon_ lib/scsi.a"
        !          70725: PATCH="${PATCH} drvl_+130=sdcon_"
        !          70726: 
        !          70727: umask 077
        !          70728: /etc/mknod -f ${DEV-/dev}/sd0a  b 13 0         || exit 1
        !          70729: @
        !          70730: 0707070064030106431004440000030000030000011777770507310700100005600000001223/newbits/kernel/USRSRC/i8086/drv/RCS/sd.toc,vhead     1.1;
        !          70731: branch   ;
        !          70732: access   ;
        !          70733: symbols  ;
        !          70734: locks    bin:1.1; strict;
        !          70735: comment  @@;
        !          70736: 
        !          70737: 
        !          70738: 1.1
        !          70739: date     91.06.10.10.25.13;  author bin;  state Exp;
        !          70740: branches ;
        !          70741: next     ;
        !          70742: 
        !          70743: 
        !          70744: desc
        !          70745: @initial version prov by hal
        !          70746: @
        !          70747: 
        !          70748: 
        !          70749: 
        !          70750: 1.1
        !          70751: log
        !          70752: @Initial revision
        !          70753: @
        !          70754: text
        !          70755: @-rw-r--r--  1 root       daemon       15118 Fri Oct  5  1990 aha.c
        !          70756: -rw-r--r--  1 root       daemon        4557 Fri Oct  5  1990 aha154x.h
        !          70757: -rw-r--r--  1 root       daemon         211 Wed Sep 19  1990 scsi
        !          70758: -rw-r--r--  1 root       daemon       10198 Fri Oct  5  1990 scsi.c
        !          70759: -rw-r--r--  1 root       daemon        1205 Fri Oct  5  1990 scsiwork.h
        !          70760: -rw-r--r--  1 root       daemon          87 Wed Sep 19  1990 sdioctl.h
        !          70761: @
        !          70762: 0707070064030104231004440000030000030000011777770507310700100005500000026472/newbits/kernel/USRSRC/i8086/drv/RCS/sem.c,vhead     1.4;
        !          70763: branch   ;
        !          70764: access   ;
        !          70765: symbols  ;
        !          70766: locks    bin:1.4; strict;
        !          70767: comment  @ * @;
        !          70768: 
        !          70769: 
        !          70770: 1.4
        !          70771: date     91.06.20.14.53.04;  author bin;  state Exp;
        !          70772: branches ;
        !          70773: next     1.3;
        !          70774: 
        !          70775: 1.3
        !          70776: date     91.06.18.08.14.27;  author bin;  state Exp;
        !          70777: branches ;
        !          70778: next     1.2;
        !          70779: 
        !          70780: 1.2
        !          70781: date     91.06.17.12.35.34;  author bin;  state Exp;
        !          70782: branches ;
        !          70783: next     1.1;
        !          70784: 
        !          70785: 1.1
        !          70786: date     91.06.10.10.25.14;  author bin;  state Exp;
        !          70787: branches ;
        !          70788: next     ;
        !          70789: 
        !          70790: 
        !          70791: desc
        !          70792: @initial version prov by hal
        !          70793: @
        !          70794: 
        !          70795: 
        !          70796: 1.4
        !          70797: log
        !          70798: @update provided by hal
        !          70799: @
        !          70800: text
        !          70801: @/* $Header: /usr/src/sys/i8086/drv/RCS/sem.c,v 2.1 88/09/03 13:11:37 src Exp $
        !          70802:  *
        !          70803:  *     The  information  contained herein  is a trade secret  of INETCO
        !          70804:  *     Systems, and is confidential information.   It is provided under
        !          70805:  *     a license agreement,  and may be copied or disclosed  only under
        !          70806:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          70807:  *     this  material  without  the express  written  authorization  of
        !          70808:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          70809:  *
        !          70810:  *     Copyright (c) 1985
        !          70811:  *     An unpublished work by INETCO Systems, Ltd.
        !          70812:  *     All rights reserved.
        !          70813:  */
        !          70814: 
        !          70815: /*
        !          70816:  * System V Compatible Semaphores
        !          70817:  *
        !          70818:  *     This module provides System V compatible semaphore operations.
        !          70819:  *
        !          70820:  *                     Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
        !          70821:  *
        !          70822:  * $Log:       /usr/src/sys/i8086/drv/RCS/sem.c,v $
        !          70823:  * Revision 2.1        88/09/03  13:11:37      src
        !          70824:  * *** empty log message ***
        !          70825:  * 
        !          70826:  * Revision 1.1        88/03/24  17:06:22      src
        !          70827:  * Initial revision
        !          70828:  * 
        !          70829:  * 85/08/06    Allan Cornish
        !          70830:  * Sem.c split into configuration (semcon.c) and implementation (sem.c).
        !          70831:  * Semload() renamed to seminit().
        !          70832:  *
        !          70833:  * 85/07/22    Allan Cornish
        !          70834:  * Semctl, semget, semop now return immediately if u.u_error is set.
        !          70835:  *
        !          70836:  * 85/07/03    Allan Cornish
        !          70837:  * Replaced use of EDOM with EIDRM.
        !          70838:  * Eliminated semlock() and semunlock() functions.
        !          70839:  * Replaced semaccess() by calls to ipcaccess(), increasing shared ipc code.
        !          70840:  */
        !          70841: 
        !          70842: #include <coherent.h>
        !          70843: #include <sched.h>
        !          70844: #include <types.h>
        !          70845: #include <uproc.h>
        !          70846: #include <errno.h>
        !          70847: #include <stat.h>
        !          70848: #include <con.h>
        !          70849: #include <sem.h>
        !          70850: 
        !          70851: #ifndef        EIDRM
        !          70852: #define        EIDRM   EDOM
        !          70853: #endif
        !          70854: 
        !          70855: /*
        !          70856:  *     Semaphore Information
        !          70857:  */
        !          70858: 
        !          70859: #define        NSEMVAL 32767
        !          70860: 
        !          70861: static
        !          70862: struct semid_ds *semids = 0;
        !          70863: 
        !          70864: unsigned NSEMID = 16;
        !          70865: unsigned NSEM   = 16;
        !          70866:                    
        !          70867: /*
        !          70868:  * Semaphore Initialization.
        !          70869:  *
        !          70870:  *     Initialize semaphore ids.
        !          70871:  */
        !          70872: 
        !          70873: seminit()
        !          70874: {
        !          70875:        register struct semid_ds *semidp;
        !          70876: 
        !          70877:        if ( semids = kalloc( NSEMID * sizeof(struct semid_ds) ) ) {
        !          70878: 
        !          70879:                for ( semidp = &semids[NSEMID]; --semidp >= semids; )
        !          70880:                        semidp->sem_perm.mode = 0;
        !          70881:        }
        !          70882:        else {
        !          70883:                printf("could not allocate %u semaphore ids\n", NSEMID);
        !          70884:                NSEMID = 0;
        !          70885:        }
        !          70886: }
        !          70887: 
        !          70888: /*
        !          70889:  * Semctl - Semaphore Control Operations.
        !          70890:  */
        !          70891: 
        !          70892: usemctl( semid, semnum, cmd, arg )
        !          70893: 
        !          70894: unsigned semid;
        !          70895: unsigned semnum;
        !          70896: int cmd;
        !          70897: union semun {
        !          70898:        int val;
        !          70899:        struct semid_ds *buf;
        !          70900:        unsigned short *array;
        !          70901: } arg;
        !          70902: 
        !          70903: {
        !          70904:        register struct semid_ds *semidp;
        !          70905:        register struct sem *semp;
        !          70906:        int nsems, val;
        !          70907: 
        !          70908:        if ( u.u_error )
        !          70909:                return -1;
        !          70910: 
        !          70911:        if ( semid >= NSEMID ) {
        !          70912:                u.u_error = EINVAL;
        !          70913:                return -1;
        !          70914:        }
        !          70915: 
        !          70916:        semidp = &semids[semid];
        !          70917: 
        !          70918:        if ( (semidp->sem_perm.mode & IPC_ALLOC) == 0 ) {
        !          70919:                u.u_error = EINVAL;
        !          70920:                return -1;
        !          70921:        }
        !          70922: 
        !          70923:        if ((ipcaccess( &semidp->sem_perm ) & SEM_R) == 0) { /* can't read */
        !          70924:                u.u_error = EACCES;
        !          70925:                return -1;
        !          70926:        }
        !          70927: 
        !          70928:        if ( semnum >= semidp->sem_nsems ) {
        !          70929:                u.u_error = EFBIG;
        !          70930:                return -1;
        !          70931:        }
        !          70932: 
        !          70933:        semp = &semidp->sem_base[semnum];
        !          70934: 
        !          70935:        switch ( cmd ) {
        !          70936: 
        !          70937:        case GETVAL:            /* Return value of semval */
        !          70938:                return semp->semval;
        !          70939: 
        !          70940:        case SETVAL:                                            /* Set semval */
        !          70941:                if ((ipcaccess( &semidp->sem_perm ) & SEM_A) == 0) {
        !          70942:                        u.u_error = EACCES;     /* can't alter */
        !          70943:                        return -1;
        !          70944:                }
        !          70945: 
        !          70946:                if ( arg.val < 0 ) {                    /* illegal value */
        !          70947:                        u.u_error = ERANGE;
        !          70948:                        return -1;
        !          70949:                }
        !          70950: 
        !          70951:                if ( semp->semval = arg.val ) {
        !          70952: 
        !          70953:                        if ( semp->semncnt )
        !          70954:                                wakeup( &semp->semncnt );
        !          70955:                }
        !          70956:                else {
        !          70957:                        if ( semp->semzcnt )
        !          70958:                                wakeup( &semp->semzcnt );
        !          70959:                }
        !          70960: 
        !          70961:                return 0;
        !          70962: 
        !          70963:        case GETPID:            /* Return value of sempid */
        !          70964:                return semp->sempid;
        !          70965: 
        !          70966:        case GETNCNT:           /* Return value of semncnt */
        !          70967:                return semp->semncnt;
        !          70968: 
        !          70969:        case GETZCNT:           /* Return value of semzcnt */
        !          70970:                return semp->semzcnt;
        !          70971: 
        !          70972:        case GETALL:            /* Return semvals array */
        !          70973:                nsems = semidp->sem_nsems;
        !          70974:                semp  = semidp->sem_base;
        !          70975: 
        !          70976:                while ( --nsems >= 0 ) {
        !          70977: 
        !          70978:                        putuwd( (arg.array)++, (semp++)->semval );
        !          70979: 
        !          70980:                        if ( u.u_error )
        !          70981:                                return -1;
        !          70982:                }
        !          70983:                return 0;
        !          70984: 
        !          70985:        case SETALL:            /* Set semvals array */
        !          70986:                if ( (ipcaccess( &semidp->sem_perm ) & SEM_A) == 0 ) {
        !          70987:                        u.u_error = EACCES;
        !          70988:                        return -1;
        !          70989:                }
        !          70990:                nsems = semidp->sem_nsems;
        !          70991:                semp  = semidp->sem_base;
        !          70992: 
        !          70993:                while ( --nsems >= 0 ) {
        !          70994: 
        !          70995:                        if ( (val = getuwd( arg.array )) < 0 ) {
        !          70996: 
        !          70997:                                if ( u.u_error == 0 )
        !          70998:                                        u.u_error = ERANGE;
        !          70999:                        }
        !          71000:                        else
        !          71001:                                semp->semval = val;
        !          71002:                        arg.array++;
        !          71003:                        semp++;
        !          71004:                }
        !          71005:                if ( u.u_error )
        !          71006:                        return -1;
        !          71007:                return 0;
        !          71008: 
        !          71009:        case IPC_STAT:
        !          71010:                kucopy( semidp, arg.buf, sizeof(struct semid_ds) );
        !          71011:                return 0;
        !          71012: 
        !          71013:        case IPC_SET:
        !          71014:                if ( (u.u_uid != 0) && (u.u_uid != semidp->sem_perm.uid) ) {
        !          71015:                        u.u_error = EPERM;
        !          71016:                        return -1;
        !          71017:                }
        !          71018:                semidp->sem_perm.uid   = getuwd( &((arg.buf)->sem_perm.uid ) );
        !          71019:                semidp->sem_perm.gid   = getuwd( &((arg.buf)->sem_perm.gid ) );
        !          71020:                semidp->sem_perm.mode  =
        !          71021:                        (getuwd(&((arg.buf)->sem_perm.mode))&0777) | IPC_ALLOC;
        !          71022:                return 0;
        !          71023: 
        !          71024:        case IPC_RMID:
        !          71025:                if ( (u.u_uid != 0) && (u.u_uid != semidp->sem_perm.uid) ) {
        !          71026:                        u.u_error = EPERM;
        !          71027:                        return -1;
        !          71028:                }
        !          71029:                semidp->sem_perm.seq++;
        !          71030:                semp = &semidp->sem_base[ semidp->sem_nsems ];
        !          71031: 
        !          71032:                while ( --semp >= semidp->sem_base ) {
        !          71033: 
        !          71034:                        if ( semp->semncnt )
        !          71035:                                wakeup( &semp->semncnt );
        !          71036:                        if ( semp->semzcnt )
        !          71037:                                wakeup( &semp->semzcnt );
        !          71038:                }
        !          71039: 
        !          71040:                kfree( semidp->sem_base );
        !          71041:                semidp->sem_perm.mode = 0;
        !          71042:                return 0;
        !          71043: 
        !          71044:        default:
        !          71045:                u.u_error = EINVAL;
        !          71046:                return -1;
        !          71047:        }
        !          71048: }
        !          71049: 
        !          71050: /*
        !          71051:  * Semget - Get set of semaphores
        !          71052:  */
        !          71053: 
        !          71054: usemget( skey, nsems, semflg )
        !          71055: 
        !          71056: key_t skey;
        !          71057: unsigned nsems;
        !          71058: int semflg;
        !          71059: 
        !          71060: {
        !          71061:        register struct semid_ds *semidp;
        !          71062:        register struct sem *semp;
        !          71063:        struct semid_ds *freeidp = 0;
        !          71064: 
        !          71065:        if ( u.u_error )
        !          71066:                return -1;
        !          71067: 
        !          71068:        if ( nsems >= NSEM ) {
        !          71069:                u.u_error = EINVAL;
        !          71070:                return -1;
        !          71071:        }
        !          71072: 
        !          71073:        for ( semidp = &semids[NSEMID]; --semidp >= semids; ) {
        !          71074: 
        !          71075:                if ( (semidp->sem_perm.mode & IPC_ALLOC) == 0 ) {
        !          71076: 
        !          71077:                        if ((freeidp == 0) ||
        !          71078:                            (freeidp->sem_ctime > semidp->sem_ctime))
        !          71079:                                freeidp = semidp;
        !          71080:                        continue;
        !          71081:                }
        !          71082: 
        !          71083: #ifdef IPC_PRIVATE
        !          71084:                if (skey == IPC_PRIVATE)
        !          71085:                        continue;
        !          71086: #endif
        !          71087: 
        !          71088:                if (skey == semidp->sem_perm.key) {             /* found! */
        !          71089: 
        !          71090:                        if ( (semflg & IPC_CREAT) && (semflg & IPC_EXCL) ) {
        !          71091:                                u.u_error = EEXIST;
        !          71092:                                return -1;
        !          71093:                        }
        !          71094: 
        !          71095:                        if ((semidp->sem_perm.mode & semflg) != (semflg&0777)) {
        !          71096:                                u.u_error = EACCES;
        !          71097:                                return -1;
        !          71098:                        }
        !          71099: 
        !          71100:                        if ( semidp->sem_nsems < nsems ) {
        !          71101:                                u.u_error = EINVAL;
        !          71102:                                return -1;
        !          71103:                        }
        !          71104: 
        !          71105:                        return semidp - semids;
        !          71106:                }
        !          71107:        }
        !          71108: 
        !          71109:        if ( !(semflg & IPC_CREAT) ) {
        !          71110:                u.u_error = ENOENT;
        !          71111:                return -1;
        !          71112:        }
        !          71113: 
        !          71114:        if ( freeidp == 0 ) {
        !          71115:                u.u_error = ENOSPC;
        !          71116:                return -1;
        !          71117:        }
        !          71118: 
        !          71119:        semidp = freeidp;
        !          71120:        semidp->sem_base = kalloc( nsems * sizeof(struct sem) );
        !          71121: 
        !          71122:        if (semidp->sem_base == 0 ) {
        !          71123:                u.u_error = ENOSPC;
        !          71124:                return -1;
        !          71125:        }
        !          71126: 
        !          71127:        semidp->sem_nsems = nsems;
        !          71128:        semidp->sem_otime = 0;
        !          71129:        semidp->sem_ctime = timer.t_time;
        !          71130: 
        !          71131:        for ( semp = &semidp->sem_base[nsems]; --semp >= semidp->sem_base; )
        !          71132:                semp->semval = semp->sempid = semp->semncnt = semp->semzcnt = 0;
        !          71133: 
        !          71134:        semidp->sem_perm.cuid = semidp->sem_perm.uid = u.u_uid;
        !          71135:        semidp->sem_perm.cgid = semidp->sem_perm.gid = u.u_gid;
        !          71136:        semidp->sem_perm.mode = (semflg & 0777) | IPC_ALLOC;
        !          71137:        semidp->sem_perm.key  = skey;
        !          71138: 
        !          71139:        return semidp - semids;
        !          71140: }
        !          71141: 
        !          71142: /*
        !          71143:  * Semop - Semaphore Operations.
        !          71144:  */
        !          71145: 
        !          71146: usemop( semid, sops, nsops )
        !          71147: 
        !          71148: unsigned semid;
        !          71149: struct sembuf *sops;
        !          71150: unsigned nsops;
        !          71151: 
        !          71152: {
        !          71153:        register struct semid_ds *semidp;
        !          71154:        register struct sem *semp;
        !          71155:        struct sembuf *sp;
        !          71156:        unsigned n, semnum, semflg;
        !          71157:        int semop, oval;
        !          71158: 
        !          71159:        if ( u.u_error )
        !          71160:                return -1;
        !          71161: 
        !          71162:        if ( semid >= NSEMID ) {
        !          71163:                u.u_error = EINVAL;
        !          71164:                return -1;
        !          71165:        }
        !          71166: 
        !          71167:        if ( nsops >= NSEM ) {
        !          71168:                u.u_error = E2BIG;
        !          71169:                return -1;
        !          71170:        }
        !          71171: 
        !          71172:        semidp = &semids[semid];
        !          71173: 
        !          71174:        if ( (semidp->sem_perm.mode & IPC_ALLOC) == 0 ) {
        !          71175:                u.u_error = EINVAL;
        !          71176:                return -1;
        !          71177:        }
        !          71178: 
        !          71179:        if ( (ipcaccess( &semidp->sem_perm ) & SEM_A) == 0 ) {
        !          71180:                u.u_error = EACCES;
        !          71181:                return -1;
        !          71182:        }
        !          71183: 
        !          71184:        sp = sops;
        !          71185:        n  = nsops;
        !          71186: 
        !          71187:        while ( n > 0 ) {                               /* do semaphore ops  */
        !          71188: 
        !          71189:                semnum = getuwd( & (sp->sem_num) );
        !          71190:                semop  = getuwd( & (sp->sem_op ) );
        !          71191:                semflg = getuwd( & (sp->sem_flg) );
        !          71192: 
        !          71193:                if ( (u.u_error != 0) || (semnum >= semidp->sem_nsems) ) {
        !          71194: 
        !          71195:                        while ( --sp >= sops ) {        /* undo prev semops  */
        !          71196: 
        !          71197:                                semnum = getuwd( &sp->sem_num );
        !          71198:                                semop  = getuwd( &sp->sem_op  );
        !          71199:                                semp   = &semidp->sem_base[ semnum ];
        !          71200:                                semundo( semp, semop );
        !          71201:                        }
        !          71202: 
        !          71203:                        if ( u.u_error == 0 )
        !          71204:                                u.u_error = EFBIG;
        !          71205:                        return -1;
        !          71206:                }
        !          71207: 
        !          71208:                semp = &semidp->sem_base[semnum];
        !          71209: 
        !          71210:                if ( (oval = semdo( semp, semop )) < 0 ) { /* can't do semop */
        !          71211: 
        !          71212:                        while ( --sp >= sops ) {        /* undo prev semops  */
        !          71213: 
        !          71214:                                unsigned unnum = getuwd( &sp->sem_num );
        !          71215:                                int      unop  = getuwd( &sp->sem_op  );
        !          71216:                                semundo( &semidp->sem_base[ unnum ], unop);
        !          71217:                        }
        !          71218: 
        !          71219:                        if ( u.u_error )
        !          71220:                                return -1;
        !          71221: 
        !          71222:                        if ( semflg & IPC_NOWAIT ) {
        !          71223:                                u.u_error = EAGAIN;
        !          71224:                                return -1;
        !          71225:                        }
        !          71226: 
        !          71227:                        if ( semop < 0 ) {      /* wait for non-zero */
        !          71228: 
        !          71229:                                if (semwait( semidp, &semp->semncnt ) < 0 )
        !          71230:                                        return -1;
        !          71231:                        }
        !          71232:                        else {                  /* wait for zero */
        !          71233: 
        !          71234:                                if ( semwait( semidp, &semp->semzcnt ) < 0 )
        !          71235:                                        return -1;
        !          71236:                        }
        !          71237: 
        !          71238:                        sp = sops;      /* retry set of semaphore operations */
        !          71239:                        n = nsops;
        !          71240:                        continue;
        !          71241:                }
        !          71242: 
        !          71243:                ++sp;
        !          71244:                --n;
        !          71245:        }
        !          71246: 
        !          71247:        for (sp=sops,n=nsops; n > 0; --n,++sp) {/* save pid in each semaphore */
        !          71248: 
        !          71249:                semnum = getuwd( &sp->sem_num );
        !          71250:                semidp->sem_base[ semnum ].sempid = SELF->p_pid;
        !          71251:        }
        !          71252: 
        !          71253:        semidp->sem_otime = timer.t_time;       /* ajust operation time */
        !          71254:        return oval;                            /* return last prev semval */
        !          71255: }
        !          71256: 
        !          71257: /*
        !          71258:  * Do a Semaphore Operation.
        !          71259:  *
        !          71260:  *     Input:  semp  = pointer to semaphore
        !          71261:  *             semop = semaphore operation
        !          71262:  *
        !          71263:  *     Action: If semop < 0 and semval > semop then add semop to semval.
        !          71264:  *             If semop > 0 then add semop to semval.
        !          71265:  *
        !          71266:  *     Return: Previous semval.
        !          71267:  */
        !          71268: 
        !          71269: static
        !          71270: semdo( semp, semop )
        !          71271: 
        !          71272: register struct sem * semp;
        !          71273: register int semop;
        !          71274: 
        !          71275: {
        !          71276:        int ret;
        !          71277: 
        !          71278:        ret = semp->semval;
        !          71279: 
        !          71280:        if ( semop < 0 ) {                      /* want to decrement semval */
        !          71281: 
        !          71282:                semop = -semop;
        !          71283: 
        !          71284:                if ( semp->semval < semop )     /* can't decrement semval */
        !          71285:                        return -1;
        !          71286: 
        !          71287:                semp->semval -= semop;
        !          71288: 
        !          71289:                if ( (semp->semval == 0)  && (semp->semzcnt != 0) )
        !          71290:                        wakeup( &semp->semzcnt );
        !          71291:        }
        !          71292:        else if ( semop > 0 ) {                 /* want to increment semval */
        !          71293: 
        !          71294:                if ( (semp->semval + semop) > NSEMVAL) {
        !          71295:                
        !          71296:                        u.u_error = ERANGE;
        !          71297:                        return -1;
        !          71298:                }
        !          71299: 
        !          71300:                semp->semval += semop;
        !          71301: 
        !          71302:                if ( semp->semncnt )
        !          71303:                        wakeup( &semp->semncnt );
        !          71304:        }
        !          71305:        else /* if ( semop == 0 ) */ {
        !          71306: 
        !          71307:                if ( semp->semval != 0 )
        !          71308:                        return -1;
        !          71309:        }
        !          71310:        return ret;
        !          71311: }
        !          71312: 
        !          71313: /*
        !          71314:  * Undo a Semaphore Operation.
        !          71315:  */
        !          71316: 
        !          71317: static
        !          71318: semundo( semp, semop )
        !          71319: 
        !          71320: register struct sem * semp;
        !          71321: register int semop;
        !          71322: 
        !          71323: {
        !          71324:        if ( semp->semval -= semop ) {
        !          71325: 
        !          71326:                if ( semp->semncnt )
        !          71327:                        wakeup( &semp->semncnt );
        !          71328:        }
        !          71329:        else {
        !          71330:                if ( semp->semzcnt )
        !          71331:                        wakeup( &semp->semzcnt );
        !          71332:        }
        !          71333: }
        !          71334: 
        !          71335: /*
        !          71336:  * Wait on Semaphore Event
        !          71337:  *
        !          71338:  *     Input:  semidp = pointer to semaphore id structure.
        !          71339:  *             ep     = pointer to semncnt or semzcnt event to wait for.
        !          71340:  *
        !          71341:  *     Action: Sleep on a semaphore event.
        !          71342:  *             If semaphore id has been deleted, error return.
        !          71343:  *             If signal has been received, error return.
        !          71344:  *
        !          71345:  *     Output:  0 = Status ok.
        !          71346:  *             -1 = Error occurred, errno is set.
        !          71347:  */
        !          71348: 
        !          71349: static
        !          71350: semwait( semidp, ep )
        !          71351: 
        !          71352: register struct semid_ds * semidp;
        !          71353: register unsigned short *ep;
        !          71354: {
        !          71355:        unsigned seqn;
        !          71356: 
        !          71357:        seqn = semidp->sem_perm.seq;
        !          71358:        ++(*ep);
        !          71359:        sleep( ep, CVTTOUT, IVTTOUT, SVTTOUT );
        !          71360: 
        !          71361:        if (semidp->sem_perm.seq != seqn ) {    /* semaphore id gone */
        !          71362:                u.u_error = EIDRM;
        !          71363:                return -1;
        !          71364:        }
        !          71365: 
        !          71366:        --(*ep);
        !          71367: 
        !          71368:        if ( SELF->p_ssig && nondsig() ) {      /* signal received */
        !          71369:                u.u_error = EINTR;
        !          71370:                return -1;
        !          71371:        }
        !          71372:        return 0;
        !          71373: }
        !          71374: @
        !          71375: 
        !          71376: 
        !          71377: 1.3
        !          71378: log
        !          71379: @update provided by hal
        !          71380: @
        !          71381: text
        !          71382: @@
        !          71383: 
        !          71384: 
        !          71385: 1.2
        !          71386: log
        !          71387: @new version provided y hal for v321
        !          71388: @
        !          71389: text
        !          71390: @@
        !          71391: 
        !          71392: 
        !          71393: 1.1
        !          71394: log
        !          71395: @Initial revision
        !          71396: @
        !          71397: text
        !          71398: @@
        !          71399: 0707070064030106421004440000030000030000011777770507310700400006000000006410/newbits/kernel/USRSRC/i8086/drv/RCS/semcon.c,vhead     1.4;
        !          71400: branch   ;
        !          71401: access   ;
        !          71402: symbols  ;
        !          71403: locks    bin:1.4; strict;
        !          71404: comment  @ * @;
        !          71405: 
        !          71406: 
        !          71407: 1.4
        !          71408: date     91.06.20.14.53.18;  author bin;  state Exp;
        !          71409: branches ;
        !          71410: next     1.3;
        !          71411: 
        !          71412: 1.3
        !          71413: date     91.06.18.08.14.41;  author bin;  state Exp;
        !          71414: branches ;
        !          71415: next     1.2;
        !          71416: 
        !          71417: 1.2
        !          71418: date     91.06.17.12.35.53;  author bin;  state Exp;
        !          71419: branches ;
        !          71420: next     1.1;
        !          71421: 
        !          71422: 1.1
        !          71423: date     91.06.10.10.25.18;  author bin;  state Exp;
        !          71424: branches ;
        !          71425: next     ;
        !          71426: 
        !          71427: 
        !          71428: desc
        !          71429: @initial version prov by hal
        !          71430: @
        !          71431: 
        !          71432: 
        !          71433: 1.4
        !          71434: log
        !          71435: @update provided by hal
        !          71436: @
        !          71437: text
        !          71438: @/* $Header: /usr/src/sys/i8086/drv/RCS/semcon.c,v 2.1 88/09/03 13:11:55 src Exp $
        !          71439:  *
        !          71440:  *     The  information  contained herein  is a trade secret  of INETCO
        !          71441:  *     Systems, and is confidential information.   It is provided under
        !          71442:  *     a license agreement,  and may be copied or disclosed  only under
        !          71443:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          71444:  *     this  material  without  the express  written  authorization  of
        !          71445:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          71446:  *
        !          71447:  *     Copyright (c) 1987, 1985, 1984.
        !          71448:  *     An unpublished work by INETCO Systems, Ltd.
        !          71449:  *     All rights reserved.
        !          71450:  */
        !          71451: 
        !          71452: /*
        !          71453:  * System V Compatible Semaphore Device Driver
        !          71454:  *
        !          71455:  *     This device driver provides System V compatible semaphore operations.
        !          71456:  *     Operations are performed through the semaphore device (/dev/sem).
        !          71457:  *     and are implemented as ioctl calls from semctl, semget, semop
        !          71458:  *     utilities.
        !          71459:  *
        !          71460:  *                     Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
        !          71461:  *
        !          71462:  * $Log:       /usr/src/sys/i8086/drv/RCS/semcon.c,v $
        !          71463:  * Revision 2.1        88/09/03  13:11:55      src
        !          71464:  * *** empty log message ***
        !          71465:  * 
        !          71466:  * Revision 1.1        88/03/24  17:06:26      src
        !          71467:  * Initial revision
        !          71468:  * 
        !          71469:  * 87/03/02    Allan Cornish           /usr/src/sys/i8086/drv/semcon.c
        !          71470:  * Semioctl() now supports long key [was short] on SEMGET operations.
        !          71471:  * This allows compatability with System V.
        !          71472:  *
        !          71473:  * 85/08/06    Allan Cornish
        !          71474:  * Sem.c split into configuration (semcon.c) and implementation (sem.c).
        !          71475:  * Semload() renamed to seminit().
        !          71476:  *
        !          71477:  * 85/07/03    Allan Cornish
        !          71478:  * Eliminated semopen() and semclose() functions.
        !          71479:  *
        !          71480:  * 84/09/30    Allan Cornish
        !          71481:  * Initial Revision.
        !          71482:  */
        !          71483: 
        !          71484: #include <coherent.h>
        !          71485: #include <types.h>
        !          71486: #include <uproc.h>
        !          71487: #include <errno.h>
        !          71488: #include <con.h>
        !          71489: #include <sem.h>
        !          71490: 
        !          71491: /*
        !          71492:  * Functions.
        !          71493:  */
        !          71494: 
        !          71495: int seminit();
        !          71496: int semioctl();
        !          71497: int nulldev();
        !          71498: int nonedev();
        !          71499: 
        !          71500: /*
        !          71501:  * Device Configuration.
        !          71502:  */
        !          71503: 
        !          71504: CON semcon = {
        !          71505:        DFCHR,                  /* Flags                        */
        !          71506:        23,                     /* Major Index                  */
        !          71507:        nulldev,                /* Open                         */
        !          71508:        nulldev,                /* Close                        */
        !          71509:        nonedev,                /* Block                        */
        !          71510:        nonedev,                /* Read                         */
        !          71511:        nonedev,                /* Write                        */
        !          71512:        semioctl,               /* Ioctl                        */
        !          71513:        nulldev,                /* Power fail                   */
        !          71514:        nulldev,                /* Timeout                      */
        !          71515:        seminit,                /* Load                         */
        !          71516:        nulldev                 /* Unload                       */
        !          71517: };
        !          71518: 
        !          71519: /*
        !          71520:  * Semaphore Device Ioctl.
        !          71521:  */
        !          71522: 
        !          71523: static
        !          71524: semioctl( dev, com, vec )
        !          71525: 
        !          71526: dev_t dev;
        !          71527: int com;
        !          71528: register int *vec;
        !          71529: 
        !          71530: {
        !          71531:        switch ( com ) {
        !          71532: 
        !          71533:        case SEMCTL:
        !          71534:                putuwd( vec+0,
        !          71535:                        usemctl(getuwd( vec+1 ),
        !          71536:                                getuwd( vec+2 ),
        !          71537:                                getuwd( vec+3 ),
        !          71538:                                getuwd( vec+4 ) ));
        !          71539:                return;
        !          71540: 
        !          71541:        case SEMGET:
        !          71542:                putuwd( vec+0,
        !          71543:                        usemget(getuwd( vec+1 ),
        !          71544:                                getuwd( vec+2 ),
        !          71545:                                getuwd( vec+3 ),
        !          71546:                                getuwd( vec+4 ) ));
        !          71547:                return;
        !          71548: 
        !          71549:        case SEMOP:
        !          71550:                putuwd( vec+0,
        !          71551:                        usemop( getuwd( vec+1 ),
        !          71552:                                getuwd( vec+2 ),
        !          71553:                                getuwd( vec+3 ) ));
        !          71554:                return;
        !          71555: 
        !          71556:        default:
        !          71557:                u.u_error = EINVAL;
        !          71558:                return;
        !          71559:        }
        !          71560: }
        !          71561: @
        !          71562: 
        !          71563: 
        !          71564: 1.3
        !          71565: log
        !          71566: @update provided by hal
        !          71567: @
        !          71568: text
        !          71569: @@
        !          71570: 
        !          71571: 
        !          71572: 1.2
        !          71573: log
        !          71574: @new version provided y hal for v321
        !          71575: @
        !          71576: text
        !          71577: @@
        !          71578: 
        !          71579: 
        !          71580: 1.1
        !          71581: log
        !          71582: @Initial revision
        !          71583: @
        !          71584: text
        !          71585: @@
        !          71586: 0707070064030106401004440000030000030000011777770507310700500006100000002314/newbits/kernel/USRSRC/i8086/drv/RCS/semstub.c,vhead     1.1;
        !          71587: branch   ;
        !          71588: access   ;
        !          71589: symbols  ;
        !          71590: locks    bin:1.1; strict;
        !          71591: comment  @ * @;
        !          71592: 
        !          71593: 
        !          71594: 1.1
        !          71595: date     91.06.10.10.25.19;  author bin;  state Exp;
        !          71596: branches ;
        !          71597: next     ;
        !          71598: 
        !          71599: 
        !          71600: desc
        !          71601: @initial version prov by hal
        !          71602: @
        !          71603: 
        !          71604: 
        !          71605: 
        !          71606: 1.1
        !          71607: log
        !          71608: @Initial revision
        !          71609: @
        !          71610: text
        !          71611: @/* $Header: /usr/src/sys/i8086/drv/RCS/semstub.c,v 2.1 88/09/03 13:12:04 src Exp $
        !          71612:  *
        !          71613:  *     The  information  contained herein  is a trade secret  of INETCO
        !          71614:  *     Systems, and is confidential information.   It is provided under
        !          71615:  *     a license agreement,  and may be copied or disclosed  only under
        !          71616:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          71617:  *     this  material  without  the express  written  authorization  of
        !          71618:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          71619:  *
        !          71620:  *     Copyright (c) 1985
        !          71621:  *     An unpublished work by INETCO Systems, Ltd.
        !          71622:  *     All rights reserved.
        !          71623:  */
        !          71624: 
        !          71625: /*
        !          71626:  * Semaphore Device Driver Stub.
        !          71627:  *
        !          71628:  *                     Author: Allan Cornish, INETCO Systems Ltd., Nov 1986.
        !          71629:  *
        !          71630:  * $Log:       /usr/src/sys/i8086/drv/RCS/semstub.c,v $
        !          71631:  * Revision 2.1        88/09/03  13:12:04      src
        !          71632:  * *** empty log message ***
        !          71633:  * 
        !          71634:  * Revision 1.1        88/03/24  17:06:29      src
        !          71635:  * Initial revision
        !          71636:  * 
        !          71637:  * 85/11/21    Allan Cornish           /usr/src/sys/i8086/drv/semstub.c
        !          71638:  * Initial Revision.
        !          71639:  */
        !          71640: 
        !          71641: semexit()
        !          71642: {
        !          71643: }
        !          71644: @
        !          71645: 0707070064030106411004440000030000030000011777770507310700500005500000012562/newbits/kernel/USRSRC/i8086/drv/RCS/shm.c,vhead     1.4;
        !          71646: branch   ;
        !          71647: access   ;
        !          71648: symbols  ;
        !          71649: locks    bin:1.4; strict;
        !          71650: comment  @ * @;
        !          71651: 
        !          71652: 
        !          71653: 1.4
        !          71654: date     91.06.20.14.53.22;  author bin;  state Exp;
        !          71655: branches ;
        !          71656: next     1.3;
        !          71657: 
        !          71658: 1.3
        !          71659: date     91.06.18.08.14.52;  author bin;  state Exp;
        !          71660: branches ;
        !          71661: next     1.2;
        !          71662: 
        !          71663: 1.2
        !          71664: date     91.06.17.12.36.00;  author bin;  state Exp;
        !          71665: branches ;
        !          71666: next     1.1;
        !          71667: 
        !          71668: 1.1
        !          71669: date     91.06.10.10.25.21;  author bin;  state Exp;
        !          71670: branches ;
        !          71671: next     ;
        !          71672: 
        !          71673: 
        !          71674: desc
        !          71675: @initial version prov by hal
        !          71676: @
        !          71677: 
        !          71678: 
        !          71679: 1.4
        !          71680: log
        !          71681: @update provided by hal
        !          71682: @
        !          71683: text
        !          71684: @/* $Header: /usr/src/sys/i8086/drv/RCS/shm.c,v 2.1 88/09/03 13:12:17 src Exp $
        !          71685:  *
        !          71686:  *     The  information  contained herein  is a trade secret  of INETCO
        !          71687:  *     Systems, and is confidential information.   It is provided under
        !          71688:  *     a license agreement,  and may be copied or disclosed  only under
        !          71689:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          71690:  *     this  material  without  the express  written  authorization  of
        !          71691:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          71692:  *
        !          71693:  *     Copyright (c) 1985, 1984
        !          71694:  *     An unpublished work by INETCO Systems, Ltd.
        !          71695:  *     All rights reserved.
        !          71696:  */
        !          71697: 
        !          71698: /*
        !          71699:  * System V Compatible Shared Memory Device Driver
        !          71700:  *
        !          71701:  *     This device driver provides System V compatible shared memory operations.
        !          71702:  *     Operations are performed through the shared memory device (/dev/shm).
        !          71703:  *     and are implemented as ioctl calls from shmctl, shmget, shmat, shmdt
        !          71704:  *     utilities.
        !          71705:  *
        !          71706:  *                     Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
        !          71707:  *
        !          71708:  * $Log:       /usr/src/sys/i8086/drv/RCS/shm.c,v $
        !          71709:  * Revision 2.1        88/09/03  13:12:17      src
        !          71710:  * *** empty log message ***
        !          71711:  * 
        !          71712:  * Revision 1.1        88/03/24  17:06:32      src
        !          71713:  * Initial revision
        !          71714:  * 
        !          71715:  * 85/10/16    Allan Cornish
        !          71716:  * Driver split into shmcon.c, shm.c [driver implementation, System V shm].
        !          71717:  *
        !          71718:  * 85/07/22    Allan Cornish
        !          71719:  * Shmget, shmctl now return immediately if u.u_error is set.
        !          71720:  *
        !          71721:  * 85/07/19    Allan Cornish
        !          71722:  * Separation of io_seek into shmid and off improved through type casting.
        !          71723:  * Errno set to EFAULT if fucopy() or ufcopy() report no bytes transferred.
        !          71724:  * This would occur if an user address fault occurred.
        !          71725:  *
        !          71726:  * 85/07/03    Allan Cornish
        !          71727:  * Replaced use of EDOM with EIDRM.
        !          71728:  * Replaced shmaccess() by calls to ipcaccess(), increasing shared ipc code.
        !          71729:  * Eliminated shmlock() and shmunlock(), as shared memory use is synchronous.
        !          71730:  */
        !          71731: 
        !          71732: #include <coherent.h>
        !          71733: #include <sched.h>
        !          71734: #include <types.h>
        !          71735: #include <uproc.h>
        !          71736: #include <errno.h>
        !          71737: #include <stat.h>
        !          71738: #include <con.h>
        !          71739: #include <seg.h>
        !          71740: #include <shm.h>
        !          71741: 
        !          71742: #ifndef        EIDRM
        !          71743: #define        EIDRM   EDOM
        !          71744: #endif
        !          71745: 
        !          71746: 
        !          71747: extern unsigned NSHMID;
        !          71748: extern struct shmid_ds *shmids;
        !          71749: extern struct seg **shmsegs;
        !          71750: 
        !          71751: /*
        !          71752:  * Shmctl - Shared Memory Control Operations.
        !          71753:  */
        !          71754: 
        !          71755: ushmctl( shmid, cmd, buf )
        !          71756: 
        !          71757: unsigned shmid;
        !          71758: int cmd;
        !          71759: struct shmid_ds *buf;
        !          71760: 
        !          71761: {
        !          71762:        register struct shmid_ds *idp;
        !          71763:        int ret = 0;
        !          71764: 
        !          71765:        if ( u.u_error )
        !          71766:                return -1;
        !          71767: 
        !          71768:        if ( shmid >= NSHMID ) {
        !          71769:                u.u_error = EINVAL;
        !          71770:                return -1;
        !          71771:        }
        !          71772: 
        !          71773:        idp = &shmids[shmid];
        !          71774: 
        !          71775:        if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
        !          71776:                u.u_error = EINVAL;
        !          71777:                return -1;
        !          71778:        }
        !          71779: 
        !          71780:        switch ( cmd ) {
        !          71781: 
        !          71782:        case IPC_STAT:
        !          71783:                if ( ( ipcaccess( &idp->shm_perm ) & SHM_R ) == 0 ) {
        !          71784:                        u.u_error = EACCES;
        !          71785:                        return -1;
        !          71786:                }
        !          71787:                kucopy( idp, buf, sizeof(struct shmid_ds) );
        !          71788:                ret = 0;
        !          71789:                break;
        !          71790: 
        !          71791:        case IPC_SET:
        !          71792:                if ( (u.u_uid != 0) && (u.u_uid != idp->shm_perm.uid) ) {
        !          71793:                        u.u_error = EPERM;
        !          71794:                        ret = -1;
        !          71795:                        break;
        !          71796:                }
        !          71797:                idp->shm_perm.uid   = getuwd( &(buf->shm_perm.uid ) );
        !          71798:                idp->shm_perm.gid   = getuwd( &(buf->shm_perm.gid ) );
        !          71799:                idp->shm_perm.mode &= ~0777;
        !          71800:                idp->shm_perm.mode |= getuwd(&(buf->shm_perm.mode)) & 0777;
        !          71801:                ret = 0;
        !          71802:                break;
        !          71803: 
        !          71804:        case IPC_RMID:
        !          71805:                if ( (u.u_uid != 0) && (u.u_uid != idp->shm_perm.uid) ) {
        !          71806:                        u.u_error = EPERM;
        !          71807:                        ret = -1;
        !          71808:                        break;
        !          71809:                }
        !          71810:                idp->shm_perm.seq++;
        !          71811:                sfree(shmsegs[shmid]);
        !          71812:                idp->shm_perm.mode = 0;
        !          71813:                ret = 0;
        !          71814:                break;
        !          71815: 
        !          71816:        default:
        !          71817:                u.u_error = EINVAL;
        !          71818:                ret = -1;
        !          71819:        }
        !          71820: 
        !          71821:        return ret;
        !          71822: }
        !          71823: 
        !          71824: /*
        !          71825:  * Shmget - Get Shared Memory Segment
        !          71826:  */
        !          71827: 
        !          71828: ushmget( skey, size, shmflg )
        !          71829: 
        !          71830: key_t skey;
        !          71831: unsigned size;
        !          71832: int shmflg;
        !          71833: 
        !          71834: {
        !          71835:        register struct shmid_ds *idp;
        !          71836:        struct shmid_ds *freeidp = 0;
        !          71837: 
        !          71838:        if ( u.u_error )
        !          71839:                return -1;
        !          71840: 
        !          71841:        for ( idp = &shmids[NSHMID]; --idp >= shmids; ) {
        !          71842: 
        !          71843:                if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
        !          71844: 
        !          71845:                        if ((freeidp == 0) ||
        !          71846:                            (freeidp->shm_ctime > idp->shm_ctime))
        !          71847:                                freeidp = idp;
        !          71848:                        continue;
        !          71849:                }
        !          71850: 
        !          71851: #ifdef IPC_PRIVATE
        !          71852:                if (skey == IPC_PRIVATE)
        !          71853:                        continue;
        !          71854: #endif
        !          71855: 
        !          71856:                if (skey == idp->shm_perm.key) {                /* found! */
        !          71857: 
        !          71858:                        if ( (shmflg & IPC_CREAT) && (shmflg & IPC_EXCL) ) {
        !          71859: 
        !          71860:                                u.u_error = EEXIST;
        !          71861:                                return -1;
        !          71862:                        }
        !          71863: 
        !          71864:                        if ((idp->shm_perm.mode & shmflg) != (shmflg&0777)) {
        !          71865: 
        !          71866:                                u.u_error = EACCES;
        !          71867:                                return -1;
        !          71868:                        }
        !          71869: 
        !          71870:                        if ( idp->shm_segsz < size ) {
        !          71871: 
        !          71872:                                u.u_error = EINVAL;
        !          71873:                                return -1;
        !          71874:                        }
        !          71875: 
        !          71876:                        return idp - shmids;
        !          71877:                }
        !          71878:        }
        !          71879: 
        !          71880:        if ( !(shmflg & IPC_CREAT) ) {
        !          71881:                u.u_error = ENOENT;
        !          71882:                return -1;
        !          71883:        }
        !          71884: 
        !          71885:        if ( freeidp == 0 ) {
        !          71886:                u.u_error = ENOSPC;
        !          71887:                return -1;
        !          71888:        }
        !          71889: 
        !          71890:        idp = freeidp;
        !          71891: 
        !          71892:        if ((shmsegs[idp - shmids] = salloc((size_t) size, SFNSWP)) == NULL){
        !          71893:                u.u_error = ENOSPC;
        !          71894:                return -1;
        !          71895:        }
        !          71896: 
        !          71897:        idp->shm_segsz = size;
        !          71898:        idp->shm_atime = 0;
        !          71899:        idp->shm_dtime = 0;
        !          71900:        idp->shm_ctime = timer.t_time;
        !          71901:        idp->shm_cpid  = SELF->p_pid;
        !          71902:        idp->shm_perm.cuid = idp->shm_perm.uid = u.u_uid;
        !          71903:        idp->shm_perm.cgid = idp->shm_perm.gid = u.u_gid;
        !          71904:        idp->shm_perm.mode = (shmflg & 0777) | IPC_ALLOC;
        !          71905:        idp->shm_perm.key  = skey;
        !          71906: 
        !          71907: #ifdef IPC_PRIVATE
        !          71908:        if ( skey == IPC_PRIVATE )
        !          71909:                idp->shm_perm.mode |= SHM_DEST;
        !          71910: #endif
        !          71911: 
        !          71912:        return idp - shmids;
        !          71913: }
        !          71914: @
        !          71915: 
        !          71916: 
        !          71917: 1.3
        !          71918: log
        !          71919: @update provided by hal
        !          71920: @
        !          71921: text
        !          71922: @@
        !          71923: 
        !          71924: 
        !          71925: 1.2
        !          71926: log
        !          71927: @new version provided y hal for v321
        !          71928: @
        !          71929: text
        !          71930: @@
        !          71931: 
        !          71932: 
        !          71933: 1.1
        !          71934: log
        !          71935: @Initial revision
        !          71936: @
        !          71937: text
        !          71938: @@
        !          71939: 0707070064030106371004440000030000030000011777770507310700700006000000014064/newbits/kernel/USRSRC/i8086/drv/RCS/shmcon.c,vhead     1.4;
        !          71940: branch   ;
        !          71941: access   ;
        !          71942: symbols  ;
        !          71943: locks    bin:1.4; strict;
        !          71944: comment  @ * @;
        !          71945: 
        !          71946: 
        !          71947: 1.4
        !          71948: date     91.06.20.14.53.29;  author bin;  state Exp;
        !          71949: branches ;
        !          71950: next     1.3;
        !          71951: 
        !          71952: 1.3
        !          71953: date     91.06.18.08.14.59;  author bin;  state Exp;
        !          71954: branches ;
        !          71955: next     1.2;
        !          71956: 
        !          71957: 1.2
        !          71958: date     91.06.17.12.36.12;  author bin;  state Exp;
        !          71959: branches ;
        !          71960: next     1.1;
        !          71961: 
        !          71962: 1.1
        !          71963: date     91.06.10.10.25.23;  author bin;  state Exp;
        !          71964: branches ;
        !          71965: next     ;
        !          71966: 
        !          71967: 
        !          71968: desc
        !          71969: @initial version prov by hal
        !          71970: @
        !          71971: 
        !          71972: 
        !          71973: 1.4
        !          71974: log
        !          71975: @update provided by hal
        !          71976: @
        !          71977: text
        !          71978: @/* $Header: /usr/src/sys/i8086/drv/RCS/shmcon.c,v 2.1 88/09/03 13:12:40 src Exp $
        !          71979:  *
        !          71980:  *     The  information  contained herein  is a trade secret  of INETCO
        !          71981:  *     Systems, and is confidential information.   It is provided under
        !          71982:  *     a license agreement,  and may be copied or disclosed  only under
        !          71983:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          71984:  *     this  material  without  the express  written  authorization  of
        !          71985:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          71986:  *
        !          71987:  *     Copyright (c) 1987, 1985, 1984.
        !          71988:  *     An unpublished work by INETCO Systems, Ltd.
        !          71989:  *     All rights reserved.
        !          71990:  */
        !          71991: 
        !          71992: /*
        !          71993:  * System V Compatible Shared Memory Device Driver
        !          71994:  *
        !          71995:  *     This device driver provides System V compatible shared memory operations.
        !          71996:  *     Operations are performed through the shared memory device (/dev/shm).
        !          71997:  *     and are implemented as ioctl calls from shmctl, shmget, shmat, shmdt
        !          71998:  *     utilities.
        !          71999:  *
        !          72000:  *                     Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
        !          72001:  *
        !          72002:  * $Log:       /usr/src/sys/i8086/drv/RCS/shmcon.c,v $
        !          72003:  * Revision 2.1        88/09/03  13:12:40      src
        !          72004:  * *** empty log message ***
        !          72005:  * 
        !          72006:  * Revision 1.1        88/03/24  17:06:36      src
        !          72007:  * Initial revision
        !          72008:  * 
        !          72009:  * 87/03/02    Allan Cornish           /usr/src/sys/i8086/drv/shmcon.c
        !          72010:  * Shmioctl() now supports long key [was short] on SHMGET operations.
        !          72011:  * This allows compatability with System V.
        !          72012:  *
        !          72013:  * 85/10/16    Allan Cornish
        !          72014:  * Driver split into shmcon.c, shm.c [driver implementation, system V shm].
        !          72015:  *
        !          72016:  * 85/07/22    Allan Cornish
        !          72017:  * Shmget, shmctl now return immediately if u.u_error is set.
        !          72018:  *
        !          72019:  * 85/07/19    Allan Cornish
        !          72020:  * Separation of io_seek into shmid and off improved through type casting.
        !          72021:  * Errno set to EFAULT if fucopy() or ufcopy() report no bytes transferred.
        !          72022:  * This would occur if an user address fault occurred.
        !          72023:  *
        !          72024:  * 85/07/03    Allan Cornish
        !          72025:  * Replaced use of EDOM with EIDRM.
        !          72026:  * Replaced shmaccess() by calls to ipcaccess(), increasing shared ipc code.
        !          72027:  * Eliminated shmlock() and shmunlock(), as shared memory use is synchronous.
        !          72028:  *
        !          72029:  * 84/09/30    Allan Cornish
        !          72030:  * Initial Revision.
        !          72031:  */
        !          72032: 
        !          72033: #include <coherent.h>
        !          72034: #include <sched.h>
        !          72035: #include <types.h>
        !          72036: #include <uproc.h>
        !          72037: #include <errno.h>
        !          72038: #include <stat.h>
        !          72039: #include <con.h>
        !          72040: #include <seg.h>
        !          72041: #include <shm.h>
        !          72042: 
        !          72043: #ifndef        EIDRM
        !          72044: #define        EIDRM   EDOM
        !          72045: #endif
        !          72046: 
        !          72047: /*
        !          72048:  * Functions.
        !          72049:  */
        !          72050: 
        !          72051: int shmload();
        !          72052: int shmread();
        !          72053: int shmwrite();
        !          72054: int shmioctl();
        !          72055: int nulldev();
        !          72056: int nonedev();
        !          72057: 
        !          72058: /*
        !          72059:  * Device Configuration.
        !          72060:  */
        !          72061: 
        !          72062: CON shmcon = {
        !          72063:        DFCHR,                  /* Flags                        */
        !          72064:        24,                     /* Major Index                  */
        !          72065:        nulldev,                /* Open                         */
        !          72066:        nulldev,                /* Close                        */
        !          72067:        nonedev,                /* Block                        */
        !          72068:        shmread,                /* Read                         */
        !          72069:        shmwrite,               /* Write                        */
        !          72070:        shmioctl,               /* Ioctl                        */
        !          72071:        nulldev,                /* Power fail                   */
        !          72072:        nulldev,                /* Timeout                      */
        !          72073:        shmload,                /* Load                         */
        !          72074:        nulldev                 /* Unload                       */
        !          72075: };
        !          72076: 
        !          72077: unsigned NSHMID = 16;
        !          72078: struct shmid_ds *shmids;
        !          72079: struct seg **shmsegs;
        !          72080: 
        !          72081: /*
        !          72082:  * Shared Memory Device Load.
        !          72083:  */
        !          72084: 
        !          72085: static
        !          72086: shmload()
        !          72087: {
        !          72088:        register struct shmid_ds * idp;
        !          72089:        register unsigned wanted;
        !          72090:        
        !          72091:        if ( NSHMID == 0 )
        !          72092:                return 0;
        !          72093: 
        !          72094:        wanted = NSHMID * (sizeof(struct shmid_ds) + sizeof(struct seg *));
        !          72095: 
        !          72096:        if ( (shmids = kalloc( wanted )) == 0 ) {
        !          72097: 
        !          72098:                printf("couldn't kalloc %u shared memory ids\n", NSHMID );
        !          72099:                NSHMID = 0;
        !          72100:                return 0;
        !          72101:        }
        !          72102:        shmsegs = (struct seg *) &shmids[ NSHMID ];
        !          72103: 
        !          72104:        for ( idp = &shmids[NSHMID]; --idp >= shmids; )
        !          72105:                idp->shm_perm.mode = 0;
        !          72106: 
        !          72107:        return 0;
        !          72108: }
        !          72109: 
        !          72110: /*
        !          72111: ** Shared Memory Read.
        !          72112: */
        !          72113: 
        !          72114: static
        !          72115: shmread( dev, iop )
        !          72116: 
        !          72117: dev_t dev;
        !          72118: register IO *iop;
        !          72119: 
        !          72120: {
        !          72121:        register struct shmid_ds *idp;
        !          72122:        int shmid;
        !          72123:        unsigned off;
        !          72124:        faddr_t faddr;
        !          72125: 
        !          72126:        off   = ((unsigned *) &iop->io_seek)[0];
        !          72127:        shmid = ((unsigned *) &iop->io_seek)[1];
        !          72128: 
        !          72129:        if ( shmid >= NSHMID ) {
        !          72130:                u.u_error = EFAULT;
        !          72131:                return -1;
        !          72132:        }
        !          72133: 
        !          72134:        idp = &shmids[shmid];
        !          72135: 
        !          72136:        if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
        !          72137:                u.u_error = EIDRM;
        !          72138:                return -1;
        !          72139:        }
        !          72140: 
        !          72141:        if ( (ipcaccess(&idp->shm_perm) & SHM_R) == 0 ) {
        !          72142:                u.u_error = EACCES;
        !          72143:                return -1;
        !          72144:        }
        !          72145: 
        !          72146:        if ( ((long) off + iop->io_ioc) > idp->shm_segsz ) {
        !          72147:                u.u_error = EFAULT;
        !          72148:                return -1;
        !          72149:        }
        !          72150: 
        !          72151:        FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr);
        !          72152:        FP_OFF(faddr) = off;
        !          72153: 
        !          72154:        if ( ! fucopy( faddr, iop->io_base, iop->io_ioc ) ) {
        !          72155:                u.u_error = EFAULT;
        !          72156:                return -1;
        !          72157:        }
        !          72158: 
        !          72159:        iop->io_ioc = 0;
        !          72160:        return 0;
        !          72161: }
        !          72162: 
        !          72163: /*
        !          72164: ** Shared Memory Write.
        !          72165: */
        !          72166: 
        !          72167: static
        !          72168: shmwrite( dev, iop )
        !          72169: 
        !          72170: dev_t dev;
        !          72171: register IO *iop;
        !          72172: 
        !          72173: {
        !          72174:        register struct shmid_ds *idp;
        !          72175:        int shmid;
        !          72176:        unsigned off;
        !          72177:        faddr_t faddr;
        !          72178: 
        !          72179:        off   = ((unsigned *) &iop->io_seek)[0];
        !          72180:        shmid = ((unsigned *) &iop->io_seek)[1];
        !          72181: 
        !          72182:        if ( shmid >= NSHMID ) {
        !          72183:                u.u_error = EFAULT;
        !          72184:                return -1;
        !          72185:        }
        !          72186: 
        !          72187:        idp = &shmids[shmid];
        !          72188: 
        !          72189:        if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
        !          72190:                u.u_error = EIDRM;
        !          72191:                return -1;
        !          72192:        }
        !          72193: 
        !          72194:        if ( (ipcaccess(&idp->shm_perm) & SHM_W) == 0 ) {
        !          72195:                u.u_error = EFAULT;
        !          72196:                return -1;
        !          72197:        }
        !          72198: 
        !          72199:        if ( ((long) off + iop->io_ioc) > idp->shm_segsz ) {
        !          72200:                u.u_error = EFAULT;
        !          72201:                return -1;
        !          72202:        }
        !          72203: 
        !          72204:        FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr);
        !          72205:        FP_OFF(faddr) = off;
        !          72206: 
        !          72207:        if ( ! ufcopy(iop->io_base, faddr, iop->io_ioc ) ) {
        !          72208:                u.u_error = EFAULT;
        !          72209:                return -1;
        !          72210:        }
        !          72211: 
        !          72212:        iop->io_ioc = 0;
        !          72213:        return 0;
        !          72214: }
        !          72215: 
        !          72216: /*
        !          72217:  * Shared Memory Device Ioctl.
        !          72218:  *
        !          72219:  *     Input:  dev = shared memory device (/dev/shm).
        !          72220:  *             com = command to perform (SHMCTL, SHMGET,SHMAT).
        !          72221:  *             vec = pointer to return value, followed by parameters.
        !          72222:  *
        !          72223:  *     Action: Initiate command.
        !          72224:  *             Save commands return value in *vec.
        !          72225:  */
        !          72226: 
        !          72227: static
        !          72228: shmioctl( dev, com, vec )
        !          72229: 
        !          72230: dev_t dev;
        !          72231: int com;
        !          72232: int *vec;
        !          72233: 
        !          72234: {
        !          72235:        switch ( com ) {
        !          72236: 
        !          72237:        case SHMCTL:
        !          72238:                putuwd( vec+0,
        !          72239:                        ushmctl( getuwd( vec+1 ),
        !          72240:                                 getuwd( vec+2 ),
        !          72241:                                 getuwd( vec+3 ) ));
        !          72242:                break;
        !          72243: 
        !          72244:        case SHMGET:
        !          72245:                putuwd( vec+0,
        !          72246:                        ushmget( getuwd( vec+1 ),
        !          72247:                                 getuwd( vec+2 ),
        !          72248:                                 getuwd( vec+3 ),
        !          72249:                                 getuwd( vec+4 ) ));
        !          72250:                break;
        !          72251: 
        !          72252:        default:
        !          72253:                u.u_error = EINVAL;
        !          72254:                break;
        !          72255:        }
        !          72256: }
        !          72257: @
        !          72258: 
        !          72259: 
        !          72260: 1.3
        !          72261: log
        !          72262: @update provided by hal
        !          72263: @
        !          72264: text
        !          72265: @@
        !          72266: 
        !          72267: 
        !          72268: 1.2
        !          72269: log
        !          72270: @new version provided y hal for v321
        !          72271: @
        !          72272: text
        !          72273: @@
        !          72274: 
        !          72275: 
        !          72276: 1.1
        !          72277: log
        !          72278: @Initial revision
        !          72279: @
        !          72280: text
        !          72281: @@
        !          72282: 0707070064030106351004440000030000030000011777770507310701100006100000002320/newbits/kernel/USRSRC/i8086/drv/RCS/shmstub.c,vhead     1.1;
        !          72283: branch   ;
        !          72284: access   ;
        !          72285: symbols  ;
        !          72286: locks    bin:1.1; strict;
        !          72287: comment  @ * @;
        !          72288: 
        !          72289: 
        !          72290: 1.1
        !          72291: date     91.06.10.10.25.25;  author bin;  state Exp;
        !          72292: branches ;
        !          72293: next     ;
        !          72294: 
        !          72295: 
        !          72296: desc
        !          72297: @initial version prov by hal
        !          72298: @
        !          72299: 
        !          72300: 
        !          72301: 
        !          72302: 1.1
        !          72303: log
        !          72304: @Initial revision
        !          72305: @
        !          72306: text
        !          72307: @/* $Header: /usr/src/sys/i8086/drv/RCS/shmstub.c,v 2.1 88/09/03 13:12:52 src Exp $
        !          72308:  *
        !          72309:  *     The  information  contained herein  is a trade secret  of INETCO
        !          72310:  *     Systems, and is confidential information.   It is provided under
        !          72311:  *     a license agreement,  and may be copied or disclosed  only under
        !          72312:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          72313:  *     this  material  without  the express  written  authorization  of
        !          72314:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          72315:  *
        !          72316:  *     Copyright (c) 1985
        !          72317:  *     An unpublished work by INETCO Systems, Ltd.
        !          72318:  *     All rights reserved.
        !          72319:  */
        !          72320: 
        !          72321: /*
        !          72322:  * Shared Memory Device Driver Stub.
        !          72323:  *
        !          72324:  *                     Author: Allan Cornish, INETCO Systems Ltd., Nov 1986.
        !          72325:  *
        !          72326:  * $Log:       /usr/src/sys/i8086/drv/RCS/shmstub.c,v $
        !          72327:  * Revision 2.1        88/09/03  13:12:52      src
        !          72328:  * *** empty log message ***
        !          72329:  * 
        !          72330:  * Revision 1.1        88/03/24  17:06:39      src
        !          72331:  * Initial revision
        !          72332:  * 
        !          72333:  * 85/11/21    Allan Cornish           /usr/src/sys/i8086/drv/shmstub.c
        !          72334:  * Initial Revision.
        !          72335:  */
        !          72336: 
        !          72337: shmexit()
        !          72338: {
        !          72339: }
        !          72340: @
        !          72341: 0707070064030106341005550000030000030000011777770507310701100005700000032115/newbits/kernel/USRSRC/i8086/drv/RCS/ssqtest,vhead     1.1;
        !          72342: branch   ;
        !          72343: access   ;
        !          72344: symbols  ;
        !          72345: locks    bin:1.1; strict;
        !          72346: comment  @# @;
        !          72347: 
        !          72348: 
        !          72349: 1.1
        !          72350: date     91.06.10.10.28.07;  author bin;  state Exp;
        !          72351: branches ;
        !          72352: next     ;
        !          72353: 
        !          72354: 
        !          72355: desc
        !          72356: @initial version prov by hal
        !          72357: @
        !          72358: 
        !          72359: 
        !          72360: 
        !          72361: 1.1
        !          72362: log
        !          72363: @Initial revision
        !          72364: @
        !          72365: text
        !          72366: @&�" |�����F� �P��́�VWU����F��"P�l       ���F�P�CP�V&���F���]�CC.;��t�.�gdrw��k�
P�&P����F��F��F��~��EW�p���v��GP�    ���D��F��t
�~��E�P�k�ฎ�!��F��tP����~��E�P��뽸�P�����~�qt�B��&P�����]_^�VWU��>�u�F����+��~�E���F�>���~����E�F����]_^�VWU�졜]_^�VWU��P�>�~/���F��>�&u
        !          72367: +�������>�����>��E����F��F���]_^�VWU��FP�N&P�P��]_^�VWU��F
        !          72368: P�v�:��]_^�VWU����F�P�v���P�v����F
        !          72369: P�F�P� ����]_^�VWU���X�F��^
        !          72370: �F
        !          72371: ��F��^��F�����-�CC.;��u5.�g
        !          72372:      
        !          72373:  %3CCC��v�v�����P�

�����u����^�G~�OS�W����^���F�^�*�ȋ�;�t��vW������^��F�����=*u�&�+��F��~�t�^��F������F���0|&��9!�F�.�.�        �ȋ��-0�F��^��F������Ճ�lu�&�+��F���hu�&�+��F�~�u�~�t�^��F������ƻ=�CC.;��uH.�g"%DEFNOX[cdefnosx3`�����:���s��n&P�&P�
���2��F��F�
        !          72374: ��F��F���F��F���F��F��F�P�v��v��v����F�V�~�u�T�~�t�)��~�t�^
        !          72375: �F
        !          72376: ���W��~��^
        !          72377: �F
        !          72378: ��F��F�����F��F�P�v��v������F��F��F��F�~�u��&�~�t���~�t9�^
        !          72379: �F
        !          72380: ��F��F��F��F���G��G��G��|��^
        !          72381: �F
        !          72382: ��F��F��F��F���G��O��F��F��^��F�����=^u�&�+��F��~�t�^��F������t��]t�^��F��ƈ���^���F��F��^�G~�OS�W����^���F��^��*���N�~�u�F�&�^�G~�OS�W����^���F��^��*���F�!&��v�������F�"&�F�&�~�u�^
        !          72383: �F
        !          72384: ��F��F����t`W�v��[���u�&�+�;F�uF�F��~�u
        !          72385: �^��F��Lj�N�u����ċ^�G~�OS�W����^���F��^��*��뛃��t
        !          72386: �vW�R ���~�t�~�t�����cu����^������~�u�^�Gt�����F��]_^�VWU����v
        !          72387: �~�F��F��~�� ~� �^��v�����F��~�-u�&�+��F��u�~�+u-�^�G~�OS�W����^���F�^�*�F��^��^;?|m�ui�~�0t�
        !          72388: �^�^�G~�OS�W����^���F�^�*�F��^��;�|+�~�xt�� ��^�G��OS�W���F��^��^;?��F�-W�F�=
        !          72389: }!�F�-7�F�=
        !          72390: }�F�-0�F��|�~�    ;v���uY�F�F�uQ�F�-x�F��uD�F���F�V�F�P�ƙRP�L��+F�V�F��V��^�G~�f��^���F�^�*��\��v�v��{���~�t�F��V��
�F��V����؃���]_^�VWU���%+��F߉F݃~
        !          72391: ~�~
        !          72392:  ~�F
        !          72393:  �^��^�;F
        !          72394: |�
        !          72395: &�^�G~�OS�W����^���Fۋ^ۊ*��{�CC.;��t��.�g$ 
        !          72396:  +-.0123456789Ee����������������                              �uw�^��^��]��t��uaG�^��F݋ƈ���&'����t
        !          72397: ��&t��u��׃�|2��-��ȃ�����t
        !          72398: ��t��u�믃�t��u���vV����^���F�P������]_^�VWU��~�E~�MW�^�W����^�?��*��= t׃�
        !          72399: t҃�   t͋�]_^�
        !          72400: VWU��FP�^&P�j��]_^�VWU��F
        !          72401: P�v�T��]_^�VWU����F�P��P�v����F
        !          72402: P�F�P�)���N�}�F��F�P+�P�V����      �~��F����]_^�VWU���^�F
        !          72403: �F��^���F�F��^��F����=%t/�u���^�O}
�GSW�W
        !          72404: ���ԋ^���F��^��Lj���F� �F����F����^��F������-u�F�&�^��F������F���0u�F�0�^��F������*u'�^��F���F��}
        !          72405: �F�&�؉F�^��F�����0�F���0|&��9!�F�.�.`�ȋ��-0�F�^��F�����Ճ�.uY�^��F������*u�^��F���F�^��F�����0�F���0|&��9!�F�.�.`�ȋ��-0�F�^��F�����Ճ�lu&�^��F������dt��ot
        !          72406: ��ut��xu��%�����F��F����F�&�ǻ��CC.;��t��.�gDOUXcdefgorsuxI���
���?
�0D�^��F���F�~�}�؉F��F�-�
        !          72407: P�v�V� �������
        !          72408: P�^��F��7������^���W�F�V�F��~�y���؃��F�V��F�-�
        !          72409: P�v��v�V�?��뤸
        !          72410: P�^��w�7V�*�����F�������V�v��v�W�F�����F��j�F��^���F��u�F��F��F��F�����F�?t�~�|��+F�;F�~�N�-�F���F�F��^��F���^����^��7�v������F��F�F�+ƉF��}�F��~�uz�~�tG�~�0uA�^��?-u9�^�O}�GS�^��F���P�^�W
        !          72411: ����^���F��^��F����^���F��N��t#�^�O} �GS�v��ŋ^���F��^��F���;v�v;�^�O}�GS�^��F���P�^�W
        !          72412: ���ڋ^���F��^��F����^�����~�u�*��F��N��u���^�O}�GS�v��W
        !          72413: ���܋^���F��^��F���ȋ�]_^�VWU����v
        !          72414: �F��F��N��^����+��v���t �N��F��F��+��v�ڊ���^������N��^������^��?t�F�F�F��F����^���F��]_^�VWU����v�~�n��N�^���ǙRP�v�v
        !          72415: ����F�V��t4�N�F�F�ǙRP�v�v
        !          72416: �����؊���^��F�V�F
        !          72417: �V��N�F�F�F
        !          72418: �؊���^��^�?t
��F�F��F���Ƌ�]_^�
        !          72419: VWU��v
        !          72420: �~�tS�|�u"�D��D
        !          72421: c�D�L�d��F�D�F�-�|�u�D��Ձ|Fu�D �ǁ|�u�DB빸��]_^�VWU��v�D��D
        !          72422: ��D�d��D]_^�VWU��v�D��D
        !          72423: ��+D�D�~�D+�D�d��D]_^�VWU��v�DF�D
        !          72424: ��D�d��D]_^�VWU��v�D��4����؉D�D]_^�VWU��v�~
        !          72425: W�U���M}
�EWV�U
        !          72426: ���
        !          72427: ���ƈ*�]_^�VWU��v�~
        !          72428: �<t!�M}�EW��P�U
        !          72429: ���   �����F��]_^�VWU��v�|u:�Du(�D
�P�������t��^&u�P����D�u�DF�D
        !          72430: ��A�Du�t��^&u�D��D
        !          72431: 6�D��D��D
        !          72432: ��D
�P���D��D�D]_^�VWU����&P+�PP�v����؋ʉ^��N����u  ���u+���F�+�.�6��‹�]_^�VWU��vV�$���V�T��]_^�VWU��v�~
        !          72433: W����WV�U
        !          72434: ��]_^�VWU��L&��&&r�<t�4�$������]_^�VWU������v���]_^�VWU��v�D&u����/V�/�����D
�P�����|t�Du  �t�(���D��]_^�VWU��v�D��D�uI�+D���~W�t�D
�P�����;�t�>u�|�D;u�D����D+���L����]_^�VWU��vV�����t����i�>h&6u
        !          72435: �^&P�o�����D+DP�t�D
�P����؉D=&u�>t�L��D믃|u�L@@룋D�D)D�<��*�]_^�VWU��P�v�>h&6u
        !          72436: �^&P������D��&P�F�P�D
�P���=��t�t�F�*���>t
        !          72437: �L���L@@�����]_^�VWU��v�D���]_^�VWU��v�~
        !          72438: W����t�����E+EH�E����*�*�]_^�VWU��P�v�~
        !          72439: �ƈF��E��Eu4W�:���u)�&P�F�P�E
�P����=&u��*���>t�M�����]_^�VWU��v�DtV�T���D;w        V������8�&P�<+|�ǙRP�D
�P����؋ʃ��u
        !          72440: ���u������D�D+�]_^�VWU����F�P�AP�v�J���|�&�+���]_^�VWU��~��׹��+��O��+�]_^�VWU��~&P�n&P�����&P�n&P����&P�����]_^�VWU����v+ɉN�N��N�����F��V���F���F�Fꘋ؋���u��=+t
        !          72441: =-u
�N�&��F������u����0�~��ws��~���w��F�tH�v��v��������F�P�v��s
        !          72442: �������
        !          72443: ��������F��F��F��F��)�v��v������F��F��F��F�N��F�&�Ǚ�<�F��&�F��V��������F��V��Ǚ�F�V�F��V��������F�V�F�V�F��V��F�u���N��&���.u�F�u�N�����F�t0�v��v��������F�P�v��    �������
        !          72444: ��������v��v������F��F��F��F��et��Eu^��F����=+t
        !          72445: =-u
�N���F�����F���t�F�.�.��ȋ��-0�F���F�������F�t�F�)F���F�&F��~�t�v������>�F�P����
        !          72446: �F�&t�F��F��F��F��6      ���F��F��F��F���]_^�
        !          72447: VWU����>�&t+���F%��F�;Fs�F�F���&��&�v���&����=��u��&&�~�&v}�n�&�~�s��F��҃>�&u��&�ƉF���&��&�/;6�&u���F��D�F���&���&-���E�F��u��&�F�-
&���F���&-����F��E�&��]_^�VWU����~u+����F%���F�;Fr�+��6�&��&�F��F��N��t$��N���&uC+��~�t
        !          72448: �F�%�����D����;6�&t�P��&P�P�0&�����v������u���t���F�%��&��F���&�F�;F�s��뜋F�)F��F�=s�%���F����F���&��F����F���&�F���&���&�D��]_^�VWU��~tE�FHH���<��s�P��&P�P����'�&�ρ������;�&t
        !          72449: ��&�&u�6�&]_^�VWU��̀��]_^�VWU��+�P�I�����~t$��F��;�v�����V�$���>u��]_^�͆��Ͷ��͓��̓��̈́��͑��VWU��v
        !          72450: ���f��V�B������tV+�PW�����]_^�VWU��F
        !          72451: �VWU��F
        !          72452: P�v�t�t�t�4�L��
        !          72453: ��D��D��D��]_^�[�6�6�6�6��VWU��^�VWU��^+��VWU��^�VWU��^�����F��G�����V���؈F��F���%�u�V�v�~
        !          72454: �F�&�F���~򥥥�F���V���؈F��F���%�u�w�����F��v�~ꥥ��V��v��~�F�N�+N�}�^��^��^����^��هV��v�~�F��9~�V��v�~�F�N��^����������n�
        !          72455: �����������N��^�:�t�vF�~�v�V�:�u��&tA�&�u�u�u
�t9�y���E��������rI��&������s     ��������A�����������؉�6�>���]_^���������&�������VWU��+�*��F�y=�ط��7VWU��+�*��F�)VWU��*��V
        !          72456: �F�y���؃����
VWU��*��V
        !          72457: �F+ɋ��t������r����������
        !          72458: ψ    ��+���]_^�VWU��v�VWU��v���F��u�G���֋L��t���v��Ċ�*�*��-�~�=&v���F��N��L�̀+ۊf*�����D�f       �ߋD&�f��*��$�f
�ߋF     ��N�+���͋D�f��͋D&�f
��͉~�+��F��f����D�f
�ʃ��F��f
��x
�n�&�f�������+�+��f�f�����V��&���F�u��
        !          72459: �u��f����߉>�      ��]_^ø������n��أ��������&�+���&����VWU��S�؋�S+��y
        !          72460: �^�W���V�F�y���؃���r&FRP�V
        !          72461: �F�y���؃�FRP�V���
        !          72462: ��s���؃�[��]_^ËË܋_��Ë܍_VWU��P�V
        !          72463: �F+�+�� ��������;wrw;?r+?w@@��[��]_^��Ë܋_��Ë܍_VWU��P�F�'����F�g��F
        !          72464: �'��֋�[��]_^��Ë܋_��Ë܍_VWU��P�v
        !          72465: �~+�+�� ��������;Wrw;r+W��[��]_^�VWU��v�~
        !          72466: �E�E;uW����u���ƈ*�=
        !          72467: uW�����t������*�]_^�VWU��v�F��D�D��F
        !          72468: �؉D�|&�}�D��D
        !          72469: ���D
        !          72470: ���]_^�VWU��v
        !          72471: �D���]_^�VWU��v
        !          72472: �D��<��F�*�]_^�VWU��N�F
        !          72473: �~��F]_^�VWU��v�f
        !          72474: ��:�t
        !          72475: �u����N��]_^�W�+������_�VWU��v�|����؋�=}%����狅���������
        !          72476: �����&2�Ʊ��H���
        !          72477: P���������������
        !          72478: ���
        !          72479: ������q��}!����狅�������������냃�&.�Ʊ��H���
        !          72480: P������������������������}�½����H]_^��VWU��v�VWU��v���F��u����[&�ҋ\����V�
        !          72481: �u�M&�Ċ�*��+��x�=&&v�6&�F��^
�π�N�~    �f*��������؃���8�F��+ы�+���+\�|��xD�ϋ|&+���>��Њ$+��[����Ӌ��L�̀;�t�r�@@���F���d+��s
        !          72482: �N|�s��ϋ>�D&�f+�ʸ��&�$�f����������t�N$|&L���T�΀�;�u����F��V�~��N��^�
        !          72483: �x     H�����������������s��H
        !          72484: �y��u"�6�>���f����߉�     ��]_^ø������V����ܣ��{NULL}0123456789ABCDEF<w>rite/<r>ead/<d>elete/<q>uit:  %cNode #%2d written to tail of queue
        !          72485: Node #%2d read from head of queue
        !          72486: Can't read head of queue - queue empty
        !          72487: Node #%2d deleted from head of queue
        !          72488: Can't delete head of queue - queue empty
        !          72489: Done
        !          72490: Bad format in scanf
        !          72491:      
        !          72492:  N&^&n&��&��&&��You must compile with the -f flag to include printf() floating point.
        !          72493: Bad pointer in malloc.
        !          72494: Bad pointer in free.
        !          72495: �@@�������>ףp=
        !          72496: �#=�O��n�;e�X��9�GG��'8il��7�6Bz�Ք��4�a�w�+3��6A_p�1�������/�$���/.�Po ̼�,
�KB.�*�\  5�$4)��:�|�'�@@ B�CzE@@GP�H$tJ��L ��M(knO�Q@@�C�R��hT*�V�� �W�1�_cY��[�p+��ŝu@@@@@@@@@@@@@@@@@@PPPPP@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@�                      &&&&&&&&&&&&&&&&&&&&&&&&&&          @@ahigh  
        !          72497: ahigh      
        !          72498: ahigh      
        !          72499: ahigh      
        !          72500: free_qbhigh  bhigh     bhigh     bhigh     ddlmulZmain_ retzW!retz�__a_first_�&errno_claim     claim     claim     __a_count_�&_fgetb_�_fgetc_Fssq_wr_tail_�retinf�"retinf�ddrmuld_fpinit_�_dtefg_�Count _stropen_�atof_.write_$lop ��exp     ��exp     ��calloc_,fscanf_�&rop     ��pa     sbrk_�fputs_�pb     
        !          72501: _stderr_n&dldivE!_fp_&&malloc_�llmodfprintf_�       _fpac_drdiv;!exit_�dicvt@@dlsub�fclose_l0ssq_rd_head_A&l1.dlcvtdsscanf_�&lrmodl24brk_(dlmul�_fgeteof_�l3Dls   ��_fputb_�l4Xllsgndrsub�_fputc_�_stdin_N&environ_ q0 ��l5k_stdout_^&rp     q1     ��overf�!rp r0     ��rp     b     
        !          72502: q2      ��_ctype_q3 ��drmul�dzero& signs     ��dpush�vldivrrs     ��sprintf_�  ungetc_bssq_rm_head_M&done�"vlrem�lrsgns3    ��done�ducvtVllmul�dvcvt�fflush_Vi memset_�scanf_�&vrdiv{l lrmul�l l     l     vrrem�vlmul�sign     ��sign     ��_fputt_6r r     r     __a_scanp_�&printf_�      alow        alow     alow     alow     lseek_blow blow     blow     blow     strchr_ u _pow10_4 close_vrmul�v String     String     String     strlen_�abort_�index_ oerror_:!bptr     negreg*_exit_dladd�lexp ��finit_�ioctl_read_ fptr ��_fpseek_Visatty_�Char     
        !          72503: Char      
        !          72504: rexp      ��dradd�_finish_�_fginit_�@
        !          72505: 0707070064030106331004440000030000030000011777770507310701400006100000003133/newbits/kernel/USRSRC/i8086/drv/RCS/ssqtest.c,vhead     1.1;
        !          72506: branch   ;
        !          72507: access   ;
        !          72508: symbols  ;
        !          72509: locks    bin:1.1; strict;
        !          72510: comment  @ * @;
        !          72511: 
        !          72512: 
        !          72513: 1.1
        !          72514: date     91.06.10.10.28.14;  author bin;  state Exp;
        !          72515: branches ;
        !          72516: next     ;
        !          72517: 
        !          72518: 
        !          72519: desc
        !          72520: @initial version prov by hal
        !          72521: @
        !          72522: 
        !          72523: 
        !          72524: 
        !          72525: 1.1
        !          72526: log
        !          72527: @Initial revision
        !          72528: @
        !          72529: text
        !          72530: @/*
        !          72531:  * File:       ssqtest.c
        !          72532:  *
        !          72533:  * Purpose:    unit test of routines in ssqueue.c
        !          72534:  *
        !          72535:  * $Log$
        !          72536:  */
        !          72537: 
        !          72538: /*
        !          72539:  * Includes.
        !          72540:  */
        !          72541: #include <stdio.h>
        !          72542: #include <coherent.h>
        !          72543: #include <sys/buf.h>
        !          72544: #include <scsiwork.h>
        !          72545: 
        !          72546: /*
        !          72547:  * Definitions.
        !          72548:  *     Constants.
        !          72549:  *     Macros with argument lists.
        !          72550:  *     Typedefs.
        !          72551:  *     Enums.
        !          72552:  */
        !          72553: 
        !          72554: /*
        !          72555:  * Global Data.
        !          72556:  *     Import Variables.
        !          72557:  *     Export Variables.
        !          72558:  *     Local Variables.
        !          72559:  */
        !          72560: 
        !          72561: /*
        !          72562:  * Functions.
        !          72563:  *     Import Functions.
        !          72564:  *     Export Functions.
        !          72565:  *     Local Functions.
        !          72566:  */
        !          72567: extern char * calloc();
        !          72568: extern void ssq_wr_tail();
        !          72569: extern scsi_work_t * ssq_rd_head();
        !          72570: extern scsi_work_t * ssq_rm_head();
        !          72571: 
        !          72572: void main();
        !          72573: 
        !          72574: /*
        !          72575:  * main()
        !          72576:  */
        !          72577: void main()
        !          72578: {
        !          72579:        char cmd;
        !          72580:        int node_num = 0;
        !          72581:        scsi_work_t * sw;
        !          72582: 
        !          72583:        do {
        !          72584:                printf("<w>rite/<r>ead/<d>elete/<q>uit: ");
        !          72585:                scanf(" %c", &cmd);
        !          72586:                switch(cmd){
        !          72587:                case 'w':
        !          72588:                        sw = (scsi_work_t *)calloc(1, sizeof(*sw));
        !          72589:                        node_num++;
        !          72590:                        sw->sw_type = node_num;
        !          72591:                        ssq_wr_tail(sw);
        !          72592:                        printf("Node #%2d written to tail of queue\n", node_num);
        !          72593:                        break;
        !          72594:                case 'r':
        !          72595:                        if (sw = ssq_rd_head())
        !          72596:                                printf("Node #%2d read from head of queue\n", sw->sw_type);
        !          72597:                        else
        !          72598:                                printf("Can't read head of queue - queue empty\n");
        !          72599:                        break;
        !          72600:                case 'd':
        !          72601:                        if (sw = ssq_rm_head()) {
        !          72602:                                free(sw);
        !          72603:                                printf("Node #%2d deleted from head of queue\n", sw->sw_type);
        !          72604:                        } else
        !          72605:                                printf("Can't delete head of queue - queue empty\n");
        !          72606:                        break;
        !          72607:                }
        !          72608:        } while (cmd != 'q');
        !          72609:        printf("Done\n");
        !          72610: }
        !          72611: @
        !          72612: 0707070064030104221004440000030000030000011777770507310701500005400000056003/newbits/kernel/USRSRC/i8086/drv/RCS/st.c,vhead     1.2;
        !          72613: branch   ;
        !          72614: access   ;
        !          72615: symbols  ;
        !          72616: locks    bin:1.2; strict;
        !          72617: comment  @ * @;
        !          72618: 
        !          72619: 
        !          72620: 1.2
        !          72621: date     91.06.20.14.54.42;  author bin;  state Exp;
        !          72622: branches ;
        !          72623: next     1.1;
        !          72624: 
        !          72625: 1.1
        !          72626: date     91.06.10.10.28.32;  author bin;  state Exp;
        !          72627: branches ;
        !          72628: next     ;
        !          72629: 
        !          72630: 
        !          72631: desc
        !          72632: @initial version prov by hal
        !          72633: @
        !          72634: 
        !          72635: 
        !          72636: 1.2
        !          72637: log
        !          72638: @update provided by hal
        !          72639: @
        !          72640: text
        !          72641: @/* (-lgl
        !          72642:  *     COHERENT Driver Kit Version 1.1.0
        !          72643:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          72644:  *     All rights reserved. May not be copied without permission.
        !          72645:  -lgl) */
        !          72646: /*
        !          72647:  * This is a driver for the
        !          72648:  * Archive SC-400 Series Tape Controller.
        !          72649:  */
        !          72650: #include       <sys/coherent.h>
        !          72651: #include       <sys/buf.h>
        !          72652: #include       <sys/con.h>
        !          72653: #include       <sys/const.h>
        !          72654: #include       <sys/inode.h>
        !          72655: #include       <sys/mtioctl.h>
        !          72656: #include       <sys/sched.h>
        !          72657: #include       <sys/seg.h>
        !          72658: #include       <sys/stat.h>
        !          72659: #include       <sys/uproc.h>
        !          72660: #include       <errno.h>
        !          72661: 
        !          72662: /*
        !          72663:  * Fixed parameters.
        !          72664:  */
        !          72665: #define        STMAJ   12                      /* Major device */
        !          72666: #define        NCMDS   8                       /* Max # chained commands */
        !          72667: 
        !          72668: /*
        !          72669:  * Configurable parameters
        !          72670:  */
        !          72671: int    STIRQ   = 3;                    /* IRQ Level 3 */
        !          72672: int    STPORT  = 0x200;                /* I/O Port    */
        !          72673: int    STDMA   = 1;                    /* DMA Channel */
        !          72674: 
        !          72675: #define        BIT(n)          (1 << (n))
        !          72676: 
        !          72677: /*
        !          72678:  * Forward referenced functions.
        !          72679:  */
        !          72680: void   stcache();
        !          72681: void   stflush();
        !          72682: void   stinvoke();
        !          72683: void   ststart();
        !          72684: void   stintr();
        !          72685: void   strecov();
        !          72686: void   stnext();
        !          72687: void   stdiag();
        !          72688: void   stspin();
        !          72689: 
        !          72690: /*
        !          72691:  * Driver configuration.
        !          72692:  */
        !          72693: int    stload();
        !          72694: int    stuload();
        !          72695: int    stopen();
        !          72696: int    stclose();
        !          72697: int    stread();
        !          72698: int    stwrite();
        !          72699: int    stioctl();
        !          72700: void   stwatch();
        !          72701: int    nulldev();
        !          72702: int    nonedev();
        !          72703: 
        !          72704: CON    stcon   = {
        !          72705:        DFCHR,                          /* Flags        */
        !          72706:        STMAJ,                          /* Major index  */
        !          72707:        stopen,                         /* Open         */
        !          72708:        stclose,                        /* Close        */
        !          72709:        nonedev,                        /* Block        */
        !          72710:        stread,                         /* Read         */
        !          72711:        stwrite,                        /* Write        */
        !          72712:        stioctl,                        /* Ioctl        */
        !          72713:        nulldev,                        /* Powerfail    */
        !          72714:        stwatch,                        /* Timeout      */
        !          72715:        stload,                         /* Load         */
        !          72716:        stuload                         /* Unload       */
        !          72717: };
        !          72718: 
        !          72719: /*
        !          72720:  * I/O Port Addresses
        !          72721:  */
        !          72722: #define        DATA_REG        (STPORT+0)      /* Data register */
        !          72723: #define        CTRL_REG        (STPORT+1)      /* Control/Status register */
        !          72724: #define        DMAGO_REG       (STPORT+2)      /* DMA Go register */
        !          72725: #define        DMARST_REG      (STPORT+3)      /* DMA reset register */
        !          72726: 
        !          72727: /*
        !          72728:  * Control Register
        !          72729:  */
        !          72730: #define        CR_RSTSAC       BIT(7)          /* 1 -> reset control micro     */
        !          72731: #define        CR_REQ          BIT(6)          /* 1 -> request to LSI chip     */
        !          72732: #define        CR_IEN          BIT(5)          /* 1 -> enables interrupts      */
        !          72733: #define        CR_DNIEN        BIT(4)          /* 1 -> enable DONE interrupts  */
        !          72734: 
        !          72735: /*
        !          72736:  * Status Register
        !          72737:  */
        !          72738: #define        SR_IRQF         BIT(7)          /* 1 -> Interrupt Request Flag  */
        !          72739: #define        SR_NRDY         BIT(6)          /* 0 -> Ready                   */
        !          72740: #define        SR_NEXC         BIT(5)          /* 0 -> Exception               */
        !          72741: #define        SR_DONE         BIT(4)          /* 1 -> DMA Done                */
        !          72742: #define        SR_TO_PC        BIT(3)          /* 1 -> Direction is to PC      */
        !          72743: 
        !          72744: /*
        !          72745:  * Controller Commands.
        !          72746:  */
        !          72747: #define        CC_SELECT       0x01            /* Select Drive 0               */
        !          72748: #define        CC_LOCK         0x11            /* Select Drive 0 and Lock      */
        !          72749: #define        CC_BOT          0x21            /* Rewind to beginning of tape  */
        !          72750: #define        CC_ERASE        0x22            /* Completely erase cartridge   */
        !          72751: #define        CC_TENSION      0x24            /* Wind tape to BOT, EOT, BOT   */
        !          72752: #define        CC_AUTO         0x25            /* Select auto-initialization   */
        !          72753: #define        CC_QIC11        0x26            /* Select QIC-11 media format   */
        !          72754: #define        CC_QIC24        0x27            /* Select QIC-24 media format   */
        !          72755: #define        CC_WRITE        0x40            /* Write to tape                */
        !          72756: #define        CC_WFM          0x60            /* Write file mark              */
        !          72757: #define        CC_READ         0x80            /* Read from tape               */
        !          72758: #define        CC_RFM          0xA0            /* Skip past next file mark     */
        !          72759: #define        CC_SENSE        0xC0            /* Read controller status       */
        !          72760: 
        !          72761: /*
        !          72762:  * Sense Status Bytes 0 and 1.
        !          72763:  */
        !          72764: #define        SS0_FIL         BIT(0)          /* File Mark Detected           */
        !          72765: #define        SS0_BNL         BIT(1)          /* Bad Block Not located        */
        !          72766: #define        SS0_UDA         BIT(2)          /* Unrecoverable data error     */
        !          72767: #define        SS0_EOM         BIT(3)          /* End of media                 */
        !          72768: #define        SS0_WRP         BIT(4)          /* Write Protected Cartridge    */
        !          72769: #define        SS0_USL         BIT(5)          /* Unselected Drive             */
        !          72770: #define        SS0_CNI         BIT(6)          /* Cartridge Not In Place       */
        !          72771: #define        SS0_ERR         (SS0_BNL+SS0_UDA+SS0_USL+SS0_CNI)
        !          72772: 
        !          72773: #define        SS1_POR         BIT(0)          /* Power on Reset Occurred      */
        !          72774: #define        SS1_BOM         BIT(3)          /* Beginning of media           */
        !          72775: #define        SS1_MBD         BIT(4)          /* Marginal Block Detected      */
        !          72776: #define        SS1_NDT         BIT(5)          /* No Data Detected             */
        !          72777: #define        SS1_ILL         BIT(6)          /* Illegal Command              */
        !          72778: #define        SS1_ERR         (SS1_NDT+SS1_ILL)
        !          72779: 
        !          72780: /*
        !          72781:  * Device States.
        !          72782:  */
        !          72783: #define        SDEAD   0               /* controller not found    */
        !          72784: #define        SIDLE   1               /* controller idle         */
        !          72785: #define        SCMD    2               /* initiating command      */
        !          72786: #define        SRUN    3               /* performing command      */
        !          72787: #define        SRDWR   4               /* starting read/write     */
        !          72788: #define        SBLOCK  5               /* performing read/write   */
        !          72789: #define        SBLEND  6               /* concluding block i/o    */
        !          72790: #define        SSENSE  7               /* reading status bytes    */
        !          72791: #define        SSDONE  8               /* concluding status sense */
        !          72792: 
        !          72793: /*
        !          72794:  * Driver State Information.
        !          72795:  */
        !          72796: struct st_s {
        !          72797:        int     st_state;
        !          72798:        int     st_mode;                /* IPR or IPW                   */
        !          72799:        int     st_iocmd;               /* CC_READ or CC_WRITE          */
        !          72800:        int     st_cmd;                 /* last command executed        */
        !          72801:        int     st_cmds[NCMDS];         /* list of chained commands     */
        !          72802:        int     st_ncmds;               /* num of chained commands      */
        !          72803:        int     st_iswr;
        !          72804:        int     st_wasio;
        !          72805:        int     st_iseof;
        !          72806:        int     st_error;
        !          72807:        paddr_t st_paddr;
        !          72808:        fsize_t st_resid;
        !          72809:        fsize_t st_size;
        !          72810:        saddr_t st_sel;
        !          72811:        SEG *   st_seg;
        !          72812:        char    st_status[6];
        !          72813:        int     st_nstat;
        !          72814:        int     st_rdys;                /* number of ready watchdogs    */
        !          72815:        int     st_nlost;               /* number of lost interrupts    */
        !          72816: } st;
        !          72817: 
        !          72818: /**
        !          72819:  *
        !          72820:  * void
        !          72821:  * stload()            -- initialize tape device
        !          72822:  *
        !          72823:  *     Action: Reset tape controller and drive.
        !          72824:  *             Seize tape interrupt vector.
        !          72825:  *
        !          72826:  *     Note:   If the tape controller is present and operational,
        !          72827:  *             a interrupt will occur and set st.st_state to SIDLE.
        !          72828:  */
        !          72829: static
        !          72830: stload()
        !          72831: {
        !          72832:        /*
        !          72833:         * Paranoia - Turn off DMA.
        !          72834:         * Should already be turned off.
        !          72835:         */
        !          72836:        dmaoff( STDMA );
        !          72837: 
        !          72838:        /*
        !          72839:         * Reset tape controller and drive
        !          72840:         */
        !          72841:        outb( CTRL_REG, CR_RSTSAC );
        !          72842: 
        !          72843:        /*
        !          72844:         * Wait at least 25 microseconds
        !          72845:         */
        !          72846:        stspin( 25 );
        !          72847: 
        !          72848:        /*
        !          72849:         * Terminate reset condition
        !          72850:         */
        !          72851:        outb( CTRL_REG, CR_IEN );
        !          72852: 
        !          72853:        /*
        !          72854:         * Seize tape interrupt vector.
        !          72855:         */
        !          72856:        setivec( STIRQ, &stintr );
        !          72857: }
        !          72858: 
        !          72859: /**
        !          72860:  *
        !          72861:  * stuload( dev )              -- Unload tape device.
        !          72862:  * dev_t dev;
        !          72863:  */
        !          72864: stuload( dev )
        !          72865: dev_t dev;
        !          72866: {
        !          72867:        /*
        !          72868:         * Turn off DMA.
        !          72869:         */
        !          72870:        dmaoff( STDMA );
        !          72871: 
        !          72872:        /*
        !          72873:         * Release tape interrupt vector.
        !          72874:         */
        !          72875:        clrivec( STIRQ );
        !          72876: 
        !          72877:        /*
        !          72878:         * Disable tape interrupts.
        !          72879:         */
        !          72880:        outb( CTRL_REG, 0 );
        !          72881: }
        !          72882: 
        !          72883: /**
        !          72884:  *
        !          72885:  * stopen( dev, mode )         -- open tape device
        !          72886:  * dev_t dev;
        !          72887:  * int mode;
        !          72888:  *
        !          72889:  *     Input:  dev  = tape device to be opened.
        !          72890:  *             mode = desired access mode.
        !          72891:  *
        !          72892:  *     Action: Refuse access if tape drive does not exist or is in use.
        !          72893:  *             Refuse simultaneous read and write access.
        !          72894:  *             Refuse access if cartridge is not inserted in tape drive.
        !          72895:  *             Refuse write access to a write protected cartridge.
        !          72896:  *             Allocate tape cache.
        !          72897:  *             Initialize device state.
        !          72898:  *             Lock tape cartridge.
        !          72899:  */
        !          72900: static
        !          72901: stopen( dev, mode )
        !          72902: register dev_t dev;
        !          72903: register int   mode;
        !          72904: {
        !          72905:        int s;
        !          72906: 
        !          72907:        /*
        !          72908:         * Refuse access if no tape drive.
        !          72909:         */
        !          72910:        if ( st.st_state == SDEAD ) {
        !          72911:                u.u_error = ENXIO;
        !          72912:                return;
        !          72913:        }
        !          72914: 
        !          72915:        /*
        !          72916:         * Refuse access if tape drive is already open.
        !          72917:         */
        !          72918:        if ( st.st_mode != 0 ) {
        !          72919:                u.u_error = EDBUSY;
        !          72920:                return;
        !          72921:        }
        !          72922: 
        !          72923:        /*
        !          72924:         * Access must be read-only or write-only.
        !          72925:         */
        !          72926:        if ( (mode != IPR) && (mode != IPW) ) {
        !          72927:                u.u_error = EINVAL;
        !          72928:                return;
        !          72929:        }
        !          72930: 
        !          72931:        /*
        !          72932:         * Wait for tape drive to become idle.
        !          72933:         */
        !          72934:        if ( stwait() < 0 ) {
        !          72935:                u.u_error = EINTR;
        !          72936:                return;
        !          72937:        }
        !          72938: 
        !          72939:        /*
        !          72940:         * Initialize tape interface.
        !          72941:         */
        !          72942:        s = sphi();
        !          72943:        outb( DMARST_REG, 0 );
        !          72944:        outb( CTRL_REG, CR_IEN );
        !          72945:        spl( s );
        !          72946: 
        !          72947:        /*
        !          72948:         * Obtain tape status.
        !          72949:         */
        !          72950:        stinvoke( CC_SENSE );
        !          72951: 
        !          72952:        /*
        !          72953:         * Wait for tape status.
        !          72954:         */
        !          72955:        if ( stwait() < 0 ) {
        !          72956:                u.u_error = EINTR;
        !          72957:                return;
        !          72958:        }
        !          72959: 
        !          72960:        /*
        !          72961:         * Refuse access if no cartridge.
        !          72962:         */
        !          72963:        if ( st.st_status[0] & (SS0_CNI|SS0_USL) ) {
        !          72964:                u.u_error = EDATTN;
        !          72965:                return;
        !          72966:        }
        !          72967: 
        !          72968:        /*
        !          72969:         * Refuse write access to a write protected cartridge.
        !          72970:         */
        !          72971:        if ( (mode == IPW) && (st.st_status[0] & SS0_WRP) ) {
        !          72972:                u.u_error = EROFS;
        !          72973:                return;
        !          72974:        }
        !          72975: 
        !          72976:        /*
        !          72977:         * Calculate desired cache size in Kbytes.
        !          72978:         */
        !          72979:        st.st_size = minor(dev) & ~0x80;
        !          72980:        if ( st.st_size == 0 )
        !          72981:                st.st_size = 256;
        !          72982: 
        !          72983:        /*
        !          72984:         * Allocate cache
        !          72985:         */
        !          72986:        for ( st.st_size *= 1024; st.st_size != 0; st.st_size -= 1024 )
        !          72987:                if ( st.st_seg = salloc( st.st_size, SFSYST|SFNSWP|SFNCLR ) )
        !          72988:                        break;
        !          72989: 
        !          72990:        /*
        !          72991:         * Refuse access if couldn't allocate cache.
        !          72992:         */
        !          72993:        if ( st.st_seg == 0 ) {
        !          72994:                u.u_error = ENOMEM;
        !          72995:                return;
        !          72996:        };
        !          72997: 
        !          72998:        /*
        !          72999:         * Initialize device state.
        !          73000:         */
        !          73001:        st.st_sel   = FP_SEL(st.st_seg->s_faddr);
        !          73002:        st.st_iswr  = (mode == IPW);
        !          73003:        st.st_paddr = st.st_seg->s_paddr;
        !          73004:        st.st_resid = (mode == IPW) ? st.st_size : 0 ;
        !          73005:        st.st_iocmd = (mode == IPW) ? CC_WRITE : CC_READ ;
        !          73006:        st.st_mode  = mode;
        !          73007:        st.st_iseof = 0;
        !          73008:        st.st_wasio = 0;
        !          73009:        st.st_error = 0;
        !          73010:        st.st_rdys  = 0;
        !          73011:        st.st_nlost = 0;
        !          73012: 
        !          73013:        /*
        !          73014:         * Lock cartridge if at beginning of media.
        !          73015:         */
        !          73016:        if ( st.st_status[1] & SS1_BOM )
        !          73017:                stinvoke( CC_LOCK );
        !          73018: }
        !          73019: 
        !          73020: /**
        !          73021:  *
        !          73022:  * stclose( dev, mode )                -- close tape device
        !          73023:  * dev_t dev;
        !          73024:  * int mode;
        !          73025:  *
        !          73026:  *     Input:  dev  = tape device to be closed.
        !          73027:  *             mode = access mode.
        !          73028:  *
        !          73029:  *     Action: If access mode was for writing, flush the tape cache.
        !          73030:  *             If data was written to tape, write a file mark.
        !          73031:  *             If data was read from tape on the non rewinding device,
        !          73032:  *             read until end of file or an error is encountered.
        !          73033:  *             Rewind the tape if the rewinding device is open.
        !          73034:  *             Unlock the tape cartridge.
        !          73035:  *             Clear tape state and release tape cache memory.
        !          73036:  */
        !          73037: static
        !          73038: stclose( dev, mode )
        !          73039: register dev_t dev;
        !          73040: {
        !          73041:        /*
        !          73042:         * Check if tape was opened for writing.
        !          73043:         */
        !          73044:        if ( st.st_iswr ) {
        !          73045: 
        !          73046:                /*
        !          73047:                 * Flush the tape cache.
        !          73048:                 */
        !          73049:                stflush();
        !          73050: 
        !          73051:                /*
        !          73052:                 * Write a file mark if data was written to tape.
        !          73053:                 */
        !          73054:                if ( st.st_wasio )
        !          73055:                        stinvoke( CC_WFM );
        !          73056:        }
        !          73057: 
        !          73058:        /*
        !          73059:         * Check if non-rewinding device was opened for reading.
        !          73060:         */
        !          73061:        else if ( st.st_wasio && (dev & 0x80 ) ) {
        !          73062: 
        !          73063:                /*
        !          73064:                 * Read file mark if not just past one.
        !          73065:                 */
        !          73066:                if ( (st.st_status[0] & SS0_FIL) == 0 )
        !          73067:                        stinvoke( CC_RFM );
        !          73068:        }
        !          73069: 
        !          73070:        /*
        !          73071:         * Rewinding device.
        !          73072:         */
        !          73073:        if ( (dev & 0x80) == 0 ) {
        !          73074: 
        !          73075:                /*
        !          73076:                 * Wait for controller to idle.
        !          73077:                 */
        !          73078:                while ( stwait() < 0 )
        !          73079:                        ;
        !          73080: 
        !          73081:                /*
        !          73082:                 * Initiate rewind.
        !          73083:                 */
        !          73084:                stinvoke( CC_BOT   );
        !          73085: 
        !          73086:                /*
        !          73087:                 * Unlock the drive [turn off the light].
        !          73088:                 */
        !          73089:                stinvoke( CC_SELECT );
        !          73090:        }
        !          73091: 
        !          73092:        /*
        !          73093:         * Clear tape state, releasing tape cache.
        !          73094:         */
        !          73095:        sfree( st.st_seg );
        !          73096:        st.st_seg  = 0;
        !          73097:        st.st_mode = 0;
        !          73098: }
        !          73099: 
        !          73100: /**
        !          73101:  *
        !          73102:  * stread( dev, iop )  -- tape device read
        !          73103:  * dev_t dev;
        !          73104:  * IO * iop;
        !          73105:  *
        !          73106:  *     Input:  dev = tape device to be read from.
        !          73107:  *             iop = pointer to IO structure.
        !          73108:  *
        !          73109:  *     Action: Transfer data from tape cache to user memory,
        !          73110:  *             filling the cache as required by initiating reads from tape.
        !          73111:  */
        !          73112: 
        !          73113: static
        !          73114: stread( dev, iop )
        !          73115: dev_t  dev;
        !          73116: register IO * iop;
        !          73117: {
        !          73118:        register int n;
        !          73119:        register int ioc;
        !          73120: 
        !          73121:        ioc = iop->io_ioc;
        !          73122:        
        !          73123:        while ( iop->io_ioc > 0 ) {
        !          73124: 
        !          73125:                /*
        !          73126:                 * Check for empty cache.
        !          73127:                 */
        !          73128:                while ( st.st_resid == 0 ) {
        !          73129: 
        !          73130:                        /*
        !          73131:                         * Special handling if end of file was encountered.
        !          73132:                         */
        !          73133:                        if ( st.st_iseof ) {
        !          73134: 
        !          73135:                                /*
        !          73136:                                 * Clear EOF if no data was transferred yet.
        !          73137:                                 */
        !          73138:                                if ( ioc == iop->io_ioc )
        !          73139:                                        st.st_iseof = 0;
        !          73140: 
        !          73141:                                return;
        !          73142:                        }
        !          73143: 
        !          73144:                        /*
        !          73145:                         * Abort on I/O error.
        !          73146:                         */
        !          73147:                        if ( u.u_error = st.st_error ) {
        !          73148:                                stdiag();
        !          73149:                                return;
        !          73150:                        }
        !          73151: 
        !          73152:                        /*
        !          73153:                         * Fill the cache from tape.
        !          73154:                         */
        !          73155:                        stcache();
        !          73156:                }
        !          73157: 
        !          73158:                /*
        !          73159:                 * Determine max data transferable in one chunk.
        !          73160:                 */
        !          73161:                n = iop->io_ioc;
        !          73162:                if ( n > st.st_resid )
        !          73163:                        n = st.st_resid;
        !          73164: 
        !          73165:                /*
        !          73166:                 * Transfer some data from cache to user memory.
        !          73167:                 */
        !          73168:                if ( pucopy( st.st_paddr, iop->io_base, n ) != n )
        !          73169:                        return;
        !          73170: 
        !          73171:                /*
        !          73172:                 * Update addresses and counts.
        !          73173:                 */
        !          73174:                iop->io_base += n;
        !          73175:                iop->io_ioc  -= n;
        !          73176:                st.st_resid  -= n;
        !          73177:                st.st_paddr  += n;
        !          73178:        }
        !          73179: }
        !          73180: 
        !          73181: /**
        !          73182:  *
        !          73183:  * stwrite( dev, iop ) -- write to tape device
        !          73184:  * dev_t dev;
        !          73185:  * IO * iop;
        !          73186:  *
        !          73187:  *     Input:  dev = tape device to be written to.
        !          73188:  *             iop = pointer to IO structure.
        !          73189:  *
        !          73190:  *     Action: Transfer data from user memory to tape cache,
        !          73191:  *             flushing the cache as required by initiating writes to tape.
        !          73192:  */
        !          73193: 
        !          73194: static
        !          73195: stwrite( dev, iop )
        !          73196: dev_t  dev;
        !          73197: register IO *iop;
        !          73198: {
        !          73199:        register int n;
        !          73200: 
        !          73201:        while ( iop->io_ioc > 0 ) {
        !          73202: 
        !          73203:                /*
        !          73204:                 * Determine max data transferable in one chunk.
        !          73205:                 */
        !          73206:                n = iop->io_ioc;
        !          73207:                if ( n > st.st_resid )
        !          73208:                        n = st.st_resid;
        !          73209: 
        !          73210:                /*
        !          73211:                 * Transfer some data from user memory to cache.
        !          73212:                 */
        !          73213:                if ( upcopy( iop->io_base, st.st_paddr, n ) != n )
        !          73214:                        break;
        !          73215: 
        !          73216:                /*
        !          73217:                 * Update addresses and counts.
        !          73218:                 */
        !          73219:                iop->io_base += n;
        !          73220:                iop->io_ioc  -= n;
        !          73221:                st.st_paddr  += n;
        !          73222:                st.st_resid  -= n;
        !          73223: 
        !          73224:                /*
        !          73225:                 * Flush the cache to tape if full.
        !          73226:                 */
        !          73227:                if ( st.st_resid == 0 )
        !          73228:                        stflush();
        !          73229: 
        !          73230:                /*
        !          73231:                 * Abort on I/O error.
        !          73232:                 */
        !          73233:                if ( u.u_error = st.st_error ) {
        !          73234:                        stdiag();
        !          73235:                        return;
        !          73236:                }
        !          73237:        }
        !          73238: }
        !          73239: 
        !          73240: /**
        !          73241:  *
        !          73242:  * stioctl( dev, cmd, arg )    -- service tape I/O control requests
        !          73243:  * int dev;
        !          73244:  * int cmd;
        !          73245:  * int arg;
        !          73246:  *
        !          73247:  *     Input:  dev = tape device to be serviced
        !          73248:  *             cmd = ioctl command
        !          73249:  *             arg = argument to ioctl command
        !          73250:  *
        !          73251:  *     Action: Service tape I/O control request.
        !          73252:  */
        !          73253: 
        !          73254: static
        !          73255: stioctl( dev, cmd, arg )
        !          73256: {
        !          73257:        if ( st.st_iswr )
        !          73258:                stflush();
        !          73259: 
        !          73260:        st.st_error = EINVAL;
        !          73261: 
        !          73262:        switch ( cmd ) {
        !          73263: 
        !          73264:        case MTERASE:
        !          73265:                stinvoke( CC_ERASE );
        !          73266:                break;
        !          73267: 
        !          73268:        case MTTENSE:
        !          73269:                stinvoke( CC_TENSION );
        !          73270:                break;
        !          73271: 
        !          73272:        case MTREWIND:
        !          73273:                if ( st.st_iswr && st.st_wasio ) {
        !          73274:                        stinvoke( CC_WFM );
        !          73275:                        st.st_wasio = 0;
        !          73276:                }
        !          73277:                stinvoke( CC_BOT );
        !          73278:                break;
        !          73279: 
        !          73280:        case MTWEOF:
        !          73281:                if ( st.st_iswr ) {
        !          73282:                        stinvoke( CC_WFM );
        !          73283:                        st.st_wasio = 0;
        !          73284:                }
        !          73285:                break;
        !          73286: 
        !          73287:        case MTFSKIP:
        !          73288:                if ( ! st.st_iswr ) {
        !          73289:                        if ( ! st.st_iseof )
        !          73290:                                stinvoke( CC_RFM );
        !          73291:                        st.st_iseof = 0;
        !          73292:                        st.st_resid = 0;
        !          73293:                }
        !          73294:                break;
        !          73295:        }
        !          73296: 
        !          73297:        /*
        !          73298:         * Record tape error code.
        !          73299:         */
        !          73300:        u.u_error = st.st_error;
        !          73301: }
        !          73302: 
        !          73303: /**
        !          73304:  *
        !          73305:  * void
        !          73306:  * stcache()   -- read from tape into cache
        !          73307:  *
        !          73308:  *     Action: Read as much data as possible into the tape cache.
        !          73309:  *             Set st.st_paddr to the cache address.
        !          73310:  *             Set st.st_resid to the number of data bytes in the cache.
        !          73311:  */
        !          73312: static void
        !          73313: stcache()
        !          73314: {
        !          73315:        /*
        !          73316:         * Try to fill cache from tape.
        !          73317:         */
        !          73318:        st.st_paddr = st.st_seg->s_paddr;
        !          73319:        st.st_resid = st.st_size;
        !          73320:        ststart();
        !          73321: 
        !          73322:        /*
        !          73323:         * Update cache information.
        !          73324:         */
        !          73325:        st.st_paddr = st.st_seg->s_paddr;
        !          73326:        st.st_resid = st.st_size - st.st_resid;
        !          73327: 
        !          73328:        /*
        !          73329:         * Clear the cache on I/O error.
        !          73330:         */
        !          73331:        if ( st.st_error )
        !          73332:                st.st_resid = 0;
        !          73333: }
        !          73334: 
        !          73335: /**
        !          73336:  *
        !          73337:  * void
        !          73338:  * stflush()   -- flush cache to tape
        !          73339:  *
        !          73340:  *     Action: Ensure tape cache is block aligned.
        !          73341:  *             Write cache to the tape.
        !          73342:  *             Set st.st_paddr to the cache address.
        !          73343:  *             Set st.st_resid to the number of cache bytes available.
        !          73344:  */
        !          73345: static void
        !          73346: stflush()
        !          73347: {
        !          73348:        static char zc;
        !          73349: 
        !          73350:        /*
        !          73351:         * Check for empty cache.
        !          73352:         */
        !          73353:        if ( st.st_resid == st.st_size )
        !          73354:                return;
        !          73355: 
        !          73356:        /*
        !          73357:         * Block align the cache.
        !          73358:         */
        !          73359:        while ( st.st_resid % BSIZE ) {
        !          73360:                kpcopy( &zc, st.st_paddr, 1 );
        !          73361:                st.st_paddr++;
        !          73362:                st.st_resid--;
        !          73363:        }
        !          73364: 
        !          73365:        /*
        !          73366:         * Flush the cache to tape.
        !          73367:         */
        !          73368:        st.st_paddr = st.st_seg->s_paddr;
        !          73369:        st.st_resid = st.st_size - st.st_resid;
        !          73370:        ststart();
        !          73371: 
        !          73372:        /*
        !          73373:         * Update cache information.
        !          73374:         */
        !          73375:        st.st_paddr = st.st_seg->s_paddr;
        !          73376:        st.st_resid = st.st_size;
        !          73377: }
        !          73378: 
        !          73379: /**
        !          73380:  *
        !          73381:  * void
        !          73382:  * stinvoke()  -- start tape control operation
        !          73383:  *
        !          73384:  *     Action: Initiate tape control operation.
        !          73385:  */
        !          73386: static void
        !          73387: stinvoke( cmd )
        !          73388: int cmd;
        !          73389: {
        !          73390:        register int s;
        !          73391: 
        !          73392:        /*
        !          73393:         * Disable interrupts.
        !          73394:         */
        !          73395:        s = sphi();
        !          73396: 
        !          73397:        /*
        !          73398:         * Wait for controller to become idle.
        !          73399:         */
        !          73400:        while ( st.st_state != SIDLE ) {
        !          73401: 
        !          73402:                /*
        !          73403:                 * Create chained command if possible.
        !          73404:                 */
        !          73405:                if ( st.st_ncmds < NCMDS ) {
        !          73406:                        st.st_cmds[ st.st_ncmds++ ] = cmd;
        !          73407:                        spl( s );
        !          73408:                        return;
        !          73409:                }
        !          73410: 
        !          73411:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          73412:        }
        !          73413: 
        !          73414:        /*
        !          73415:         * Setup for tape operation.
        !          73416:         */
        !          73417:        drvl[STMAJ].d_time = 1;
        !          73418:        st.st_state = SCMD;
        !          73419:        st.st_error = 0;
        !          73420:        st.st_rdys  = 0;
        !          73421:        stspin( 100 );
        !          73422: 
        !          73423:        /*
        !          73424:         * Request tape operation.
        !          73425:         * Do NOT wait for results.
        !          73426:         */
        !          73427:        outb( DATA_REG, st.st_cmd = cmd );
        !          73428:        outb( CTRL_REG, CR_IEN+CR_REQ );
        !          73429: 
        !          73430:        /*
        !          73431:         * Enable interrupts.
        !          73432:         */
        !          73433:        spl( s );
        !          73434: }
        !          73435: 
        !          73436: /**
        !          73437:  *
        !          73438:  * void
        !          73439:  * ststart()   -- start tape read/write operation
        !          73440:  *
        !          73441:  *     Action: Initiate tape read/write operation.
        !          73442:  *             Wait for tape operation to complete.
        !          73443:  */
        !          73444: static void
        !          73445: ststart()
        !          73446: {
        !          73447:        register int s;
        !          73448: 
        !          73449:        /*
        !          73450:         * Disable interrupts.
        !          73451:         */
        !          73452:        s = sphi();
        !          73453: 
        !          73454:        /*
        !          73455:         * Wait for controller to become idle.
        !          73456:         */
        !          73457:        while ( st.st_state != SIDLE )
        !          73458:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          73459: 
        !          73460:        /*
        !          73461:         * Setup for tape read/write.
        !          73462:         */
        !          73463:        drvl[STMAJ].d_time = 1;
        !          73464:        st.st_state = SRDWR;
        !          73465:        st.st_error = 0;
        !          73466:        st.st_rdys  = 0;
        !          73467:        stspin( 100 );
        !          73468: 
        !          73469:        /*
        !          73470:         * Tape read/write was last command executed.
        !          73471:         */
        !          73472:        if ( st.st_cmd == st.st_iocmd ) {
        !          73473:                /*
        !          73474:                 * Resume tape i/o operation.
        !          73475:                 * Simulate RDY interrupt.
        !          73476:                 */
        !          73477:                stintr();
        !          73478:        }
        !          73479:        else {
        !          73480:                /*
        !          73481:                 * Request tape operation.
        !          73482:                 */
        !          73483:                outb( DATA_REG, st.st_cmd = st.st_iocmd );
        !          73484:                outb( CTRL_REG, CR_IEN+CR_REQ );
        !          73485:        }
        !          73486: 
        !          73487:        /*
        !          73488:         * Wait for tape operation to complete.
        !          73489:         */
        !          73490:        while ( st.st_state != SIDLE )
        !          73491:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          73492: 
        !          73493:        /*
        !          73494:         * Enable interrupts.
        !          73495:         */
        !          73496:        spl( s );
        !          73497: }
        !          73498: 
        !          73499: /**
        !          73500:  *
        !          73501:  * void
        !          73502:  * stintr()    -- tape interrupt handler
        !          73503:  *
        !          73504:  *     Action: Service tape interrupts.
        !          73505:  *             Perform transitions to new tape states.
        !          73506:  *             Wake sleeping processes if appropriate.
        !          73507:  */
        !          73508: static void
        !          73509: stintr()
        !          73510: {
        !          73511:        register int csr;
        !          73512:        register int s;
        !          73513: 
        !          73514:        s   = sphi();
        !          73515:        csr = inb( CTRL_REG );
        !          73516: 
        !          73517:        /*
        !          73518:         * Initiate exception recovery.
        !          73519:         */
        !          73520:        if ( (csr & SR_NEXC) == 0 ) {
        !          73521:                strecov();
        !          73522:                spl( s );
        !          73523:                return;
        !          73524:        }
        !          73525: 
        !          73526:        /*
        !          73527:         * Clear ready watchdog count.
        !          73528:         */
        !          73529:        st.st_rdys = 0;
        !          73530: 
        !          73531:        /*
        !          73532:         * Process normal operations.
        !          73533:         */
        !          73534:        switch ( st.st_state ) {
        !          73535: 
        !          73536:        case SCMD:
        !          73537:                /*
        !          73538:                 * Command has been acknowledged.
        !          73539:                 * Wait for command completion.
        !          73540:                 */
        !          73541:                outb( CTRL_REG, CR_IEN );
        !          73542:                st.st_state = (st.st_cmd == CC_SENSE) ? SSENSE : SRUN;
        !          73543:                st.st_nstat = 0;
        !          73544:                break;
        !          73545: 
        !          73546:        case SRUN:
        !          73547:                /*
        !          73548:                 * Command has completed.
        !          73549:                 * Chain a sense status command if no other chained commands.
        !          73550:                 */
        !          73551:                if ( st.st_ncmds == 0 )
        !          73552:                        st.st_cmds[ st.st_ncmds++ ] = CC_SENSE;
        !          73553: 
        !          73554:                /*
        !          73555:                 * Initiate next chained command.
        !          73556:                 */
        !          73557:                stnext();
        !          73558:                break;
        !          73559: 
        !          73560:        case SRDWR:
        !          73561:                /*
        !          73562:                 * Read/Write command had been acknowledged.
        !          73563:                 * Clear tape request, enable done interrupt.
        !          73564:                 */
        !          73565:                outb( CTRL_REG, CR_IEN+CR_DNIEN );
        !          73566: 
        !          73567:                /*
        !          73568:                 * Define direct memory access parameters.
        !          73569:                 */
        !          73570:                dmaon( STDMA, st.st_paddr, BSIZE, st.st_iswr );
        !          73571: 
        !          73572:                /*
        !          73573:                 * If tape read command, wait for interface to switch direction
        !          73574:                 */
        !          73575:                if ( st.st_iocmd == CC_READ )
        !          73576:                        while ( (inb(CTRL_REG) & SR_TO_PC) != SR_TO_PC )
        !          73577:                                ;
        !          73578: 
        !          73579:                /*
        !          73580:                 * Enable DMA transfer on tape interface and at DMA controller chip.
        !          73581:                 */
        !          73582:                st.st_state = SBLOCK;
        !          73583:                outb( DMAGO_REG, 0 );
        !          73584:                dmago( STDMA );
        !          73585:                break;
        !          73586: 
        !          73587:        case SBLOCK:
        !          73588:                /*
        !          73589:                 * Perform Block I/O.
        !          73590:                 * Ignore RDY interrupt, wait for [DMA] DONE interrupt.
        !          73591:                 */
        !          73592:                if ( (csr & SR_DONE) == 0 )
        !          73593:                        break;
        !          73594: 
        !          73595:                /*
        !          73596:                 * Turn off DMA.
        !          73597:                 */
        !          73598:                dmaoff( STDMA );
        !          73599: 
        !          73600:                /*
        !          73601:                 * If more data remains to be transferred, reenable DMA.
        !          73602:                 * NOTE: do -= BEFORE if() to avoid potential compiler bug.
        !          73603:                 */
        !          73604:                st.st_resid -= BSIZE;
        !          73605:                if ( st.st_resid > 0 ) {
        !          73606:                        st.st_paddr += BSIZE;
        !          73607:                        dmaon( STDMA, st.st_paddr, BSIZE, st.st_iswr );
        !          73608:                        outb( DMAGO_REG, 0 );
        !          73609:                        dmago( STDMA );
        !          73610:                        break;
        !          73611:                }
        !          73612: 
        !          73613:                /*
        !          73614:                 * Disable done interrupt.
        !          73615:                 * Wait for I/O completion.
        !          73616:                 */
        !          73617:                outb( CTRL_REG, CR_IEN );
        !          73618:                st.st_state = SBLEND;
        !          73619:                break;
        !          73620: 
        !          73621:        case SBLEND:
        !          73622:                /*
        !          73623:                 * Completion of Block I/O.
        !          73624:                 * Clear the file mark and beginning of media indicators.
        !          73625:                 * Record the fact that data has been transferred.
        !          73626:                 */
        !          73627:                st.st_status[0] &= ~SS0_FIL;
        !          73628:                st.st_status[1] &= ~SS1_BOM;
        !          73629:                st.st_wasio = 1;
        !          73630:                stnext();
        !          73631:                break;
        !          73632: 
        !          73633:        case SSENSE:
        !          73634:                /*
        !          73635:                 * Sense Status Byte.
        !          73636:                 * Wait for availability.
        !          73637:                 */
        !          73638:                do {
        !          73639:                        csr = inb(CTRL_REG) & (SR_NRDY|SR_TO_PC);
        !          73640:                } while ( csr != SR_TO_PC );
        !          73641: 
        !          73642:                /*
        !          73643:                 * Save status byte.
        !          73644:                 */
        !          73645:                st.st_status[st.st_nstat] = inb(DATA_REG);
        !          73646: 
        !          73647:                /*
        !          73648:                 * Acknowledge reception.
        !          73649:                 * CR_REQ must be present for at least 20 microseconds.
        !          73650:                 */
        !          73651:                outb( CTRL_REG, CR_IEN+CR_REQ );
        !          73652:                stspin( 20 );
        !          73653:                outb( CTRL_REG, CR_IEN );
        !          73654: 
        !          73655:                /*
        !          73656:                 * Change state to status completion if all bytes saved.
        !          73657:                 */
        !          73658:                if ( ++(st.st_nstat) == 6 )
        !          73659:                        st.st_state = SSDONE;
        !          73660:                break;
        !          73661: 
        !          73662:        case SSDONE:
        !          73663:                /*
        !          73664:                 * Completion of Sense Status Command.
        !          73665:                 * Check for file mark.
        !          73666:                 */
        !          73667:                if ( st.st_status[0] & SS0_FIL ) {
        !          73668:                        outb( DMARST_REG, 0 );
        !          73669:                        st.st_iseof = 1;
        !          73670:                }
        !          73671: 
        !          73672:                /*
        !          73673:                 * Check for I/O error.
        !          73674:                 */
        !          73675:                else if ( (st.st_status[0] & SS0_ERR) ||
        !          73676:                          (st.st_status[1] & SS1_ERR) ) {
        !          73677:                        st.st_error = EIO;
        !          73678:                }
        !          73679: 
        !          73680:                /*
        !          73681:                 * Check for write protected cartridge.
        !          73682:                 */
        !          73683:                else if ( (st.st_iocmd == CC_WRITE) &&
        !          73684:                          (st.st_status[0] & SS0_WRP) ) {
        !          73685:                        st.st_error = EROFS;
        !          73686:                }
        !          73687: 
        !          73688:                stnext();
        !          73689:                break;
        !          73690:        }
        !          73691: 
        !          73692:        spl( s );
        !          73693: }
        !          73694: 
        !          73695: /**
        !          73696:  *
        !          73697:  * void
        !          73698:  * strecov()   -- initiate recovery from exception conditions
        !          73699:  *
        !          73700:  *     Action: Invoked when the tape controller asserts EXCEPTION.
        !          73701:  *             A sense status command is initiated to clear the exception.
        !          73702:  */
        !          73703: static void
        !          73704: strecov()
        !          73705: {
        !          73706:        /*
        !          73707:         * Ensure tape interface is idle.
        !          73708:         */
        !          73709:        outb( CTRL_REG, CR_IEN );
        !          73710:        stspin( 100 );
        !          73711: 
        !          73712:        /*
        !          73713:         * Turn off DMA on read/write exception.
        !          73714:         */
        !          73715:        if ( st.st_cmd == st.st_iocmd )
        !          73716:                dmaoff( STDMA );
        !          73717: 
        !          73718:        /*
        !          73719:         * Initiate sense status command.
        !          73720:         */
        !          73721:        outb( DATA_REG, st.st_cmd = CC_SENSE );
        !          73722:        outb( CTRL_REG, CR_IEN+CR_REQ );
        !          73723:        drvl[STMAJ].d_time = 1;
        !          73724:        st.st_state = SCMD;
        !          73725:        st.st_error = 0;
        !          73726:        st.st_rdys  = 0;
        !          73727: }
        !          73728: 
        !          73729: /**
        !          73730:  *
        !          73731:  * static void
        !          73732:  * stnext()    -- initiate next chained command.
        !          73733:  */
        !          73734: static void
        !          73735: stnext()
        !          73736: {
        !          73737:        /*
        !          73738:         * Ensure tape interface is idle.
        !          73739:         */
        !          73740:        outb( CTRL_REG, CR_IEN );
        !          73741:        drvl[STMAJ].d_time = 0;
        !          73742:        st.st_state = SIDLE;
        !          73743:        stspin( 100 );
        !          73744: 
        !          73745:        /*
        !          73746:         * Initiate a chained command.
        !          73747:         */
        !          73748:        if ( st.st_ncmds ) {
        !          73749:                outb( DATA_REG, st.st_cmd = st.st_cmds[ --st.st_ncmds ] );
        !          73750:                outb( CTRL_REG, CR_IEN+CR_REQ );
        !          73751:                drvl[STMAJ].d_time = 1;
        !          73752:                st.st_state = SCMD;
        !          73753:                st.st_error = 0;
        !          73754:                st.st_rdys  = 0;
        !          73755:                return;
        !          73756:        }
        !          73757: 
        !          73758:        /*
        !          73759:         * Wake waiting processes.
        !          73760:         */
        !          73761:        wakeup( &st );
        !          73762: }
        !          73763: 
        !          73764: /**
        !          73765:  *
        !          73766:  * void
        !          73767:  * stwatch()   -- periodic [1 sec] watchdog
        !          73768:  *
        !          73769:  *     Action: If an exception condition exists, initate recovery actions.
        !          73770:  *             If ready condition exists for 1-2 seconds, simulate interrupt.
        !          73771:  *
        !          73772:  *     Notes:  If an exception condition occurs after a ready interrupt has
        !          73773:  *             been serviced, but before the ready condition is cleared,
        !          73774:  *             the exception interrupt will not occur, and is simulated here.
        !          73775:  */
        !          73776: static void
        !          73777: stwatch()
        !          73778: {
        !          73779:        register int csr;
        !          73780:        register int s;
        !          73781: 
        !          73782:        /*
        !          73783:         * Disable interrupts, preventing critical race with stintr().
        !          73784:         */
        !          73785:        s   = sphi();
        !          73786:        csr = inb(CTRL_REG);
        !          73787: 
        !          73788:        /*
        !          73789:         * Initiate recovery from exception conditions.
        !          73790:         */
        !          73791:        if ( (csr & SR_NEXC) == 0 )
        !          73792:                strecov();
        !          73793: 
        !          73794:        /*
        !          73795:         * Reset ready watchdog if not ready.
        !          73796:         */
        !          73797:        else if ( csr & SR_NRDY ) 
        !          73798:                st.st_rdys = 0;
        !          73799: 
        !          73800:        /*
        !          73801:         * Simulate lost ready interrupts after 2 seconds.
        !          73802:         */
        !          73803:        else if ( ++st.st_rdys >= 2 )
        !          73804:                stintr();
        !          73805: 
        !          73806:        /*
        !          73807:         * Enable interrupts.
        !          73808:         */
        !          73809:        spl( s );
        !          73810: }
        !          73811: 
        !          73812: /**
        !          73813:  * 
        !          73814:  * void
        !          73815:  * stdiag()    - Report tape status.
        !          73816:  *
        !          73817:  *     Action: Identify and report the highest priority tape error.
        !          73818:  *             There will normally only be one valid error present.
        !          73819:  *             The USL error can invalidate most remaining flags.
        !          73820:  *             The CNI error can invalidate cartridge related flags.
        !          73821:  *
        !          73822:  *     Notes:  Never called from interrupt level, but always from background.
        !          73823:  */
        !          73824: static void
        !          73825: stdiag()
        !          73826: {
        !          73827:        if ( st.st_status[0] & SS0_USL )
        !          73828:                printf( "st: Unselected Drive\n" );
        !          73829: 
        !          73830:        else if ( st.st_status[0] & SS0_CNI )
        !          73831:                printf( "st: Cartridge missing\n" );
        !          73832: 
        !          73833:        else if ( st.st_status[1] & SS1_NDT )
        !          73834:                printf( "st: No data detected\n" );
        !          73835: 
        !          73836:        else if ( st.st_status[0] & SS0_BNL )
        !          73837:                printf( "st: Bad block not located\n" );
        !          73838: 
        !          73839:        else if ( st.st_status[0] & SS0_UDA )
        !          73840:                printf( "st: Unrecoverable data error\n" );
        !          73841: 
        !          73842:        else if ( st.st_status[1] & SS1_ILL )
        !          73843:                printf( "st: Illegal command\n" );
        !          73844: 
        !          73845:        else
        !          73846:                printf( "st: %x\n", (st.st_status[1] << 8) + st.st_status[0] );
        !          73847: }
        !          73848: 
        !          73849: /**
        !          73850:  *
        !          73851:  * int
        !          73852:  * stwait()    -- wait for tape controller to idle.
        !          73853:  *
        !          73854:  *     Return: 0  = tape controller idle.
        !          73855:  *             -1 = signal received.
        !          73856:  */
        !          73857: static int
        !          73858: stwait()
        !          73859: {
        !          73860:        int s;
        !          73861: 
        !          73862:        s = sphi();
        !          73863:        while ( st.st_state != SIDLE ) {
        !          73864: 
        !          73865:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
        !          73866: 
        !          73867:                if ( SELF->p_ssig ) {
        !          73868:                        spl( s );
        !          73869:                        return -1;
        !          73870:                }
        !          73871:        }
        !          73872:        spl( s );
        !          73873: 
        !          73874:        return 0;
        !          73875: }
        !          73876: 
        !          73877: /**
        !          73878:  *
        !          73879:  * void
        !          73880:  * stspin( usec )      -- delay execution
        !          73881:  * int usec;
        !          73882:  *
        !          73883:  *     Input:  usec = number of micro-seconds to delay.
        !          73884:  *
        !          73885:  *     Action: Wait at least 'usec' micro-seconds.
        !          73886:  *
        !          73887:  *     Notes:  Provides minimum delay required at times by tape controller.
        !          73888:  *             Should function properly up to at least 16 Mhz system clock.
        !          73889:  */
        !          73890: 
        !          73891: static void
        !          73892: stspin( usec )
        !          73893: register int usec;
        !          73894: {
        !          73895:        while ( --usec >= 0 )
        !          73896:                ;
        !          73897: }
        !          73898: @
        !          73899: 
        !          73900: 
        !          73901: 1.1
        !          73902: log
        !          73903: @Initial revision
        !          73904: @
        !          73905: text
        !          73906: @d10 1
        !          73907: a10 1
        !          73908: #include       <coherent.h>
        !          73909: @
        !          73910: 0707070064030106321004440000030000030000011777770507310702200006200000001273/newbits/kernel/USRSRC/i8086/drv/RCS/template.c,vhead     1.2;
        !          73911: branch   ;
        !          73912: access   ;
        !          73913: symbols  ;
        !          73914: locks    bin:1.2; strict;
        !          73915: comment  @ * @;
        !          73916: 
        !          73917: 
        !          73918: 1.2
        !          73919: date     91.06.20.14.55.08;  author bin;  state Exp;
        !          73920: branches ;
        !          73921: next     1.1;
        !          73922: 
        !          73923: 1.1
        !          73924: date     91.06.10.10.28.39;  author bin;  state Exp;
        !          73925: branches ;
        !          73926: next     ;
        !          73927: 
        !          73928: 
        !          73929: desc
        !          73930: @initial version prov by hal
        !          73931: @
        !          73932: 
        !          73933: 
        !          73934: 1.2
        !          73935: log
        !          73936: @update provided by hal
        !          73937: @
        !          73938: text
        !          73939: @/*
        !          73940:  * File:
        !          73941:  *
        !          73942:  * Purpose:
        !          73943:  *
        !          73944:  * $Log$
        !          73945:  */
        !          73946: 
        !          73947: /*
        !          73948:  * Includes.
        !          73949:  */
        !          73950: 
        !          73951: /*
        !          73952:  * Definitions.
        !          73953:  *     Constants.
        !          73954:  *     Macros with argument lists.
        !          73955:  *     Typedefs.
        !          73956:  *     Enums.
        !          73957:  */
        !          73958: 
        !          73959: /*
        !          73960:  * Functions.
        !          73961:  *     Import Functions.
        !          73962:  *     Export Functions.
        !          73963:  *     Local Functions.
        !          73964:  */
        !          73965: 
        !          73966: /*
        !          73967:  * Global Data.
        !          73968:  *     Import Variables.
        !          73969:  *     Export Variables.
        !          73970:  *     Local Variables.
        !          73971:  */
        !          73972: @
        !          73973: 
        !          73974: 
        !          73975: 1.1
        !          73976: log
        !          73977: @Initial revision
        !          73978: @
        !          73979: text
        !          73980: @@
        !          73981: 0707070064030106311004440000030000030000011777770507310702200005400000065450/newbits/kernel/USRSRC/i8086/drv/RCS/tn.c,vhead     1.2;
        !          73982: branch   ;
        !          73983: access   ;
        !          73984: symbols  ;
        !          73985: locks    bin:1.2; strict;
        !          73986: comment  @ * @;
        !          73987: 
        !          73988: 
        !          73989: 1.2
        !          73990: date     91.06.20.14.55.15;  author bin;  state Exp;
        !          73991: branches ;
        !          73992: next     1.1;
        !          73993: 
        !          73994: 1.1
        !          73995: date     91.06.10.10.28.41;  author bin;  state Exp;
        !          73996: branches ;
        !          73997: next     ;
        !          73998: 
        !          73999: 
        !          74000: desc
        !          74001: @initial version prov by hal
        !          74002: @
        !          74003: 
        !          74004: 
        !          74005: 1.2
        !          74006: log
        !          74007: @update provided by hal
        !          74008: @
        !          74009: text
        !          74010: @/* (-lgl
        !          74011:  *     COHERENT Driver Kit Version 1.1.0
        !          74012:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          74013:  *     All rights reserved. May not be copied without permission.
        !          74014:  -lgl) */
        !          74015: /*
        !          74016:  * Tiac ARCNET PC-234 Device Driver
        !          74017:  *
        !          74018:  * True support for up to 4 network cards through minor devices 0-3.
        !          74019:  * Up to 4 protocols now supported.  Novell access is through normal
        !          74020:  * minor device.  Netbios access is through novell minor device + 16.
        !          74021:  */
        !          74022: 
        !          74023: #include <sys/coherent.h>
        !          74024: #include <sys/con.h>
        !          74025: #include <sys/sched.h>
        !          74026: #include <sys/seg.h>
        !          74027: #include <sys/stat.h>
        !          74028: #include <sys/uproc.h>
        !          74029: #include <sys/tnioctl.h>
        !          74030: #include <errno.h>
        !          74031: 
        !          74032: /*
        !          74033:  * Network Major Device.
        !          74034:  */
        !          74035: #define        TNMAJOR 20
        !          74036: 
        !          74037: /*
        !          74038:  * External functions.
        !          74039:  */
        !          74040: extern int  wakeup();
        !          74041: extern void pollwake();
        !          74042: extern void defer();
        !          74043: 
        !          74044: /*
        !          74045:  * Driver functions.
        !          74046:  */
        !          74047: void   tnopen();
        !          74048: void   tnclose();
        !          74049: int    tnread();
        !          74050: int    tnwrite();
        !          74051: int    tnioctl();
        !          74052: void   tncycle();
        !          74053: void   tnload();
        !          74054: void   tnuload();
        !          74055: int    tnpoll();
        !          74056: int    nonedev();
        !          74057: int    nulldev();
        !          74058: void   tn0intr();
        !          74059: void   tn1intr();
        !          74060: void   tn2intr();
        !          74061: void   tn3intr();
        !          74062: void   tnintr();
        !          74063: 
        !          74064: /*
        !          74065:  * Driver Configuration.
        !          74066:  */
        !          74067: CON
        !          74068: tncon = {
        !          74069:        DFCHR|DFPOL,                    /* Flags        */
        !          74070:        TNMAJOR,                        /* Major Index  */
        !          74071:        tnopen,                         /* Open         */
        !          74072:        tnclose,                        /* Close        */
        !          74073:        nonedev,                        /* Block        */
        !          74074:        tnread,                         /* Read         */
        !          74075:        tnwrite,                        /* Write        */
        !          74076:        tnioctl,                        /* Ioctl        */
        !          74077:        nulldev,                        /* Power fail   */
        !          74078:        tncycle,                        /* Timeout      */
        !          74079:        tnload,                         /* Load         */
        !          74080:        tnuload,                        /* Unload       */
        !          74081:        tnpoll                          /* Poll         */
        !          74082: };
        !          74083: 
        !          74084: /*
        !          74085:  * Interrupt Entry Points.
        !          74086:  */
        !          74087: void (*tnintf[4])() = {
        !          74088:        tn0intr,
        !          74089:        tn1intr,
        !          74090:        tn2intr,
        !          74091:        tn3intr
        !          74092: };
        !          74093: 
        !          74094: #define        BIT(n)          (1 << (n))
        !          74095: 
        !          74096: /*
        !          74097:  * Bitmask, indexed by bit numbers 0..7.
        !          74098:  */
        !          74099: static unsigned char bitm[8] = { BIT(0), BIT(1), BIT(2), BIT(3),
        !          74100:                                 BIT(4), BIT(5), BIT(6), BIT(7) };
        !          74101: 
        !          74102: /*
        !          74103:  * Patchable parameters - Cards 0-3.
        !          74104:  */
        !          74105:                /* Card    0       1       2      3  */
        !          74106: int    TNIRQ [4] = {      2,      7,      4,      0 };
        !          74107: saddr_t        TNSEL [4] = { 0xD000, 0x0000, 0x0000, 0x0000 };
        !          74108: int    TNPORT[4] = {  0x2E0,  0x220,  0x240,  0x000 };
        !          74109: 
        !          74110: /*
        !          74111:  * Patchable parameters - Prefix Byte.
        !          74112:  * Indexed by high nibble of minor device.
        !          74113:  */
        !          74114: int    TNPREFIX[4] = { 0x00,   0xF3,   0x00,   0x00 };
        !          74115: 
        !          74116: /*
        !          74117:  * Patchable variables.
        !          74118:  * TNTIME = Transmit watchdog timer in seconds.
        !          74119:  */
        !          74120: int TNTIME = 5;
        !          74121: 
        !          74122: /*
        !          74123:  * Register addresses.
        !          74124:  */
        !          74125: #define        NIR             (tp->tnport)    /* Network Interrupt Mask Reg (w)  */
        !          74126: #define        NSR             (tp->tnport)    /* Network Status Register    (r)  */
        !          74127: #define        NCR             (tp->tnport+1)  /* Network Command Register   (w)  */
        !          74128: #define        NZR             (tp->tnport+8)  /* Network Zap (reset) Reg    (w)  */
        !          74129: 
        !          74130: /*
        !          74131:  * Network Interrupt Register (NIR).
        !          74132:  */
        !          74133: #define        NI_Tx           BIT(0)          /* Enable Transmitter Avail Intr   */
        !          74134: #define        NI_RECON        BIT(2)          /* Enable Reconfiguration   Intr   */
        !          74135: #define        NI_Rx           BIT(7)          /* Enable Receiver Full     Intr   */
        !          74136: 
        !          74137: /*
        !          74138:  * Network Status Register (NSR).
        !          74139:  */
        !          74140: #define        NS_TxRDY        BIT(0)          /* Transmitter Available           */
        !          74141: #define        NS_TxACK        BIT(1)          /* Transmit Message Acknowledged   */
        !          74142: #define        NS_RECON        BIT(2)          /* Network Reconfiguration         */
        !          74143: #define        NS_TEST         BIT(3)          /* Test                            */
        !          74144: #define        NS_POR          BIT(4)          /* Power on Reset                  */
        !          74145: #define        NS_ETS1         BIT(5)          /* Extended Timeout Status 1       */
        !          74146: #define        NS_ETS2         BIT(6)          /* Extended Timeout Status 2       */
        !          74147: #define        NS_RxRDY        BIT(7)          /* Packet Received - Receiver Off  */
        !          74148: 
        !          74149: /*
        !          74150:  * Network Command Register (NCR).
        !          74151:  */
        !          74152: #define        NC_TxDIS        (((0)<<3) + 1)  /* Disable Transmitter             */
        !          74153: #define        NC_RxDIS        (((0)<<3) + 2)  /* Disable Receiver                */
        !          74154: #define        NC_TxENA(n)     (((n)<<3) + 3)  /* Enable Transmitter on Page n    */
        !          74155: #define        NC_RxENA(n)     (((n)<<3)+0x84) /* Enable Receiver    on Page n    */
        !          74156: #define        NC_DFC          (((1)<<3) + 5)  /* Define Configuration (2k buf)   */
        !          74157: #define        NC_POR          (((1)<<3) + 6)  /* Clear NS_POR flag               */
        !          74158: #define        NC_RECON        (((2)<<3) + 6)  /* Clear NS_RECON flag             */
        !          74159: 
        !          74160: /*
        !          74161:  * Packet Control.
        !          74162:  */
        !          74163: struct tnet_s {
        !          74164: 
        !          74165:        /*
        !          74166:         * Four buffers per card - 2 receive, 2 transmit.
        !          74167:         */
        !          74168:        struct tnbuf_s {                /* tnget*,tnput* use tn_sel:tn_off */
        !          74169:                unsigned        tn_off; /* tn_sel:tn_off  = current byte   */
        !          74170:                saddr_t         tn_sel; /* network buffer selector         */
        !          74171:                struct tnbuf_s *tn_next;/* pointer to next pkt in queue    */
        !          74172:                unsigned        tn_ena; /* Command to enable packet        */
        !          74173:                unsigned        tn_base;/* tn_sel:tn_base = pkt address    */
        !          74174:                unsigned        tn_xnid;/* Transmit node id                */
        !          74175:                unsigned        tn_xlen;/* Transmit length                 */
        !          74176:        } tnbuf [4];
        !          74177: 
        !          74178:        struct tnbuf_s *        RxBusy[4];/* Queues of full receive packets*/
        !          74179:        struct tnbuf_s *        RxIdle; /* Queue of empty receive packets  */
        !          74180: 
        !          74181:        struct tnbuf_s *        TxBusy; /* Queue of full transmit packets  */
        !          74182:        struct tnbuf_s *        TxIdle; /* Queue of empty transmit packets */
        !          74183: 
        !          74184:        event_t                 RxPoll[4];/* Polls for input packets       */
        !          74185:        event_t                 TxPoll; /* Polls for empty output packets  */
        !          74186: 
        !          74187:        char                    RxReq[4];/* 1 = Proc waiting for recv buf  */
        !          74188:        char                    TxReq;  /* 1 = Proc waiting for xmit buf   */
        !          74189:        char                    refc[4];/* # opens, indexed by prefix code */
        !          74190: 
        !          74191:        unsigned                tnmask; /* Interrupt enable mask           */
        !          74192:        unsigned                tnport; /* Base I/O port                   */
        !          74193:        char                    tnaddr[8];/* ARC-NET Node ID, low byte 1st */
        !          74194: 
        !          74195:        unsigned                tntime; /* transmit watchdog timer         */
        !          74196:        unsigned                recon;  /* number of long reconfigurations */
        !          74197:        unsigned                pri;    /* priority event occurred         */
        !          74198:        long                    rbolt;  /* lbolt at last reconfiguration   */
        !          74199:        unsigned char           bad[32];/* bit mask of bad nodes           */
        !          74200:        unsigned char           mod[32];/* bit mask of changed nodes       */
        !          74201:        long                    recons; /* reconfiguration statistic       */
        !          74202:        SEG *                   statseg;/* Segment containing stats        */
        !          74203: 
        !          74204: } tnet [4];
        !          74205: 
        !          74206: /*
        !          74207:  * Load Routine.
        !          74208:  */
        !          74209: void
        !          74210: tnload()
        !          74211: {
        !          74212:        register struct tnet_s  * tp;
        !          74213:        register struct tnbuf_s * np;
        !          74214:        faddr_t faddr;
        !          74215:        paddr_t paddr;
        !          74216:        int i;
        !          74217:        int nid;
        !          74218:        long delay;
        !          74219: 
        !          74220:        for ( tp = &tnet[0], i = 0; i < 4; i++, tp++ ) {
        !          74221: 
        !          74222:                /*
        !          74223:                 * Validate patchable parameters.
        !          74224:                 */
        !          74225:                if ( (TNSEL[i] == 0) || (TNPORT[i] == 0) || (TNIRQ[i] == 0) ) {
        !          74226:                        TNPORT[i] = 0;
        !          74227:                        TNSEL[i]  = 0;
        !          74228:                        TNIRQ[i]  = 0;
        !          74229:                        continue;
        !          74230:                }
        !          74231: 
        !          74232:                tp->tnport = TNPORT[i];
        !          74233: 
        !          74234:                /*
        !          74235:                 * Clear Power-On-Reset Flag.
        !          74236:                 */
        !          74237:                outb( NCR, NC_POR );
        !          74238: 
        !          74239:                /*
        !          74240:                 * Validate card presence.
        !          74241:                 * NOTE: tp->tnport must be programmed before using NIR macro.
        !          74242:                 */
        !          74243:                if ( inb(NSR) & (NS_TEST|NS_POR) ) {
        !          74244:                        tp->tnport = 0;
        !          74245:                        continue;
        !          74246:                }
        !          74247: 
        !          74248:                /*
        !          74249:                 * Convert physical address into virtual address.
        !          74250:                 */
        !          74251:                paddr = TNSEL[i] << 4L;
        !          74252:                faddr = ptov( paddr, (fsize_t) 2048 );
        !          74253: 
        !          74254:                /*
        !          74255:                 * Verify dual-port memory existence.
        !          74256:                 * NOTE: Do not overwrite first two bytes [0xD1,nid].
        !          74257:                 */
        !          74258:                sfword( faddr+8, 0x1234 );
        !          74259:                if ( ffword( faddr+8 ) != 0x1234 ) {
        !          74260:                        vrelse( faddr );
        !          74261:                        tp->tnport = 0;
        !          74262:                        continue;
        !          74263:                }
        !          74264: 
        !          74265:                /*
        !          74266:                 * Allocate statistics segment.
        !          74267:                 */
        !          74268:                tp->statseg = salloc( (fsize_t) (256*NTNST*4), SFSYST|SFHIGH );
        !          74269: 
        !          74270:                /*
        !          74271:                 * Out of memory.
        !          74272:                 */
        !          74273:                if ( ! tp->statseg ) {
        !          74274:                        printf( "tn%d: out of memory\n", i );
        !          74275:                        vrelse( faddr );
        !          74276:                        tp->tnport = 0;
        !          74277:                        continue;
        !          74278:                }
        !          74279: 
        !          74280:                tp->tnbuf[0].tn_sel =
        !          74281:                tp->tnbuf[1].tn_sel =
        !          74282:                tp->tnbuf[2].tn_sel =
        !          74283:                tp->tnbuf[3].tn_sel = FP_SEL(faddr);
        !          74284: 
        !          74285:                tp->tnbuf[0].tn_ena  = NC_TxENA(0);
        !          74286:                tp->tnbuf[1].tn_ena  = NC_TxENA(1);
        !          74287:                tp->tnbuf[2].tn_ena  = NC_RxENA(2);
        !          74288:                tp->tnbuf[3].tn_ena  = NC_RxENA(3);
        !          74289: 
        !          74290:                tp->tnbuf[0].tn_base = 0 * 512;
        !          74291:                tp->tnbuf[1].tn_base = 1 * 512;
        !          74292:                tp->tnbuf[2].tn_base = 2 * 512;
        !          74293:                tp->tnbuf[3].tn_base = 3 * 512;
        !          74294: 
        !          74295:                /*
        !          74296:                 * Initialize transmit idle queue.
        !          74297:                 */
        !          74298:                tp->TxIdle              = &tp->tnbuf[0];
        !          74299:                tp->tnbuf[0].tn_next    = &tp->tnbuf[1];
        !          74300: 
        !          74301:                /*
        !          74302:                 * Initialize receive idle queue.
        !          74303:                 */
        !          74304:                tp->RxIdle              = &tp->tnbuf[2];
        !          74305:                tp->tnbuf[2].tn_next    = &tp->tnbuf[3];
        !          74306: 
        !          74307:                /*
        !          74308:                 * Validate Node Id.
        !          74309:                 */
        !          74310:                np = &tp->tnbuf[0];
        !          74311:                np->tn_off = 0;
        !          74312:                if ( tngetc(np) != 0xD1 ) {
        !          74313: 
        !          74314:                        /*
        !          74315:                         * Initiate Power On Reset.
        !          74316:                         */
        !          74317:                        outb( NZR, 1 );
        !          74318: 
        !          74319:                        /*
        !          74320:                         * Wait minimimum of 180 [suggest 250] milli-seconds.
        !          74321:                         * Should function properly up to at least 16 Mhz clock.
        !          74322:                         */
        !          74323:                        for ( delay = 250000L; --delay != 0; )
        !          74324:                                ;
        !          74325:                }
        !          74326: 
        !          74327:                /*
        !          74328:                 * Validate and Remember Node Id.
        !          74329:                 */
        !          74330:                np->tn_off = 0;
        !          74331:                if ( tngetc(np) == 0xD1 )
        !          74332:                        tp->tnaddr[0] = tngetc( np );
        !          74333: 
        !          74334:                /*
        !          74335:                 * Record starting time of statistics collection.
        !          74336:                 */
        !          74337:                faddr = tp->statseg->s_faddr + TnELAPSED*4;
        !          74338:                for ( nid = 0; nid < 256; nid++, faddr += NTNST*4 )
        !          74339:                        kfcopy( &lbolt, faddr, sizeof(lbolt) );
        !          74340: 
        !          74341:                memset( tp->bad, -1, 32 );      /* Assume LAN is down      */
        !          74342:                memset( tp->mod,  0, 32 );      /* Assume no node changes  */
        !          74343:                tp->tnmask = NI_Rx | NI_RECON;  /* Interrupts to enable    */
        !          74344:                outb( NIR, 0 );                 /* Disable Interrupts      */
        !          74345:                outb( NCR, NC_POR );            /* Clear POR Flag          */
        !          74346:                outb( NCR, NC_DFC );            /* Define 2K buf config    */
        !          74347:                outb( NCR, NC_TxDIS );          /* Disable Transmitter     */
        !          74348:                outb( NCR, tp->RxIdle->tn_ena); /* Enable receiver         */
        !          74349:                setivec( TNIRQ[i], tnintf[i] ); /* Seize Interrupt Vector  */
        !          74350:                outb( NIR, tp->tnmask );        /* Enable Interrupts       */
        !          74351:        }
        !          74352: 
        !          74353:        /*
        !          74354:         * Enable watchdog timer
        !          74355:         */
        !          74356:        drvl[TNMAJOR].d_time = 1;
        !          74357: }
        !          74358: 
        !          74359: /*
        !          74360:  * Unload Routine.
        !          74361:  */
        !          74362: void
        !          74363: tnuload( dev )
        !          74364: dev_t dev;
        !          74365: {
        !          74366:        register struct tnet_s  * tp;
        !          74367:        register int i;
        !          74368:        faddr_t faddr;
        !          74369: 
        !          74370:        /*
        !          74371:         * Disable watchdog timer.
        !          74372:         */
        !          74373:        drvl[TNMAJOR].d_time = 0;
        !          74374: 
        !          74375:        /*
        !          74376:         * Scan network adaptors.
        !          74377:         */
        !          74378:        for ( tp = &tnet[0], i = 0; i < 4; i++, tp++ ) {
        !          74379: 
        !          74380:                if ( tp->tnport == 0 )
        !          74381:                        continue;
        !          74382: 
        !          74383:                /*
        !          74384:                 * Disable Interrupts
        !          74385:                 */
        !          74386:                outb( NIR, 0 );
        !          74387: 
        !          74388:                /*
        !          74389:                 * Release interrupt vector.
        !          74390:                 */
        !          74391:                clrivec( TNIRQ[i] );
        !          74392: 
        !          74393:                /*
        !          74394:                 * Release virtual address AFTER disabling interrupts.
        !          74395:                 */
        !          74396:                if ( FP_SEL(faddr) = tp->tnbuf[0].tn_sel )
        !          74397:                        vrelse( faddr );
        !          74398: 
        !          74399:                /*
        !          74400:                 * Release stats segment.
        !          74401:                 */
        !          74402:                if ( tp->statseg != NULL )
        !          74403:                        sfree( tp->statseg );
        !          74404:        }
        !          74405: }
        !          74406: 
        !          74407: /*
        !          74408:  * Open Routine.
        !          74409:  *
        !          74410:  *     Low nibble  of minor device is card identifier 0 to 3.
        !          74411:  *     High nibble of minor device is code identifier 0 to 3.
        !          74412:  */
        !          74413: void
        !          74414: tnopen( dev, mode )
        !          74415: dev_t dev;
        !          74416: {
        !          74417:        register struct tnet_s * tp;
        !          74418:        int card = (dev & 0x0F);
        !          74419:        int code = (dev & 0xF0) >> 4;
        !          74420: 
        !          74421:        /*
        !          74422:         * Validate minor device and card existence.
        !          74423:         */
        !          74424:        if ( (card > 3) || (code > 3) || (tnet[card].tnport == 0)) {
        !          74425:                u.u_error = ENXIO;
        !          74426:                return;
        !          74427:        }
        !          74428: 
        !          74429:        /*
        !          74430:         * Code identifiers 1 to 3 are only valid if a prefix code is known.
        !          74431:         */
        !          74432:        if ( (code > 0) && (TNPREFIX[code] == 0) ) {
        !          74433:                u.u_error = ENXIO;
        !          74434:                return;
        !          74435:        }
        !          74436: 
        !          74437:        /*
        !          74438:         * Access network information.
        !          74439:         */
        !          74440:        tp = &tnet[card];
        !          74441: 
        !          74442:        /*
        !          74443:         * Increment reference count (# opens).
        !          74444:         */
        !          74445:        tp->refc[code]++;
        !          74446: }
        !          74447: 
        !          74448: /*
        !          74449:  * Close Routine.
        !          74450:  */
        !          74451: void
        !          74452: tnclose( dev )
        !          74453: dev_t dev;
        !          74454: {
        !          74455:        register struct tnet_s  * tp =tp = &tnet[ dev & 3];
        !          74456:        register struct tnbuf_s * np;
        !          74457:        int code = (dev & 0x30) >> 4;
        !          74458:        int s;
        !          74459: 
        !          74460:        /*
        !          74461:         * Decrement reference count.
        !          74462:         */
        !          74463:        if ( --tp->refc[code] != 0 )
        !          74464:                return;
        !          74465: 
        !          74466:        /*
        !          74467:         * Last close.
        !          74468:         * Release all queued packets.
        !          74469:         */
        !          74470:        while ( np = tp->RxBusy[code] ) {
        !          74471:                s = sphi( );
        !          74472:                tp->RxBusy[code] = np->tn_next;
        !          74473:                tn_rxena( tp, np );
        !          74474:                spl( s );
        !          74475:        }
        !          74476: }
        !          74477: 
        !          74478: /*
        !          74479:  * Watchdog Timing Routine
        !          74480:  *
        !          74481:  *     If transmit has been enabled for 1-2 seconds:
        !          74482:  *             Abort transmission of packet, forcing interrupt.
        !          74483:  */
        !          74484: void
        !          74485: tncycle( )
        !          74486: {
        !          74487:        register struct tnet_s * tp;
        !          74488:        register int code;
        !          74489:        int s;
        !          74490: 
        !          74491:        /*
        !          74492:         * Scan all network cards.
        !          74493:         */
        !          74494:        for ( tp = &tnet[0]; tp <= &tnet[3]; tp++ ) {
        !          74495: 
        !          74496:                if ( ! tp->tnport )
        !          74497:                        continue;
        !          74498: 
        !          74499:                /*
        !          74500:                 * Disable interrupts.
        !          74501:                 */
        !          74502:                s = sphi();
        !          74503: 
        !          74504:                /*
        !          74505:                 * Enable broadcasts after 5 seconds without reconfiguration.
        !          74506:                 */
        !          74507:                if ( (tp->recon > 0) && ((lbolt - tp->rbolt) > (5*HZ)) ) {
        !          74508:                        /*
        !          74509:                         * LAN was previously down.
        !          74510:                         */
        !          74511:                        if ( tp->bad[0] & 1 ) {
        !          74512:                                faddr_t fp = tp->statseg->s_faddr;
        !          74513:                                aflong( fp+TnSTATMOD*4, 1 );
        !          74514:                                tp->mod[0] |= 1;
        !          74515:                                tp->pri = 1;
        !          74516:                        }
        !          74517:                        tp->bad[0] &= ~1;
        !          74518:                        tp->recon   =  0;
        !          74519:                }
        !          74520: 
        !          74521:                /*
        !          74522:                 * Discard bad packet on transmit watchdog timeout.
        !          74523:                 */
        !          74524:                if ( (tp->tntime > 0) && (--(tp->tntime) == 0) )
        !          74525:                        outb( NCR, NC_TxDIS );
        !          74526: 
        !          74527:                /*
        !          74528:                 * Enable interrupts.
        !          74529:                 */
        !          74530:                spl( s );
        !          74531: 
        !          74532:                /*
        !          74533:                 * LAN/DEVICE UP/DOWN event has occurred.
        !          74534:                 */
        !          74535:                if ( tp->pri == 1 ) {
        !          74536: 
        !          74537:                        tp->pri = 2;
        !          74538: 
        !          74539:                        for ( code = 0; code < 4; code++ )
        !          74540:                                if ( tp->RxPoll[code].e_procp )
        !          74541:                                        pollwake( &tp->RxPoll[code] );
        !          74542:                }
        !          74543:        }
        !          74544: }
        !          74545: 
        !          74546: static
        !          74547: tnioctl( dev, com, arg )
        !          74548: dev_t dev;
        !          74549: int com;
        !          74550: register tnattr_t * arg;
        !          74551: {
        !          74552:        register struct tnet_s * tp = &tnet[dev & 3];
        !          74553:        faddr_t fp;
        !          74554:        int nid;
        !          74555:        long t;
        !          74556:        tnattr_t local;                 /* to avoid fucopy() problems */
        !          74557: 
        !          74558:        switch ( com ) {
        !          74559: 
        !          74560:        case TNGETA:
        !          74561:        case TNGETAF:
        !          74562:                /*
        !          74563:                 * Access node statistics.
        !          74564:                 */
        !          74565:                nid = getubd( &arg->host[5] );
        !          74566:                fp  = tp->statseg->s_faddr + nid * (NTNST*4);
        !          74567: 
        !          74568:                /*
        !          74569:                 * Disable interrupts to avoid race condition with tnintr().
        !          74570:                 */
        !          74571:                sphi();
        !          74572: 
        !          74573:                /*
        !          74574:                 * Copy node status.
        !          74575:                 */
        !          74576:                if ( tp->bad[nid/8] & bitm[nid%8] )
        !          74577:                        putubd( &arg->bad, 1 );
        !          74578:                else
        !          74579:                        putubd( &arg->bad, 0 );
        !          74580: 
        !          74581:                /*
        !          74582:                 * Copy network reconfigurations to user space.
        !          74583:                 * NOTE: This is not a node statistic, but a network stat.
        !          74584:                 */
        !          74585:                kucopy( &tp->recons, &arg->recons, sizeof(tp->recons) );
        !          74586: 
        !          74587:                /*
        !          74588:                 * Copy node statistics to user space.
        !          74589:                 */
        !          74590:                fkcopy( fp, &local.stats[0], sizeof(local.stats) );
        !          74591:                kucopy( &local.stats[0], &arg->stats[0], sizeof(arg->stats) );
        !          74592: 
        !          74593:                /*
        !          74594:                 * Copy true elapsed time of statistics collection.
        !          74595:                 */
        !          74596:                fkcopy( fp+TnELAPSED*4, &t, sizeof(t) );
        !          74597:                t = lbolt - t;
        !          74598:                kucopy( &t, &arg->stats[TnELAPSED], sizeof(arg->stats[0]) );
        !          74599: 
        !          74600:                /*
        !          74601:                 * Clear node statistics.
        !          74602:                 * NOTE: Elapsed time statistic is time of last clear.
        !          74603:                 */
        !          74604:                if ( com == TNGETAF ) {
        !          74605:                        fclear( fp, NTNST * 4 );
        !          74606:                        kfcopy( &lbolt, fp+TnELAPSED*4, sizeof(lbolt) );
        !          74607:                        if ( nid == 0 )
        !          74608:                                tp->recons = 0;
        !          74609:                }
        !          74610: 
        !          74611:                /*
        !          74612:                 * Enable interrupts.
        !          74613:                 */
        !          74614:                splo();
        !          74615: 
        !          74616:                return( 0 );
        !          74617: 
        !          74618:        default:
        !          74619:                u.u_error = EINVAL;
        !          74620:        }
        !          74621: }
        !          74622: 
        !          74623: /*
        !          74624:  * Polling Routine.
        !          74625:  *
        !          74626:  *     Note:   Double-looks are performed to prevent critical race with
        !          74627:  *             interrupt handlers,  without having to disable interrupts.
        !          74628:  */
        !          74629: static
        !          74630: tnpoll( dev, ev, msec )
        !          74631: dev_t dev;
        !          74632: int ev;
        !          74633: int msec;
        !          74634: {
        !          74635:        register struct tnet_s * tp = &tnet[dev & 3];
        !          74636:        int code = (dev & 0x30) >> 4;
        !          74637:        int rev = 0;
        !          74638: 
        !          74639:        /*
        !          74640:         * Fast check for priority, input, and output polls.
        !          74641:         * Priority poll checks for LAN UP/DOWN transition.
        !          74642:         * Input    poll checks for a full receive buffer.
        !          74643:         * Output   poll checks for an empty transmit buffer, or LAN down.
        !          74644:         */
        !          74645:        if ( (ev & POLLPRI) && (tp->pri != 0) )
        !          74646:                rev |= POLLPRI;
        !          74647:        if ( (ev & POLLIN) && (tp->RxBusy[code] != NULL) )
        !          74648:                rev |= POLLIN;
        !          74649:        if ( (ev & POLLOUT) && ((tp->TxIdle != 0) || (tp->bad[0] & 1)) )
        !          74650:                rev |= POLLOUT;
        !          74651: 
        !          74652:        /*
        !          74653:         * Fast check found an event, or this is a non-blocking poll.
        !          74654:         */
        !          74655:        if ( (rev != 0) || (msec == 0) )
        !          74656:                return( rev );
        !          74657: 
        !          74658:        /*
        !          74659:         * Blocking Input poll.
        !          74660:         */
        !          74661:        if ( ev & POLLIN ) {
        !          74662: 
        !          74663:                pollopen( &tp->RxPoll[code] );
        !          74664: 
        !          74665:                /*
        !          74666:                 * Second look to avoid interrupt race.
        !          74667:                 */
        !          74668:                if ( tp->RxBusy[code] )
        !          74669:                        return( POLLIN );
        !          74670:        }
        !          74671: 
        !          74672:        /*
        !          74673:         * Blocking Output poll.
        !          74674:         */
        !          74675:        if ( ev & POLLOUT ) {
        !          74676: 
        !          74677:                pollopen( &tp->TxPoll );
        !          74678: 
        !          74679:                /*
        !          74680:                 * Second look to avoid interrupt race.
        !          74681:                 * NOTE: When the LAN is down broadcasts [nid 0] are disabled.
        !          74682:                 */
        !          74683:                if ( (tp->TxIdle != 0) || (tp->bad[0] & 1) )
        !          74684:                        return( POLLOUT );
        !          74685:        }
        !          74686: 
        !          74687:        return( rev );
        !          74688: }
        !          74689: 
        !          74690: /*
        !          74691:  * Interrupt Entry Point - Card 0.
        !          74692:  */
        !          74693: void
        !          74694: tn0intr()
        !          74695: {
        !          74696:        tnintr( &tnet[0] );
        !          74697: }
        !          74698: 
        !          74699: /*
        !          74700:  * Interrupt Entry Point - Card 1.
        !          74701:  */
        !          74702: void
        !          74703: tn1intr()
        !          74704: {
        !          74705:        tnintr( &tnet[1] );
        !          74706: }
        !          74707: 
        !          74708: /*
        !          74709:  * Interrupt Entry Point - Card 2.
        !          74710:  */
        !          74711: void
        !          74712: tn2intr()
        !          74713: {
        !          74714:        tnintr( &tnet[2] );
        !          74715: }
        !          74716: 
        !          74717: /*
        !          74718:  * Interrupt Entry Point - Card 3.
        !          74719:  */
        !          74720: void
        !          74721: tn3intr()
        !          74722: {
        !          74723:        tnintr( &tnet[3] );
        !          74724: }
        !          74725: 
        !          74726: /*
        !          74727:  * Interrupt Handler.
        !          74728:  *
        !          74729:  *     Process transmit/receive interrupts.
        !          74730:  */
        !          74731: void
        !          74732: tnintr( tp )
        !          74733: register struct tnet_s * tp;
        !          74734: {
        !          74735:        register struct tnbuf_s * np;
        !          74736:        register int csr;
        !          74737:        int nid;
        !          74738:        int n;
        !          74739:        int bit;
        !          74740: 
        !          74741:        /*
        !          74742:         * Read interrupt status.
        !          74743:         * Disable interrupts to ensure edge occurs later.
        !          74744:         */
        !          74745:        csr = inb( NSR );
        !          74746:        tp->tnmask = NI_RECON;
        !          74747:        outb( NIR, 0 );
        !          74748: 
        !          74749:        /*
        !          74750:         * Reconfigurations with a period of 840 msec [600-1100]
        !          74751:         * increment tp->recon.  Other periods clear tp->recon.
        !          74752:         * After 5 reconfigurations at 840 msecs, the network is down.
        !          74753:         * After 1 reconfiguration at another interval, the network is up.
        !          74754:         * Network also comes up in tncycle() 5 seconds after last reconfig.
        !          74755:         */
        !          74756:        if ( csr & NS_RECON ) {
        !          74757: 
        !          74758:                outb( NCR, NC_RECON );
        !          74759:                nid = (unsigned) (lbolt - tp->rbolt) * (1000/HZ);
        !          74760:                tp->rbolt = lbolt;
        !          74761:                tp->recons++;
        !          74762: 
        !          74763:                /*
        !          74764:                 * Not a chained reconfiguration.
        !          74765:                 * Assume the network is up.
        !          74766:                 * NOTE: Expect 840 msecs, but allow interrupt latency slip.
        !          74767:                 */
        !          74768:                if ( (nid < 700) || (nid > 1000) ) {
        !          74769:                        if ( tp->bad[0] & 1 ) {
        !          74770:                                tp->mod[0] |=  1;
        !          74771:                                tp->bad[0] &= ~1;
        !          74772:                                tp->pri = 1;
        !          74773:                        }
        !          74774:                        tp->recon   =  0;
        !          74775:                }
        !          74776: 
        !          74777:                /*
        !          74778:                 * Chained reconfiguration - threshold exceeded.
        !          74779:                 */
        !          74780:                else if ( (++(tp->recon) == 5) && ((tp->bad[0] & 1) == 0) ) {
        !          74781:                        faddr_t fp = tp->statseg->s_faddr;
        !          74782:                        aflong( fp+TnSTATMOD*4, 1 );
        !          74783:                        memset( tp->bad, -1, sizeof(tp->bad) );
        !          74784:                        tp->mod[0] |= 1;
        !          74785:                        tp->pri = 1;
        !          74786:                }
        !          74787:        }
        !          74788: 
        !          74789:        /*
        !          74790:         * Service Power on Resets.
        !          74791:         */
        !          74792:        if ( csr & NS_POR ) {
        !          74793: 
        !          74794:                csr &= ~(NS_RxRDY|NS_TxRDY);    /* Ignore receive/transmit */
        !          74795:                outb( NCR, NC_DFC );            /* Define 2K buf config    */
        !          74796:                outb( NCR, NC_POR );            /* Clear POR flag          */
        !          74797: 
        !          74798:                /*
        !          74799:                 * Enable receiver
        !          74800:                 */
        !          74801:                if ( np = tp->RxIdle )
        !          74802:                        outb( NCR, np->tn_ena );
        !          74803: 
        !          74804:                /*
        !          74805:                 * Enable transmitter
        !          74806:                 */
        !          74807:                if ( np = tp->TxBusy )
        !          74808:                        outb( NCR, np->tn_ena );
        !          74809:        }
        !          74810: 
        !          74811:        /*
        !          74812:         * Service transmit interupts if transmit is pending.
        !          74813:         */
        !          74814:        if ( np = tp->TxBusy ) {
        !          74815: 
        !          74816:                tp->tnmask |= NI_Tx;
        !          74817: 
        !          74818:                /*
        !          74819:                 * Check for transmission completed.
        !          74820:                 */
        !          74821:                if ( csr & NS_TxRDY ) {
        !          74822: 
        !          74823:                        /*
        !          74824:                         * Destination Node Id is in 2nd byte of packet.
        !          74825:                         */
        !          74826:                        np->tn_off = np->tn_base + 1;
        !          74827:                        nid = tngetc( np );
        !          74828: 
        !          74829:                        /*
        !          74830:                         * Get length of short/long packets.
        !          74831:                         */
        !          74832:                        n = 256 - tngetc(np);
        !          74833:                        if ( n == 256 )
        !          74834:                                n = 512 - tngetc(np);
        !          74835: 
        !          74836:                        /*
        !          74837:                         * Transmitted packet was acknowledged.
        !          74838:                         */
        !          74839:                        if ( csr & NS_TxACK ) {
        !          74840:                                /*
        !          74841:                                 * Adjust global and node statistics.
        !          74842:                                 */
        !          74843:                                faddr_t fp = tp->statseg->s_faddr;
        !          74844:                                aflong( fp+TnTxPACKS*4, 1 );
        !          74845:                                aflong( fp+TnTxBYTES*4, n );
        !          74846:                                fp += nid * (NTNST * 4);
        !          74847:                                aflong( fp+TnTxPACKS*4, 1 );
        !          74848:                                aflong( fp+TnTxBYTES*4, n );
        !          74849:                        }
        !          74850: 
        !          74851:                        /*
        !          74852:                         * Transmitted packet was discarded.
        !          74853:                         * NOTE: Do not flag broadcast [nid 0] as bad.
        !          74854:                         */
        !          74855:                        else if ( nid != 0 ) {
        !          74856:                                /*
        !          74857:                                 * Adjust global and node statistics.
        !          74858:                                 */
        !          74859:                                faddr_t fp = tp->statseg->s_faddr;
        !          74860:                                aflong( fp+TnDISCARD*4, 1 );
        !          74861:                                fp += nid * (NTNST * 4);
        !          74862:                                aflong( fp+TnDISCARD*4, 1 );
        !          74863:                                aflong( fp+TnSTATMOD*4, 1 );
        !          74864: 
        !          74865:                                /*
        !          74866:                                 * Flag node as being bad.
        !          74867:                                 */
        !          74868:                                bit = bitm[ nid % 8 ];
        !          74869:                                tp->bad[ nid / 8 ] |= bit;
        !          74870:                                tp->mod[ nid / 8 ] |= bit;
        !          74871:                                tp->pri = 1;
        !          74872:                        }
        !          74873: 
        !          74874:                        /*
        !          74875:                         * Move packet buffer to idle transmit queue.
        !          74876:                         */
        !          74877:                        tp->TxBusy  = np->tn_next;
        !          74878:                        np->tn_next = tp->TxIdle;
        !          74879:                        tp->TxIdle  = np;
        !          74880: 
        !          74881:                        /*
        !          74882:                         * Check for another packet to transmit.
        !          74883:                         */
        !          74884:                        if ( np = tp->TxBusy ) {
        !          74885: 
        !          74886:                                /*
        !          74887:                                 * Enable transmitter, start watchdog timer.
        !          74888:                                 */
        !          74889:                                outb( NCR, np->tn_ena );
        !          74890:                                tp->tntime = TNTIME;
        !          74891:                        }
        !          74892: 
        !          74893:                        /*
        !          74894:                         * Disable Transmit Interrupt, clear watchdog timer.
        !          74895:                         */
        !          74896:                        else {
        !          74897:                                tp->tnmask &= ~NI_Tx;
        !          74898:                                tp->tntime  =  0;
        !          74899:                        }
        !          74900: 
        !          74901:                        /*
        !          74902:                         * Wake processes waiting to transmit.
        !          74903:                         */
        !          74904:                        if ( tp->TxReq ) {
        !          74905:                                tp->TxReq = 0;
        !          74906:                                defer( wakeup, &tp->TxReq );
        !          74907:                        }
        !          74908: 
        !          74909:                        if ( tp->TxPoll.e_procp )
        !          74910:                                defer( pollwake, &tp->TxPoll );
        !          74911:                }
        !          74912:        }
        !          74913: 
        !          74914:        /*
        !          74915:         * Check for receive request.
        !          74916:         */
        !          74917:        if ( np = tp->RxIdle ) {
        !          74918: 
        !          74919:                tp->tnmask |= NI_Rx;
        !          74920: 
        !          74921:                /*
        !          74922:                 * Check for packet received.
        !          74923:                 */
        !          74924:                if ( csr & NS_RxRDY ) {
        !          74925: 
        !          74926:                        /*
        !          74927:                         * Remove first packet from receive ready queue.
        !          74928:                         * Re-enable receiver or disable receive interrupts.
        !          74929:                         */
        !          74930:                        if ( tp->RxIdle = np->tn_next ) {
        !          74931:                                outb( NCR, np->tn_next->tn_ena );
        !          74932:                                np->tn_next = 0;
        !          74933:                        }
        !          74934:                        else
        !          74935:                                tp->tnmask &= ~NI_Rx;
        !          74936: 
        !          74937:                        /*
        !          74938:                         * Source Node Id is in 1st byte of packet.
        !          74939:                         */
        !          74940:                        np->tn_off = np->tn_base;
        !          74941:                        nid = tngetc( np );
        !          74942: 
        !          74943:                        /*
        !          74944:                         * Try to establish our Node Id if not already set.
        !          74945:                         * Destination Node Id (our station)
        !          74946:                         * is in 2nd byte of the received packet.
        !          74947:                         * NOTE: Always read node id byte.
        !          74948:                         *       This ensures offset bytes can be read.
        !          74949:                         */
        !          74950:                        if ( (n = tngetc(np)) && (tp->tnaddr[0] == 0) )
        !          74951:                                tp->tnaddr[0] = n;
        !          74952: 
        !          74953:                        /*
        !          74954:                         * Get offset to first data byte in short/long packet.
        !          74955:                         * Short packet offset is in 3rd byte of packet.
        !          74956:                         * Long  packet offset is in 4th byte of packet.
        !          74957:                         */
        !          74958:                        if ( n = tngetc(np) )
        !          74959:                                np->tn_off = np->tn_base + n;
        !          74960:                        else
        !          74961:                                np->tn_off = np->tn_base + tngetc(np);
        !          74962: 
        !          74963:                        /*
        !          74964:                         * LAN has come up.
        !          74965:                         * Clear bad flag for the broadcast node.
        !          74966:                         */
        !          74967:                        if ( tp->bad[0] & 1 ) {
        !          74968:                                tp->bad[ 0 ] &= ~1;
        !          74969:                                tp->mod[ 0 ] |=  1;
        !          74970:                                tp->pri = 1;
        !          74971:                        }
        !          74972: 
        !          74973:                        /*
        !          74974:                         * Node has come up.
        !          74975:                         * Clear bad flag for the Source Node.
        !          74976:                         */
        !          74977:                        bit = bitm[ nid % 8 ];
        !          74978:                        if ( tp->bad[ nid / 8 ] & bit ) {
        !          74979:                                faddr_t fp = tp->statseg->s_faddr;
        !          74980:                                aflong( fp+TnSTATMOD*4, 1 );
        !          74981:                                fp += nid * (NTNST * 4);
        !          74982:                                aflong( fp+TnSTATMOD*4, 1 );
        !          74983:                                tp->bad[ nid / 8 ] &= ~bit;
        !          74984:                                tp->mod[ nid / 8 ] |=  bit;
        !          74985:                                tp->pri = 1;
        !          74986:                        }
        !          74987: 
        !          74988:                        /*
        !          74989:                         * Get first data byte from packet.
        !          74990:                         */
        !          74991:                        bit = tngetc( np );
        !          74992: 
        !          74993:                        /*
        !          74994:                         * Determine prefix code associated with packet.
        !          74995:                         */
        !          74996:                        for ( n = 3; n > 0; n-- ) {
        !          74997:                                if ( TNPREFIX[n] == bit )
        !          74998:                                        break;
        !          74999:                        }
        !          75000: 
        !          75001:                        /*
        !          75002:                         * Interface is open.
        !          75003:                         */
        !          75004:                        if ( tp->refc[n] ) {
        !          75005: 
        !          75006:                                /*
        !          75007:                                 * Append received packet to received queue.
        !          75008:                                 * NOTE: At most 2 packets in any queue.
        !          75009:                                 */
        !          75010:                                if ( tp->RxBusy[n] )
        !          75011:                                        tp->RxBusy[n]->tn_next = np;
        !          75012:                                else
        !          75013:                                        tp->RxBusy[n] = np;
        !          75014:        
        !          75015:                                /*
        !          75016:                                 * Wake processes waiting to read.
        !          75017:                                 */
        !          75018:                                if ( tp->RxReq[n] ) {
        !          75019:                                        tp->RxReq[n] = 0;
        !          75020:                                        defer( wakeup, &tp->RxReq[n] );
        !          75021:                                }
        !          75022:        
        !          75023:                                if ( tp->RxPoll[n].e_procp )
        !          75024:                                        defer( pollwake, &tp->RxPoll[n] );
        !          75025:                        }
        !          75026: 
        !          75027:                        /*
        !          75028:                         * Interface is closed.
        !          75029:                         * Return packet to end of receive idle queue.
        !          75030:                         */
        !          75031:                        else
        !          75032:                                tn_rxena( tp, np );
        !          75033:                }
        !          75034:        }
        !          75035: 
        !          75036:        /*
        !          75037:         * Restore interrupt mask.
        !          75038:         */
        !          75039:        outb( NIR, tp->tnmask );
        !          75040: }
        !          75041: 
        !          75042: /*
        !          75043:  * Read Routine.
        !          75044:  *
        !          75045:  *     Wait for a packet to be received.
        !          75046:  *     Transform packet header and copy packet body.
        !          75047:  *     Place packet buffer on receive idle queue.
        !          75048:  *     If receiver was inhibited, enable receiver.
        !          75049:  */
        !          75050: 
        !          75051: 
        !          75052: tnread ( dev, iop )
        !          75053: 
        !          75054: dev_t dev;
        !          75055: register IO * iop;
        !          75056: 
        !          75057: {
        !          75058:        register struct tnet_s  * tp = &tnet[ dev & 3 ];
        !          75059:        register struct tnbuf_s * np;
        !          75060:        int code = (dev & 0x30) >> 4;
        !          75061:        unsigned len;
        !          75062:        unsigned cnt;
        !          75063:        unsigned srcid;
        !          75064:        int s;
        !          75065: 
        !          75066:        /*
        !          75067:         * Driver information requested.
        !          75068:         */
        !          75069:        if ( iop->io_ioc <= 2 + sizeof(tp->bad) + sizeof(tp->mod) ) {
        !          75070: 
        !          75071:                /*
        !          75072:                 * Supply null byte, then our node id.
        !          75073:                 */
        !          75074:                ioputc( 0, iop );
        !          75075:                ioputc( tp->tnaddr[0], iop );
        !          75076: 
        !          75077:                /*
        !          75078:                 * Bad and modified node bit masks requested.
        !          75079:                 * Disable interrupts during transfer to prevent
        !          75080:                 * critical race with tnintr().
        !          75081:                 */
        !          75082:                if ( iop->io_ioc == sizeof(tp->bad) + sizeof(tp->mod) ) {
        !          75083:                        sphi();
        !          75084:                        iowrite( iop, tp->bad, sizeof(tp->bad) );
        !          75085:                        iowrite( iop, tp->mod, sizeof(tp->mod) );
        !          75086:                        kclear( tp->mod, sizeof(tp->mod) );
        !          75087:                        tp->pri = 0;
        !          75088:                        splo();
        !          75089:                }
        !          75090: 
        !          75091:                /*
        !          75092:                 * Bad node bit mask requested.
        !          75093:                 */
        !          75094:                else if ( iop->io_ioc == sizeof(tp->bad) )
        !          75095:                        iowrite( iop, tp->bad, sizeof(tp->bad) );
        !          75096: 
        !          75097:                return;
        !          75098:        }
        !          75099: 
        !          75100:        /*
        !          75101:         * Wait for packet reception.
        !          75102:         */
        !          75103:        for ( ; ; ) {
        !          75104: 
        !          75105:                s = sphi( );
        !          75106: 
        !          75107:                /*
        !          75108:                 * Check for received packet.
        !          75109:                 */
        !          75110:                if ( np = tp->RxBusy[code] ) {
        !          75111:                        tp->RxBusy[code] = np->tn_next;
        !          75112:                        np->tn_next = 0;
        !          75113:                        spl( s );
        !          75114:                        break;
        !          75115:                }
        !          75116: 
        !          75117:                /*
        !          75118:                 * Non-blocking reads.
        !          75119:                 */
        !          75120:                if ( iop->io_flag & IONDLY ) {
        !          75121:                        u.u_error = EAGAIN;
        !          75122:                        spl( s );
        !          75123:                        return;
        !          75124:                }
        !          75125: 
        !          75126:                tp->RxReq[code] = 1;
        !          75127: 
        !          75128:                sleep( &tp->RxReq[code], CVTTIN, IVTTIN, SVTTIN );
        !          75129:                spl( s );
        !          75130: 
        !          75131:                /*
        !          75132:                 * Check for pending signal.
        !          75133:                 */
        !          75134:                if ( nondsig() ) {
        !          75135:                        u.u_error = EINTR;
        !          75136:                        return;
        !          75137:                }
        !          75138:        }
        !          75139: 
        !          75140:        /*
        !          75141:         * Copy source and destination node ids
        !          75142:         */
        !          75143:        np->tn_off = np->tn_base;
        !          75144:        ioputc( srcid = tngetc(np), iop );
        !          75145:        ioputc( tngetc(np), iop );
        !          75146: 
        !          75147:        /*
        !          75148:         * Check for short packet.
        !          75149:         */
        !          75150:        if ( cnt = tngetc(np) ) {
        !          75151: 
        !          75152:                np->tn_off = np->tn_base + cnt;
        !          75153:                len = 256 - cnt;
        !          75154:        }
        !          75155: 
        !          75156:        /*
        !          75157:         * Check for long packet.
        !          75158:         */
        !          75159:        else if ( cnt = tngetc(np) ) {
        !          75160: 
        !          75161:                np->tn_off = np->tn_base + cnt;
        !          75162:                len = 512 - cnt;
        !          75163:        }
        !          75164: 
        !          75165:        /*
        !          75166:         * Check for non-empty packet.
        !          75167:         */
        !          75168:        if ( cnt != 0 ) {
        !          75169: 
        !          75170:                /*
        !          75171:                 * Truncate packet if necessary.
        !          75172:                 */
        !          75173:                if ( iop->io_ioc < len )
        !          75174:                        len = iop->io_ioc;
        !          75175: 
        !          75176:                /*
        !          75177:                 * Copy packet body.
        !          75178:                 */
        !          75179:                tucopy( np, iop->io_base, len );
        !          75180:                iop->io_ioc  -= len;
        !          75181:                iop->io_base += len;
        !          75182:        }
        !          75183: 
        !          75184:        /*
        !          75185:         * Adjust received data statistics.
        !          75186:         */
        !          75187:        if ( tp->statseg != NULL ) {
        !          75188:                faddr_t fp = tp->statseg->s_faddr;
        !          75189:                aflong( fp+TnRxPACKS*4, 1 );
        !          75190:                aflong( fp+TnRxBYTES*4, len );
        !          75191:                fp += srcid * (NTNST * 4);
        !          75192:                aflong( fp+TnRxPACKS*4, 1 );
        !          75193:                aflong( fp+TnRxBYTES*4, len );
        !          75194:        }
        !          75195: 
        !          75196:        /*
        !          75197:         * Enable packet reception with buffer.
        !          75198:         */
        !          75199:        tn_rxena( tp, np );
        !          75200: }
        !          75201: 
        !          75202: 
        !          75203: /*
        !          75204:  * Write Routine.
        !          75205:  *
        !          75206:  *     Wait for a empty transmit buffer to become available.
        !          75207:  *     Format the buffer and place on transmit queue.
        !          75208:  *     If transmit queue was empty, start transmitter.
        !          75209:  */
        !          75210: 
        !          75211: tnwrite ( dev, iop )
        !          75212: 
        !          75213: dev_t dev;
        !          75214: register IO * iop;
        !          75215: 
        !          75216: {
        !          75217:        register struct tnet_s  * tp = &tnet[ dev & 3 ];
        !          75218:        register struct tnbuf_s * np;
        !          75219:        unsigned len, cnt;
        !          75220:        int dstid;
        !          75221:        int s;
        !          75222: 
        !          75223:        /*
        !          75224:         * Validate size of write.
        !          75225:         */
        !          75226:        if ( ( iop->io_ioc < 3 ) || ( iop->io_ioc > 510 ) ) {
        !          75227:                u.u_error = EINVAL;
        !          75228:                return;
        !          75229:        }
        !          75230: 
        !          75231:        /*
        !          75232:         * Destination Node Id is 2nd byte of write.
        !          75233:         */
        !          75234:        iogetc( iop );
        !          75235:        dstid = iogetc( iop );
        !          75236: 
        !          75237:        /*
        !          75238:         * Wait for empty transmit buffer.
        !          75239:         */
        !          75240:        for ( ; ; ) {
        !          75241: 
        !          75242:                /*
        !          75243:                 * If Destination Node appears bad, set errno to EDATTN.
        !          75244:                 */
        !          75245:                if ( tp->bad[ dstid / 8 ] & (1 << (dstid % 8)) ) {
        !          75246:                        u.u_error = EDATTN;
        !          75247:                        return;
        !          75248:                }
        !          75249: 
        !          75250:                s = sphi( );
        !          75251: 
        !          75252:                /*
        !          75253:                 * Check for empty transmit buffer.
        !          75254:                 */
        !          75255:                if ( np = tp->TxIdle ) {
        !          75256: 
        !          75257:                        tp->TxIdle  = np->tn_next;
        !          75258:                        np->tn_next = 0;
        !          75259:                        spl( s );
        !          75260:                        break;
        !          75261:                }
        !          75262: 
        !          75263:                /*
        !          75264:                 * Non-blocking writes.
        !          75265:                 */
        !          75266:                if ( iop->io_flag & IONDLY ) {
        !          75267:                        /*
        !          75268:                         * Adjust delayed write stats.
        !          75269:                         */
        !          75270:                        faddr_t fp = tp->statseg->s_faddr;
        !          75271:                        aflong( fp+TnWRTDLYS*4, 1 );
        !          75272:                        fp += dstid * (NTNST * 4);
        !          75273:                        aflong( fp+TnWRTDLYS*4, 1 );
        !          75274: 
        !          75275:                        u.u_error = EAGAIN;
        !          75276:                        spl( s );
        !          75277:                        return;
        !          75278:                }
        !          75279: 
        !          75280:                tp->TxReq = 1;
        !          75281:                sleep( &tp->TxReq, CVTTOUT, IVTTOUT, SVTTOUT );
        !          75282:                spl( s );
        !          75283: 
        !          75284:                /*
        !          75285:                 * Check for pending signal.
        !          75286:                 */
        !          75287:                if ( nondsig() ) {
        !          75288:                        u.u_error = EINTR;
        !          75289:                        return;
        !          75290:                }
        !          75291:        }
        !          75292: 
        !          75293:        /*
        !          75294:         * Copy source and destination node ids
        !          75295:         * NOTE: Hardware inserts source node id automatically.
        !          75296:         */
        !          75297:        np->tn_off = np->tn_base;
        !          75298:        tnputc( np, 0 );
        !          75299:        tnputc( np, dstid );
        !          75300: 
        !          75301:        len = iop->io_ioc;
        !          75302: 
        !          75303:        /*
        !          75304:         * Check for long packet.
        !          75305:         */
        !          75306:        if ( len > 253 ) {
        !          75307:                tnputc( np, 0 );
        !          75308:                tnputc( np, cnt = 512 - len );
        !          75309:                np->tn_off = np->tn_base + cnt;
        !          75310:        }
        !          75311: 
        !          75312:        /*
        !          75313:         * Short packet.
        !          75314:         */
        !          75315:        else {
        !          75316:                tnputc( np, cnt = 256 - len );
        !          75317:                np->tn_off = np->tn_base + cnt;
        !          75318:        }
        !          75319: 
        !          75320:        /*
        !          75321:         * Copy packet body.
        !          75322:         */
        !          75323:        utcopy( iop->io_base, np, len );
        !          75324:        iop->io_base += len;
        !          75325:        iop->io_ioc  -= len;
        !          75326: 
        !          75327:        /*
        !          75328:         * Record length in header structure.
        !          75329:         */
        !          75330:        np->tn_xlen = iop->io_ioc;
        !          75331: 
        !          75332:        sphi();
        !          75333: 
        !          75334:        /*
        !          75335:         * Put packet on transmit ready queue, prime transmitter if necessary.
        !          75336:         */
        !          75337:        if ( ! tp->TxBusy ) {
        !          75338:                tp->TxBusy = np;
        !          75339:                outb( NCR, np->tn_ena );         /* enable transmitter  */
        !          75340:                outb( NIR, tp->tnmask |= NI_Tx); /* enable xmit intr    */
        !          75341:                tp->tntime = TNTIME;             /* restart watchdog    */
        !          75342:        }
        !          75343:        else
        !          75344:                tp->TxBusy->tn_next = np;
        !          75345: 
        !          75346:        spl(s);
        !          75347: }
        !          75348: 
        !          75349: /*
        !          75350:  * Enable packet reception with buffer.
        !          75351:  */
        !          75352: tn_rxena( tp, np )
        !          75353: register struct tnet_s  * tp;
        !          75354: register struct tnbuf_s * np;
        !          75355: {
        !          75356:        int s;
        !          75357: 
        !          75358:        s = sphi( );
        !          75359: 
        !          75360:        /*
        !          75361:         * Put packet on receive ready queue, prime receiver if necessary.
        !          75362:         */
        !          75363:        if ( tp->RxIdle == NULL ) {
        !          75364:                tp->RxIdle = np;
        !          75365:                outb( NCR, np->tn_ena );
        !          75366:                outb( NIR, tp->tnmask |= NI_Rx );
        !          75367:        }
        !          75368:        else
        !          75369:                tp->RxIdle->tn_next = np;
        !          75370: 
        !          75371:        np->tn_next = 0;
        !          75372:        spl( s );
        !          75373: }
        !          75374: 
        !          75375: /*
        !          75376:  * Adjust far long.
        !          75377:  */
        !          75378: static
        !          75379: aflong( fp, i )
        !          75380: faddr_t fp;
        !          75381: int i;
        !          75382: {
        !          75383:        long lw;
        !          75384: 
        !          75385:        fkcopy( fp, &lw, sizeof(lw) );
        !          75386:        lw += i;
        !          75387:        kfcopy( &lw, fp, sizeof(lw) );
        !          75388: }
        !          75389: @
        !          75390: 
        !          75391: 
        !          75392: 1.1
        !          75393: log
        !          75394: @Initial revision
        !          75395: @
        !          75396: text
        !          75397: @d14 1
        !          75398: a14 1
        !          75399: #include <coherent.h>
        !          75400: a15 1
        !          75401: #include <sys/fun.h>
        !          75402: a18 1
        !          75403: #include <sys/types.h>
        !          75404: a19 1
        !          75405: #include <sys/timeout.h>
        !          75406: @
        !          75407: 0707070064030106271004440000030000030000011777770507310703100005600000007407/newbits/kernel/USRSRC/i8086/drv/RCS/tnas.s,vhead     1.1;
        !          75408: branch   ;
        !          75409: access   ;
        !          75410: symbols  ;
        !          75411: locks    bin:1.1; strict;
        !          75412: comment  @@;
        !          75413: 
        !          75414: 
        !          75415: 1.1
        !          75416: date     91.06.10.10.28.49;  author bin;  state Exp;
        !          75417: branches ;
        !          75418: next     ;
        !          75419: 
        !          75420: 
        !          75421: desc
        !          75422: @initial version prov by hal
        !          75423: @
        !          75424: 
        !          75425: 
        !          75426: 
        !          75427: 1.1
        !          75428: log
        !          75429: @Initial revision
        !          75430: @
        !          75431: text
        !          75432: @/ (lgl-
        !          75433: /      COHERENT Driver Kit Version 1.1.0
        !          75434: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          75435: /      All rights reserved. May not be copied without permission.
        !          75436: / -lgl)
        !          75437: ////////
        !          75438: /
        !          75439: / Tiac Network Assembler Support
        !          75440: /
        !          75441: /      tngetc( np )            -- get a character from a tiac network buffer
        !          75442: /      tnputc( np, c)          -- put a character into a tiac network buffer
        !          75443: /      tucopy( np, up, n)      -- copy n bytes from tiac buffer to user space
        !          75444: /      utcopy( up, np, n)      -- copy n bytes from user space to tiac buffer
        !          75445: /
        !          75446: ////////
        !          75447: 
        !          75448:        .globl  tngetc_
        !          75449:        .globl  tnputc_
        !          75450:        .globl  tucopy_
        !          75451:        .globl  utcopy_
        !          75452: 
        !          75453: ////////
        !          75454: /
        !          75455: / Tngetc ( np )
        !          75456: /
        !          75457: /      Input:  np = pointer to seg:offset pair for tiac network buffer
        !          75458: /
        !          75459: /      Action: Read character from network buffer, increment offset.
        !          75460: /
        !          75461: /      Return: Character.
        !          75462: /
        !          75463: ////////
        !          75464: 
        !          75465: tngetc_:                               / tngetc( np )
        !          75466:        push    si                      / char **np;
        !          75467:        push    bp                      / {
        !          75468:        mov     bp, sp                  /       register char c;        /* AX */
        !          75469:        mov     bx, 6(bp)               /       register char *cp;      /* SI */
        !          75470:        push    ds                      /
        !          75471:        lds     si, (bx)                /       cp = *np;
        !          75472:        cld                             /
        !          75473:        lodsb                           /       c = *cp++;
        !          75474:        pop     ds                      /
        !          75475:        mov     (bx), si                /       *np = cp;
        !          75476:        subb    ah, ah                  /
        !          75477:        pop     bp                      /       return( c );
        !          75478:        pop     si                      / }
        !          75479:        ret
        !          75480: 
        !          75481: ////////
        !          75482: /
        !          75483: / Tnputc ( np, c )
        !          75484: / char **np;
        !          75485: / char c;
        !          75486: /
        !          75487: /      Input:  np = pointer to seg:offset pair for tiac network buffer
        !          75488: /              c  = character to transfer
        !          75489: /
        !          75490: /      Action: Transfer character C to network buffer, increment offset.
        !          75491: /
        !          75492: /      Return: Character C.
        !          75493: /
        !          75494: ////////
        !          75495: 
        !          75496: tnputc_:                               / tnputc( np, c )
        !          75497:        push    di                      / char **np;                    /* BX */
        !          75498:        push    bp                      / char c;                       /* AX */
        !          75499:        mov     bp, sp                  / {
        !          75500:        mov     ax, 8(bp)               /       register char *cp;      /* DI */
        !          75501:        mov     bx, 6(bp)               /
        !          75502:        push    es                      /
        !          75503:        les     di, (bx)                /       cp = *np;
        !          75504:        cld                             /
        !          75505:        stosb                           /       *cp++ = c;
        !          75506:        pop     es                      /
        !          75507:        mov     (bx), di                /       *np = cp;
        !          75508:        pop     bp                      /
        !          75509:        pop     di                      /       return c;
        !          75510:        ret                             / }
        !          75511: 
        !          75512: ////////
        !          75513: /
        !          75514: / utcopy( up, np, n )
        !          75515: / char * up;
        !          75516: / char **np;
        !          75517: / unsigned n;
        !          75518: /
        !          75519: /      Input:  up = offset in user data space for source data
        !          75520: /              np = pointer to seg:offset pair for tiac network buffer
        !          75521: /              n  = number of bytes to transfer
        !          75522: /
        !          75523: /      Action: Copy N bytes from user data space to network data space.
        !          75524: /              Add N to network data space offset.
        !          75525: /
        !          75526: /      Return: None.
        !          75527: /
        !          75528: ////////
        !          75529: 
        !          75530: utcopy_:                               / utcopy( up, np, n )
        !          75531:        push    si                      /
        !          75532:        push    di                      / register char *  up;          /* SI */
        !          75533:        push    bp                      / register char ** np;          /* BX */
        !          75534:        mov     bp, sp                  / register unsigned n;          /* CX */
        !          75535:        push    ds                      /
        !          75536:        push    es                      / {
        !          75537:        mov     bx, 10(bp)              /       register char * cp;     /* DI */
        !          75538:                                        /
        !          75539:        les     di, (bx)                /       cp = *np;
        !          75540:                                        /
        !          75541:        mov     si, 8(bp)               /       up;
        !          75542:        mov     ds, uds_                /
        !          75543:                                        /
        !          75544:        mov     cx, 12(bp)              /       n;
        !          75545:                                        /
        !          75546:        cld                             /
        !          75547:        clc                             /
        !          75548:        rcr     cx, $1                  /
        !          75549:        rep                             /       for ( ; n != 0; --n )
        !          75550:        movsw                           /               *cp++ = *up++;
        !          75551:        rcl     cx, $1                  /
        !          75552:        rep                             /
        !          75553:        movsb                           /
        !          75554:                                        /
        !          75555:        pop     es                      /
        !          75556:        pop     ds                      /
        !          75557:        mov     (bx), di                /       *np = cp;
        !          75558:        pop     bp                      / }
        !          75559:        pop     di
        !          75560:        pop     si
        !          75561:        ret
        !          75562: 
        !          75563: ////////
        !          75564: /
        !          75565: / tucopy( np, up, n )
        !          75566: / char **np;
        !          75567: / char * up;
        !          75568: / unsigned n;
        !          75569: /
        !          75570: /      Input:  np = pointer to seg:offset pair for tiac network buffer
        !          75571: /              up = offset in user data space for destination
        !          75572: /              n  = number of bytes to transfer
        !          75573: /
        !          75574: /      Action: Copy N bytes from network data space to user data space.
        !          75575: /              Add N to network data space offset.
        !          75576: /
        !          75577: /      Return: None.
        !          75578: /
        !          75579: ////////
        !          75580: 
        !          75581: tucopy_:                               / tucopy( np, up, n )
        !          75582:        push    si                      /
        !          75583:        push    di                      / register char ** np;          /* BX */
        !          75584:        push    bp                      / register char *  up;          /* DI */
        !          75585:        mov     bp, sp                  / register unsigned n;          /* CX */
        !          75586:        push    ds                      /
        !          75587:        push    es                      / {
        !          75588:        mov     bx, 8(bp)               /       register char * cp;     /* SI */
        !          75589:                                        /
        !          75590:        mov     di, 10(bp)              /       up;
        !          75591:        mov     es, uds_                /
        !          75592:                                        /
        !          75593:        lds     si, (bx)                /       cp = *np;
        !          75594:                                        /
        !          75595:        mov     cx, 12(bp)              /       n;
        !          75596:                                        /
        !          75597:        cld                             /
        !          75598:        clc                             /
        !          75599:        rcr     cx, $1                  /
        !          75600:        rep                             /       for ( ; n != 0; --n )
        !          75601:        movsw                           /               *up++ = *cp++;
        !          75602:        rcl     cx, $1                  /
        !          75603:        rep                             /
        !          75604:        movsb                           /
        !          75605:                                        /
        !          75606:        pop     es                      /
        !          75607:        pop     ds                      /
        !          75608:        mov     (bx), si                /       *np = cp;
        !          75609:        pop     bp                      / }
        !          75610:        pop     di
        !          75611:        pop     si
        !          75612:        ret
        !          75613: @
        !          75614: 0707070064030106571004440000030000030000011777770507310703100005500000047027/newbits/kernel/USRSRC/i8086/drv/RCS/nkb.c,vhead     1.4;
        !          75615: branch   ;
        !          75616: access   ;
        !          75617: symbols  ;
        !          75618: locks    bin:1.4; strict;
        !          75619: comment  @ * @;
        !          75620: 
        !          75621: 
        !          75622: 1.4
        !          75623: date     91.06.20.14.51.43;  author bin;  state Exp;
        !          75624: branches ;
        !          75625: next     1.3;
        !          75626: 
        !          75627: 1.3
        !          75628: date     91.06.17.12.33.54;  author bin;  state Exp;
        !          75629: branches ;
        !          75630: next     1.2;
        !          75631: 
        !          75632: 1.2
        !          75633: date     91.06.13.12.53.07;  author bin;  state Exp;
        !          75634: branches ;
        !          75635: next     1.1;
        !          75636: 
        !          75637: 1.1
        !          75638: date     91.06.10.14.31.59;  author bin;  state Exp;
        !          75639: branches ;
        !          75640: next     ;
        !          75641: 
        !          75642: 
        !          75643: desc
        !          75644: @loadable keyboard driver
        !          75645: initial version prov by hal
        !          75646: @
        !          75647: 
        !          75648: 
        !          75649: 1.4
        !          75650: log
        !          75651: @update provided by hal
        !          75652: @
        !          75653: text
        !          75654: @/*
        !          75655:  * User configurable AT keyboard/display driver.
        !          75656:  * AT COHERENT
        !          75657:  */
        !          75658: #include <sys/coherent.h>
        !          75659: #include <sys/i8086.h>
        !          75660: #include <sys/con.h>
        !          75661: #include <errno.h>
        !          75662: #include <sys/stat.h>
        !          75663: #include <sys/tty.h>
        !          75664: #include <sys/uproc.h>
        !          75665: #include <signal.h>
        !          75666: #include <sys/seg.h>
        !          75667: #include <sys/sched.h>
        !          75668: #include <sys/kb.h>
        !          75669: 
        !          75670: #define        ISMAJ           2               /* Keyboard major device */
        !          75671: #define        ISVEC           1               /* Keyboard interrupt vector */
        !          75672: 
        !          75673: #if    DEBUG
        !          75674: #define        KBDEBUG(x)      printf(x)       /* debugging output */
        !          75675: #define        KBDEBUG2(x,y)   printf(x,y)     /* debugging output */
        !          75676: #define        KBDEBUG3(x,y,z) printf(x,y,z)   /* debugging output */
        !          75677: #else
        !          75678: #define        KBDEBUG(x)                      /* no output */
        !          75679: #define        KBDEBUG2(x,y)                   /* no output */
        !          75680: #define        KBDEBUG3(x,y,z)                 /* no output */
        !          75681: #endif
        !          75682: 
        !          75683: /*
        !          75684:  * values for kbstate
        !          75685:  */
        !          75686: #define        KB_IDLE         0               /* nothing going on right now */
        !          75687: #define        KB_SINGLE       1               /* sent a single byte cmd to the kbd */
        !          75688: #define        KB_DOUBLE_1     2               /* sent 1st byte of 2-byte cmd to kbd */
        !          75689: #define        KB_DOUBLE_2     3               /* sent 2nd byte of 2-byte cmd to kbd */
        !          75690: 
        !          75691: /*
        !          75692:  * patchable params for non-standard keyboards
        !          75693:  */
        !          75694: int    KBDATA = 0x60;                  /* Keyboard data */
        !          75695: int    KBCTRL = 0x61;                  /* Keyboard control */
        !          75696: int    KBSTS_CMD = 0x64;               /* Keyboard status/command */
        !          75697: int    KBFLAG = 0x80;                  /* Keyboard reset flag */
        !          75698: int    KBBOOT = 1;                     /* 0: disallow reboot from keyboard */
        !          75699: int    KBTIMEOUT = 10000;              /* shouldn't need this much */
        !          75700: int    KBCMDBYTE = 0x05;               /* no translation */
        !          75701: 
        !          75702: /*
        !          75703:  * KBSTATUS bits
        !          75704:  */
        !          75705: #define        STS_OBUF_FULL   0x01            /* kbd output buffer full */
        !          75706: #define        STS_IBUF_FULL   0x02            /* kbd input buffer full */
        !          75707: #define        STS_SYSTEM      0x04
        !          75708: #define        STS_CMD_DATA    0x08            /* 1: command or status */
        !          75709: #define        STS_INHIBIT     0x10            /* 0: keyboard inhibited */
        !          75710: #define        STS_AUX_OBUF_FULL       0x20
        !          75711: #define        STS_TIMEOUT     0x40            /* general timeout */
        !          75712: #define        STS_PAR_ERR     0x80            /* parity error */
        !          75713: 
        !          75714: /*
        !          75715:  * The following are magic commands which read from or write to the
        !          75716:  * controller command byte. These get output to the KBSTS_CMD port.
        !          75717:  */
        !          75718: #define        C_READ_CMD      0x20            /* read controller command byte */
        !          75719: #define        C_WRITE_CMD     0x60            /* write controller command byte */
        !          75720: #define        C_TRANSLATE     0x40            /* translate enable bit in cmd byte */
        !          75721: 
        !          75722: /*
        !          75723:  * Globals
        !          75724:  * The keyboard mapping table is too large to fit into kernel data space,
        !          75725:  * so we need to allocate a segment to it.
        !          75726:  * The function keys tend to be small and tend to change substantially
        !          75727:  * more often than the mapping table, so we keep them in the kernel data space.
        !          75728:  */
        !          75729: static unsigned shift;                 /* state of all shift/lock keys */
        !          75730: static SEG     *kbsegp;                /* keyboard table segment */
        !          75731: static unsigned char   **funkeyp = 0;  /* ptr to array of func. keys ptrs */
        !          75732: static FNKEY   *fnkeys = 0;            /* pointer to structure of values */
        !          75733: static unsigned fklength;              /* length of k_fnval field in fnkeys */
        !          75734: static unsigned prev_cmd;              /* previous command sent to KBD */
        !          75735: static unsigned cmd2;                  /* 2nd byte of command to KBD */
        !          75736: static unsigned sh_index;              /* shift/lock state index */
        !          75737: 
        !          75738: /*
        !          75739:  * State variables.
        !          75740:  */
        !          75741: int            islock;                 /* Keyboard locked flag */
        !          75742: int            isbusy;                 /* Raw input conversion busy */
        !          75743: static char    table_loaded;           /* true == keyboard table resident */
        !          75744: static char    fk_loaded;              /* true == function keys resident */
        !          75745: static int     kbstate = KB_IDLE;      /* current keyboard state */
        !          75746: 
        !          75747: /*
        !          75748:  * Functions.
        !          75749:  */
        !          75750: int            isrint();
        !          75751: int            istime();
        !          75752: void           isbatch();
        !          75753: int            mmstart();
        !          75754: int            isopen();
        !          75755: int            isclose();
        !          75756: int            isread();
        !          75757: int            mmwrite();
        !          75758: int            isioctl();
        !          75759: void           mmwatch();
        !          75760: int            isload();
        !          75761: int            isuload();
        !          75762: int            ispoll();
        !          75763: int            nulldev();
        !          75764: int            nonedev();
        !          75765: int            updleds();
        !          75766: 
        !          75767: /*
        !          75768:  * Configuration table.
        !          75769:  */
        !          75770: CON iscon ={
        !          75771:        DFCHR|DFPOL,                    /* Flags */
        !          75772:        ISMAJ,                          /* Major index */
        !          75773:        isopen,                         /* Open */
        !          75774:        isclose,                        /* Close */
        !          75775:        nulldev,                        /* Block */
        !          75776:        isread,                         /* Read */
        !          75777:        mmwrite,                        /* Write */
        !          75778:        isioctl,                        /* Ioctl */
        !          75779:        nulldev,                        /* Powerfail */
        !          75780:        mmwatch,                        /* Timeout */
        !          75781:        isload,                         /* Load */
        !          75782:        isuload,                        /* Unload */
        !          75783:        ispoll                          /* Poll */
        !          75784: };
        !          75785: 
        !          75786: /*
        !          75787:  * Terminal structure.
        !          75788:  */
        !          75789: TTY    istty = {
        !          75790:        {0}, {0}, 0, mmstart, NULL, 0, 0
        !          75791: };
        !          75792: 
        !          75793: /*
        !          75794:  * Load entry point.
        !          75795:  */
        !          75796: isload()
        !          75797: {
        !          75798:        kbstate = KB_IDLE;
        !          75799:        table_loaded = 0;               /* no keyboard table yet */
        !          75800:        fk_loaded = 0;                  /* no Fn keys yet */
        !          75801: 
        !          75802:        /*
        !          75803:         * Enable mmwatch() invocation every second.
        !          75804:         */
        !          75805:        drvl[ISMAJ].d_time = 1;
        !          75806: 
        !          75807:        /*
        !          75808:         * Seize keyboard interrupt.
        !          75809:         */
        !          75810:        setivec(ISVEC, isrint);
        !          75811: 
        !          75812:        /*
        !          75813:         * Initiailize video display.
        !          75814:         */
        !          75815:        mmstart( &istty );
        !          75816: 
        !          75817:        /*
        !          75818:         * Allocate a segment to store the in-core keyboard table.
        !          75819:         * This would be a lot more convenient in kernel data space,
        !          75820:         * but small model COHERENT doesn't have that luxury.
        !          75821:         */
        !          75822:        kbsegp = salloc((fsize_t)MAX_TABLE_SIZE, SFSYST|SFNSWP|SFHIGH);
        !          75823:        if (kbsegp == (SEG *)0)
        !          75824:                printf("kb: unable to allocate keyboard table segment\n");
        !          75825:        fklength = 0;
        !          75826:        KBDEBUG("Exiting kbload()\n");
        !          75827: }
        !          75828: 
        !          75829: /*
        !          75830:  * Unload entry point.
        !          75831:  */
        !          75832: isuload()
        !          75833: {
        !          75834:        if (kbstate != KB_IDLE)
        !          75835:                printf("kb: keyboard busy during unload\n");
        !          75836:        clrivec(ISVEC);
        !          75837:        if (kbsegp != (SEG *)0) {
        !          75838:                table_loaded = 0;
        !          75839:                sfree(kbsegp);
        !          75840:        }
        !          75841: }
        !          75842: 
        !          75843: /*
        !          75844:  * Open routine.
        !          75845:  */
        !          75846: isopen(dev)
        !          75847: dev_t dev;
        !          75848: {
        !          75849:        register int s;
        !          75850: 
        !          75851:        KBDEBUG(" kbopen()");
        !          75852:        if (minor(dev) != 0) {
        !          75853:                u.u_error = ENXIO;
        !          75854:                return;
        !          75855:        }
        !          75856:        if ((istty.t_flags&T_EXCL) != 0 && !super()) {
        !          75857:                u.u_error = ENODEV;
        !          75858:                return;
        !          75859:        }
        !          75860:        ttsetgrp(&istty, dev);
        !          75861: 
        !          75862:        s = sphi();
        !          75863:        if (istty.t_open++ == 0) {
        !          75864:                istty.t_flags = T_CARR; /* indicate "carrier" */
        !          75865:                ttopen(&istty);
        !          75866:        }
        !          75867:        spl(s);
        !          75868: #if 0
        !          75869:        updleds();                      /* update keyboard status LEDS */
        !          75870: #endif
        !          75871: }
        !          75872: 
        !          75873: /*
        !          75874:  * Close a tty.
        !          75875:  */
        !          75876: isclose(dev)
        !          75877: {
        !          75878:        register int s;
        !          75879: 
        !          75880:        s = sphi();
        !          75881:        if (--istty.t_open == 0) {
        !          75882:                ttclose(&istty);
        !          75883:        }
        !          75884:        spl(s);
        !          75885: }
        !          75886: 
        !          75887: /*
        !          75888:  * Read routine.
        !          75889:  */
        !          75890: isread(dev, iop)
        !          75891: dev_t dev;
        !          75892: IO *iop;
        !          75893: {
        !          75894:        ttread(&istty, iop, 0);
        !          75895:        if (istty.t_oq.cq_cc)
        !          75896:                mmtime(&istty);
        !          75897: }
        !          75898: 
        !          75899: /*
        !          75900:  * Ioctl routine.
        !          75901:  * nb: archaic TIOCSHIFT and TIOCCSHIFT no longer needed/supported.
        !          75902:  */
        !          75903: isioctl(dev, com, vec)
        !          75904: dev_t dev;
        !          75905: struct sgttyb *vec;
        !          75906: {
        !          75907:        register int s;
        !          75908: 
        !          75909:        switch (com) {
        !          75910:        case TIOCSETF:
        !          75911:        case TIOCGETF:
        !          75912:                isfunction(com, (char *)vec);
        !          75913:                break;
        !          75914:        case TIOCSETKBT:
        !          75915:                issettable(vec);
        !          75916:                break;
        !          75917:        case TIOCGETKBT:
        !          75918:                isgettable(vec);
        !          75919:                break;
        !          75920:        default:                                /* pass to TTY driver */
        !          75921:                s = sphi();
        !          75922:                ttioctl(&istty, com, vec);
        !          75923:                spl(s);
        !          75924:                break;
        !          75925:        }
        !          75926: }
        !          75927: 
        !          75928: /*
        !          75929:  * Set the in-core keyboard mapping table.
        !          75930:  * The table is sorted by scan code prior to calling ioctl().
        !          75931:  * All unused table entries (holes in the scan code map) have
        !          75932:  * a zero for the k_key field.
        !          75933:  * This makes key lookup at interrupt time fast by using the scan code
        !          75934:  * as an index into the table.
        !          75935:  */
        !          75936: issettable(vec)
        !          75937: char   *vec;
        !          75938: {
        !          75939:        register unsigned i;
        !          75940:        register int s;
        !          75941:        int timeout;
        !          75942:        register faddr_t faddr;         /* address of keyboard table */
        !          75943:        static  KBTBL   this_key;       /* current key from kbd table */
        !          75944:        unsigned int cmd_byte;
        !          75945: 
        !          75946:        KBDEBUG(" TIOCSETKBT");
        !          75947:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
        !          75948:        kb_cmd(K_ALL_TMB_CMD);                  /* default: TMB for all keys */
        !          75949:        faddr = kbsegp->s_faddr;
        !          75950:        for (i = 0; i < MAX_KEYS; ++i) {
        !          75951:                ukcopy(vec, &this_key, sizeof(this_key));
        !          75952:                kfcopy(&this_key, faddr, sizeof(this_key));
        !          75953:                faddr += sizeof(this_key);
        !          75954:                vec += sizeof(this_key);
        !          75955:                if (this_key.k_key != i && this_key.k_key != 0) {
        !          75956:                        printf("kb: incorrect or unsorted table entry %d\n", i);
        !          75957:                        u.u_error = EBADFMT;
        !          75958:                        return;
        !          75959:                }
        !          75960:                if (this_key.k_key != i)
        !          75961:                        continue;               /* no key */
        !          75962:                switch (this_key.k_flags&TMODE) {
        !          75963:                case T:                         /* typematic */
        !          75964:                        kb_cmd2(K_KEY_T_CMD, i);
        !          75965:                        break;
        !          75966:                case M:                         /* make only */
        !          75967:                        kb_cmd2(K_KEY_M_CMD, i);
        !          75968:                        break;
        !          75969:                case MB:                        /* make/break */
        !          75970:                        kb_cmd2(K_KEY_MB_CMD, i);
        !          75971:                        break;
        !          75972:                case TMB:                       /* typematic make/break */
        !          75973:                        break;                  /* this is the default */
        !          75974:                default:
        !          75975:                        printf("kb: bad key mode\n");
        !          75976:                }
        !          75977:        }
        !          75978:        updleds();
        !          75979:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
        !          75980:        kb_cmd(K_ENABLE_CMD);                   /* start scanning */
        !          75981:        /*
        !          75982:         * The following code disables translation from the on-board
        !          75983:         * keyboard/aux controller. Without disabling translation, the
        !          75984:         * received scan codes still look like code set 1 codes even
        !          75985:         * though we put the keyboard controller in scan code set 3.
        !          75986:         * Yes, this is progress....
        !          75987:         */
        !          75988: #if 0
        !          75989:        while (inb(KBSTS_CMD) & STS_IBUF_FULL)
        !          75990:                ;
        !          75991:        outb(KBSTS_CMD, C_READ_CMD);            /* read controller cmd byte */
        !          75992:        while (!(inb(KBSTS_CMD) & STS_OBUF_FULL))
        !          75993:                ;
        !          75994:        cmd_byte = inb(KBDATA);
        !          75995:        KBDEBUG2(" cmd_byte=%x", cmd_byte);
        !          75996: #endif
        !          75997:        timeout = KBTIMEOUT;
        !          75998:        s = sphi();
        !          75999:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
        !          76000:                ;
        !          76001:        outb(KBSTS_CMD, C_WRITE_CMD);           /* write controller cmd byte */
        !          76002:        for (timeout = 50; --timeout > 0; )
        !          76003:                ;
        !          76004:        timeout = KBTIMEOUT;
        !          76005:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
        !          76006:                ;
        !          76007:        outb(KBDATA, KBCMDBYTE);                 /* turn off translation */     
        !          76008:        timeout = KBTIMEOUT;
        !          76009:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
        !          76010:                ;
        !          76011:        spl(s);
        !          76012: #if DEBUG
        !          76013:        kb_cmd2(K_SCANCODE_CMD, 0);             /* query s.c. mode */
        !          76014: #endif
        !          76015:        ++table_loaded;
        !          76016: }
        !          76017: 
        !          76018: /*
        !          76019:  * Get the in-core keyboard mapping table and pass it to the user.
        !          76020:  */
        !          76021: isgettable(vec)
        !          76022: char   *vec;
        !          76023: {
        !          76024:        register unsigned i;
        !          76025:        register faddr_t faddr;         /* address of keyboard table */
        !          76026:        static  KBTBL   this_key;       /* current key from kbd table */
        !          76027: 
        !          76028:        KBDEBUG(" TIOCGETKBT");
        !          76029:        faddr = kbsegp->s_faddr;
        !          76030:        for (i = 0; i < MAX_KEYS; ++i) {
        !          76031:                fkcopy( faddr, &this_key, sizeof(this_key));
        !          76032:                kucopy( &this_key, vec, sizeof(this_key));
        !          76033:                faddr += sizeof(this_key);
        !          76034:                vec += sizeof(this_key);
        !          76035:        }
        !          76036: }
        !          76037: 
        !          76038: /*
        !          76039:  * Set and receive the function keys.
        !          76040:  */
        !          76041: isfunction(c, v)
        !          76042: int c;
        !          76043: FNKEY *v;
        !          76044: {
        !          76045:        register unsigned char *cp;
        !          76046:        register unsigned i;
        !          76047:        unsigned char   numkeys = 0;
        !          76048: 
        !          76049:        if (c == TIOCGETF) {
        !          76050:                KBDEBUG(" TIOCGETF");
        !          76051:                if (!fk_loaded)
        !          76052:                        u.u_error = EINVAL;
        !          76053:                else
        !          76054:                        kucopy(fnkeys, v, fklength);    /* copy ours to user */
        !          76055:        } else { /* TIOCSETF */
        !          76056:                /*
        !          76057:                 * If we had a previous function key arena, free it up.
        !          76058:                 * Since we don't know how large the function key arena will
        !          76059:                 * be, we must size it in the user data space prior to
        !          76060:                 * (re)kalloc()'ing it. This is ugly, but a helluva lot better
        !          76061:                 * than the old driver which used a hard coded limit of 150!
        !          76062:                 */
        !          76063:                KBDEBUG(" TIOCSETF");
        !          76064:                fk_loaded = 0;
        !          76065:                if (fnkeys != (FNKEY *)0)
        !          76066:                        kfree(fnkeys);          /* free old arena */
        !          76067:                if (funkeyp != NULL)
        !          76068:                        kfree(funkeyp);         /* free old ptr array */
        !          76069:                ukcopy(&v->k_nfkeys, &numkeys, sizeof(numkeys));
        !          76070:                fklength = sizeof(FNKEY);
        !          76071:                cp = v->k_fnval;
        !          76072:                for (i = 0; i < numkeys; i++) {
        !          76073:                        do {
        !          76074:                                ++fklength;
        !          76075:                        } while (getubd(cp++) != DELIM);
        !          76076:                }
        !          76077:                fnkeys = (FNKEY *)kalloc(fklength);
        !          76078:                funkeyp = (unsigned char **)kalloc(numkeys * sizeof(char *));
        !          76079:                if (fnkeys == (FNKEY *)0 || funkeyp == NULL) {
        !          76080:                        if (fnkeys != (FNKEY *)0) {
        !          76081:                                kfree(fnkeys);
        !          76082:                                fnkeys = 0;
        !          76083:                        }
        !          76084:                        if (funkeyp != NULL) {
        !          76085:                                kfree(funkeyp);
        !          76086:                                funkeyp = 0;
        !          76087:                        }
        !          76088:                        u.u_error = ENOMEM;
        !          76089:                        return;
        !          76090:                }
        !          76091:                cp = fnkeys->k_fnval;                   /* point to Fn ... */
        !          76092:                v = v->k_fnval;                         /* ... key arena */
        !          76093:                for (i = 0; i < numkeys; i++) {
        !          76094:                        funkeyp[i] = cp;                   /* save pointer */
        !          76095:                        while ((*cp++ = getubd(v++)) != DELIM)  /* copy key */
        !          76096:                                ;
        !          76097:                }
        !          76098:                fnkeys->k_nfkeys = numkeys;
        !          76099:                fk_loaded = 1;
        !          76100:        }
        !          76101: }
        !          76102: 
        !          76103: 
        !          76104: /*
        !          76105:  * Poll routine.
        !          76106:  */
        !          76107: ispoll( dev, ev, msec )
        !          76108: dev_t dev;
        !          76109: int ev;
        !          76110: int msec;
        !          76111: {
        !          76112:        /*
        !          76113:         * Priority polls not supported.
        !          76114:         */
        !          76115:        ev &= ~POLLPRI;
        !          76116: 
        !          76117:        /*
        !          76118:         * Input poll failure.
        !          76119:         */
        !          76120:        if ( (ev & POLLIN) && (istty.t_iq.cq_cc == 0) ) {
        !          76121:                if ( msec != 0 )
        !          76122:                        pollopen( &istty.t_ipolls );
        !          76123:                /*
        !          76124:                 * Second look AFTER enabling monitor, avoiding interrupt race.
        !          76125:                 */
        !          76126:                if ( istty.t_iq.cq_cc == 0 )
        !          76127:                        ev &= ~POLLIN;
        !          76128:        }
        !          76129:        return ev;
        !          76130: }
        !          76131: 
        !          76132: /*
        !          76133:  * Receive interrupt.
        !          76134:  */
        !          76135: isrint()
        !          76136: {
        !          76137:        register unsigned c;
        !          76138:        register unsigned r;
        !          76139:        static  char keyup;
        !          76140: 
        !          76141:        /*
        !          76142:         * Schedule raw input handler if not already active.
        !          76143:         */
        !          76144:        if ( !isbusy ) {
        !          76145:                defer( isbatch, &istty );
        !          76146:                isbusy = 1;
        !          76147:        }
        !          76148: 
        !          76149:        /*
        !          76150:         * Pull character from the data
        !          76151:         * port. Pulse the KBFLAG in the control
        !          76152:         * port to reset the data buffer.
        !          76153:         */
        !          76154:        r = inb(KBDATA) & 0xFF;
        !          76155:        c = inb(KBCTRL);
        !          76156:        outb(KBCTRL, c|KBFLAG);
        !          76157:        outb(KBCTRL, c);
        !          76158: 
        !          76159:        /*
        !          76160:         * check returned value from keyboard to see if it's a command
        !          76161:         * or status back to us. If not, it we assume that it's a key code.
        !          76162:         */
        !          76163:        KBDEBUG2(" intr(%x)", r);
        !          76164:        switch (r) {
        !          76165:        case K_BREAK:
        !          76166:                keyup = 1;                      /* key going up */
        !          76167:                break;
        !          76168:        case K_ECHO_R:
        !          76169:        case K_BAT_OK:
        !          76170:                break;                          /* very nice, but ignored */
        !          76171:        case K_BAT_BAD:
        !          76172:                printf("kb: keyboard BAT failed\n");
        !          76173:                break;
        !          76174:        case K_RESEND:
        !          76175:                KBDEBUG("\nkb: request to resend command\n");
        !          76176:                outb(KBDATA, prev_cmd);
        !          76177:                break;
        !          76178:        case K_OVERRUN_23:
        !          76179:                printf("kb: keyboard buffer overrun\n");
        !          76180:                break;
        !          76181:        case K_ACK:
        !          76182:                /*
        !          76183:                 * we received an ACKnowledgement from the keyboard.
        !          76184:                 * advance the state machine and continue.
        !          76185:                 */
        !          76186:                KBDEBUG(" ACK");
        !          76187:                switch (kbstate) {
        !          76188:                case KB_IDLE:                   /* shouldn't happen */
        !          76189:                        printf("kb: ACK while keyboard idle\n");
        !          76190:                        break;
        !          76191:                case KB_SINGLE:                 /* done with 1-byte command */
        !          76192:                case KB_DOUBLE_2:               /* done w/ 2nd of 2-byte cmd */
        !          76193:                        kbstate = KB_IDLE;
        !          76194:                        wakeup(&kbstate);
        !          76195:                        break;
        !          76196:                case KB_DOUBLE_1:
        !          76197:                        kbstate = KB_DOUBLE_2;
        !          76198:                        outb(KBDATA, cmd2);
        !          76199:                        break;
        !          76200:                default:
        !          76201:                        printf("kb: bad kbstate %d\n", kbstate);
        !          76202:                        break;
        !          76203:                }
        !          76204:                break;
        !          76205:        default:
        !          76206:                process_key(r, keyup);
        !          76207:                keyup = 0;
        !          76208:        }
        !          76209: }
        !          76210: 
        !          76211: /*
        !          76212:  * Process a key given its scan code and direction.
        !          76213:  * 
        !          76214:  * In this table driven version of the keyboard driver, we trade off the
        !          76215:  * code complexity associated with all the black magic that used to be
        !          76216:  * performed on a per-key basis with the increased memory requirements
        !          76217:  * associated with the table driven approach.
        !          76218:  */
        !          76219: process_key( key, up)
        !          76220: unsigned key;
        !          76221: int     up;
        !          76222: {
        !          76223:        register unsigned char *cp;
        !          76224:        KBTBL   key_vals;                       /* table values for this key */
        !          76225:        unsigned val;
        !          76226:        unsigned char flags;
        !          76227: 
        !          76228:        KBDEBUG3(" proc(%x %s)", key, (up ? "up" : "down"));
        !          76229:        if (!table_loaded)
        !          76230:                return;                         /* throw away key */
        !          76231:        fkcopy( kbsegp->s_faddr + (key * sizeof(KBTBL)),
        !          76232:                &key_vals, sizeof(key_vals));
        !          76233:        if (key_vals.k_key != key)              /* empty entry */
        !          76234:                return;
        !          76235:        flags = key_vals.k_flags;
        !          76236: 
        !          76237:        if (flags & S) {                        /* some shift/lock key ? */
        !          76238:                switch (key_vals.k_val[BASE]) {
        !          76239:                case caps:
        !          76240:                case num:
        !          76241:                        if (!up) {
        !          76242:                                shift ^= (1 << key_vals.k_val[BASE]);
        !          76243:                                updleds2();
        !          76244:                        }
        !          76245:                        break;
        !          76246:                case scroll:
        !          76247:                        if (!up) {
        !          76248:                                shift ^= (1 << key_vals.k_val[BASE]);
        !          76249:                                updleds2();
        !          76250:                                if (!(istty.t_sgttyb.sg_flags&RAWIN)) {
        !          76251:                                        if (istty.t_flags & T_STOP) {
        !          76252:                                                isin(istty.t_tchars.t_startc);
        !          76253:                                        } else {
        !          76254:                                                isin(istty.t_tchars.t_stopc);
        !          76255:                                        }
        !          76256:                                }
        !          76257:                        }
        !          76258:                        break;
        !          76259:                default:
        !          76260:                        if (up)
        !          76261:                                shift &= ~(1 << key_vals.k_val[BASE]);
        !          76262:                        else
        !          76263:                                shift |= (1 << key_vals.k_val[BASE]);
        !          76264:                        break;
        !          76265:                }
        !          76266:                /*
        !          76267:                 * Calculate the shift index based upon the state of
        !          76268:                 * the shift and lock keys.
        !          76269:                 */
        !          76270:                sh_index = BASE;                /* default condition */
        !          76271:                if (shift & (1 << altgr))
        !          76272:                        sh_index = ALT_GR;
        !          76273:                else {
        !          76274:                        if (shift & ((1 << lalt)|(1 << ralt)))
        !          76275:                                sh_index |= ALT;
        !          76276:                        if (shift & ((1 << lctrl)|(1 << rctrl)))
        !          76277:                                sh_index |= CTRL;
        !          76278:                        if (shift & ((1 << lshift)|(1 << rshift)))
        !          76279:                                sh_index |= SHIFT;
        !          76280:                }
        !          76281:                return;
        !          76282:        } /* if (flags & S) */
        !          76283: 
        !          76284:        /*
        !          76285:         * If the tty is not open or the key has no value in the current
        !          76286:         * shift state, the key is just tossed away.
        !          76287:         */
        !          76288:        if (up || !istty.t_open || key_vals.k_val[sh_index] == none)
        !          76289:                return;
        !          76290:        if (((flags & C) && (shift & (1 << caps)))
        !          76291:           || ((flags & N) && (shift & (1 << num))))
        !          76292:                val = key_vals.k_val[sh_index^SHIFT];
        !          76293:        else
        !          76294:                val = key_vals.k_val[sh_index];
        !          76295: 
        !          76296:        /*
        !          76297:         * Check for function key or special key implemented as
        !          76298:         * a function key (reboot == f0, tab and back-tab, etc).
        !          76299:         */
        !          76300:        if (flags & F) {
        !          76301:                if (val == 0 && !up && KBBOOT)
        !          76302:                        boot();
        !          76303:                if (!fk_loaded || val >= fnkeys->k_nfkeys)
        !          76304:                        return;
        !          76305:                if ((cp = funkeyp[val]) == NULL) /* has a value? */
        !          76306:                        return;
        !          76307:                while (*cp != DELIM)
        !          76308:                        isin(*cp++);            /* queue up Fn key value */
        !          76309:                return;
        !          76310:        }
        !          76311: 
        !          76312:        /*
        !          76313:         * Normal key processing.
        !          76314:         */
        !          76315:        isin(val);               /* send the char */
        !          76316:        return;
        !          76317: }
        !          76318: 
        !          76319: /**
        !          76320:  *
        !          76321:  * void
        !          76322:  * ismmfunc( c )       -- process keyboard related output escape sequences
        !          76323:  * char c;
        !          76324:  */
        !          76325: void
        !          76326: ismmfunc(c)
        !          76327: register int c;
        !          76328: {
        !          76329:        switch (c) {
        !          76330:        case 't':       /* Enter numlock */
        !          76331:                shift |= (1 << num);
        !          76332:                updleds();                      /* update LED status */
        !          76333:                break;
        !          76334:        case 'u':       /* Leave numlock */
        !          76335:                shift &= ~(1 << num);
        !          76336:                updleds();                      /* update LED status */
        !          76337:                break;
        !          76338:        case '=':                       /* Enter alternate keypad -- ignored */
        !          76339:        case '>':                       /* Exit alternate keypad -- ignored */
        !          76340:                break;
        !          76341:        case 'c':       /* Reset terminal */
        !          76342:                islock = 0;
        !          76343:                break;
        !          76344:        }
        !          76345: }
        !          76346: 
        !          76347: /**
        !          76348:  *
        !          76349:  * void
        !          76350:  * isin( c )   -- append character to raw input silo
        !          76351:  * char c;
        !          76352:  */
        !          76353: static
        !          76354: isin( c )
        !          76355: register int c;
        !          76356: {
        !          76357:        /*
        !          76358:         * Cache received character.
        !          76359:         */
        !          76360:        istty.t_rawin.si_buf[ istty.t_rawin.si_ix ] = c;
        !          76361: 
        !          76362:        if ( ++istty.t_rawin.si_ix >= sizeof(istty.t_rawin.si_buf) )
        !          76363:                istty.t_rawin.si_ix = 0;
        !          76364: }
        !          76365: 
        !          76366: /**
        !          76367:  *
        !          76368:  * void
        !          76369:  * isbatch()   -- raw input conversion routine
        !          76370:  *
        !          76371:  *     Action: Enable the video display.
        !          76372:  *             Canonize the raw input silo.
        !          76373:  *
        !          76374:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
        !          76375:  */
        !          76376: static void
        !          76377: isbatch( tp )
        !          76378: register TTY * tp;
        !          76379: {
        !          76380:        register int c;
        !          76381:        static int lastc;
        !          76382: 
        !          76383:        /*
        !          76384:         * Ensure video display is enabled.
        !          76385:         */
        !          76386:        mm_von();
        !          76387:        isbusy = 0;
        !          76388: 
        !          76389:        /*
        !          76390:         * Process all cached characters.
        !          76391:         */
        !          76392:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          76393:                /*
        !          76394:                 * Get next cached char.
        !          76395:                 */
        !          76396:                c = tp->t_rawin.si_buf[ tp->t_rawin.si_ox ];
        !          76397: 
        !          76398:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          76399:                        tp->t_rawin.si_ox = 0;
        !          76400:                else
        !          76401:                        tp->t_rawin.si_ox++;
        !          76402: 
        !          76403:                if ( (islock == 0) || ISINTR || ISQUIT ) {
        !          76404:                        ttin( tp, c );
        !          76405:                } else if ( (c == 'b') && (lastc == '\033') ) {
        !          76406:                        islock = 0;
        !          76407:                        ttin( tp, lastc );
        !          76408:                        ttin( tp, c );
        !          76409:                } else if ( (c == 'c') && (lastc == '\033') ) {
        !          76410:                        ttin( tp, lastc );
        !          76411:                        ttin( tp, c );
        !          76412:                } else
        !          76413:                        putchar('\007');
        !          76414:                lastc = c;
        !          76415:        }
        !          76416: }
        !          76417: 
        !          76418: /*
        !          76419:  * update the keyboard status LEDS.
        !          76420:  * we chose the shift/lock key positions so this would be easy.
        !          76421:  * this flavor of routine is called while processing a system call on
        !          76422:  * behalf of the user.
        !          76423:  */
        !          76424: updleds()
        !          76425: {
        !          76426:        kb_cmd2(K_LED_CMD, (shift >> 1) & 0x7);
        !          76427: }
        !          76428: 
        !          76429: /*
        !          76430:  * same as above, but callable from interrupt routines and other places
        !          76431:  * which cannot sleep() waiting for the state machine to go idle.
        !          76432:  */
        !          76433: updleds2()
        !          76434: {
        !          76435:        register timeout;
        !          76436:        register int s;
        !          76437: 
        !          76438:        timeout = KBTIMEOUT;
        !          76439:        s = sphi();
        !          76440:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
        !          76441:                ;
        !          76442:        kbstate = KB_DOUBLE_1;
        !          76443:        cmd2 = (shift >> 1) & 0x7;
        !          76444:        prev_cmd = K_LED_CMD;
        !          76445:        outb(KBDATA, K_LED_CMD);
        !          76446:        spl(s);
        !          76447: }
        !          76448: 
        !          76449: /*
        !          76450:  * unlock the scroll in case an interrupt character is received
        !          76451:  */
        !          76452: kbunscroll()
        !          76453: {
        !          76454:        shift &= ~(1 << scroll);
        !          76455:        updleds();
        !          76456: }
        !          76457: 
        !          76458: /*
        !          76459:  * ship a single byte command to the keyboard
        !          76460:  */
        !          76461: kb_cmd(cmd)
        !          76462: unsigned cmd;
        !          76463: {
        !          76464:        register int timeout;
        !          76465:        register int s;
        !          76466: 
        !          76467:        s = sphi();
        !          76468:        KBDEBUG2(" kb_cmd(%x)", cmd);
        !          76469:        while (kbstate != KB_IDLE)
        !          76470:                sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
        !          76471:        kbstate = KB_SINGLE;
        !          76472:        timeout = KBTIMEOUT;
        !          76473:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
        !          76474:                ;
        !          76475:        if (!timeout)
        !          76476:                printf("kb: command timeout\n");
        !          76477:        else {
        !          76478:                outb(KBDATA, cmd);
        !          76479:                while (kbstate != KB_IDLE)
        !          76480:                        sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
        !          76481:        }
        !          76482:        spl(s);
        !          76483: }
        !          76484: 
        !          76485: /*
        !          76486:  * ship a two byte command to the keyboard
        !          76487:  */
        !          76488: kb_cmd2(cmd, arg)
        !          76489: unsigned cmd, arg;
        !          76490: {
        !          76491:        register int timeout;
        !          76492:        register int s;
        !          76493: 
        !          76494:        s = sphi();
        !          76495:        KBDEBUG3(" kb_cmd2(%x, %x)", cmd, arg);
        !          76496:        while (kbstate != KB_IDLE)
        !          76497:                sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
        !          76498:        kbstate = KB_DOUBLE_1;
        !          76499:        cmd2 = arg;
        !          76500:        prev_cmd = cmd;
        !          76501:        timeout = KBTIMEOUT;
        !          76502:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
        !          76503:                ;
        !          76504:        if (!timeout)
        !          76505:                printf("kb: command timeout\n");
        !          76506:        else {
        !          76507:                outb(KBDATA, cmd);
        !          76508:                while (kbstate != KB_IDLE)
        !          76509:                        sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
        !          76510:        }
        !          76511:        spl(s);
        !          76512: }
        !          76513: 
        !          76514: /* End of nkb.c */
        !          76515: @
        !          76516: 
        !          76517: 
        !          76518: 1.3
        !          76519: log
        !          76520: @new version provided y hal for v321
        !          76521: @
        !          76522: text
        !          76523: @d5 2
        !          76524: a6 2
        !          76525: #include <coherent.h>
        !          76526: #include <i8086.h>
        !          76527: a12 1
        !          76528: #include <sys/timeout.h>
        !          76529: @
        !          76530: 
        !          76531: 
        !          76532: 1.2
        !          76533: log
        !          76534: @update provided by norm
        !          76535: @
        !          76536: text
        !          76537: @d7 1
        !          76538: a7 1
        !          76539: #include <con.h>
        !          76540: d9 3
        !          76541: a11 3
        !          76542: #include <stat.h>
        !          76543: #include <tty.h>
        !          76544: #include <uproc.h>
        !          76545: d15 1
        !          76546: a15 1
        !          76547: #include <sched.h>
        !          76548: @
        !          76549: 
        !          76550: 
        !          76551: 1.1
        !          76552: log
        !          76553: @Initial revision
        !          76554: @
        !          76555: text
        !          76556: @d16 1
        !          76557: a16 1
        !          76558: #include <kb.h>
        !          76559: @
        !          76560: 0707070064030106251004440000030000030000011777770507310703600006000000013077/newbits/kernel/USRSRC/i8086/drv/RCS/kbmain.c,vhead     1.1;
        !          76561: branch   ;
        !          76562: access   ;
        !          76563: symbols  ;
        !          76564: locks    bin:1.1; strict;
        !          76565: comment  @ * @;
        !          76566: 
        !          76567: 
        !          76568: 1.1
        !          76569: date     91.06.13.12.52.59;  author bin;  state Exp;
        !          76570: branches ;
        !          76571: next     ;
        !          76572: 
        !          76573: 
        !          76574: desc
        !          76575: @init ver prov by norm
        !          76576: @
        !          76577: 
        !          76578: 
        !          76579: 
        !          76580: 1.1
        !          76581: log
        !          76582: @Initial revision
        !          76583: @
        !          76584: text
        !          76585: @/*
        !          76586:  * driver routine for loadable keyboard tables.
        !          76587:  *
        !          76588:  * prior to firing off the ioctl() which loads the new keyboard tables,
        !          76589:  * permform some simple validity checks on the table.
        !          76590:  * if errors are found, bail out without setting the new table.
        !          76591:  *
        !          76592:  * Version 1.0, 6/8/91
        !          76593:  */
        !          76594: #include <stdio.h>
        !          76595: #include <sgtty.h>
        !          76596: #include <sys/kb.h>
        !          76597: #include <sys/kbscan.h>
        !          76598: #include <errno.h>
        !          76599: 
        !          76600: #define        VERSION "1.0"
        !          76601: #define        FALSE   (0 != 0)
        !          76602: #define        TRUE    (0 == 0)
        !          76603: 
        !          76604: /*
        !          76605:  * globals
        !          76606:  */
        !          76607: char   *argv0;                         /* name of this executable */
        !          76608: int    errors;                         /* for exit status */
        !          76609: char   verbose;                        /* step-by-step details */
        !          76610: char   debug;                          /* print out cooked table & exit */
        !          76611: KBTBL  table[MAX_KEYS];                /* cooked table for ioctl() */
        !          76612: FNKEY  *arena;                         /* function key arena */
        !          76613: 
        !          76614: unsigned char  keyval[] = {            /* code set 3 mapped value */
        !          76615: none, K_1, K_2, K_3, K_4, K_5, K_6, K_7,
        !          76616: K_8, K_9, K_10, K_11, K_12, K_13, none, K_15,
        !          76617: K_16, K_17, K_18, K_19, K_20, K_21, K_22, K_23,
        !          76618: K_24, K_25, K_26, K_27, K_28, K_29, K_30, K_31,
        !          76619: K_32, K_33, K_34, K_35, K_36, K_37, K_38, K_39,
        !          76620: K_40, K_41, K_42, K_43, K_44, K_45, K_46, K_47,
        !          76621: K_48, K_49, K_50, K_51, K_52, K_53, K_54, K_55,
        !          76622: none, K_57, K_58, none, K_60, K_61, K_62, none,
        !          76623: K_64, none, none, none, none, none, none, none,
        !          76624: none, none, none, K_75, K_76, none, none, K_79,
        !          76625: K_80, K_81, none, K_83, K_84, K_85, K_86, none,
        !          76626: none, K_89, K_90, K_91, K_92, K_93, none, K_95,
        !          76627: K_96, K_97, K_98, K_99, K_100, K_101, K_102, K_103,
        !          76628: K_104, K_105, K_106, none, K_108, none, K_110, none,
        !          76629: K_112, K_113, K_114, K_115, K_116, K_117, K_118, K_119,
        !          76630: K_120, K_121, K_122, K_123, K_124, K_125, K_126
        !          76631: };
        !          76632: 
        !          76633: /*
        !          76634:  * externs from user-defined keyboard table
        !          76635:  */
        !          76636: extern KBTBL   kbtbl[];                        /* actual table */
        !          76637: extern char    tbl_name[];                     /* name of table as text */
        !          76638: extern unsigned char *funkey[];                /* function key definitions */
        !          76639: extern int     numfun;                         /* # of function keys in tbl */
        !          76640: extern int     numkey;                         /* number of keys in kbtbl[] */
        !          76641: 
        !          76642: main(argc, argv)
        !          76643: char *argv[];
        !          76644: {
        !          76645:        unsigned char *cp, *ncp;
        !          76646:        int i, j;
        !          76647:        int fd;                                 /* console file descriptor */
        !          76648: 
        !          76649:        argv0 = argv[0];
        !          76650:        if ((arena = (FNKEY *)malloc(sizeof(FNKEY) + MAX_FCHAR)) == NULL) {
        !          76651:                err("out of memory");
        !          76652:                exit(errors);
        !          76653:        }
        !          76654:        if (argc > 1) {
        !          76655:                if (strcmp(argv[1], "-V") == 0)
        !          76656:                        printf("Version %s\n", VERSION);
        !          76657:                else if (strcmp(argv[1], "-D") == 0)
        !          76658:                        ++debug;
        !          76659:                else
        !          76660:                        usage();
        !          76661:        }
        !          76662: 
        !          76663:        if ((fd = open("/dev/console", 2)) < 0) {
        !          76664:                err("unable to access console");
        !          76665:                exit(errors);
        !          76666:        }
        !          76667: 
        !          76668:        /*
        !          76669:         * loop through the user's keyboard table validating each entry.
        !          76670:         * if the entry is good, copy it to the destination table.
        !          76671:         */
        !          76672:        for (i = 0; i < numkey; ++i) {          /* loop thru user's keys */
        !          76673:                if (ok_entry(i)) {
        !          76674:                        j = kbtbl[i].k_key;             /* map key */
        !          76675:                        table[j] = kbtbl[i];            /* copy entry */
        !          76676:                } else
        !          76677:                        ++errors;
        !          76678:        }
        !          76679: 
        !          76680:        if (errors)
        !          76681:                exit(errors);
        !          76682:        /*
        !          76683:         * build a function key arena consisting of the user defined
        !          76684:         * special and function keys.
        !          76685:         */
        !          76686:        ncp = arena->k_fnval;
        !          76687:        for (i = 0; i < numfun; ++i) {
        !          76688:                cp = funkey[i];
        !          76689:                do {
        !          76690:                        if (ncp >= &arena->k_fnval[MAX_FCHAR]) {
        !          76691:                                err("function key table overflow");
        !          76692:                                exit(errors);
        !          76693:                        }
        !          76694:                        *ncp++ = *cp;
        !          76695:                } while (*cp++ != DELIM);
        !          76696:        }
        !          76697:        arena->k_nfkeys = numfun;
        !          76698: 
        !          76699:        if (debug) {
        !          76700:                dump();                         /* print out cooked table */
        !          76701:                exit(0);
        !          76702:        }
        !          76703: 
        !          76704:        /*
        !          76705:         * load the cooked keyboard table into the driver via a
        !          76706:         * special ioctl() call.
        !          76707:         */
        !          76708:        ioctl(fd, TIOCSETKBT, table);
        !          76709:        if (errno) {
        !          76710:                perror("keyboard table ioctl() failed");
        !          76711:                exit(++errors);
        !          76712:        }
        !          76713: 
        !          76714:        /*
        !          76715:         * load the cooked function key table into the driver via a
        !          76716:         * special ioctl() call.
        !          76717:         */
        !          76718:        ioctl(fd, TIOCSETF, arena);
        !          76719:        if (errno) {
        !          76720:                perror("function key ioctl() failed");
        !          76721:                exit(++errors);
        !          76722:        }
        !          76723: 
        !          76724:        printf("Loaded %s\n", tbl_name);
        !          76725:        close(fd);
        !          76726:        exit(errors);
        !          76727: }
        !          76728: 
        !          76729: /*
        !          76730:  * validate a table entry
        !          76731:  */
        !          76732: ok_entry(n)
        !          76733: register int n;
        !          76734: {
        !          76735:        int i;
        !          76736:        int key = lookup(kbtbl[n].k_key);
        !          76737: 
        !          76738:        if (!key) {
        !          76739:                err("invalid key #0x%x in kbtbl[%d]", kbtbl[n].k_key, n);
        !          76740:                return FALSE;
        !          76741:        }
        !          76742:        if ((kbtbl[n].k_flags & (S|F)) == (S|F)) {
        !          76743:                err("invalid flag field for key K_%d", key);
        !          76744:                return FALSE;
        !          76745:        }
        !          76746:        if (kbtbl[n].k_flags & S) {
        !          76747:                for (i = BASE; i <= ALT_GR; ++i) {
        !          76748:                        if (kbtbl[n].k_val[i] != kbtbl[n].k_val[BASE]) {
        !          76749:                                err("inconsistent shift key entry for K_%d",
        !          76750:                                    key);
        !          76751:                                return FALSE;
        !          76752:                        }
        !          76753:                        if (kbtbl[n].k_val[i] < scroll
        !          76754:                           || kbtbl[n].k_val[i] > altgr) {
        !          76755:                                err("bad shift key entry for K_%d",
        !          76756:                                    key);
        !          76757:                                return FALSE;
        !          76758:                        }
        !          76759:                } /* for */
        !          76760:        } else if (kbtbl[n].k_flags & F) {
        !          76761:                for (i = BASE; i <= ALT_GR; ++i) {
        !          76762:                        if (kbtbl[n].k_val[i] != none)
        !          76763:                                if (kbtbl[n].k_val[i] >= numfun) {
        !          76764:                                        err("bad function key entry for K_%d",
        !          76765:                                            key);
        !          76766:                                        return FALSE;
        !          76767:                                }
        !          76768:                } /* for */
        !          76769:        } /* flag key */
        !          76770: 
        !          76771:        key = kbtbl[n].k_key;
        !          76772:        if (table[key].k_key != 0) {
        !          76773:                err("multiple entries for K_%d", key);
        !          76774:                return FALSE;
        !          76775:        }
        !          76776:        return TRUE;
        !          76777: }
        !          76778: 
        !          76779: /*
        !          76780:  * lookup the physical key number associated with a given
        !          76781:  * code set 3 scan code.
        !          76782:  *
        !          76783:  * return 0 if not found.
        !          76784:  */
        !          76785: lookup(sc)
        !          76786: unsigned sc;
        !          76787: {
        !          76788:        register int i;
        !          76789: 
        !          76790:        if (sc == none)
        !          76791:                return 0;
        !          76792:        for (i = 0; i < sizeof(keyval)/sizeof(keyval[0]); ++i)
        !          76793:                if (keyval[i] == (unsigned char)sc)
        !          76794:                        return (i);
        !          76795:        return 0;
        !          76796: }
        !          76797: 
        !          76798: usage()
        !          76799: {
        !          76800:        fprintf(stderr, "usage:\t%s [-V]\n", argv0);
        !          76801:        exit(1);
        !          76802: }
        !          76803: 
        !          76804: err(msg)
        !          76805: char *msg;
        !          76806: {
        !          76807:        fprintf(stderr, "%s: ERROR: %r\n", argv0, &msg);
        !          76808:        ++errors;
        !          76809: }
        !          76810: 
        !          76811: /*
        !          76812:  * dump the cooked keyboard table to stdout
        !          76813:  */
        !          76814: dump()
        !          76815: {
        !          76816:        int i, j;
        !          76817: 
        !          76818:        for (i = 0; i < MAX_KEYS; ++i) {
        !          76819:                printf("%02x: %02x ", i, table[i].k_key);
        !          76820:                for (j = 0; j < 9; ++j)
        !          76821:                        printf("%02x ", table[i].k_val[j]);
        !          76822:                printf("(%02x)\n", table[i].k_flags);
        !          76823:        }
        !          76824: }
        !          76825: @
        !          76826: 0707070064030106651004440000030000030000011777770507310704000005500000046523/newbits/kernel/USRSRC/i8086/drv/RCS/gkb.c,vhead     1.1;
        !          76827: branch   ;
        !          76828: access   ;
        !          76829: symbols  ;
        !          76830: locks    bin:1.1; strict;
        !          76831: comment  @ * @;
        !          76832: 
        !          76833: 
        !          76834: 1.1
        !          76835: date     91.07.15.14.46.35;  author bin;  state Exp;
        !          76836: branches ;
        !          76837: next     ;
        !          76838: 
        !          76839: 
        !          76840: desc
        !          76841: @german keyboard driver
        !          76842: @
        !          76843: 
        !          76844: 
        !          76845: 
        !          76846: 1.1
        !          76847: log
        !          76848: @Initial revision
        !          76849: @
        !          76850: text
        !          76851: @/*
        !          76852:  * Keyboard/display driver for German keyboard.
        !          76853:  * Coherent, IBM PC/XT and AT (in XT mode).
        !          76854:  */
        !          76855: #include <sys/coherent.h>
        !          76856: #include <sys/i8086.h>
        !          76857: #include <sys/con.h>
        !          76858: #include <errno.h>
        !          76859: #include <sys/stat.h>
        !          76860: #include <sys/tty.h>
        !          76861: #include <sys/uproc.h>
        !          76862: #include <signal.h>
        !          76863: #include <sys/sched.h>
        !          76864: 
        !          76865: #define        ISMAJ   2                       /* Keyboard major device */
        !          76866: 
        !          76867: #define        SPC     0376                    /* Special encoding */
        !          76868: #define XXX    0377                    /* Non-character */
        !          76869: #define        KBDATA  0x60                    /* Keyboard data */
        !          76870: #define        KBCTRL  0x61                    /* Keyboard control */
        !          76871: #define        KBFLAG  0x80                    /* Keyboard reset flag */
        !          76872: #define        LEDCMD  0xED                    /* status indicator command */
        !          76873: #define        KBACK   0xFA                    /* status indicator acknowledge */
        !          76874: #define        EXTENDED0 0xE0                  /* extended key seq initiator */
        !          76875: #define        EXTENDED1 0xE1                  /* extended key seq initiator */
        !          76876: 
        !          76877: #define        KEYUP   0x80                    /* Key up change */
        !          76878: #define        KEYSC   0x7F                    /* Key scan code mask */
        !          76879: #define        LSHIFT  0x2A-1                  /* Left shift key */
        !          76880: #define LSHIFTA 0x2B-1                 /* Alternate left-shift key */
        !          76881: #define        RSHIFT  0x36-1                  /* Right shift key */
        !          76882: #define        CTRL    0x1D-1                  /* Control key */
        !          76883: /*-- #define   CAPLOCK 0x1D-1  --*/            /* Control key */
        !          76884: #define        ALT     0x38-1                  /* ALT key or ALT GR */
        !          76885: #define        CAPLOCK 0x3A-1                  /* Caps lock key */
        !          76886: /*-- #define   CTRL    0x3A-1  --*/            /* Caps lock key */
        !          76887: #define        NUMLOCK 0x45-1                  /* Numeric lock key */
        !          76888: #define        DELETE  0x53-1                  /* Del, as in CTRL-ALT-DEL */
        !          76889: #define BACKSP 0x0E-1                  /* Back space */
        !          76890: #define SCRLOCK        0x46-1                  /* Scroll lock */
        !          76891: 
        !          76892: /* Shift flags */
        !          76893: #define        SRS     0x01                    /* Right shift key on */
        !          76894: #define        SLS     0x02                    /* Left shift key on */
        !          76895: #define CTS    0x04                    /* Ctrl key on */
        !          76896: #define ALS    0x08                    /* Alt key on */
        !          76897: #define CPLS   0x10                    /* Caps lock on */
        !          76898: #define NMLS   0x20                    /* Num lock on */
        !          76899: #define AKPS   0x40                    /* Alternate keypad shift */
        !          76900: #define SHFT   0x80                    /* Shift key flag */
        !          76901: #define        AGS     0x100                   /* Alt Graphics on */
        !          76902: 
        !          76903: /* Function key information */
        !          76904: #define        NFKEY   20                      /* Number of settable functions */
        !          76905: #define        NFCHAR  150                     /* Number of characters settable */
        !          76906: #define        NFBUF   (NFKEY*2+NFCHAR+1)      /* Size of buffer */
        !          76907: 
        !          76908: /*
        !          76909:  * Functions.
        !          76910:  */
        !          76911: int    isrint();
        !          76912: int    istime();
        !          76913: void   isbatch();
        !          76914: int    mmstart();
        !          76915: int    isopen();
        !          76916: int    isclose();
        !          76917: int    isread();
        !          76918: int    mmwrite();
        !          76919: int    isioctl();
        !          76920: void   mmwatch();
        !          76921: int    isload();
        !          76922: int    isuload();
        !          76923: int    ispoll();
        !          76924: int    nulldev();
        !          76925: int    nonedev();
        !          76926: 
        !          76927: /*
        !          76928:  * Configuration table.
        !          76929:  */
        !          76930: CON iscon ={
        !          76931:        DFCHR|DFPOL,                    /* Flags */
        !          76932:        ISMAJ,                          /* Major index */
        !          76933:        isopen,                         /* Open */
        !          76934:        isclose,                        /* Close */
        !          76935:        nulldev,                        /* Block */
        !          76936:        isread,                         /* Read */
        !          76937:        mmwrite,                        /* Write */
        !          76938:        isioctl,                        /* Ioctl */
        !          76939:        nulldev,                        /* Powerfail */
        !          76940:        mmwatch,                        /* Timeout */
        !          76941:        isload,                         /* Load */
        !          76942:        isuload,                        /* Unload */
        !          76943:        ispoll                          /* Poll */
        !          76944: };
        !          76945: 
        !          76946: /*
        !          76947:  * Flag indicating turbo machine.
        !          76948:  */
        !          76949: int isturbo = 0;
        !          76950: 
        !          76951: /*
        !          76952:  * Terminal structure.
        !          76953:  */
        !          76954: TTY    istty = {
        !          76955:        {0}, {0}, 0, mmstart, NULL, 0, 0
        !          76956: };
        !          76957: 
        !          76958: /*
        !          76959:  * State variables.
        !          76960:  */
        !          76961: int            islock;                 /* Keyboard locked flag */
        !          76962: int            isbusy;                 /* Raw input conversion busy */
        !          76963: static int     shift;                  /* Overall shift state */
        !          76964: static char    scroll;                 /* Scroll lock state */
        !          76965: static  char   lshift = LSHIFT;        /* Left shift alternate state */
        !          76966: static char    isfbuf[NFBUF];          /* Function key values */
        !          76967: static char    *isfval[NFKEY];         /* Function key string pointers */
        !          76968: static int     ledcmd;                 /* LED update command flag */
        !          76969: static char    extended;               /* extended key scan count */
        !          76970: static char    extmode;                /* use extended mode for this key */
        !          76971: static char    ext0seen;               /* 0xE0 prefix seen */
        !          76972: 
        !          76973: /*
        !          76974:  * Tables for converting key code to ASCII.
        !          76975:  * lmaptab specifies unshifted conversion,
        !          76976:  * umaptab specifies shifted conversion,
        !          76977:  * smaptab specifies the shift states which are active.
        !          76978:  * An entry of XXX says the key is dead.
        !          76979:  * An entry of SPC requires further processing.
        !          76980:  *
        !          76981:  * Key codes:
        !          76982:  *     ESC .. <- == 1 .. 14
        !          76983:  *     -> .. \n == 15 .. 28
        !          76984:  *     CTRL .. ` == 29 .. 41
        !          76985:  *     ^Shift .. PrtSc == 42 .. 55
        !          76986:  *     ALT .. CapsLock == 56 .. 58
        !          76987:  *     F1 .. F10 == 59 .. 68
        !          76988:  *     NumLock .. Del == 69 .. 83
        !          76989:  *     ISO, F11, F12 == 86 .. 88
        !          76990:  */
        !          76991: unsigned char agmaptab[] ={                                    /* Alt Gr */
        !          76992:               XXX,  XXX,'\375','\374',XXX,  XXX,  XXX,         /* 1 - 7 */
        !          76993:         '{',  '[',  ']',  '}', '\\',  XXX,  XXX,  XXX,         /* 8 - 15 */
        !          76994:         '@@',  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,                /* 16 - 23 */
        !          76995:         XXX,  XXX,  XXX,  '~',  XXX,  XXX,  XXX,  XXX,         /* 24 - 31 */
        !          76996:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 32 - 39 */
        !          76997:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 40 - 47 */
        !          76998:         XXX,  XXX,'\346', XXX,  XXX,  XXX,  XXX,  XXX,         /* 48 - 55 */
        !          76999:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 56 - 63 */
        !          77000:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 64 - 71 */
        !          77001:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 72 - 79 */
        !          77002:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  '|',  XXX,         /* 80 - 87 */
        !          77003:         XXX                                                    /* 88 */
        !          77004: };
        !          77005: 
        !          77006: static unsigned char lmaptab[] ={
        !          77007:             '\33',  '1',  '2',  '3',  '4',  '5',  '6',         /* 1 - 7 */
        !          77008:         '7',  '8',  '9',  '0','\341','\'', '\b', '\t',         /* 8 - 15 */
        !          77009:         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',         /* 16 - 23 */
        !          77010:         'o',  'p','\201', '+', '\r',  XXX,  'a',  's',         /* 24 - 31 */
        !          77011:         'd',  'f',  'g',  'h',  'j',  'k',  'l','\224',        /* 32 - 39 */
        !          77012:        '\204','^',  XXX,  '#',  'y', 'x',  'c',  'v',          /* 40 - 47 */
        !          77013:         'b',  'n',  'm',  ',',  '.',  SPC,  XXX,  SPC,         /* 48 - 55 */
        !          77014:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
        !          77015:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
        !          77016:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
        !          77017:         SPC,  SPC,  SPC,  SPC,  XXX,  XXX,  '<',  XXX,         /* 80 - 87 */
        !          77018:         XXX                                                    /* 88 */
        !          77019: };
        !          77020: 
        !          77021: static unsigned char umaptab[] ={
        !          77022:             '\33',  '!',  '"','\025', '$',  '%',  '&',         /* 1 - 7 */
        !          77023:         '/',  '(',  ')',  '=',  '?',  '`', '\b',  SPC,         /* 8 - 15 */
        !          77024:         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',         /* 16 - 23 */
        !          77025:         'O',  'P','\232',  '*', '\r',  XXX,  'A',  'S',        /* 24 - 31 */
        !          77026:         'D',  'F',  'G',  'H',  'J',  'K',  'L','\231',        /* 32 - 39 */
        !          77027:        '\216','\370',XXX,'\'',  'Y',  'X',  'C',  'V',         /* 40 - 47 */
        !          77028:         'B',  'N',  'M',  ';',  ':',  SPC,  XXX,  SPC,         /* 48 - 55 */
        !          77029:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
        !          77030:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
        !          77031:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
        !          77032:         SPC,  SPC,  SPC,  SPC,  XXX,  XXX,  '>',  XXX,         /* 80 - 87 */
        !          77033:         XXX                                                    /* 88 */
        !          77034: };
        !          77035: 
        !          77036: #define SS0    0                       /* No shift */
        !          77037: #define SS1    (SLS|SRS|CTS)           /* Shift, Ctrl */
        !          77038: #define SES    (SLS|SRS)               /* Shift */
        !          77039: #define LET    (SLS|SRS|CPLS|CTS)      /* Shift, Caps, Ctrl */
        !          77040: #define KEY    (SLS|SRS|NMLS|AKPS)     /* Shift, Num, Alt keypad */
        !          77041: 
        !          77042: static unsigned char smaptab[] ={
        !          77043:               SS0,  SES,  SS1,  SES,  SES,  SES,  SS1,         /* 1 - 7 */
        !          77044:         SES,  SES,  SES,  SES,  SS1,  SES,  CTS,  SES,         /* 8 - 15 */
        !          77045:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  LET,         /* 16 - 23 */
        !          77046:         LET,  LET,  SS1,  SS1,  CTS, SHFT,  LET,  LET,         /* 24 - 31 */
        !          77047:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  SES,         /* 32 - 39 */
        !          77048:         SES,  SS1, SHFT,  SS1,  LET,  LET,  LET,  LET,         /* 40 - 47 */
        !          77049:         LET,  LET,  LET,  SES,  SES,  SES, SHFT,  SES,         /* 48 - 55 */
        !          77050:        SHFT,  SS1, SHFT,  SS0,  SS0,  SS0,  SS0,  SS0,         /* 56 - 63 */
        !          77051:         SS0,  SS0,  SS0,  SS0,  SS0, SHFT,  KEY,  KEY,         /* 64 - 71 */
        !          77052:         KEY,  KEY,  SS0,  KEY,  KEY,  KEY,  SS0,  KEY,         /* 72 - 79 */
        !          77053:         KEY,  KEY,  KEY,  KEY,  SS0,  SS0,  SES,  SS0,         /* 80 - 87 */
        !          77054:         SS0
        !          77055: };
        !          77056: 
        !          77057: /*
        !          77058:  * Load entry point.
        !          77059:  *  Do reset the keyboard because it gets terribly munged
        !          77060:  *  if you type during the boot.
        !          77061:  */
        !          77062: isload()
        !          77063: {
        !          77064:        register int i;
        !          77065: 
        !          77066:        /*
        !          77067:         * Reset keyboard if NOT an XT turbo.
        !          77068:         */
        !          77069:        if ( ! isturbo ) {
        !          77070:                outb(KBCTRL, 0x0C);             /* Clock low */
        !          77071:                for (i = 10582; --i >= 0; );    /* For 20ms */
        !          77072:                outb(KBCTRL, 0xCC);             /* Clock high */
        !          77073:                for (i = 0; --i != 0; )
        !          77074:                        ;
        !          77075:                i = inb(KBDATA);
        !          77076:                outb(KBCTRL, 0xCC);                     /* Clear keyboard */
        !          77077:                outb(KBCTRL, 0x4D);                     /* Enable keyboard */
        !          77078:        }
        !          77079: 
        !          77080:        /*
        !          77081:         * Enable mmwatch() invocation every second.
        !          77082:         */
        !          77083:        drvl[ISMAJ].d_time = 1;
        !          77084: 
        !          77085:        /*
        !          77086:         * Seize keyboard interrupt.
        !          77087:         */
        !          77088:        setivec(1, isrint);
        !          77089: 
        !          77090:        /*
        !          77091:         * Initiailize video display.
        !          77092:         */
        !          77093:        mmstart( &istty );
        !          77094: }
        !          77095: 
        !          77096: /*
        !          77097:  * Unload entry point.
        !          77098:  */
        !          77099: isuload()
        !          77100: {
        !          77101:        clrivec(1);
        !          77102: }
        !          77103: 
        !          77104: /*
        !          77105:  * Default function key strings (terminated by -1 [\377])
        !          77106:  */
        !          77107: static char *deffuncs[] = {
        !          77108:        "\33[1x\377",   /* F1 */
        !          77109:        "\33[2x\377",   /* F2 */
        !          77110:        "\33[3x\377",   /* F3 */
        !          77111:        "\33[4x\377",   /* F4 */
        !          77112:        "\33[5x\377",   /* F5 */
        !          77113:        "\33[6x\377",   /* F6 */
        !          77114:        "\33[7x\377",   /* F7 */
        !          77115:        "\33[8x\377",   /* F8 */
        !          77116:        "\33[9x\377",   /* F9 */
        !          77117:        "\33[0x\377",   /* F10 - historical value */
        !          77118:        "\33[1y\377",   /* F11 */
        !          77119:        "\33[2y\377",   /* F12 */
        !          77120:        "\33[3y\377",   /* F13 */
        !          77121:        "\33[4y\377",   /* F14 */
        !          77122:        "\33[5y\377",   /* F15 */
        !          77123:        "\33[6y\377",   /* F16 */
        !          77124:        "\33[7y\377",   /* F17 */
        !          77125:        "\33[8y\377",   /* F18 */
        !          77126:        "\33[9y\377",   /* F19 */
        !          77127:        "\33[0y\377"    /* F20 */
        !          77128: };
        !          77129: 
        !          77130: /*
        !          77131:  * Open routine.
        !          77132:  */
        !          77133: isopen(dev)
        !          77134: dev_t dev;
        !          77135: {
        !          77136:        register int s;
        !          77137: 
        !          77138:        if (minor(dev) != 0) {
        !          77139:                u.u_error = ENXIO;
        !          77140:                return;
        !          77141:        }
        !          77142:        if ((istty.t_flags&T_EXCL)!=0 && super()==0) {
        !          77143:                u.u_error = ENODEV;
        !          77144:                return;
        !          77145:        }
        !          77146:        ttsetgrp(&istty, dev);
        !          77147: 
        !          77148:        s = sphi();
        !          77149:        if (istty.t_open++ == 0)
        !          77150:        {  initkeys();   /* init function keys */
        !          77151:           istty.t_flags = T_CARR;  /* indicate "carrier" */
        !          77152:           ttopen(&istty);
        !          77153:        }
        !          77154:        spl(s);
        !          77155:        updleds();                      /* update keyboard status LEDS */
        !          77156: }
        !          77157: 
        !          77158: /* Init function keys */
        !          77159: initkeys()
        !          77160: {      register int i;
        !          77161:        register char *cp1, *cp2;
        !          77162: 
        !          77163:        for (i=0; i<NFKEY; i++)
        !          77164:            isfval[i] = 0;          /* clear function key buffer */
        !          77165:        cp2 = isfbuf;               /* pointer to key buffer */   
        !          77166:        for (i=0; i<NFKEY; i++)
        !          77167:        {  isfval[i] = cp2;         /* save pointer to key string */
        !          77168:           cp1 = deffuncs[i];       /* get init string pointer */
        !          77169:           while ((*cp2++ = *cp1++) != -1)  /* copy key data */
        !          77170:             if (cp2 >= &isfbuf[NFBUF-3])   /* overflow? */
        !          77171:                return;
        !          77172:        }
        !          77173: }
        !          77174: 
        !          77175: /*
        !          77176:  * Close a tty.
        !          77177:  */
        !          77178: isclose(dev)
        !          77179: {
        !          77180:        register int s;
        !          77181: 
        !          77182:        s = sphi();
        !          77183:        if (--istty.t_open == 0)
        !          77184:        {       s = sphi();
        !          77185:                ttclose(&istty);
        !          77186:                spl(s);
        !          77187:        }
        !          77188: }
        !          77189: 
        !          77190: /*
        !          77191:  * Read routine.
        !          77192:  */
        !          77193: isread(dev, iop)
        !          77194: dev_t dev;
        !          77195: IO *iop;
        !          77196: {
        !          77197:        ttread(&istty, iop, 0);
        !          77198:        if (istty.t_oq.cq_cc)
        !          77199:                mmtime(&istty);
        !          77200: }
        !          77201: 
        !          77202: /*
        !          77203:  * Ioctl routine.
        !          77204:  */
        !          77205: isioctl(dev, com, vec)
        !          77206: dev_t dev;
        !          77207: struct sgttyb *vec;
        !          77208: {
        !          77209:        register int s;
        !          77210: 
        !          77211:        switch(com) {
        !          77212:        case TIOCSETF:
        !          77213:        case TIOCGETF:
        !          77214:                isfunction(com, (char *)vec);
        !          77215:                return;
        !          77216:        case TIOCSHIFT:   /* switch left-SHIFT and "\" */
        !          77217:                lshift = LSHIFTA;    /* alternate values */
        !          77218:                lmaptab[41] = '\\';
        !          77219:                lmaptab[42] = XXX;
        !          77220:                umaptab[41] = '|';
        !          77221:                umaptab[42] = XXX;
        !          77222:                smaptab[41] = SS1;
        !          77223:                smaptab[42] = SHFT;
        !          77224:                return;
        !          77225:        case TIOCCSHIFT:  /* normal (default) left-SHIFT and "\" */
        !          77226:                lshift = LSHIFT;     /* normal values */
        !          77227:                lmaptab[41] = XXX;
        !          77228:                lmaptab[42] = '\\';
        !          77229:                umaptab[41] = XXX;
        !          77230:                umaptab[42] = '|';
        !          77231:                smaptab[41] = SHFT;
        !          77232:                smaptab[42] = SS1;
        !          77233:                return;
        !          77234:        }
        !          77235:        s = sphi();
        !          77236:        ttioctl(&istty, com, vec);
        !          77237:        spl(s);
        !          77238: }
        !          77239: 
        !          77240: /*
        !          77241:  * Set and receive the function keys.
        !          77242:  */
        !          77243: isfunction(c, v)
        !          77244: int c;
        !          77245: char *v;
        !          77246: {
        !          77247:        register char *cp;
        !          77248:        register int i;
        !          77249: 
        !          77250:        if (c == TIOCGETF) {
        !          77251:                for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++)
        !          77252:                    putubd(v++, *cp);
        !          77253:        } else {
        !          77254:                for (i=0; i<NFKEY; i++)         /* zap current settings */
        !          77255:                        isfval[i] = 0;
        !          77256:                cp = isfbuf;                    /* pointer to key buffer */
        !          77257:                for (i=0; i<NFKEY; i++) {
        !          77258:                        isfval[i] = cp;         /* save pointer to key string */
        !          77259:                        while ((*cp++ = getubd(v++)) != -1)  /* copy key data */
        !          77260:                                if (cp >= &isfbuf[NFBUF-3])  /* overflow? */
        !          77261:                                        return;
        !          77262:                }
        !          77263:        }
        !          77264: }
        !          77265: 
        !          77266: 
        !          77267: /*
        !          77268:  * Poll routine.
        !          77269:  */
        !          77270: ispoll( dev, ev, msec )
        !          77271: dev_t dev;
        !          77272: int ev;
        !          77273: int msec;
        !          77274: {
        !          77275:        /*
        !          77276:         * Priority polls not supported.
        !          77277:         */
        !          77278:        ev &= ~POLLPRI;
        !          77279: 
        !          77280:        /*
        !          77281:         * Input poll failure.
        !          77282:         */
        !          77283:        if ( (ev & POLLIN) && (istty.t_iq.cq_cc == 0) ) {
        !          77284: 
        !          77285:                if ( msec != 0 )
        !          77286:                        pollopen( &istty.t_ipolls );
        !          77287: 
        !          77288:                /*
        !          77289:                 * Second look AFTER enabling monitor, avoiding interrupt race.
        !          77290:                 */
        !          77291:                if ( istty.t_iq.cq_cc == 0 )
        !          77292:                        ev &= ~POLLIN;
        !          77293:        }
        !          77294: 
        !          77295:        return ev;
        !          77296: }
        !          77297: 
        !          77298: /*
        !          77299:  * Receive interrupt.
        !          77300:  */
        !          77301: isrint()
        !          77302: {
        !          77303:        register int    c;
        !          77304:        register int    s;
        !          77305:        register int    r;
        !          77306:        int     savests;
        !          77307:        int     update_leds = 0;
        !          77308: 
        !          77309:        /*
        !          77310:         * Schedule raw input handler if not already active.
        !          77311:         */
        !          77312:        if ( isbusy == 0 ) {
        !          77313:                defer( isbatch, &istty );
        !          77314:                isbusy = 1;
        !          77315:        }
        !          77316: 
        !          77317:        /*
        !          77318:         * Pull character from the data
        !          77319:         * port. Pulse the KBFLAG in the control
        !          77320:         * port to reset the data buffer.
        !          77321:         */
        !          77322:        r = inb(KBDATA) & 0xFF;
        !          77323:        c = inb(KBCTRL);
        !          77324:        outb(KBCTRL, c|KBFLAG);
        !          77325:        outb(KBCTRL, c);
        !          77326: #if    0
        !          77327:        printf("kbd: %x %s\n", r&0x7F, (r&KEYUP) ? "up" : "down");
        !          77328: #endif
        !          77329:        if (ledcmd) {
        !          77330:                ledcmd = 0;
        !          77331:                if (r == KBACK) {               /* output to status LEDS */
        !          77332:                        c = scroll & 1;
        !          77333:                        if (shift & NMLS)
        !          77334:                                c |= 2;
        !          77335:                        if (shift & CPLS)
        !          77336:                                c |= 4;
        !          77337:                        outb(KBDATA, c);
        !          77338:                }
        !          77339:                return;
        !          77340:        }
        !          77341:        if (extended > 0) {                     /* if multi-character seq, */
        !          77342:                --extended;                     /* ... ignore this char */
        !          77343:                return;
        !          77344:        }
        !          77345: 
        !          77346:        switch (r) {
        !          77347:        case EXTENDED0:                         /* 0xE0 prefix found */
        !          77348:                ext0seen = 1;
        !          77349:                return;
        !          77350:        case EXTENDED1:                         /* ignore extended sequences */
        !          77351:                extended = 5;
        !          77352:                return;
        !          77353:        case 0xFF:                              /* Overrun */
        !          77354:                return;
        !          77355:        }
        !          77356: 
        !          77357:        if (ext0seen) {
        !          77358:                ext0seen = 0;
        !          77359:                extmode = 1;
        !          77360:        } else 
        !          77361:                extmode = 0;
        !          77362: 
        !          77363:        c = (r & KEYSC) - 1;                    /* bias to internal format */
        !          77364: 
        !          77365:        /*
        !          77366:         * Check for reset.
        !          77367:         */
        !          77368:        if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS))
        !          77369:                boot();
        !          77370: 
        !          77371:        /*
        !          77372:         * Track "shift" keys.
        !          77373:         */
        !          77374:        s = smaptab[c];
        !          77375:        if (s&SHFT) {
        !          77376:                if (r&KEYUP) {                  /* "shift" released */
        !          77377:                        if (c == RSHIFT)
        !          77378:                                shift &= ~SRS;
        !          77379:                        else if (c == lshift)
        !          77380:                                shift &= ~SLS;
        !          77381:                        else if (c == CTRL)
        !          77382:                                shift &= ~CTS;
        !          77383:                        else if (c == ALT)
        !          77384:                                shift &= extmode ? ~AGS : ~ALS;
        !          77385:                } else {                        /* "shift" pressed */
        !          77386:                        if (c == lshift)
        !          77387:                                shift |= SLS;
        !          77388:                        else if (c == RSHIFT)
        !          77389:                                shift |= SRS;
        !          77390:                        else if (c == CTRL)
        !          77391:                                shift |= CTS;
        !          77392:                        else if (c == ALT)
        !          77393:                                shift |= extmode ? AGS : ALS;
        !          77394:                        else if (c == CAPLOCK) {
        !          77395:                                shift ^= CPLS;  /* toggle cap lock */
        !          77396:                                updleds();
        !          77397:                        } else if (c == NUMLOCK) {
        !          77398:                                shift ^= NMLS;  /* toggle num lock */
        !          77399:                                updleds();
        !          77400:                        }
        !          77401:                }
        !          77402:                return;
        !          77403:        }
        !          77404: 
        !          77405:        /*
        !          77406:         * No other key up codes of interest.
        !          77407:         */
        !          77408:        if (r&KEYUP)
        !          77409:                return;
        !          77410: 
        !          77411:        /*
        !          77412:         * If the tty is not open the character is
        !          77413:         * just tossed away.
        !          77414:         */
        !          77415:        if (istty.t_open == 0)
        !          77416:                return;
        !          77417: 
        !          77418:        /*
        !          77419:         * Map character, based on the
        !          77420:         * current state of the shift, control, alt graphics,
        !          77421:         * meta (ALT) and lock flags.
        !          77422:         */
        !          77423:        if (shift & AGS)                        /* Alt Graphics ? */
        !          77424:                c = agmaptab[c];
        !          77425:        else if (shift & CTS) {
        !          77426:                if (s == CTS)                   /* Map Ctrl (BS | NL) */
        !          77427:                        c = (c == BACKSP) ? 0x7F : 0x0A;  
        !          77428:                else if (s==SS1 || s==LET)      /* Normal Ctrl map */
        !          77429:                        c = umaptab[c]&0x1F;    /* Clear bits 5-6 */
        !          77430:                else                            
        !          77431:                        return;                 /* Ignore this char */
        !          77432:        } else if (s &= shift) {
        !          77433:                if (shift & SES) {               /* if shift on */
        !          77434:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
        !          77435:                                c = lmaptab[c];  /* use unshifted */
        !          77436:                        else
        !          77437:                                c = umaptab[c];  /* use shifted */
        !          77438:                } else {                         /* if shift not on */
        !          77439:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
        !          77440:                                c = umaptab[c];  /* use shifted */
        !          77441:                        else
        !          77442:                                c = lmaptab[c];  /* use unshifted */
        !          77443:                }
        !          77444:        } else                                   
        !          77445:                c = lmaptab[c];                  /* use unshifted */
        !          77446: 
        !          77447:        /*
        !          77448:         * Act on character.
        !          77449:         */
        !          77450:        if (c == XXX)                           
        !          77451:                return;                          /* char to ignore */
        !          77452: 
        !          77453:        if (c != SPC) {                  /* not special char? */
        !          77454:                if (shift & ALS)         /* ALT (meta bit)? */
        !          77455:                        c |= 0x80;       /* set meta */
        !          77456:                isin(c);                 /* send the char */
        !          77457:        } else
        !          77458:                update_leds += isspecial(r);     /* special chars */
        !          77459:        if (update_leds) {
        !          77460:                savests = sphi();
        !          77461:                outb(KBDATA, LEDCMD);
        !          77462:                ledcmd = 1;
        !          77463:                spl(savests);
        !          77464:        }
        !          77465: }
        !          77466: 
        !          77467: /*
        !          77468:  * Handle special input sequences.
        !          77469:  * The character passed is the key number.
        !          77470:  *
        !          77471:  * The keypad is translated by the following table,
        !          77472:  * the first entry is the normal sequence, the second the shifted,
        !          77473:  * and the third the alternate keypad sequence.
        !          77474:  */
        !          77475: static char *keypad[][3] = {
        !          77476:        { "\33[H",  "7", "\33?w" },     /* 71 */
        !          77477:        { "\33[A",  "8", "\33?x" },     /* 72 */
        !          77478:        { "\33[V",  "9", "\33?y" },     /* 73 */
        !          77479:        { "\33[D",  "4", "\33?t" },     /* 75 */
        !          77480:        { "\0337",  "5", "\33?u" },     /* 76 */
        !          77481:        { "\33[C",  "6", "\33?v" },     /* 77 */
        !          77482:        { "\33[24H","1", "\33?q" },     /* 79 */
        !          77483:        { "\33[B",  "2", "\33?r" },     /* 80 */
        !          77484:        { "\33[U",  "3", "\33?s" },     /* 81 */
        !          77485:        { "\33[@@",  "0", "\33?p" },    /* 82 */
        !          77486:        { "\33[P", ".",  "\33?n" }      /* 83 */
        !          77487: };
        !          77488: 
        !          77489: isspecial(c)
        !          77490: int c;
        !          77491: {
        !          77492:        register char *cp;
        !          77493:        register int s;
        !          77494:        int     update_leds = 0;
        !          77495: 
        !          77496:        cp = 0;
        !          77497: 
        !          77498:        switch (c) {
        !          77499:        case 15:                                        /* cursor back tab */
        !          77500:                cp = "\033[Z";
        !          77501:                break;
        !          77502:        case 53:
        !          77503:                if (extmode)
        !          77504:                        cp = "/";
        !          77505:                else if (shift & SES)
        !          77506:                        cp = "_";
        !          77507:                else
        !          77508:                        cp = "-";
        !          77509:                break;
        !          77510:        case 55:                                        /* ignore PrtScr */
        !          77511:                if (!extmode)
        !          77512:                        cp = "*";
        !          77513:                break;
        !          77514:        case 59: case 60: case 61: case 62: case 63:    /* Function keys */
        !          77515:        case 64: case 65: case 66: case 67: case 68:
        !          77516:                /* offset to function string */
        !          77517:                if ( shift & ALS )
        !          77518:                        cp = isfval[c-49];
        !          77519:                else
        !          77520:                        cp = isfval[c-59];
        !          77521:                break;
        !          77522: 
        !          77523:        case 70:                /* Scroll Lock -- stop/start output */
        !          77524:        {
        !          77525:                static char cbuf[2];
        !          77526: 
        !          77527:                cp = &cbuf[0];  /* working buffer */
        !          77528:                if (!(istty.t_sgttyb.sg_flags&RAWIN)) { /* not if in RAW mode */
        !          77529:                        ++update_leds;
        !          77530:                        if (istty.t_flags & T_STOP) {   /* output stopped? */
        !          77531:                           cbuf[0] = istty.t_tchars.t_startc;  /* start it */
        !          77532:                           scroll = 0;
        !          77533:                        } else {
        !          77534:                           cbuf[0] = istty.t_tchars.t_stopc;   /* stop output */
        !          77535:                           scroll = 1;
        !          77536:                        }
        !          77537:                }
        !          77538:                break;
        !          77539:        }
        !          77540: 
        !          77541:        case 79:                /* 1/End */
        !          77542:        case 80:                /* 2/DOWN */
        !          77543:        case 81:                /* 3/PgDn */
        !          77544:        case 82:                /* 0/Ins */
        !          77545:        case 83:                /* ./Del */
        !          77546:                --c;            /* adjust code */
        !          77547:        case 75:                /* 4/LEFT */
        !          77548:        case 76:                /* 5 */
        !          77549:        case 77:                /* 6/RIGHT */
        !          77550:                --c;            /* adjust code */
        !          77551:        case 71:                /* 7/Home/Clear */
        !          77552:        case 72:                /* 8/UP */
        !          77553:        case 73:                /* 9/PgUp */
        !          77554:                s = 0;                  /* start off with normal keypad */
        !          77555:                if (shift & NMLS)       /* num lock? */
        !          77556:                        s = 1;          /* set shift pad */
        !          77557:                if (shift & SES)        /* shift? */
        !          77558:                        s ^= 1;         /* toggle shift pad */
        !          77559:                if (shift & AKPS)       /* alternate pad? */
        !          77560:                        s = 2;          /* set alternate pad */         
        !          77561:                if (extmode)            /* not from keypad? */
        !          77562:                        s = 0;          /* force normal sequence */
        !          77563:                cp = keypad[c-71][s];   /* get keypad value */
        !          77564:                break;
        !          77565:        }
        !          77566:        if (cp)                                 /* send string */
        !          77567:                while ((*cp != 0) && (*cp != -1))
        !          77568:                        isin( *cp++ & 0377 );
        !          77569:        return update_leds;
        !          77570: }
        !          77571: 
        !          77572: /**
        !          77573:  *
        !          77574:  * void
        !          77575:  * ismmfunc( c )       -- process keyboard related output escape sequences
        !          77576:  * char c;
        !          77577:  */
        !          77578: void
        !          77579: ismmfunc(c)
        !          77580: register int c;
        !          77581: {
        !          77582:        switch (c) {
        !          77583:        case 't':       /* Enter numlock */
        !          77584:                shift |= NMLS;
        !          77585:                updleds();                      /* update LED status */
        !          77586:                break;
        !          77587:        case 'u':       /* Leave numlock */
        !          77588:                shift &= ~NMLS;
        !          77589:                updleds();                      /* update LED status */
        !          77590:                break;
        !          77591:        case '=':       /* Enter alternate keypad */
        !          77592:                shift |= AKPS;
        !          77593:                break;
        !          77594:        case '>':       /* Exit alternate keypad */
        !          77595:                shift &= ~AKPS;
        !          77596:                break;
        !          77597:        case 'c':       /* Reset terminal */
        !          77598:                islock = 0;
        !          77599:                shift  = 0;
        !          77600:                initkeys();
        !          77601:                updleds();                      /* update LED status */
        !          77602:                break;
        !          77603:        }
        !          77604: }
        !          77605: 
        !          77606: /**
        !          77607:  *
        !          77608:  * void
        !          77609:  * isin( c )   -- append character to raw input silo
        !          77610:  * char c;
        !          77611:  */
        !          77612: static
        !          77613: isin( c )
        !          77614: register int c;
        !          77615: {
        !          77616:        /*
        !          77617:         * Cache received character.
        !          77618:         */
        !          77619:        istty.t_rawin.si_buf[ istty.t_rawin.si_ix ] = c;
        !          77620: 
        !          77621:        if ( ++istty.t_rawin.si_ix >= sizeof(istty.t_rawin.si_buf) )
        !          77622:                istty.t_rawin.si_ix = 0;
        !          77623: }
        !          77624: 
        !          77625: /**
        !          77626:  *
        !          77627:  * void
        !          77628:  * isbatch()   -- raw input conversion routine
        !          77629:  *
        !          77630:  *     Action: Enable the video display.
        !          77631:  *             Canonize the raw input silo.
        !          77632:  *
        !          77633:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
        !          77634:  */
        !          77635: static void
        !          77636: isbatch( tp )
        !          77637: register TTY * tp;
        !          77638: {
        !          77639:        register int c;
        !          77640:        static int lastc;
        !          77641: 
        !          77642:        /*
        !          77643:         * Ensure video display is enabled.
        !          77644:         */
        !          77645:        mm_von();
        !          77646: 
        !          77647:        isbusy = 0;
        !          77648: 
        !          77649:        /*
        !          77650:         * Process all cached characters.
        !          77651:         */
        !          77652:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          77653: 
        !          77654:                /*
        !          77655:                 * Get next cached char.
        !          77656:                 */
        !          77657:                c = tp->t_rawin.si_buf[ tp->t_rawin.si_ox ];
        !          77658: 
        !          77659:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          77660:                        tp->t_rawin.si_ox = 0;
        !          77661:                else
        !          77662:                        tp->t_rawin.si_ox++;
        !          77663: 
        !          77664:                if ( (islock == 0) || ISINTR || ISQUIT ) {
        !          77665:                        ttin( tp, c );
        !          77666:                }
        !          77667: 
        !          77668:                else if ( (c == 'b') && (lastc == '\033') ) {
        !          77669:                        islock = 0;
        !          77670:                        ttin( tp, lastc );
        !          77671:                        ttin( tp, c );
        !          77672:                }
        !          77673: 
        !          77674:                else if ( (c == 'c') && (lastc == '\033') ) {
        !          77675:                        ttin( tp, lastc );
        !          77676:                        ttin( tp, c );
        !          77677:                }
        !          77678: 
        !          77679:                else
        !          77680:                        putchar('\007');
        !          77681: 
        !          77682:                lastc = c;
        !          77683:        }
        !          77684: }
        !          77685: 
        !          77686: /*
        !          77687:  * update the keyboard status LEDS
        !          77688:  */
        !          77689: updleds()
        !          77690: {
        !          77691:        int     s;
        !          77692: 
        !          77693:        s = sphi();
        !          77694:        outb(KBDATA, LEDCMD);
        !          77695:        ledcmd = 1;
        !          77696:        spl(s);
        !          77697: }
        !          77698: 
        !          77699: /*
        !          77700:  * unlock the scroll in case an interrupt character is received
        !          77701:  */
        !          77702: kbunscroll()
        !          77703: {
        !          77704:        scroll = 0;
        !          77705:        updleds();
        !          77706: }
        !          77707: @
        !          77708: 0707070064030050461004440000000000000000011777770507310704600005600000075100/newbits/kernel/USRSRC/i8086/drv/RCS/mmas.m,vhead     1.1;
        !          77709: branch   ;
        !          77710: access   ;
        !          77711: symbols  ;
        !          77712: locks    bin:1.1; strict;
        !          77713: comment  @@;
        !          77714: 
        !          77715: 
        !          77716: 1.1
        !          77717: date     91.07.24.08.11.46;  author bin;  state Exp;
        !          77718: branches ;
        !          77719: next     ;
        !          77720: 
        !          77721: 
        !          77722: desc
        !          77723: @prov by hal
        !          77724: @
        !          77725: 
        !          77726: 
        !          77727: 
        !          77728: 1.1
        !          77729: log
        !          77730: @Initial revision
        !          77731: @
        !          77732: text
        !          77733: @/ (lgl-
        !          77734: /      COHERENT Driver Kit Version 1.0.0
        !          77735: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          77736: /      All rights reserved. May not be copied without permission.
        !          77737: / -lgl)
        !          77738: ////////
        !          77739: /
        !          77740: /      Memory mapped video driver assembler assist.
        !          77741: /
        !          77742: ////////
        !          77743: /
        !          77744: / State driven code
        !          77745: /
        !          77746: /      Input:  DS:SI - input string
        !          77747: /              ES:DI - current screen location
        !          77748: /              SS:BP - terminal information
        !          77749: /              CX    - input count
        !          77750: /              BP    - references terminal information
        !          77751: /              AH    - character attributes
        !          77752: /              AL    - character
        !          77753: /              BH    - (usually) kept zeroed for efficiency
        !          77754: /              DH    - current row
        !          77755: /              DL    - current column
        !          77756: /
        !          77757: ////////
        !          77758: 
        !          77759:        NCOL    = 80            / number of columns
        !          77760:        NCB     = 2             / number of horizontal bytes per char
        !          77761:        NCR     = 1             / number of horizontal lines per char
        !          77762:        NHB     = 160           / number of horizontal bytes per line
        !          77763:        NRB     = NCR*NHB       / number of bytes per character row
        !          77764: 
        !          77765:        ATTR    = ah            / attribute byte
        !          77766:        ZERO    = bh            / (almost) always zero
        !          77767:        ROW     = dh            / currently active vertical position
        !          77768:        COL     = dl            / currently active horizontal position
        !          77769:        POS     = di            / currently active display address
        !          77770: 
        !          77771:        INTENSE = 0x08          / high intensity attribute bit
        !          77772:        BLINK   = 0x80          / blinking attribute bit
        !          77773:        REVERSE = 0x70          / reverse video
        !          77774: 
        !          77775: ////////
        !          77776: /
        !          77777: / Magic constants from <sys/io.h>
        !          77778: /
        !          77779: ////////
        !          77780: 
        !          77781:        IO_SEG  = 0
        !          77782:        IO_IOC  = 2
        !          77783:        IO_BASE = 8
        !          77784: 
        !          77785:        IOSYS   = 0
        !          77786:        IOUSR   = 1
        !          77787: 
        !          77788: ////////
        !          77789: /
        !          77790: / Data
        !          77791: /
        !          77792: ////////
        !          77793: 
        !          77794: MM_FUNC                = 0             / current state
        !          77795: MM_PORT                = 2             / adapter base i/o port
        !          77796: MM_BASE                = 4             / adapter base memory address
        !          77797: MM_ROW         = 6             / screen row
        !          77798: MM_COL         = 7             / screen column
        !          77799: MM_POS         = 8             / screen position
        !          77800: MM_ATTR                = 10            / attributes
        !          77801: MM_N1          = 11            / numeric argument 1
        !          77802: MM_N2          = 12            / numeric argument 2
        !          77803: MM_BROW                = 13            / base row
        !          77804: MM_EROW                = 14            / end row
        !          77805: MM_LROW                = 15            / legal row limit
        !          77806: MM_SROW                = 16            / saved cursor row
        !          77807: MM_SCOL                = 17            / saved cursor column
        !          77808: MM_IBROW       = 18            / initial base row
        !          77809: MM_IEROW       = 19            / initial end row
        !          77810: MM_INVIS       = 20            / cursor invisible mask
        !          77811: MM_SLOW                = 22            / slow [no flicker] video update
        !          77812: MM_WRAP                = 23            / wrap to start of next line
        !          77813: 
        !          77814: / Characters
        !          77815: AZERO          = 0x30
        !          77816: CLOWER         = 0x63
        !          77817: HLOWER         = 0x68
        !          77818: LLOWER         = 0x6C
        !          77819: SEMIC          = 0x3B
        !          77820: SPACE          = 0x20
        !          77821: 
        !          77822:        .globl  VIDSLOW_        / Patchable kernel variable.
        !          77823:        .prvd
        !          77824: mmdata:        .word   mminit
        !          77825:        .word   0x03B4
        !          77826:        .word   0xB000
        !          77827:        .byte   0, 0
        !          77828:        .word   0
        !          77829:        .byte   0x7, 0, 0, 0, 23, 24, 0, 0, 0, 23
        !          77830:        .word   0
        !          77831: VIDSLOW_:.byte 0
        !          77832:        .byte   1
        !          77833:        .shri
        !          77834: 
        !          77835: ////////
        !          77836: /
        !          77837: / mmgo( iop )
        !          77838: / IO *iop;
        !          77839: /
        !          77840: ////////
        !          77841: 
        !          77842:        .globl  mmgo_
        !          77843: 
        !          77844: mmgo_:
        !          77845:        push    si
        !          77846:        push    di
        !          77847:        push    bp
        !          77848:        mov     bp, sp
        !          77849:        push    ds
        !          77850:        push    es
        !          77851:        cld
        !          77852:        mov     bx, 8(bp)               / iop
        !          77853:        mov     si, IO_BASE(bx)         / iop->io_base
        !          77854:        mov     cx, IO_IOC(bx)          / iop->io_ioc
        !          77855: 
        !          77856:        cmp     IO_SEG(bx), $IOSYS      / user address space
        !          77857:        je      0f
        !          77858:        mov     bx, uds_
        !          77859:        mov     ds, bx
        !          77860: 0:
        !          77861:        mov     bp, $mmdata
        !          77862:        mov     dx, MM_PORT(bp)         / turn video off if color board
        !          77863:        cmp     dx, $0x3B4
        !          77864:        je      3f
        !          77865:        cmpb    MM_SLOW(bp), $0         / check for slow [flicker-free]
        !          77866:        je      2f
        !          77867: 
        !          77868:        mov     dx, $0x3DA
        !          77869: 1:     inb     al, dx                  / wait for vertical retrace
        !          77870:        testb   al, $8
        !          77871:        je      1b
        !          77872: 2:
        !          77873:        mov     dx, $0x3D8              / disable video
        !          77874:        movb    al, $0x25
        !          77875:        outb    dx, al
        !          77876: 3:
        !          77877:        movb    ROW, MM_ROW(bp)
        !          77878:        movb    COL, MM_COL(bp)
        !          77879:        mov     es,  MM_BASE(bp)
        !          77880:        mov     POS, MM_POS(bp)
        !          77881:        sub     bx, bx
        !          77882:        movb    ATTR, MM_ATTR(bp)
        !          77883:        ijmp    MM_FUNC(bp)
        !          77884: 
        !          77885: exit:  pop     bx
        !          77886:        pop     es
        !          77887:        pop     ds
        !          77888:        movb    MM_ATTR(bp), ATTR
        !          77889:        mov     MM_FUNC(bp), bx
        !          77890:        movb    MM_ROW(bp), ROW         / save row,column
        !          77891:        movb    MM_COL(bp), COL
        !          77892:        mov     MM_POS(bp), POS         / save position
        !          77893: 
        !          77894:        mov     dx, MM_PORT(bp)         / adjust cursor location
        !          77895:        mov     bx, POS
        !          77896:        or      bx, MM_INVIS(bp)
        !          77897:        shr     bx, $1
        !          77898: 
        !          77899:        movb    al, $14
        !          77900:        outb    dx, al
        !          77901:        inc     dx
        !          77902:        movb    al, bh
        !          77903:        outb    dx, al
        !          77904:        dec     dx
        !          77905:        movb    al, $15
        !          77906:        outb    dx, al
        !          77907:        inc     dx
        !          77908:        movb    al, bl
        !          77909:        outb    dx, al
        !          77910: 
        !          77911:        mov     dx, MM_PORT(bp)         / turn video on
        !          77912:        add     dx, $4
        !          77913:        movb    al, $0x29
        !          77914:        outb    dx, al
        !          77915:        mov     mmvcnt_, $600           / 600 seconds before video disabled
        !          77916: 
        !          77917:        mov     bp, sp
        !          77918:        mov     bx, 8(bp)
        !          77919:        mov     ax, cx
        !          77920:        xchg    cx, IO_IOC(bx)
        !          77921:        sub     cx, IO_IOC(bx)
        !          77922:        add     IO_BASE(bx), cx
        !          77923:        pop     bp
        !          77924:        pop     di
        !          77925:        pop     si
        !          77926:        ret
        !          77927: 
        !          77928: 
        !          77929: ////////
        !          77930: /
        !          77931: / mminit - initialize screen
        !          77932: /
        !          77933: ////////
        !          77934: 
        !          77935: mminit:        movb    ss:mmesc_, $CLOWER              / schedule keyboard initialization
        !          77936:        call    int11_                  / read equipment status
        !          77937:        and     ax, $0x30               / isolate video bits
        !          77938:        cmp     ax, $0x30               / if not monochrome
        !          77939:        je      0f
        !          77940:        mov     MM_PORT(bp), $0x3D4     /       set color port
        !          77941:        mov     MM_BASE(bp), $0xB800    /       set color base
        !          77942:        mov     es, MM_BASE(bp)         /
        !          77943: 0:                                     /
        !          77944:        mov     dx, MM_PORT(bp)         / turn video off
        !          77945:        add     dx, $4
        !          77946:        movb    al, $0x21
        !          77947:        outb    dx, al
        !          77948: 
        !          77949:        mov     dx, MM_PORT(bp)         / zero display offset
        !          77950:        movb    al, $12
        !          77951:        outb    dx, al
        !          77952:        inc     dx
        !          77953:        subb    al, al
        !          77954:        outb    dx, al
        !          77955:        dec     dx
        !          77956:        movb    al, $13
        !          77957:        outb    dx, al
        !          77958:        inc     dx
        !          77959:        subb    al, al
        !          77960:        outb    dx, al
        !          77961: 
        !          77962:        mov     dx, MM_PORT(bp)         / reset border to black
        !          77963:        add     dx, $5
        !          77964:        subb    al, al
        !          77965:        outb    dx, al
        !          77966: 
        !          77967:        inc     dx                      / reset TECMAR XMSR register
        !          77968:        outb    dx, al
        !          77969: 
        !          77970:        mov     MM_INVIS(bp), $0
        !          77971:        movb    ATTR, $0x07
        !          77972:        movb    MM_ATTR(bp), ATTR
        !          77973:        movb    MM_WRAP(bp), $1
        !          77974:        movb    ROW, MM_IBROW(bp)
        !          77975:        movb    MM_BROW(bp), ROW
        !          77976:        movb    bl, MM_IEROW(bp)
        !          77977:        movb    MM_EROW(bp), bl
        !          77978:        sub     bx, bx
        !          77979:        movb    MM_N1(bp), $2
        !          77980:        jmp     mm_ed
        !          77981: 
        !          77982: ////////
        !          77983: /
        !          77984: / mmspec - schedule special keyboard function
        !          77985: /
        !          77986: ////////
        !          77987: 
        !          77988: mmspec:        movb    ss:mmesc_, al
        !          77989:        jmp     eval
        !          77990: 
        !          77991: ////////
        !          77992: /
        !          77993: / mmbell - schedule beep
        !          77994: /
        !          77995: ////////
        !          77996: 
        !          77997: mmbell:        movb    ss:mmbeeps_, $-1
        !          77998:        jmp     eval
        !          77999: 
        !          78000: ////////
        !          78001: /
        !          78002: / mm_cnl - cursor next line
        !          78003: /
        !          78004: /      Moves the active position to the first column of the next display line.
        !          78005: /      Scrolls the active display if necessary.
        !          78006: /
        !          78007: ////////
        !          78008: 
        !          78009: mm_cnl:        subb    COL, COL
        !          78010:        incb    ROW
        !          78011:        cmpb    ROW, MM_EROW(bp)
        !          78012:        jna     repos
        !          78013:        movb    ROW, MM_EROW(bp)
        !          78014: /      jmp     scrollup
        !          78015: 
        !          78016: ////////
        !          78017: /
        !          78018: / scrollup - scroll display upwards
        !          78019: /
        !          78020: ////////
        !          78021: 
        !          78022: scrollup:
        !          78023:        push    ds
        !          78024:        push    si
        !          78025:        push    cx
        !          78026:        mov     ds, MM_BASE(bp)
        !          78027:        movb    bl, MM_BROW(bp)
        !          78028:        shlb    bl, $1
        !          78029:        mov     di, cs:rowtab(bx)
        !          78030:        mov     si, cs:rowtab+2(bx)
        !          78031:        movb    bl, ROW
        !          78032:        shlb    bl, $1
        !          78033:        mov     cx, cs:rowtab(bx)
        !          78034:        push    cx
        !          78035:        sub     cx, di
        !          78036:        shr     cx, $1
        !          78037:        cld
        !          78038:        rep
        !          78039:        movsw
        !          78040:        movb    al, $SPACE
        !          78041:        pop     di
        !          78042:        mov     cx, $NCOL
        !          78043:        rep
        !          78044:        stosw
        !          78045:        pop     cx
        !          78046:        pop     si
        !          78047:        pop     ds
        !          78048:        movb    bl, COL                 / reposition to ROW and COL
        !          78049:        shlb    bl, $1
        !          78050:        mov     POS, cs:coltab(bx)
        !          78051:        movb    bl, ROW
        !          78052:        shlb    bl, $1
        !          78053:        add     POS, cs:rowtab(bx)
        !          78054:        call    exit
        !          78055:        jmp     eval
        !          78056: 
        !          78057: ////////
        !          78058: /
        !          78059: / repos - reposition cursor
        !          78060: /
        !          78061: ////////
        !          78062: 
        !          78063: repos: movb    bl, COL                 / reposition to ROW and COL
        !          78064:        shlb    bl, $1
        !          78065:        mov     POS, cs:coltab(bx)
        !          78066:        movb    bl, ROW
        !          78067:        shlb    bl, $1
        !          78068:        add     POS, cs:rowtab(bx)
        !          78069: /      jmp     eval
        !          78070: 
        !          78071: ////////
        !          78072: /
        !          78073: / eval - evaluate input character
        !          78074: /
        !          78075: ////////
        !          78076: 
        !          78077: eval:  jcxz    ewait
        !          78078:        dec     cx                              / evaluate next char
        !          78079:        lodsb
        !          78080:        movb    bl, al
        !          78081:        shlb    bl, $1
        !          78082:        jc      mmputc
        !          78083:        ijmp    cs:asctab(bx)
        !          78084: 
        !          78085: ////////
        !          78086: /
        !          78087: / mmputc - put character on screen
        !          78088: /
        !          78089: ////////
        !          78090: 
        !          78091: mmputc:        stosw                           / Update display memory.
        !          78092:        incb    COL
        !          78093:        cmpb    COL, $NCOL              / Past end of line?
        !          78094:        jge     0f
        !          78095:        jcxz    ewait                   / Not past, evaluate next character.
        !          78096:        dec     cx
        !          78097:        lodsb
        !          78098:        movb    bl, al
        !          78099:        shlb    bl, $1
        !          78100:        jc      mmputc
        !          78101:        ijmp    cs:asctab(bx)
        !          78102: 
        !          78103: 0:     cmpb    MM_WRAP(bp), $0         / Yes past, Wrap around?
        !          78104:        jne     0f
        !          78105:        sub     di, $2                  / No wrap, adjust back to end of line.
        !          78106:        decb    COL
        !          78107:        jcxz    ewait                   / Not past, evaluate next character.
        !          78108:        dec     cx
        !          78109:        lodsb
        !          78110:        movb    bl, al
        !          78111:        shlb    bl, $1
        !          78112:        jc      mmputc
        !          78113:        ijmp    cs:asctab(bx)
        !          78114: 
        !          78115: 0:     subb    COL, COL                / Wrap to next line.
        !          78116:        incb    ROW
        !          78117:        cmpb    ROW, MM_EROW(bp)        / Past scrolling region?
        !          78118:        jg      0f
        !          78119:        jcxz    ewait                   / Not past, evaluate next character.
        !          78120:        dec     cx
        !          78121:        lodsb
        !          78122:        movb    bl, al
        !          78123:        shlb    bl, $1
        !          78124:        jc      mmputc
        !          78125:        ijmp    cs:asctab(bx)
        !          78126: 
        !          78127: 0:     movb    ROW, MM_EROW(bp)        / Yes past, scroll up 1 line.
        !          78128:        jmp     scrollup
        !          78129: 
        !          78130: ////////
        !          78131: /
        !          78132: / Ewait - wait for next input char to evaluate
        !          78133: /
        !          78134: ////////
        !          78135: 
        !          78136: ewait: call    exit
        !          78137:        jcxz    ewait
        !          78138:        dec     cx
        !          78139:        lodsb
        !          78140:        movb    bl, al
        !          78141:        shlb    bl, $1
        !          78142:        jc      mmputc
        !          78143:        ijmp    cs:asctab(bx)
        !          78144: 
        !          78145: ////////
        !          78146: /
        !          78147: / mm_cr - carriage return
        !          78148: /
        !          78149: /      Moves the active position to first position of current display line.
        !          78150: /
        !          78151: ////////
        !          78152: 
        !          78153: mm_cr: subb    COL, COL
        !          78154:        movb    bl, ROW
        !          78155:        shlb    bl, $1
        !          78156:        mov     POS, cs:rowtab(bx)
        !          78157:        jcxz    ewait
        !          78158:        dec     cx
        !          78159:        lodsb
        !          78160:        movb    bl, al
        !          78161:        shlb    bl, $1
        !          78162:        jc      mmputc
        !          78163:        ijmp    cs:asctab(bx)
        !          78164: 
        !          78165: ////////
        !          78166: /
        !          78167: / mm_cub - cursor backwards
        !          78168: /
        !          78169: ////////
        !          78170: 
        !          78171: mm_cub:        sub     POS, $2
        !          78172:        decb    COL
        !          78173:        jge     0f
        !          78174:        movb    COL, $NCOL-1
        !          78175:        decb    ROW
        !          78176:        cmpb    ROW, MM_BROW(bp)
        !          78177:        jge     0f
        !          78178:        subb    COL, COL
        !          78179:        movb    ROW, MM_BROW(bp)
        !          78180:        movb    bl, ROW
        !          78181:        shlb    bl, $1
        !          78182:        mov     POS, cs:rowtab(bx)
        !          78183: 0:     jcxz    ewait
        !          78184:        dec     cx
        !          78185:        lodsb
        !          78186:        movb    bl, al
        !          78187:        shlb    bl, $1
        !          78188:        jc      mmputc
        !          78189:        ijmp    cs:asctab(bx)
        !          78190: 
        !          78191: ////////
        !          78192: /
        !          78193: / Esc state - entered when last char was ESC - transient state.
        !          78194: /
        !          78195: ////////
        !          78196: 
        !          78197: 0:     call    exit
        !          78198: mm_esc:        jcxz    0b
        !          78199:        dec     cx
        !          78200:        lodsb
        !          78201:        movb    MM_N1(bp), ZERO
        !          78202:        movb    MM_N2(bp), ZERO
        !          78203:        movb    bl, al
        !          78204:        shlb    bl, $1
        !          78205:        jc      mmputc
        !          78206:        ijmp    cs:esctab(bx)
        !          78207: 
        !          78208: ////////
        !          78209: /
        !          78210: / Csi_n1 state - entered when last two chars were ESC [
        !          78211: /
        !          78212: /      Action: Evaluates numeric chars as numeric parameter 1.
        !          78213: /
        !          78214: ////////
        !          78215: 
        !          78216: 0:     call    exit
        !          78217: csi_n1:        jcxz    0b
        !          78218:        dec     cx
        !          78219:        lodsb
        !          78220:        cmpb    al, $SEMIC
        !          78221:        je      csi_n2
        !          78222:        movb    bl, al
        !          78223:        subb    bl, $AZERO
        !          78224:        cmpb    bl, $9
        !          78225:        ja      csival
        !          78226:        shlb    MM_N1(bp), $1   / n1 * 2
        !          78227:        movb    al, MM_N1(bp)   / n1 * 2
        !          78228:        shlb    al, $1          / n1 * 4
        !          78229:        shlb    al, $1          / n1 * 8
        !          78230:        addb    al, MM_N1(bp)   / n1 * 10
        !          78231:        addb    al, bl          / n1 * 10 + digit
        !          78232:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          78233:        jmp     csi_n1
        !          78234: 
        !          78235: ////////
        !          78236: /
        !          78237: / Csi_n2 state - entered after input sequence ESC [ n ;
        !          78238: /
        !          78239: ////////
        !          78240: 
        !          78241: 0:     call    exit
        !          78242: csi_n2:        jcxz    0b
        !          78243:        dec     cx
        !          78244:        lodsb
        !          78245:        movb    bl, al
        !          78246:        subb    bl, $AZERO
        !          78247:        cmpb    bl, $9
        !          78248:        ja      csival
        !          78249:        shlb    MM_N2(bp), $1   / n2 * 2
        !          78250:        movb    al, MM_N2(bp)   / n2 * 2
        !          78251:        shlb    al, $1          / n2 * 4
        !          78252:        shlb    al, $1          / n2 * 8
        !          78253:        addb    al, MM_N2(bp)   / n2 * 10
        !          78254:        addb    al, bl          / n2 * 10 + digit
        !          78255:        movb    MM_N2(bp), al   / n2 = (n2 * 10) + digit
        !          78256:        jmp     csi_n2
        !          78257: 
        !          78258: csival:        movb    bl, al
        !          78259:        shlb    bl, $1
        !          78260:        jc      mmputc
        !          78261:        ijmp    cs:csitab(bx)
        !          78262: 
        !          78263: ////////
        !          78264: /
        !          78265: / Csi_gt state - entered after input sequence ESC [ >
        !          78266: /      
        !          78267: ////////
        !          78268: 
        !          78269: 0:     call    exit
        !          78270: csi_gt:        jcxz    0b
        !          78271:        dec     cx
        !          78272:        lodsb
        !          78273:        movb    bl, al
        !          78274:        subb    bl, $AZERO
        !          78275:        cmpb    bl, $9
        !          78276:        ja      0f
        !          78277:        shlb    MM_N1(bp), $1   / n1 * 2
        !          78278:        movb    al, MM_N1(bp)   / n1 * 2
        !          78279:        shlb    al, $1          / n1 * 4
        !          78280:        shlb    al, $1          / n1 * 8
        !          78281:        addb    al, MM_N1(bp)   / n1 * 10
        !          78282:        addb    al, bl          / n1 * 10 + digit
        !          78283:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          78284:        jmp     csi_gt
        !          78285: 
        !          78286: 0:     cmpb    al, $HLOWER
        !          78287:        je      mm_cgh
        !          78288:        cmpb    al, $LLOWER
        !          78289:        je      mm_cgl
        !          78290:        jmp     eval
        !          78291: 
        !          78292: ////////
        !          78293: /
        !          78294: / Csi_q state - entered after input sequence ESC [ ?
        !          78295: /      
        !          78296: ////////
        !          78297: 
        !          78298: 0:     call    exit
        !          78299: csi_q: jcxz    0b
        !          78300:        dec     cx
        !          78301:        lodsb
        !          78302:        movb    bl, al
        !          78303:        subb    bl, $AZERO
        !          78304:        cmpb    bl, $9
        !          78305:        ja      0f
        !          78306:        shlb    MM_N1(bp), $1   / n1 * 2
        !          78307:        movb    al, MM_N1(bp)   / n1 * 2
        !          78308:        shlb    al, $1          / n1 * 4
        !          78309:        shlb    al, $1          / n1 * 8
        !          78310:        addb    al, MM_N1(bp)   / n1 * 10
        !          78311:        addb    al, bl          / n1 * 10 + digit
        !          78312:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          78313:        jmp     csi_q
        !          78314: 
        !          78315: 0:     cmpb    al, $HLOWER
        !          78316:        je      mm_cqh
        !          78317:        cmpb    al, $LLOWER
        !          78318:        je      mm_cql
        !          78319:        jmp     eval
        !          78320: 
        !          78321: ////////
        !          78322: /
        !          78323: / mm_cbt - cursor backward tabulation
        !          78324: /
        !          78325: /      Moves the active position horizontally in the backward direction
        !          78326: /      to the preceding in a series of predetermined positions.
        !          78327: /
        !          78328: ////////
        !          78329: 
        !          78330: mm_cbt:        orb     COL, $7                 / calculate next tab stop
        !          78331:        incb    COL
        !          78332:        subb    COL, $16                / step back two tab positions
        !          78333:        jg      0f
        !          78334:        subb    COL, COL                / cannot step past column 0
        !          78335: 0:     jmp     repos                   / reposition cursor
        !          78336: 
        !          78337: ////////
        !          78338: /
        !          78339: / mm_cgh - process ESC [ > N1 h escape sequence
        !          78340: /
        !          78341: /      Recognized sequences:   ESC [ > 13 h    -- Set CRT saver enabled.
        !          78342: /
        !          78343: ////////
        !          78344: 
        !          78345: mm_cgh:        cmpb    MM_N1(bp), $13
        !          78346:        jne     0f
        !          78347:        mov     ss:mmcrtsav_, $1
        !          78348: 0:     jmp     eval
        !          78349: 
        !          78350: ////////
        !          78351: /
        !          78352: / mm_cgl - process ESC [ > N1 l escape sequence
        !          78353: /
        !          78354: /      Recognized sequences:   ESC [ > 13 l    -- Reset CRT saver.
        !          78355: /
        !          78356: ////////
        !          78357: 
        !          78358: mm_cgl:        cmpb    MM_N1(bp), $13
        !          78359:        jne     0f
        !          78360:        mov     ss:mmcrtsav_, $0
        !          78361: 0:     jmp     eval
        !          78362: 
        !          78363: ////////
        !          78364: /
        !          78365: / mm_cha - cursor horizontal absolute
        !          78366: /
        !          78367: /      Advances the active position forward or backward along the active line
        !          78368: /      to the character position specified by the parameter.
        !          78369: /      A parameter value of zero or one moves the active position to the
        !          78370: /      first character position of the active line.
        !          78371: /      A parameter value of N moves the active position to character position
        !          78372: /      N of the active line.
        !          78373: /
        !          78374: ////////
        !          78375: 
        !          78376: mm_cha:        movb    COL, MM_N1(bp)
        !          78377:        decb    COL
        !          78378:        jge     0f
        !          78379:        subb    COL, COL
        !          78380: 0:     cmpb    COL, $NCOL
        !          78381:        jb      0f
        !          78382:        movb    COL, $NCOL-1
        !          78383: 0:     jmp     repos                   / reposition cursor
        !          78384: 
        !          78385: 
        !          78386: ////////
        !          78387: /
        !          78388: / mm_cht - cursor horizontal tabulation
        !          78389: /
        !          78390: /      Advances the active position horizontally to the next or following
        !          78391: /      in a series of predetermined positions.
        !          78392: /
        !          78393: ////////
        !          78394: 
        !          78395: mm_cht:        push    cx
        !          78396:        sub     cx, cx
        !          78397:        movb    cl, COL
        !          78398:        orb     cl, $7
        !          78399:        incb    cl
        !          78400:        subb    cl, COL
        !          78401:        addb    COL, cl
        !          78402:        movb    al, $SPACE
        !          78403:        rep
        !          78404:        stosw
        !          78405:        pop     cx
        !          78406:        cmpb    COL, $NCOL
        !          78407:        jb      0f
        !          78408:        subb    COL, $NCOL
        !          78409:        incb    ROW
        !          78410:        cmpb    ROW, MM_EROW(bp)
        !          78411:        jna     0f
        !          78412:        movb    ROW, MM_EROW(bp)
        !          78413:        jmp     scrollup
        !          78414: 0:     jmp     eval
        !          78415: 
        !          78416: ////////
        !          78417: /
        !          78418: / mm_cpl - cursor preceding line
        !          78419: /
        !          78420: /      Moves the active position to the first position of the preceding
        !          78421: /      display line.
        !          78422: /
        !          78423: ////////
        !          78424: 
        !          78425: mm_cpl:        subb    COL, COL
        !          78426:        decb    ROW
        !          78427:        cmpb    ROW, MM_BROW(bp)
        !          78428:        jnb     0f
        !          78429:        movb    ROW, MM_BROW(bp)
        !          78430:        jmp     scrolldown
        !          78431: 0:     jmp     repos                   / reposition cursor
        !          78432: 
        !          78433: ////////
        !          78434: /
        !          78435: / mm_cqh - process ESC [ ? N1 h escape sequence
        !          78436: /
        !          78437: /      Recognized sequences:   ESC [ ? 4 h     -- Set smooth scroll.
        !          78438: /                              ESC [ ? 7 h     -- Set wraparound.
        !          78439: /
        !          78440: ////////
        !          78441: 
        !          78442: mm_cqh:        cmpb    MM_N1(bp), $4           / Smooth scroll.
        !          78443:        jne     0f
        !          78444:        movb    MM_SLOW(bp), $1
        !          78445: 0:     cmpb    MM_N1(bp), $7           / Wraparound.
        !          78446:        jne     0f
        !          78447:        movb    MM_WRAP(bp), $1
        !          78448: 0:     jmp     eval
        !          78449: 
        !          78450: ////////
        !          78451: /
        !          78452: / mm_cql - process ESC [ ? N1 l escape sequence
        !          78453: /
        !          78454: /      Recognized sequences:   ESC [ ? 4 l     -- Set jump scroll.
        !          78455: /                              ESC [ ? 7 l     -- Reset wraparound.
        !          78456: /
        !          78457: ////////
        !          78458: 
        !          78459: mm_cql:        cmpb    MM_N1(bp), $4           / Jump scroll.
        !          78460:        jne     0f
        !          78461:        movb    MM_SLOW(bp), $0
        !          78462: 0:     cmpb    MM_N1(bp), $7           / No wraparound.
        !          78463:        jne     0f
        !          78464:        movb    MM_WRAP(bp), $0
        !          78465: 0:     jmp     eval
        !          78466: 
        !          78467: ////////
        !          78468: /
        !          78469: / mm_cud - cursor down
        !          78470: /
        !          78471: /      Moves the active position downward without altering the
        !          78472: /      horizontal position.
        !          78473: /
        !          78474: ////////
        !          78475: 
        !          78476: mm_cud:        incb    ROW
        !          78477:        cmpb    ROW, MM_EROW(bp)
        !          78478:        jna     0f
        !          78479:        movb    ROW, MM_EROW(bp)
        !          78480: 0:     jmp     repos                   / reposition cursor
        !          78481: 
        !          78482: ////////
        !          78483: /
        !          78484: / mm_cuf - cursor forward
        !          78485: /
        !          78486: /      Moves the active position in the forward direction.
        !          78487: /
        !          78488: ////////
        !          78489: 
        !          78490: mm_cuf:        incb    COL
        !          78491:        cmpb    COL, $NCOL
        !          78492:        jb      0f
        !          78493:        subb    COL, $NCOL
        !          78494:        incb    ROW
        !          78495:        cmpb    ROW, MM_EROW(bp)
        !          78496:        jna     0f
        !          78497:        movb    ROW, MM_EROW(bp)
        !          78498:        movb    COL, $NCOL-1
        !          78499: 0:     jmp     repos
        !          78500: 
        !          78501: ////////
        !          78502: /
        !          78503: / mm_cup - cursor position
        !          78504: /
        !          78505: /      Moves the active position to the position specified by two parameters.
        !          78506: /      The first parameter (mm_n1) specifies the vertical position (MM_ROW(bp)).
        !          78507: /      The second parameter (mm_n2) specifies the horizontal position (MM_COL(bp)).
        !          78508: /      A parameter value of 0 or 1 for the first or second parameter
        !          78509: /      moves the active position to the first line or column in the
        !          78510: /      display respectively.
        !          78511: /
        !          78512: ////////
        !          78513: 
        !          78514: mm_cup:        movb    ROW, MM_N1(bp)
        !          78515:        decb    ROW
        !          78516:        jg      0f
        !          78517:        subb    ROW, ROW
        !          78518: 0:     addb    ROW, MM_BROW(bp)
        !          78519:        cmpb    ROW, MM_EROW(bp)
        !          78520:        jb      0f
        !          78521:        movb    ROW, MM_EROW(bp)
        !          78522: 0:     movb    COL, MM_N2(bp)
        !          78523:        decb    COL
        !          78524:        jg      0f
        !          78525:        subb    COL, COL
        !          78526: 0:     cmpb    COL, $NCOL
        !          78527:        jb      0f
        !          78528:        movb    COL, $NCOL-1
        !          78529: 0:     jmp     repos                   / reposition cursor
        !          78530: 
        !          78531: ////////
        !          78532: /
        !          78533: / mm_cuu - cursor up
        !          78534: /
        !          78535: /      Moves the active position upward without altering the horizontal
        !          78536: /      position.
        !          78537: /
        !          78538: ////////
        !          78539: 
        !          78540: mm_cuu:        decb    ROW
        !          78541:        cmpb    ROW, MM_BROW(bp)
        !          78542:        jge     0f
        !          78543:        movb    ROW, MM_BROW(bp)
        !          78544: 0:     jmp     repos                   / reposition cursor
        !          78545: 
        !          78546: ////////
        !          78547: /
        !          78548: / mm_dl - delete line
        !          78549: /
        !          78550: /      Removes the contents of the active line.
        !          78551: /      The contents of all following lines are shifted in a block
        !          78552: /      toward the active line.
        !          78553: /
        !          78554: ////////
        !          78555: 
        !          78556: mm_dl: push    ds
        !          78557:        push    si
        !          78558:        push    cx
        !          78559:        mov     ds, MM_BASE(bp)
        !          78560:        movb    bl, ROW
        !          78561:        shlb    bl, $1
        !          78562:        mov     di, cs:rowtab(bx)
        !          78563:        mov     si, cs:rowtab+2(bx)
        !          78564:        movb    bl, MM_EROW(bp)
        !          78565:        shlb    bl, $1
        !          78566:        mov     cx, cs:rowtab(bx)
        !          78567:        sub     cx, di
        !          78568:        jle     0f
        !          78569:        shr     cx, $1
        !          78570:        rep
        !          78571:        movsw
        !          78572:        mov     di, cs:rowtab(bx)
        !          78573:        mov     cx, $NCOL
        !          78574:        movb    al, $SPACE
        !          78575:        rep
        !          78576:        stosw
        !          78577:        subb    COL, COL
        !          78578:        movb    bl, ROW
        !          78579:        shlb    bl, $1
        !          78580:        mov     di, cs:rowtab(bx)
        !          78581: 0:     pop     cx
        !          78582:        pop     si
        !          78583:        pop     ds
        !          78584:        call    exit
        !          78585:        jmp     eval
        !          78586: 
        !          78587: ////////
        !          78588: /
        !          78589: / mm_dmi - disable manual input
        !          78590: /
        !          78591: /      Set flag preventing keyboard input, and causing cursor to vanish.
        !          78592: /
        !          78593: ////////
        !          78594: 
        !          78595: mm_dmi:
        !          78596:        mov     ss:islock_, $1
        !          78597:        jmp     eval
        !          78598: 
        !          78599: ////////
        !          78600: /
        !          78601: / mm_ea - erase in area
        !          78602: /
        !          78603: /      Erase some or all of the characters in the currently active area
        !          78604: /      according to the parameter:
        !          78605: /              0 - erase from active position to end inclusive (default)
        !          78606: /              1 - erase from start to active position inclusive
        !          78607: /              2 - erase all of active area
        !          78608: /
        !          78609: ////////
        !          78610: 
        !          78611: mm_ea: movb    al, MM_N1(bp)
        !          78612:        cmpb    al, $0
        !          78613:        jne     0f
        !          78614:        movb    bl, MM_EROW(bp)
        !          78615:        jmp     mm_e0
        !          78616: 0:     cmpb    al, $1
        !          78617:        jne     0f
        !          78618:        movb    bl, MM_BROW(bp)
        !          78619:        jmp     mm_e1
        !          78620: 0:     subb    COL, COL
        !          78621:        movb    ROW, MM_BROW(bp)
        !          78622:        movb    bl, ROW
        !          78623:        shlb    bl, $1
        !          78624:        mov     POS, cs:rowtab(bx)
        !          78625:        movb    bl, MM_EROW(bp)
        !          78626:        subb    bl, ROW
        !          78627:        jmp     mm_e2
        !          78628: 
        !          78629: 
        !          78630: ////////
        !          78631: /
        !          78632: / mm_ed - erase in display
        !          78633: /
        !          78634: /      Erase some or all of the characters in the display according to the
        !          78635: /      parameter
        !          78636: /              0 - erase from active position to end inclusive (default)
        !          78637: /              1 - erase from start to active position inclusive
        !          78638: /              2 - erase all of display
        !          78639: /
        !          78640: ////////
        !          78641: 
        !          78642: mm_ed: movb    al, MM_N1(bp)
        !          78643:        cmpb    al, $0
        !          78644:        jne     0f
        !          78645:        movb    bl, MM_LROW(bp)
        !          78646:        jmp     mm_e0
        !          78647: 0:     cmpb    al, $1
        !          78648:        jne     0f
        !          78649:        subb    bl, bl
        !          78650:        jmp     mm_e1
        !          78651: 0:     subb    COL, COL
        !          78652:        movb    ROW, MM_BROW(bp)
        !          78653:        sub     POS, POS
        !          78654:        movb    bl, MM_LROW(bp)
        !          78655:        jmp     mm_e2
        !          78656: 
        !          78657: ////////
        !          78658: /
        !          78659: / mm_el - erase in line
        !          78660: /
        !          78661: /      Erase some or all of the characters in the line according to the
        !          78662: /      parameter:
        !          78663: /              0 - erase from active position to end inclusive (default)
        !          78664: /              1 - erase from start to active position inclusive
        !          78665: /              2 - erase entire line
        !          78666: /
        !          78667: ////////
        !          78668: 
        !          78669: mm_el: movb    al, MM_N1(bp)
        !          78670:        movb    bl, ROW
        !          78671:        cmpb    al, $0
        !          78672:        je      mm_e0
        !          78673:        cmpb    al, $1
        !          78674:        je      mm_e1
        !          78675:        shlb    bl, $1
        !          78676:        mov     POS, cs:rowtab(bx)
        !          78677:        subb    COL, COL
        !          78678:        subb    bl, bl
        !          78679: /      jmp     mm_e2
        !          78680: 
        !          78681: mm_e2: push    cx
        !          78682:        movb    al, $SPACE
        !          78683: 0:     mov     cx, $NCOL
        !          78684:        rep
        !          78685:        stosw
        !          78686:        decb    bl
        !          78687:        jge     0b
        !          78688:        pop     cx
        !          78689:        jmp     repos
        !          78690: 
        !          78691: mm_e1: push    cx
        !          78692:        mov     cx, POS
        !          78693:        shlb    bl, $1
        !          78694:        mov     POS, cs:rowtab(bx)
        !          78695:        sub     cx, POS
        !          78696:        jl      0f
        !          78697:        movb    al, $SPACE
        !          78698:        shr     cx, $1
        !          78699:        rep
        !          78700:        stosw
        !          78701: 0:     pop     cx
        !          78702:        jmp     repos
        !          78703: 
        !          78704: mm_e0: push    cx
        !          78705:        shlb    bl, $1
        !          78706:        mov     cx, cs:rowtab+2(bx)
        !          78707:        sub     cx, POS
        !          78708:        jl      0f
        !          78709:        movb    al, $SPACE
        !          78710:        shr     cx, $1
        !          78711:        rep
        !          78712:        stosw
        !          78713: 0:     pop     cx
        !          78714:        jmp     repos
        !          78715: 
        !          78716: ////////
        !          78717: /
        !          78718: / mm_emi - enable manual input
        !          78719: /
        !          78720: /      Clear flag preventing keyboard input.
        !          78721: /
        !          78722: ////////
        !          78723: 
        !          78724: mm_emi:
        !          78725:        mov     ss:islock_, $0
        !          78726:        jmp     eval
        !          78727: 
        !          78728: ////////
        !          78729: /
        !          78730: / mm_il - insert line
        !          78731: /
        !          78732: /      Insert a erased line at the active line by shifting the contents
        !          78733: /      of the active line and all following lines away from the active line.
        !          78734: /      The contents of the last line in the scrolling region are removed.
        !          78735: /
        !          78736: ////////
        !          78737: 
        !          78738: scrolldown:
        !          78739: mm_il: push    ds
        !          78740:        push    si
        !          78741:        push    cx
        !          78742:        mov     ds, MM_BASE(bp)
        !          78743:        movb    bl, MM_EROW(bp)
        !          78744:        shlb    bl, $1
        !          78745:        mov     si, cs:rowtab(bx)
        !          78746:        mov     cx, si
        !          78747:        sub     si, $2
        !          78748:        mov     di, cs:rowtab+2(bx)
        !          78749:        sub     di, $2
        !          78750:        movb    bl, ROW
        !          78751:        shlb    bl, $1
        !          78752:        sub     cx, cs:rowtab(bx)
        !          78753:        jle     0f
        !          78754:        shr     cx, $1
        !          78755:        std
        !          78756:        rep
        !          78757:        movsw
        !          78758:        mov     di, cs:rowtab(bx)
        !          78759:        mov     cx, $NCOL
        !          78760:        movb    al, $SPACE
        !          78761:        cld
        !          78762:        rep
        !          78763:        stosw
        !          78764:        subb    COL, COL
        !          78765:        movb    bl, ROW
        !          78766:        shlb    bl, $1
        !          78767:        mov     di, cs:rowtab(bx)
        !          78768: 0:     pop     cx
        !          78769:        pop     si
        !          78770:        pop     ds
        !          78771:        call    exit
        !          78772:        jmp     eval
        !          78773: 
        !          78774: ////////
        !          78775: /
        !          78776: / mm_hpa - horizontal position absolute
        !          78777: /
        !          78778: /      Moves the active position within the active line to the position
        !          78779: /      specified by the parameter.  A parameter value of zero or one
        !          78780: /      moves the active position to the first position of the active line.
        !          78781: /
        !          78782: ////////
        !          78783: 
        !          78784: mm_hpa:        movb    COL, MM_N1(bp)
        !          78785:        decb    COL
        !          78786:        jg      0f
        !          78787:        subb    COL, COL
        !          78788: 0:     cmpb    COL, $NCOL
        !          78789:        jb      0f
        !          78790:        movb    COL, $NCOL-1
        !          78791: 0:     jmp     repos                   / reposition cursor
        !          78792: 
        !          78793: ////////
        !          78794: /
        !          78795: / mm_hpr - horizontal position relative
        !          78796: /
        !          78797: /      Moves the active position forward the number of positions specified
        !          78798: /      by the parameter.  A parameter value of zero or one indicates a
        !          78799: /      single-position move.
        !          78800: /
        !          78801: ////////
        !          78802: 
        !          78803: mm_hpr:        movb    al, MM_N1(bp)
        !          78804:        orb     al, al
        !          78805:        jne     0f
        !          78806:        incb    al
        !          78807: 0:     addb    COL, al
        !          78808:        cmpb    COL, $NCOL
        !          78809:        jb      0f
        !          78810:        movb    COL, $NCOL-1
        !          78811: 0:     jmp     repos                   / reposition cursor
        !          78812: 
        !          78813: ////////
        !          78814: /
        !          78815: / mm_hvp - horizontal and vertical position
        !          78816: /
        !          78817: /      Moves the active position to the position specified by two parameters.
        !          78818: /      The first parameter specifies the vertical position (MM_ROW(bp)).
        !          78819: /      The second parameter specifies the horizontal position (MM_COL(bp)).
        !          78820: /      A parameter value of zero or one moves the active position to the
        !          78821: /      first line or column in the display.
        !          78822: /
        !          78823: ////////
        !          78824: 
        !          78825: mm_hvp:        movb    ROW, MM_N1(bp)
        !          78826:        decb    ROW
        !          78827:        jg      0f
        !          78828:        subb    ROW, ROW
        !          78829: 0:     cmpb    ROW, MM_LROW(bp)
        !          78830:        jna     0f
        !          78831:        movb    ROW, MM_LROW(bp)
        !          78832: 0:     movb    COL, MM_N2(bp)
        !          78833:        decb    COL
        !          78834:        jg      0f
        !          78835:        subb    COL, COL
        !          78836: 0:     cmpb    COL, $NCOL
        !          78837:        jb      0f
        !          78838:        movb    COL, $NCOL-1
        !          78839: 0:     jmp     repos                   / reposition cursor
        !          78840: 
        !          78841: ////////
        !          78842: /
        !          78843: / mm_ind - index
        !          78844: /
        !          78845: /      Causes the active position to move downward one line without changing
        !          78846: /      the horizontal position.  Scrolling occurs if below scrolling region.
        !          78847: /
        !          78848: ////////
        !          78849: 
        !          78850: mm_ind:        incb    ROW
        !          78851:        cmpb    ROW, MM_EROW(bp)
        !          78852:        jg      0f
        !          78853:        jmp     repos
        !          78854: 0:     movb    ROW, MM_EROW(bp)
        !          78855:        jmp     scrollup
        !          78856: 
        !          78857: ////////
        !          78858: /
        !          78859: / mm_new - save cursor position
        !          78860: /
        !          78861: ////////
        !          78862: 
        !          78863: mm_new:        movb    MM_SCOL(bp), COL
        !          78864:        movb    MM_SROW(bp), ROW
        !          78865:        jmp     eval
        !          78866: 
        !          78867: ////////
        !          78868: /
        !          78869: / mm_old - restore old cursor position
        !          78870: /
        !          78871: ////////
        !          78872: 
        !          78873: mm_old:        movb    COL, MM_SCOL(bp)
        !          78874:        movb    ROW, MM_SROW(bp)
        !          78875:        jmp     repos
        !          78876: 
        !          78877: ////////
        !          78878: /
        !          78879: / mm_ri - reverse index
        !          78880: /
        !          78881: /      Moves the active position to the same horizontal position on the
        !          78882: /      preceding line.  Scrolling occurs if above scrolling region.
        !          78883: /
        !          78884: ////////
        !          78885: 
        !          78886: mm_ri: decb    ROW
        !          78887:        cmpb    ROW, MM_BROW(bp)
        !          78888:        jge     0f
        !          78889:        movb    ROW, MM_BROW(bp)
        !          78890:        jmp     scrolldown
        !          78891: 0:     jmp     repos
        !          78892: 
        !          78893: ////////
        !          78894: /
        !          78895: / mm_scr - select cursor rendition
        !          78896: /
        !          78897: /      Invokes the cursor rendition specified by the parameter.
        !          78898: /
        !          78899: /      Recognized renditions are:      0 - cursor visible
        !          78900: /                                      1 - cursor invisible
        !          78901: ////////
        !          78902: 
        !          78903: mm_scr:        decb     MM_N1(bp)
        !          78904:        je      0f
        !          78905:        jg      1f
        !          78906:        mov     MM_INVIS(bp), $0
        !          78907:        jmp     eval
        !          78908: 
        !          78909: 0:     mov     MM_INVIS(bp), $-1
        !          78910: 1:     jmp     eval
        !          78911: 
        !          78912: ////////
        !          78913: /
        !          78914: / mm_sgr - select graphic rendition
        !          78915: /
        !          78916: /      Invokes the graphic rendition specified by the parameter.
        !          78917: /      All following characters in the data stream are rendered
        !          78918: /      according to the parameters until the next occurrence of
        !          78919: /      SGR in the data stream.
        !          78920: /
        !          78921: /      Recognized renditions are:      1 - high intensity
        !          78922: /                                      4 - underline
        !          78923: /                                      5 - slow blink
        !          78924: /                                      7 - reverse video
        !          78925: /                                      8 - concealed on
        !          78926: /                                      30-37 - foreground color
        !          78927: /                                      40-47 - background color
        !          78928: /                                      50-57 - border color
        !          78929: /
        !          78930: ////////
        !          78931: 
        !          78932: mm_sgr:        movb    al, MM_N1(bp)
        !          78933: 
        !          78934:        cmpb    al, $0                  / reset all = 0
        !          78935:        jne     0f
        !          78936:        movb    ATTR, $0x07
        !          78937: 1:     jmp     eval
        !          78938: 
        !          78939: 0:     cmpb    al, $1                  / bold = 1
        !          78940:        jne     0f
        !          78941:        orb     ATTR, $INTENSE
        !          78942:        jmp     1b
        !          78943: 
        !          78944: 0:     cmpb    al, $4                  / underline = 4
        !          78945:        jne     0f
        !          78946:        cmp     MM_PORT(bp), $0x03D4    / color card?
        !          78947:        je      1b                      / yes, ignore underline
        !          78948:        andb    ATTR, $~0x77
        !          78949:        orb     ATTR, $0x01
        !          78950:        jmp     1b
        !          78951: 
        !          78952: 0:     cmpb    al, $5                  / blinking = 5
        !          78953:        jne     0f
        !          78954:        orb     ATTR, $BLINK
        !          78955:        jmp     1b
        !          78956: 
        !          78957: 0:     cmpb    al, $7                  / reverse video = 7
        !          78958:        jne     0f
        !          78959:        movb    al, $0x70
        !          78960:        cmp     MM_PORT(bp), $0x3D4     / color card?
        !          78961:        jne     2f
        !          78962:        movb    al, ATTR                / yes, exchange foreground/background
        !          78963:        andb    al, $0x77
        !          78964:        rolb    al, $1
        !          78965:        rolb    al, $1
        !          78966:        rolb    al, $1
        !          78967:        rolb    al, $1
        !          78968: 2:     andb    ATTR, $~0x77
        !          78969:        orb     ATTR, al
        !          78970:        jmp     1b
        !          78971: 
        !          78972: 0:     cmpb    al, $8                  / concealed on = 8
        !          78973:        jne     0f
        !          78974:        cmp     MM_PORT(bp), $0x3D4     / color card?
        !          78975:        jne     2f
        !          78976: 
        !          78977:        andb    ATTR, $0x70             / Yes,  Set foreground color
        !          78978:        movb    al, ATTR                /       to background color.
        !          78979:        rorb    al, $1
        !          78980:        rorb    al, $1
        !          78981:        rorb    al, $1
        !          78982:        rorb    al, $1
        !          78983:        orb     ATTR, al
        !          78984:        jmp     1b
        !          78985: 
        !          78986: 2:     andb    ATTR, $0x80             / No, set attributes to non-display.
        !          78987:        jmp     1b                      /       retain blink attribute.
        !          78988: 
        !          78989: 0:     cmp     MM_PORT(bp), $0x03D4    / color card?
        !          78990:        jne     1b                      / no, ignore remaining options
        !          78991: 0:     subb    al, $30                 / foreground color
        !          78992:        jl      1f
        !          78993:        cmpb    al, $7
        !          78994:        jg      0f
        !          78995:        movb    bl, al
        !          78996:        andb    ATTR, $~0x07
        !          78997:        orb     ATTR, cs:fcolor(bx)
        !          78998:        jmp     1f
        !          78999: 0:     subb    al, $10
        !          79000:        jl      1f
        !          79001:        cmpb    al, $7
        !          79002:        jg      0f
        !          79003:        movb    bl, al
        !          79004:        andb    ATTR, $~0x70
        !          79005:        orb     ATTR, cs:bcolor(bx)
        !          79006:        jmp     1f
        !          79007: 0:     subb    al, $10
        !          79008:        jl      1f
        !          79009:        cmpb    al, $7
        !          79010:        jg      0f
        !          79011:        movb    bl, al
        !          79012:        movb    al, cs:fcolor(bx)
        !          79013:        push    dx
        !          79014:        mov     dx, MM_PORT(bp)
        !          79015:        add     dx, $5
        !          79016:        outb    dx, al
        !          79017:        pop     dx
        !          79018: /      jmp     1f
        !          79019: 0:
        !          79020: 1:     jmp     eval
        !          79021: 
        !          79022: ////////
        !          79023: /
        !          79024: / mm_ssr - set scrolling region
        !          79025: /
        !          79026: ////////
        !          79027: 
        !          79028: mm_ssr:        movb    al, MM_N1(bp)
        !          79029:        decb    al
        !          79030:        jge     0f
        !          79031:        subb    al, al
        !          79032: 0:     cmpb    al, MM_LROW(bp)
        !          79033:        ja      1f
        !          79034:        movb    bl, MM_N2(bp)
        !          79035:        decb    bl
        !          79036:        jge     0f
        !          79037:        subb    bl, bl
        !          79038: 0:     cmpb    bl, MM_LROW(bp)
        !          79039:        ja      1f
        !          79040:        cmpb    al, bl
        !          79041:        ja      1f
        !          79042:        movb    MM_BROW(bp), al
        !          79043:        movb    MM_EROW(bp), bl
        !          79044:        movb    ROW, al
        !          79045:        subb    COL, COL
        !          79046: 1:     jmp     repos
        !          79047: 
        !          79048: ////////
        !          79049: /
        !          79050: / mm_vpa - vertical position absolute
        !          79051: /
        !          79052: /      Moves the active position to the line specified by the parameter
        !          79053: /      without changing the horizontal position.
        !          79054: /      A parameter value of 0 or 1 moves the active position vertically
        !          79055: /      to the first line.
        !          79056: /
        !          79057: ////////
        !          79058: 
        !          79059: mm_vpa:        movb    ROW, MM_N1(bp)
        !          79060:        decb    ROW
        !          79061:        jg      0f
        !          79062:        subb    ROW, ROW
        !          79063: 0:     cmpb    ROW, MM_LROW(bp)
        !          79064:        jna     0f
        !          79065:        movb    ROW, MM_LROW(bp)
        !          79066: 0:     jmp     repos                   / reposition cursor
        !          79067: 
        !          79068: ////////
        !          79069: /
        !          79070: / mm_vpr - vertical position relative
        !          79071: /
        !          79072: /      Moves the active position downward the number of lines specified
        !          79073: /      by the parameter without changing the horizontal position.
        !          79074: /      A parameter value of zero or one moves the active position
        !          79075: /      one line downward.
        !          79076: /
        !          79077: ////////
        !          79078: 
        !          79079: mm_vpr:        movb    al, MM_N1(bp)
        !          79080:        orb     al, al
        !          79081:        jne     0f
        !          79082:        incb    al
        !          79083: 0:     addb    ROW, al
        !          79084:        cmpb    ROW, MM_LROW(bp)
        !          79085:        jb      0f
        !          79086:        movb    ROW, MM_LROW(bp)
        !          79087: 0:     jmp     repos                   / reposition cursor
        !          79088: 
        !          79089: ////////
        !          79090: /
        !          79091: / asctab - table of functions indexed by ascii characters
        !          79092: /
        !          79093: ////////
        !          79094: 
        !          79095: asctab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          79096:        .word   eval,   eval,   eval,   mmbell  /* EOT  ENQ  ACK  BEL  */
        !          79097:        .word   mm_cub, mm_cht, mm_cnl, mm_ind  /* BS   HT   LF   VT   */
        !          79098:        .word   eval,   mm_cr,  eval,   eval    /* FF   CR   SO   SI   */
        !          79099:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3  */
        !          79100:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          79101:        .word   eval,   eval,   eval,   mm_esc  /* CAN  EM   SUB  ESC  */
        !          79102:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          79103:        .word   mmputc, mmputc, mmputc, mmputc  /*   ! " # \040 - \043 */
        !          79104:        .word   mmputc, mmputc, mmputc, mmputc  /* $ % & quote \044 - \047 */
        !          79105:        .word   mmputc, mmputc, mmputc, mmputc  /* ( ) * + \050 - \053 */
        !          79106:        .word   mmputc, mmputc, mmputc, mmputc  /* , - . / \054 - \057 */
        !          79107:        .word   mmputc, mmputc, mmputc, mmputc  /* 0 1 2 3 \060 - \063 */
        !          79108:        .word   mmputc, mmputc, mmputc, mmputc  /* 4 5 6 7 \064 - \067 */
        !          79109:        .word   mmputc, mmputc, mmputc, mmputc  /* 8 9 : ; \070 - \073 */
        !          79110:        .word   mmputc, mmputc, mmputc, mmputc  /* < = > ? \074 - \077 */
        !          79111:        .word   mmputc, mmputc, mmputc, mmputc  /* @@ A B C \100 - \103 */
        !          79112:        .word   mmputc, mmputc, mmputc, mmputc  /* D E F G \104 - \107 */
        !          79113:        .word   mmputc, mmputc, mmputc, mmputc  /* H I J K \110 - \113 */
        !          79114:        .word   mmputc, mmputc, mmputc, mmputc  /* L M N O \114 - \117 */
        !          79115:        .word   mmputc, mmputc, mmputc, mmputc  /* P Q R S \120 - \123 */
        !          79116:        .word   mmputc, mmputc, mmputc, mmputc  /* T U V W \124 - \127 */
        !          79117:        .word   mmputc, mmputc, mmputc, mmputc  /* X Y Z [ \130 - \133 */
        !          79118:        .word   mmputc, mmputc, mmputc, mmputc  /* \ ] ^ _ \134 - \137 */
        !          79119:        .word   mmputc, mmputc, mmputc, mmputc  /* ` a b c \140 - \143 */
        !          79120:        .word   mmputc, mmputc, mmputc, mmputc  /* d e f g \144 - \147 */
        !          79121:        .word   mmputc, mmputc, mmputc, mmputc  /* h i j k \150 - \153 */
        !          79122:        .word   mmputc, mmputc, mmputc, mmputc  /* l m n o \154 - \157 */
        !          79123:        .word   mmputc, mmputc, mmputc, mmputc  /* p q r s \160 - \163 */
        !          79124:        .word   mmputc, mmputc, mmputc, mmputc  /* t u v w \164 - \167 */
        !          79125:        .word   mmputc, mmputc, mmputc, mmputc  /* x y z { \170 - \173 */
        !          79126:        .word   mmputc, mmputc, mmputc, mmputc  /* | } ~ ? \174 - \177 */
        !          79127: 
        !          79128: ////////
        !          79129: /
        !          79130: / esctab - table of functions indexed by ESC characters.
        !          79131: /
        !          79132: ////////
        !          79133: 
        !          79134: esctab:        .word   mmputc, mmputc, mmputc, mmputc  /* NUL  SOH  STX  ETX  */
        !          79135:        .word   mmputc, mmputc, mmputc, mmputc  /* EOT  ENQ  ACK  BEL  */
        !          79136:        .word   mmputc, mmputc, mmputc, mmputc  /* BS   HT   LF   VT   */
        !          79137:        .word   mmputc, mmputc, mmputc, mmputc  /* FF   CR   SO   SI   */
        !          79138:        .word   mmputc, mmputc, mmputc, mmputc  /* DLE  DC1  DC2  DC3  */
        !          79139:        .word   mmputc, mmputc, mmputc, mmputc  /* DC4  NAK  SYN  ETB  */
        !          79140:        .word   mmputc, mmputc, mmputc, mmputc  /* CAN  EM   SUB  ESC  */
        !          79141:        .word   mmputc, mmputc, mmputc, mmputc  /* FS   GS   RS   US   */
        !          79142:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          79143:        .word   eval,   eval,   eval,   eval    /* $ % & quote \044 - \047 */
        !          79144:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          79145:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          79146:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          79147:        .word   eval,   eval,   eval,   mm_new  /* 4 5 6 7 \064 - \067 */
        !          79148:        .word   mm_old, eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          79149:        .word   eval,   mmspec, mmspec, eval    /* < = > ? \074 - \077 */
        !          79150:        .word   eval,   eval,   eval,   eval    /* @@ A B C \100 - \103 */
        !          79151:        .word   mm_ind, mm_cnl, eval,   eval    /* D E F G \104 - \107 */
        !          79152:        .word   eval,   eval,   eval,   eval    /* H I J K \110 - \113 */
        !          79153:        .word   eval,   mm_ri,  eval,   eval    /* L M N O \114 - \117 */
        !          79154:        .word   eval,   eval,   eval,   eval    /* P Q R S \120 - \123 */
        !          79155:        .word   eval,   eval,   eval,   eval    /* T U V W \124 - \127 */
        !          79156:        .word   eval,   eval,   eval,   csi_n1  /* X Y Z [ \130 - \133 */
        !          79157:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          79158:        .word   mm_dmi, eval,   mm_emi, mminit  /* ` a b c \140 - \143 */
        !          79159:        .word   eval,   eval,   eval,   eval    /* d e f g \144 - \147 */
        !          79160:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          79161:        .word   eval,   eval,   eval,   eval    /* l m n o \154 - \157 */
        !          79162:        .word   eval,   eval,   eval,   eval    /* p q r s \160 - \163 */
        !          79163:        .word   mmspec, mmspec, eval,   eval    /* t u v w \164 - \167 */
        !          79164:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          79165:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          79166: 
        !          79167: 
        !          79168: ////////
        !          79169: /
        !          79170: / csitab - table of functions indexed by ESC [ characters.
        !          79171: /
        !          79172: ////////
        !          79173: 
        !          79174: csitab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          79175:        .word   eval,   eval,   eval,   eval    /* EOT  ENQ  ACK  BEL  */
        !          79176:        .word   eval,   eval,   eval,   eval    /* BS   HT   LF   VT   */
        !          79177:        .word   eval,   eval,   eval,   eval    /* FF   CR   SO   SI   */
        !          79178:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3  */
        !          79179:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          79180:        .word   eval,   eval,   eval,   eval    /* CAN  EM   SUB  ESC  */
        !          79181:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          79182:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          79183:        .word   eval,   eval,   eval,   eval    /* $ % & quote \044 - \047 */
        !          79184:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          79185:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          79186:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          79187:        .word   eval,   eval,   eval,   eval    /* 4 5 6 7 \064 - \067 */
        !          79188:        .word   eval,   eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          79189:        .word   eval,   eval,   csi_gt, csi_q   /* < = > ? \074 - \077 */
        !          79190:        .word   eval,   mm_cuu, mm_cud, mm_cuf  /* @@ A B C \100 - \103 */
        !          79191:        .word   mm_cub, mm_cnl, mm_cpl, mm_cha  /* D E F G \104 - \107 */
        !          79192:        .word   mm_cup, mm_cht, mm_ed,  mm_el   /* H I J K \110 - \113 */
        !          79193:        .word   mm_il,  mm_dl,  eval,   mm_ea   /* L M N O \114 - \117 */
        !          79194:        .word   eval,   eval,   eval,   mm_ind  /* P Q R S \120 - \123 */
        !          79195:        .word   mm_ri,  eval,   eval,   eval    /* T U V W \124 - \127 */
        !          79196:        .word   eval,   eval,   mm_cbt, eval    /* X Y Z [ \130 - \133 */
        !          79197:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          79198:        .word   mm_hpa, mm_hpr, eval,   eval    /* ` a b c \140 - \143 */
        !          79199:        .word   mm_vpa, mm_vpr, mm_hvp, mm_cup  /* d e f g \144 - \147 */
        !          79200:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          79201:        .word   eval,   mm_sgr, eval,   eval    /* l m n o \154 - \157 */
        !          79202:        .word   eval,   eval,   mm_ssr, eval    /* p q r s \160 - \163 */
        !          79203:        .word   eval,   eval,   mm_scr, eval    /* t u v w \164 - \167 */
        !          79204:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          79205:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          79206: 
        !          79207: ////////
        !          79208: /
        !          79209: / coltab - integer array of offsets to each column
        !          79210: /
        !          79211: ////////
        !          79212: 
        !          79213: coltab:        .word    0*NCB,  1*NCB,  2*NCB,  3*NCB
        !          79214:        .word    4*NCB,  5*NCB,  6*NCB,  7*NCB
        !          79215:        .word    8*NCB,  9*NCB, 10*NCB, 11*NCB
        !          79216:        .word   12*NCB, 13*NCB, 14*NCB, 15*NCB
        !          79217:        .word   16*NCB, 17*NCB, 18*NCB, 19*NCB
        !          79218:        .word   20*NCB, 21*NCB, 22*NCB, 23*NCB
        !          79219:        .word   24*NCB, 25*NCB, 26*NCB, 27*NCB
        !          79220:        .word   28*NCB, 29*NCB, 30*NCB, 31*NCB
        !          79221:        .word   32*NCB, 33*NCB, 34*NCB, 35*NCB
        !          79222:        .word   36*NCB, 37*NCB, 38*NCB, 39*NCB
        !          79223:        .word   40*NCB, 41*NCB, 42*NCB, 43*NCB
        !          79224:        .word   44*NCB, 45*NCB, 46*NCB, 47*NCB
        !          79225:        .word   48*NCB, 49*NCB, 50*NCB, 51*NCB
        !          79226:        .word   52*NCB, 53*NCB, 54*NCB, 55*NCB
        !          79227:        .word   56*NCB, 57*NCB, 58*NCB, 59*NCB
        !          79228:        .word   60*NCB, 61*NCB, 62*NCB, 63*NCB
        !          79229:        .word   64*NCB, 65*NCB, 66*NCB, 67*NCB
        !          79230:        .word   68*NCB, 69*NCB, 70*NCB, 71*NCB
        !          79231:        .word   72*NCB, 73*NCB, 74*NCB, 75*NCB
        !          79232:        .word   76*NCB, 77*NCB, 78*NCB, 79*NCB
        !          79233: 
        !          79234: ////////
        !          79235: /
        !          79236: / rowtab - array of offsets to each row
        !          79237: /
        !          79238: ////////
        !          79239: 
        !          79240: rowtab:        .word    0*NRB,  1*NRB,  2*NRB,  3*NRB
        !          79241:        .word    4*NRB,  5*NRB,  6*NRB,  7*NRB
        !          79242:        .word    8*NRB,  9*NRB, 10*NRB, 11*NRB
        !          79243:        .word   12*NRB, 13*NRB, 14*NRB, 15*NRB
        !          79244:        .word   16*NRB, 17*NRB, 18*NRB, 19*NRB
        !          79245:        .word   20*NRB, 21*NRB, 22*NRB, 23*NRB
        !          79246:        .word   24*NRB, 25*NRB, 26*NRB, 27*NRB
        !          79247:        .word   28*NRB, 29*NRB, 30*NRB, 31*NRB
        !          79248: 
        !          79249: ////////
        !          79250: /
        !          79251: / fcolor - foreground color
        !          79252: / bcolor - background color
        !          79253: /
        !          79254: /      indexed by ansi color (black,red,green,brown,blue,magenta,cyan,white)
        !          79255: /      yields graphics color (black,blue,green,cyan,red,magenta,brown,white)
        !          79256: /              which is properly shifted for installation in attribute byte.
        !          79257: /
        !          79258: ////////
        !          79259: 
        !          79260: fcolor:        .byte   0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07
        !          79261: bcolor:        .byte   0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70
        !          79262: 
        !          79263: ////////
        !          79264: /
        !          79265: / mm_voff()    -- turn video display off
        !          79266: /
        !          79267: ////////
        !          79268:        .globl  mm_voff_
        !          79269: mm_voff_:
        !          79270:        mov     dx, mmdata+MM_PORT
        !          79271:        add     dx, $4
        !          79272:        movb    al, $0x21
        !          79273:        outb    dx, al
        !          79274:        ret
        !          79275: 
        !          79276: ////////
        !          79277: /
        !          79278: / mm_von()     -- turn video display on
        !          79279: /
        !          79280: ////////
        !          79281:        .globl  mm_von_
        !          79282: mm_von_:
        !          79283:        mov     dx, mmdata+MM_PORT      / enable video display
        !          79284:        add     dx, $4
        !          79285:        movb    al, $0x29
        !          79286:        outb    dx, al
        !          79287:        mov     mmvcnt_, $900           / 900 seconds before video disabled
        !          79288:        ret
        !          79289: @
        !          79290: 0707070064030031051004440000000000000000011777770507310705700005500000105150/newbits/kernel/USRSRC/i8086/drv/RCS/ati.m,vhead     1.1;
        !          79291: branch   ;
        !          79292: access   ;
        !          79293: symbols  ;
        !          79294: locks    bin:1.1; strict;
        !          79295: comment  @@;
        !          79296: 
        !          79297: 
        !          79298: 1.1
        !          79299: date     91.07.24.08.12.00;  author bin;  state Exp;
        !          79300: branches ;
        !          79301: next     ;
        !          79302: 
        !          79303: 
        !          79304: desc
        !          79305: @prov by hal, replaced ati.s
        !          79306: @
        !          79307: 
        !          79308: 
        !          79309: 
        !          79310: 1.1
        !          79311: log
        !          79312: @Initial revision
        !          79313: @
        !          79314: text
        !          79315: @/ (lgl-
        !          79316: /      COHERENT Driver Kit Version 1.0.0
        !          79317: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          79318: /      All rights reserved. May not be copied without permission.
        !          79319: / -lgl)
        !          79320: ////////
        !          79321: /
        !          79322: / Array Technologies Inc - Graphics Solution - Device Driver
        !          79323: /
        !          79324: /       Supports 40/80/132 column color text
        !          79325: /                   80/132 column monochrome text
        !          79326: /
        !          79327: / State driven code
        !          79328: /
        !          79329: /      Input:  DS:SI - input string
        !          79330: /              ES:DI - current screen location
        !          79331: /              SS:BP - terminal information
        !          79332: /              CX    - input count
        !          79333: /              BP    - references terminal information
        !          79334: /              AH    - character attributes
        !          79335: /              AL    - character
        !          79336: /              BH    - (usually) kept zeroed for efficiency
        !          79337: /              DH    - current row
        !          79338: /              DL    - current column
        !          79339: /
        !          79340: / 
        !          79341: ////////
        !          79342: 
        !          79343:        NCB     = 2             / number of horizontal bytes per char
        !          79344:        NCR     = 1             / number of horizontal lines per char
        !          79345:        NHB     = 160           / number of horizontal bytes per line
        !          79346:        NRB     = NCR*NHB       / number of bytes per character row
        !          79347: 
        !          79348:        ATTR    = ah            / attribute byte
        !          79349:        ZERO    = bh            / (almost) always zero
        !          79350:        ROW     = dh            / currently active vertical position
        !          79351:        COL     = dl            / currently active horizontal position
        !          79352:        POS     = di            / currently active display address
        !          79353: 
        !          79354:        INTENSE = 0x08          / high intensity attribute bit
        !          79355:        BLINK   = 0x80          / blinking attribute bit
        !          79356:        REVERSE = 0x70          / reverse video
        !          79357: 
        !          79358: ////////
        !          79359: /
        !          79360: / Magic constants from <sys/io.h>
        !          79361: /
        !          79362: ////////
        !          79363: 
        !          79364:        IO_SEG  = 0
        !          79365:        IO_IOC  = 2
        !          79366:        IO_BASE = 8
        !          79367: 
        !          79368:        IOSYS   = 0
        !          79369:        IOUSR   = 1
        !          79370: 
        !          79371: ////////
        !          79372: /
        !          79373: / Data
        !          79374: /
        !          79375: ////////
        !          79376: 
        !          79377: MM_FUNC                = 0             / current state
        !          79378: MM_PORT                = 2             / adapter base i/o port
        !          79379: MM_BASE                = 4             / adapter base memory address
        !          79380: MM_ROW         = 6             / screen row
        !          79381: MM_COL         = 7             / screen column
        !          79382: MM_POS         = 8             / screen position
        !          79383: MM_ATTR                = 10            / attributes
        !          79384: MM_N1          = 11            / numeric argument 1
        !          79385: MM_N2          = 12            / numeric argument 2
        !          79386: MM_BROW                = 13            / base row
        !          79387: MM_EROW                = 14            / end row
        !          79388: MM_LROW                = 15            / legal row limit
        !          79389: MM_SROW                = 16            / saved cursor row
        !          79390: MM_SCOL                = 17            / saved cursor column
        !          79391: MM_IBROW       = 18            / initial base row
        !          79392: MM_IEROW       = 19            / initial end row
        !          79393: MM_INVIS       = 20            / cursor invisible mask
        !          79394: MM_NCOL                = 22            / number of columns
        !          79395: MM_DATA                = 24            / pointer to crt data
        !          79396: MM_MODE                = 26            / mode register [0x21=col80/132,0x20=col40]
        !          79397: 
        !          79398: / ASCII characters
        !          79399: AZERO          = 0x30
        !          79400: CLOWER         = 0x63
        !          79401: SEMIC          = 0x3B
        !          79402: SPACE          = 0x20
        !          79403: 
        !          79404:        .prvd
        !          79405: mmdata:        .word   mminit
        !          79406:        .word   0x03D4
        !          79407:        .word   0xB800
        !          79408:        .byte   0, 0
        !          79409:        .word   0
        !          79410:        .byte   0x7, 0, 0, 0, 23, 24, 0, 0, 0, 23
        !          79411:        .word   0
        !          79412:        .word   80
        !          79413:        .word   creg80
        !          79414:        .byte   0x21, 0x00
        !          79415:        .shri
        !          79416: 
        !          79417: ////////
        !          79418: /
        !          79419: / creg40, creg80, creg132 - crt register values for 40/80/132 column color
        !          79420: /         mreg80, mreg132 - crt register values for 80/132 column monochrome
        !          79421: /
        !          79422: ////////
        !          79423: 
        !          79424: creg40:        .byte   0x38, 0x28, 0x2D, 0x0A, 0x1F, 0x06, 0x19, 0x1C
        !          79425:        .byte   0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          79426: 
        !          79427: creg80:        .byte   0x71, 0x50, 0x5A, 0x0A, 0x1F, 0x06, 0x19, 0x1C
        !          79428:        .byte   0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          79429: 
        !          79430: mreg80:        .byte   0x61, 0x50, 0x52, 0x0F, 0x19, 0x06, 0x19, 0x19
        !          79431:        .byte   0x02, 0x0D, 0x0B, 0x0C, 0x00, 0x00, 0x00, 0x00
        !          79432: 
        !          79433: #ifdef ATI_132
        !          79434:        .globl  creg132
        !          79435: creg132:.byte  0xB5, 0x84, 0x97, 0x0A, 0x1F, 0x06, 0x19, 0x1C
        !          79436:        .byte   0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          79437: 
        !          79438:        .globl  mreg132
        !          79439: mreg132:.byte  0x9F, 0x84, 0x89, 0x0F, 0x19, 0x06, 0x19, 0x19
        !          79440:        .byte   0x02, 0x0D, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
        !          79441: #endif
        !          79442: 
        !          79443: ////////
        !          79444: /
        !          79445: / mmgo( iop )
        !          79446: / IO *iop;
        !          79447: /
        !          79448: ////////
        !          79449: 
        !          79450:        .globl  mmgo_
        !          79451: 
        !          79452: mmgo_:
        !          79453:        push    si
        !          79454:        push    di
        !          79455:        push    bp
        !          79456:        mov     bp, sp
        !          79457:        push    ds
        !          79458:        push    es
        !          79459:        cld
        !          79460:        mov     bx, 8(bp)               / iop
        !          79461:        mov     si, IO_BASE(bx)         / iop->io_base
        !          79462:        mov     cx, IO_IOC(bx)          / iop->io_ioc
        !          79463:        cmp     IO_SEG(bx), $IOSYS
        !          79464:        je      0f
        !          79465:        mov     ds, uds_
        !          79466: 0:     mov     bp, $mmdata
        !          79467: 
        !          79468:        mov     dx, MM_PORT(bp)         / turn video off if color board
        !          79469:        cmp     dx, $0x3B4
        !          79470:        je      0f
        !          79471:        add     dx, $4
        !          79472:        movb    al, MM_MODE(bp)
        !          79473:        outb    dx, al
        !          79474: 0:
        !          79475:        movb    ROW, MM_ROW(bp)
        !          79476:        movb    COL, MM_COL(bp)
        !          79477:        mov     es,  MM_BASE(bp)
        !          79478:        mov     POS, MM_POS(bp)
        !          79479:        sub     bx, bx
        !          79480:        movb    ATTR, MM_ATTR(bp)
        !          79481:        ijmp    MM_FUNC(bp)
        !          79482: 
        !          79483: exit:  pop     bx
        !          79484:        pop     es
        !          79485:        pop     ds
        !          79486:        movb    MM_ATTR(bp), ATTR
        !          79487:        mov     MM_FUNC(bp), bx
        !          79488:        movb    MM_ROW(bp), ROW         / save row,column
        !          79489:        movb    MM_COL(bp), COL
        !          79490:        mov     MM_POS(bp), POS         / save position
        !          79491: 
        !          79492:        mov     dx, MM_PORT(bp)         / adjust cursor location
        !          79493:        mov     bx, POS
        !          79494:        or      bx, MM_INVIS(bp)
        !          79495:        shr     bx, $1
        !          79496: 
        !          79497:        movb    al, $14
        !          79498:        outb    dx, al
        !          79499:        inc     dx
        !          79500:        movb    al, bh
        !          79501:        outb    dx, al
        !          79502:        dec     dx
        !          79503:        movb    al, $15
        !          79504:        outb    dx, al
        !          79505:        inc     dx
        !          79506:        movb    al, bl
        !          79507:        outb    dx, al
        !          79508: 
        !          79509:        mov     dx, MM_PORT(bp)         / turn video on
        !          79510:        add     dx, $4
        !          79511:        movb    al, MM_MODE(bp)
        !          79512:        orb     al, $0x08
        !          79513:        outb    dx, al
        !          79514:        mov     mmvcnt_, $300           / 300 seconds before video disabled
        !          79515: 
        !          79516:        mov     bp, sp
        !          79517:        mov     bx, 8(bp)
        !          79518:        mov     ax, cx
        !          79519:        xchg    cx, IO_IOC(bx)
        !          79520:        sub     cx, IO_IOC(bx)
        !          79521:        add     IO_BASE(bx), cx
        !          79522:        pop     bp
        !          79523:        pop     di
        !          79524:        pop     si
        !          79525:        ret
        !          79526: 
        !          79527: ////////
        !          79528: /
        !          79529: / mminit - initialize screen
        !          79530: /
        !          79531: ////////
        !          79532: 
        !          79533: mminit:        movb    ss:mmesc_, $CLOWER              / schedule keyboard initialization
        !          79534:        mov     MM_NCOL(bp), $80        / set 80 column mode
        !          79535:        movb    MM_MODE(bp), $0x21
        !          79536:        mov     MM_DATA(bp), $creg80
        !          79537: 
        !          79538: #ifdef ATI_132
        !          79539:        mov     dx, $0x3DF              / clear 132 column color
        !          79540:        movb    al, $0x00               / in mode select register
        !          79541:        outb    dx, al
        !          79542: 
        !          79543:        mov     dx, $0x3BA              / clear 132 column monochrome
        !          79544:        movb    al, $0x00               / in mode select register
        !          79545:        outb    dx, al
        !          79546: #endif
        !          79547: 
        !          79548:        call    int11_                  / read equipment status
        !          79549:        andb    al, $0x30               / isolate video bits
        !          79550:        cmpb    al, $0x30               / if monochrome
        !          79551:        jne     0f
        !          79552:        mov     MM_DATA(bp), $mreg80    /       set monochrome register info
        !          79553:        mov     MM_PORT(bp), $0x3B4     /       set monochrome port
        !          79554:        mov     MM_BASE(bp), $0xB000    /       set monochrome base
        !          79555:        mov     es, MM_BASE(bp)         /               and extra segment.
        !          79556: 
        !          79557: 0:     call    newcrt                  / reprogram crt registers
        !          79558: 
        !          79559: reinit:        sub     ax, ax                  / regenerate row table
        !          79560:        mov     bx, $rowtab
        !          79561: 1:     mov     ss:(bx), ax
        !          79562:        add     ax, MM_NCOL(bp)
        !          79563:        add     ax, MM_NCOL(bp)
        !          79564:        add     bx, $2
        !          79565:        cmp     bx, $rowend
        !          79566:        jb      1b
        !          79567: 
        !          79568:        mov     dx, MM_PORT(bp)         / zero display offset
        !          79569:        movb    al, $12
        !          79570:        outb    dx, al
        !          79571:        inc     dx
        !          79572:        subb    al, al
        !          79573:        outb    dx, al
        !          79574:        dec     dx
        !          79575:        movb    al, $13
        !          79576:        outb    dx, al
        !          79577:        inc     dx
        !          79578:        subb    al, al
        !          79579:        outb    dx, al
        !          79580: 
        !          79581:        mov     dx, MM_PORT(bp)         / reset border to black
        !          79582:        add     dx, $5
        !          79583:        subb    al, al
        !          79584:        outb    dx, al
        !          79585: 
        !          79586:        mov     MM_INVIS(bp), $0
        !          79587:        movb    ATTR, $0x07
        !          79588:        movb    MM_ATTR(bp), ATTR
        !          79589:        movb    ROW, MM_IBROW(bp)
        !          79590:        movb    MM_BROW(bp), ROW
        !          79591:        movb    bl, MM_IEROW(bp)
        !          79592:        movb    MM_EROW(bp), bl
        !          79593:        sub     bx, bx
        !          79594:        movb    MM_N1(bp), $2
        !          79595:        jmp     mm_ed
        !          79596: 
        !          79597: ////////
        !          79598: /
        !          79599: / newcrt -- reload crt registers
        !          79600: /
        !          79601: /      Action: Program crt registers with values defined in code space
        !          79602: /              at offset given by MM_DATA(bp).
        !          79603: /
        !          79604: /      Note:   AX, BX, DX, DI trashed on exit.
        !          79605: /
        !          79606: ////////
        !          79607: 
        !          79608: newcrt:        mov     dx, MM_PORT(bp)         / turn video off
        !          79609:        add     dx, $4
        !          79610:        movb    al, MM_MODE(bp)
        !          79611:        outb    dx, al
        !          79612: 
        !          79613:        mov     di, MM_DATA(bp)         / program crt registers, last to first
        !          79614:        mov     bx, $15                 / [delay between i/o]
        !          79615:        mov     dx, MM_PORT(bp)         / [NOTE:DI=obsolete screen offset]
        !          79616: 0:     movb    al, bl
        !          79617:        outb    dx, al
        !          79618:        movb    al, cs:(bx,di)
        !          79619:        inc     dx
        !          79620:        outb    dx, al
        !          79621:        dec     dx
        !          79622:        dec     bx
        !          79623:        jge     0b
        !          79624:        ret
        !          79625: 
        !          79626: ////////
        !          79627: /
        !          79628: / mm_so - stand out - define 40 column attributes
        !          79629: /
        !          79630: ////////
        !          79631: 
        !          79632: mm_so:
        !          79633:        cmp     MM_PORT(bp), $0x3D4     / if color card
        !          79634:        jne     mm_si
        !          79635: 
        !          79636:        mov     MM_NCOL(bp), $40        /       setup for 40 column color
        !          79637:        movb    MM_MODE(bp), $0x20
        !          79638:        mov     MM_DATA(bp), $creg40
        !          79639: 
        !          79640: #ifdef ATI_132
        !          79641:        mov     dx, $0x3DF              /       clear 132 column color
        !          79642:        movb    al, $0x00               /       in mode select register
        !          79643:        outb    dx, al                  /       [delay between i/o]
        !          79644: #endif
        !          79645: 
        !          79646:        call    newcrt                  / program crt registers
        !          79647:        jmp     reinit
        !          79648: 
        !          79649: ////////
        !          79650: /
        !          79651: / mm_si - define 80 column attributes
        !          79652: /
        !          79653: ////////
        !          79654: 
        !          79655: mm_si:
        !          79656:        cmp     MM_PORT(bp), $0x3D4     / if color card
        !          79657:        jne     0f
        !          79658: 
        !          79659:        mov     MM_NCOL(bp), $80
        !          79660:        movb    MM_MODE(bp), $0x21
        !          79661:        mov     MM_DATA(bp), $creg80
        !          79662: 
        !          79663: #ifdef ATI_132
        !          79664:        mov     dx, $0x3DF              /       clear 132 column color
        !          79665:        movb    al, $0x00               /       in mode select register
        !          79666:        outb    dx, al                  /       [delay between i/o]
        !          79667: #endif
        !          79668: 
        !          79669:        call    newcrt                  /       reprogram crt registers.
        !          79670:        jmp     reinit
        !          79671: 
        !          79672: 0:     mov     MM_NCOL(bp), $80
        !          79673:        mov     MM_DATA(bp), $mreg80
        !          79674:        movb    MM_MODE(bp), $0x21
        !          79675: 
        !          79676: #ifdef ATI_132
        !          79677:        mov     dx, $0x3BA              /       clear 132 column monochrome
        !          79678:        movb    al, $0x00               /       in mode select register
        !          79679:        outb    dx, al                  /       [delay between i/o]
        !          79680: #endif
        !          79681: 
        !          79682:        call    newcrt                  /       reprogram crt registers
        !          79683:        jmp     reinit
        !          79684: 
        !          79685: ////////
        !          79686: /
        !          79687: / mm_132 - define 132 column attributes
        !          79688: /
        !          79689: ////////
        !          79690: 
        !          79691: mm_132:
        !          79692:        cmp     MM_PORT(bp), $0x3D4     / if color card
        !          79693:        jne     0f
        !          79694: 
        !          79695: #ifdef ATI_132
        !          79696:        mov     MM_DATA(bp), $creg132   /       set color crt values
        !          79697:        mov     MM_NCOL(bp), $132       /       set columns to 132
        !          79698:        movb    MM_MODE(bp), $0x21
        !          79699: 
        !          79700:        call    newcrt                  /       set 132 column crt values
        !          79701:                                        /       BEFORE setting mode select reg
        !          79702: 
        !          79703:        mov     dx, $0x3DF              /       set 132 columns
        !          79704:        movb    al, $0x10               /               in mode select register
        !          79705:        outb    dx, al
        !          79706: #endif
        !          79707:        jmp     reinit
        !          79708: 
        !          79709: 0:
        !          79710: #ifdef ATI_132
        !          79711:        mov     MM_NCOL(bp), $132       /       set columns to 132
        !          79712:        movb    MM_MODE(bp), $0x21      /       set 80/132 column display mode
        !          79713:        mov     MM_DATA(bp), $mreg132   /       set monochrome crt values
        !          79714: 
        !          79715:        call    newcrt                  /       set 132 column crt values
        !          79716:                                        /       BEFORE setting mode select reg
        !          79717: 
        !          79718:        mov     dx, $0x3BA              /       set 132 columns monochrome
        !          79719:        movb    al, $0x08               /               in mode select register
        !          79720:        outb    dx, al
        !          79721: #endif
        !          79722:        jmp     reinit
        !          79723: 
        !          79724: ////////
        !          79725: /
        !          79726: / mmspec - schedule special keyboard function
        !          79727: /
        !          79728: ////////
        !          79729: 
        !          79730: mmspec:        movb    ss:mmesc_, al
        !          79731:        jmp     eval
        !          79732: 
        !          79733: ////////
        !          79734: /
        !          79735: / mmbell - schedule beep
        !          79736: /
        !          79737: ////////
        !          79738: 
        !          79739: mmbell:        movb    ss:mmbeeps_, $-1
        !          79740:        jmp     eval
        !          79741: 
        !          79742: ////////
        !          79743: /
        !          79744: / mm_cnl - cursor next line
        !          79745: /
        !          79746: /      Moves the active position to the first column of the next display line.
        !          79747: /      Scrolls the active display if necessary.
        !          79748: /
        !          79749: ////////
        !          79750: 
        !          79751: mm_cnl:        subb    COL, COL
        !          79752:        incb    ROW
        !          79753:        cmpb    ROW, MM_EROW(bp)
        !          79754:        jna     repos
        !          79755:        movb    ROW, MM_EROW(bp)
        !          79756: /      jmp     scrollup
        !          79757: 
        !          79758: ////////
        !          79759: /
        !          79760: / scrollup - scroll display upwards
        !          79761: /
        !          79762: ////////
        !          79763: 
        !          79764: scrollup:
        !          79765:        push    ds
        !          79766:        push    si
        !          79767:        push    cx
        !          79768:        mov     ds, MM_BASE(bp)
        !          79769:        movb    bl, MM_BROW(bp)
        !          79770:        shlb    bl, $1
        !          79771:        mov     di, ss:rowtab(bx)
        !          79772:        mov     si, ss:rowtab+2(bx)
        !          79773:        movb    bl, ROW
        !          79774:        shlb    bl, $1
        !          79775:        mov     cx, ss:rowtab(bx)
        !          79776:        push    cx
        !          79777:        sub     cx, di
        !          79778:        shr     cx, $1
        !          79779:        cld
        !          79780:        rep
        !          79781:        movsw
        !          79782:        movb    al, $SPACE
        !          79783:        pop     di
        !          79784:        mov     cx, MM_NCOL(bp)
        !          79785:        rep
        !          79786:        stosw
        !          79787:        pop     cx
        !          79788:        pop     si
        !          79789:        pop     ds
        !          79790:        movb    bl, COL                 / reposition to ROW and COL
        !          79791:        shlb    bl, $1
        !          79792:        mov     POS, cs:coltab(bx)
        !          79793:        movb    bl, ROW
        !          79794:        shlb    bl, $1
        !          79795:        add     POS, ss:rowtab(bx)
        !          79796:        call    exit
        !          79797:        jmp     eval
        !          79798: 
        !          79799: ////////
        !          79800: /
        !          79801: / repos - reposition cursor
        !          79802: /
        !          79803: ////////
        !          79804: 
        !          79805: repos: movb    bl, COL                 / reposition to ROW and COL
        !          79806:        shl     bx, $1                  / [trash BH]
        !          79807:        mov     POS, cs:coltab(bx)
        !          79808:        subb    bh, bh                  / [clear BH]
        !          79809:        movb    bl, ROW
        !          79810:        shlb    bl, $1
        !          79811:        add     POS, ss:rowtab(bx)
        !          79812: /      jmp     eval
        !          79813: 
        !          79814: ////////
        !          79815: /
        !          79816: / eval - evaluate input character
        !          79817: /
        !          79818: ////////
        !          79819: 
        !          79820: eval:  jcxz    ewait
        !          79821:        dec     cx                              / evaluate next char
        !          79822:        lodsb
        !          79823:        movb    bl, al
        !          79824:        shlb    bl, $1
        !          79825:        ijmp    cs:asctab(bx)
        !          79826: 
        !          79827: ////////
        !          79828: /
        !          79829: / mmputc - put character on screen
        !          79830: /
        !          79831: ////////
        !          79832: 
        !          79833: mmputc:        stosw
        !          79834:        incb    COL
        !          79835:        cmpb    COL, MM_NCOL(bp)
        !          79836:        jnb     0f
        !          79837:        jcxz    ewait
        !          79838:        dec     cx
        !          79839:        lodsb
        !          79840:        movb    bl, al
        !          79841:        shlb    bl, $1
        !          79842:        ijmp    cs:asctab(bx)
        !          79843: 
        !          79844: 0:     subb    COL, COL
        !          79845:        incb    ROW
        !          79846:        cmpb    ROW, MM_EROW(bp)
        !          79847:        jg      0f
        !          79848:        jcxz    ewait
        !          79849:        dec     cx
        !          79850:        lodsb
        !          79851:        movb    bl, al
        !          79852:        shlb    bl, $1
        !          79853:        ijmp    cs:asctab(bx)
        !          79854: 
        !          79855: 0:     movb    ROW, MM_EROW(bp)
        !          79856:        jmp     scrollup
        !          79857: 
        !          79858: ////////
        !          79859: /
        !          79860: / Ewait - wait for next input char to evaluate
        !          79861: /
        !          79862: ////////
        !          79863: 
        !          79864: ewait: call    exit
        !          79865:        jcxz    ewait
        !          79866:        dec     cx
        !          79867:        lodsb
        !          79868:        movb    bl, al
        !          79869:        shlb    bl, $1
        !          79870:        ijmp    cs:asctab(bx)
        !          79871: 
        !          79872: ////////
        !          79873: /
        !          79874: / mm_cr - carriage return
        !          79875: /
        !          79876: /      Moves the active position to first position of current display line.
        !          79877: /
        !          79878: ////////
        !          79879: 
        !          79880: mm_cr: subb    COL, COL
        !          79881:        movb    bl, ROW
        !          79882:        shlb    bl, $1
        !          79883:        mov     POS, ss:rowtab(bx)
        !          79884:        jcxz    ewait
        !          79885:        dec     cx
        !          79886:        lodsb
        !          79887:        movb    bl, al
        !          79888:        shlb    bl, $1
        !          79889:        ijmp    cs:asctab(bx)
        !          79890: 
        !          79891: ////////
        !          79892: /
        !          79893: / mm_cub - cursor backwards
        !          79894: /
        !          79895: ////////
        !          79896: 
        !          79897: mm_cub:        sub     POS, $2
        !          79898:        subb    COL, $1
        !          79899:        jnb     0f
        !          79900:        movb    COL, MM_NCOL(bp)
        !          79901:        decb    COL
        !          79902:        decb    ROW
        !          79903:        cmpb    ROW, MM_BROW(bp)
        !          79904:        jge     0f
        !          79905:        subb    COL, COL
        !          79906:        movb    ROW, MM_BROW(bp)
        !          79907:        movb    bl, ROW
        !          79908:        shlb    bl, $1
        !          79909:        mov     POS, ss:rowtab(bx)
        !          79910: 0:     jcxz    ewait
        !          79911:        dec     cx
        !          79912:        lodsb
        !          79913:        movb    bl, al
        !          79914:        shlb    bl, $1
        !          79915:        ijmp    cs:asctab(bx)
        !          79916: 
        !          79917: ////////
        !          79918: /
        !          79919: / Esc state - entered when last char was ESC - transient state.
        !          79920: /
        !          79921: ////////
        !          79922: 
        !          79923: 0:     call    exit
        !          79924: mm_esc:        jcxz    0b
        !          79925:        dec     cx
        !          79926:        lodsb
        !          79927:        movb    MM_N1(bp), ZERO
        !          79928:        movb    MM_N2(bp), ZERO
        !          79929:        movb    bl, al
        !          79930:        shlb    bl, $1
        !          79931:        jc      mmputc
        !          79932:        ijmp    cs:esctab(bx)
        !          79933: 
        !          79934: ////////
        !          79935: /
        !          79936: / Csi_n1 state - entered when last two chars were ESC [
        !          79937: /
        !          79938: /      Action: Evaluates numeric chars as numeric parameter 1.
        !          79939: /
        !          79940: ////////
        !          79941: 
        !          79942: 0:     call    exit
        !          79943: csi_n1:        jcxz    0b
        !          79944:        dec     cx
        !          79945:        lodsb
        !          79946:        cmpb    al, $SEMIC
        !          79947:        je      csi_n2
        !          79948:        movb    bl, al
        !          79949:        subb    bl, $AZERO
        !          79950:        cmpb    bl, $9
        !          79951:        ja      csival
        !          79952:        shlb    MM_N1(bp), $1   / n1 * 2
        !          79953:        movb    al, MM_N1(bp)   / n1 * 2
        !          79954:        shlb    al, $1          / n1 * 4
        !          79955:        shlb    al, $1          / n1 * 8
        !          79956:        addb    al, MM_N1(bp)   / n1 * 10
        !          79957:        addb    al, bl          / n1 * 10 + digit
        !          79958:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          79959:        jmp     csi_n1
        !          79960: 
        !          79961: ////////
        !          79962: /
        !          79963: / Csi_n2 state - entered after input sequence ESC [ n ;
        !          79964: /
        !          79965: ////////
        !          79966: 
        !          79967: 0:     call    exit
        !          79968: csi_n2:        jcxz    0b
        !          79969:        dec     cx
        !          79970:        lodsb
        !          79971:        movb    bl, al
        !          79972:        subb    bl, $AZERO
        !          79973:        cmpb    bl, $9
        !          79974:        ja      csival
        !          79975:        shlb    MM_N2(bp), $1   / n2 * 2
        !          79976:        movb    al, MM_N2(bp)   / n2 * 2
        !          79977:        shlb    al, $1          / n2 * 4
        !          79978:        shlb    al, $1          / n2 * 8
        !          79979:        addb    al, MM_N2(bp)   / n2 * 10
        !          79980:        addb    al, bl          / n2 * 10 + digit
        !          79981:        movb    MM_N2(bp), al   / n2 = (n2 * 10) + digit
        !          79982:        jmp     csi_n2
        !          79983: 
        !          79984: csival:        movb    bl, al
        !          79985:        shlb    bl, $1
        !          79986:        ijmp    cs:csitab(bx)
        !          79987: 
        !          79988: ////////
        !          79989: /
        !          79990: / Csi_gt state - entered after input sequence ESC [ >
        !          79991: /      
        !          79992: ////////
        !          79993: 
        !          79994: 0:     call    exit
        !          79995: csi_gt:        jcxz    0b
        !          79996:        dec     cx
        !          79997:        lodsb
        !          79998:        movb    bl, al
        !          79999:        subb    bl, $AZERO
        !          80000:        cmpb    bl, $9
        !          80001:        ja      1f
        !          80002:        shlb    MM_N1(bp), $1   / n1 * 2
        !          80003:        movb    al, MM_N1(bp)   / n1 * 2
        !          80004:        shlb    al, $1          / n1 * 4
        !          80005:        shlb    al, $1          / n1 * 8
        !          80006:        addb    al, MM_N1(bp)   / n1 * 10
        !          80007:        addb    al, bl          / n1 * 10 + digit
        !          80008:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          80009:        jmp     csi_gt
        !          80010: 
        !          80011: 1:     movb    bl, al
        !          80012:        shlb    bl, $1
        !          80013:        ijmp    cs:csgtab(bx)
        !          80014: 
        !          80015: ////////
        !          80016: /
        !          80017: / mm_cbt - cursor backward tabulation
        !          80018: /
        !          80019: /      Moves the active position horizontally in the backward direction
        !          80020: /      to the preceding in a series of predetermined positions.
        !          80021: /
        !          80022: ////////
        !          80023: 
        !          80024: mm_cbt:        orb     COL, $7                 / calculate next tab stop
        !          80025:        incb    COL
        !          80026:        subb    COL, $16                / step back two tab positions
        !          80027:        jnb     0f
        !          80028:        subb    COL, COL                / cannot step past column 0
        !          80029: 0:     jmp     repos                   / reposition cursor
        !          80030: 
        !          80031: ////////
        !          80032: /
        !          80033: / mm_cgh - process ESC [ > N1 h escape sequence
        !          80034: /
        !          80035: /      Recognized sequences:   ESC [ > 13 h    -- Set CRT saver enabled.
        !          80036: /
        !          80037: ////////
        !          80038: 
        !          80039: mm_cgh:        cmpb    MM_N1(bp), $13
        !          80040:        jne     0f
        !          80041:        mov     ss:mmcrtsav_, $1
        !          80042: 0:     jmp     eval
        !          80043: 
        !          80044: ////////
        !          80045: /
        !          80046: / mm_cgl - process ESC [ > N1 l escape sequence
        !          80047: /
        !          80048: /      Recognized sequences:   ESC [ > 13 l    -- Reset CRT saver.
        !          80049: /
        !          80050: ////////
        !          80051: 
        !          80052: mm_cgl:        cmpb    MM_N1(bp), $13
        !          80053:        jne     0f
        !          80054:        mov     ss:mmcrtsav_, $0
        !          80055: 0:     jmp     eval
        !          80056: 
        !          80057: ////////
        !          80058: /
        !          80059: / mm_cha - cursor horizontal absolute
        !          80060: /
        !          80061: /      Advances the active position forward or backward along the active line
        !          80062: /      to the character position specified by the parameter.
        !          80063: /      A parameter value of zero or one moves the active position to the
        !          80064: /      first character position of the active line.
        !          80065: /      A parameter value of N moves the active position to character position
        !          80066: /      N of the active line.
        !          80067: /
        !          80068: ////////
        !          80069: 
        !          80070: mm_cha:        movb    COL, MM_N1(bp)
        !          80071:        orb     COL, COL
        !          80072:        je      0f
        !          80073:        decb    COL
        !          80074: 0:     cmpb    COL, MM_NCOL(bp)
        !          80075:        jb      0f
        !          80076:        movb    COL, MM_NCOL(bp)
        !          80077:        decb    COL
        !          80078: 0:     jmp     repos                   / reposition cursor
        !          80079: 
        !          80080: 
        !          80081: ////////
        !          80082: /
        !          80083: / mm_cht - cursor horizontal tabulation
        !          80084: /
        !          80085: /      Advances the active position horizontally to the next or following
        !          80086: /      in a series of predetermined positions.
        !          80087: /
        !          80088: ////////
        !          80089: 
        !          80090: mm_cht:        push    cx
        !          80091:        sub     cx, cx
        !          80092:        movb    cl, COL
        !          80093:        orb     cl, $7
        !          80094:        incb    cl
        !          80095:        subb    cl, COL
        !          80096:        addb    COL, cl
        !          80097:        movb    al, $SPACE
        !          80098:        rep
        !          80099:        stosw
        !          80100:        pop     cx
        !          80101:        cmpb    COL, MM_NCOL(bp)
        !          80102:        jb      0f
        !          80103:        subb    COL, MM_NCOL(bp)
        !          80104:        incb    ROW
        !          80105:        cmpb    ROW, MM_EROW(bp)
        !          80106:        jna     0f
        !          80107:        movb    ROW, MM_EROW(bp)
        !          80108:        jmp     scrollup
        !          80109: 0:     jmp     eval
        !          80110: 
        !          80111: ////////
        !          80112: /
        !          80113: / mm_cpl - cursor preceding line
        !          80114: /
        !          80115: /      Moves the active position to the first position of the preceding
        !          80116: /      display line.
        !          80117: /
        !          80118: ////////
        !          80119: 
        !          80120: mm_cpl:        subb    COL, COL
        !          80121:        decb    ROW
        !          80122:        cmpb    ROW, MM_BROW(bp)
        !          80123:        jnb     0f
        !          80124:        movb    ROW, MM_BROW(bp)
        !          80125:        jmp     scrolldown
        !          80126: 0:     jmp     repos                   / reposition cursor
        !          80127: 
        !          80128: ////////
        !          80129: /
        !          80130: / mm_cud - cursor down
        !          80131: /
        !          80132: /      Moves the active position downward without altering the
        !          80133: /      horizontal position.
        !          80134: /
        !          80135: ////////
        !          80136: 
        !          80137: mm_cud:        incb    ROW
        !          80138:        cmpb    ROW, MM_EROW(bp)
        !          80139:        jna     0f
        !          80140:        movb    ROW, MM_EROW(bp)
        !          80141: 0:     jmp     repos                   / reposition cursor
        !          80142: 
        !          80143: ////////
        !          80144: /
        !          80145: / mm_cuf - cursor forward
        !          80146: /
        !          80147: /      Moves the active position in the forward direction.
        !          80148: /
        !          80149: ////////
        !          80150: 
        !          80151: mm_cuf:        incb    COL
        !          80152:        cmpb    COL, MM_NCOL(bp)
        !          80153:        jb      0f
        !          80154:        subb    COL, MM_NCOL(bp)
        !          80155:        incb    ROW
        !          80156:        cmpb    ROW, MM_EROW(bp)
        !          80157:        jna     0f
        !          80158:        movb    ROW, MM_EROW(bp)
        !          80159:        movb    COL, MM_NCOL(bp)
        !          80160:        decb    COL
        !          80161: 0:     jmp     repos
        !          80162: 
        !          80163: ////////
        !          80164: /
        !          80165: / mm_cup - cursor position
        !          80166: /
        !          80167: /      Moves the active position to the position specified by two parameters.
        !          80168: /      The 1st parameter (mm_n1) specifies the vertical   position MM_ROW(bp).
        !          80169: /      The 2nd parameter (mm_n2) specifies the horizontal position MM_COL(bp).
        !          80170: /      A parameter value of 0 or 1 for the first or second parameter
        !          80171: /      moves the active position to the first line or column in the
        !          80172: /      display respectively.
        !          80173: /
        !          80174: ////////
        !          80175: 
        !          80176: mm_cup:        movb    ROW, MM_N1(bp)
        !          80177:        orb     ROW, ROW
        !          80178:        je      0f
        !          80179:        decb    ROW
        !          80180: 0:     addb    ROW, MM_BROW(bp)
        !          80181:        cmpb    ROW, MM_EROW(bp)
        !          80182:        jb      0f
        !          80183:        movb    ROW, MM_EROW(bp)
        !          80184: 0:     movb    COL, MM_N2(bp)
        !          80185:        orb     COL, COL
        !          80186:        je      0f
        !          80187:        decb    COL
        !          80188: 0:     cmpb    COL, MM_NCOL(bp)
        !          80189:        jb      0f
        !          80190:        movb    COL, MM_NCOL(bp)
        !          80191:        decb    COL
        !          80192: 0:     jmp     repos                   / reposition cursor
        !          80193: 
        !          80194: ////////
        !          80195: /
        !          80196: / mm_cuu - cursor up
        !          80197: /
        !          80198: /      Moves the active position upward without altering the horizontal
        !          80199: /      position.
        !          80200: /
        !          80201: ////////
        !          80202: 
        !          80203: mm_cuu:        decb    ROW
        !          80204:        cmpb    ROW, MM_BROW(bp)
        !          80205:        jge     0f
        !          80206:        movb    ROW, MM_BROW(bp)
        !          80207: 0:     jmp     repos                   / reposition cursor
        !          80208: 
        !          80209: ////////
        !          80210: /
        !          80211: / mm_dl - delete line
        !          80212: /
        !          80213: /      Removes the contents of the active line.
        !          80214: /      The contents of all following lines are shifted in a block
        !          80215: /      toward the active line.
        !          80216: /
        !          80217: ////////
        !          80218: 
        !          80219: mm_dl: push    ds
        !          80220:        push    si
        !          80221:        push    cx
        !          80222:        mov     ds, MM_BASE(bp)
        !          80223:        movb    bl, ROW
        !          80224:        shlb    bl, $1
        !          80225:        mov     di, ss:rowtab(bx)
        !          80226:        mov     si, ss:rowtab+2(bx)
        !          80227:        movb    bl, MM_EROW(bp)
        !          80228:        shlb    bl, $1
        !          80229:        mov     cx, ss:rowtab(bx)
        !          80230:        sub     cx, di
        !          80231:        jle     0f
        !          80232:        shr     cx, $1
        !          80233:        rep
        !          80234:        movsw
        !          80235:        mov     di, ss:rowtab(bx)
        !          80236:        mov     cx, MM_NCOL(bp)
        !          80237:        movb    al, $SPACE
        !          80238:        rep
        !          80239:        stosw
        !          80240:        subb    COL, COL
        !          80241:        movb    bl, ROW
        !          80242:        shlb    bl, $1
        !          80243:        mov     di, ss:rowtab(bx)
        !          80244: 0:     pop     cx
        !          80245:        pop     si
        !          80246:        pop     ds
        !          80247:        call    exit
        !          80248:        jmp     eval
        !          80249: 
        !          80250: ////////
        !          80251: /
        !          80252: / mm_dmi - disable manual input
        !          80253: /
        !          80254: /      Set flag preventing keyboard input, and causing cursor to vanish.
        !          80255: /
        !          80256: ////////
        !          80257: 
        !          80258: mm_dmi:
        !          80259:        mov     ss:islock_, $1
        !          80260:        jmp     eval
        !          80261: 
        !          80262: ////////
        !          80263: /
        !          80264: / mm_ea - erase in area
        !          80265: /
        !          80266: /      Erase some or all of the characters in the currently active area
        !          80267: /      according to the parameter:
        !          80268: /              0 - erase from active position to end inclusive (default)
        !          80269: /              1 - erase from start to active position inclusive
        !          80270: /              2 - erase all of active area
        !          80271: /
        !          80272: ////////
        !          80273: 
        !          80274: mm_ea: movb    al, MM_N1(bp)
        !          80275:        cmpb    al, $0
        !          80276:        jne     0f
        !          80277:        movb    bl, MM_EROW(bp)
        !          80278:        jmp     mm_e0
        !          80279: 0:     cmpb    al, $1
        !          80280:        jne     0f
        !          80281:        movb    bl, MM_BROW(bp)
        !          80282:        jmp     mm_e1
        !          80283: 0:     subb    COL, COL
        !          80284:        movb    ROW, MM_BROW(bp)
        !          80285:        movb    bl, ROW
        !          80286:        shlb    bl, $1
        !          80287:        mov     POS, ss:rowtab(bx)
        !          80288:        movb    bl, MM_EROW(bp)
        !          80289:        subb    bl, ROW
        !          80290:        jmp     mm_e2
        !          80291: 
        !          80292: 
        !          80293: ////////
        !          80294: /
        !          80295: / mm_ed - erase in display
        !          80296: /
        !          80297: /      Erase some or all of the characters in the display according to the
        !          80298: /      parameter
        !          80299: /              0 - erase from active position to end inclusive (default)
        !          80300: /              1 - erase from start to active position inclusive
        !          80301: /              2 - erase all of display
        !          80302: /
        !          80303: ////////
        !          80304: 
        !          80305: mm_ed: movb    al, MM_N1(bp)
        !          80306:        cmpb    al, $0
        !          80307:        jne     0f
        !          80308:        movb    bl, MM_LROW(bp)
        !          80309:        jmp     mm_e0
        !          80310: 0:     cmpb    al, $1
        !          80311:        jne     0f
        !          80312:        subb    bl, bl
        !          80313:        jmp     mm_e1
        !          80314: 0:     subb    COL, COL
        !          80315:        movb    ROW, MM_BROW(bp)
        !          80316:        sub     POS, POS
        !          80317:        movb    bl, MM_LROW(bp)
        !          80318:        jmp     mm_e2
        !          80319: 
        !          80320: ////////
        !          80321: /
        !          80322: / mm_el - erase in line
        !          80323: /
        !          80324: /      Erase some or all of the characters in the line according to the
        !          80325: /      parameter:
        !          80326: /              0 - erase from active position to end inclusive (default)
        !          80327: /              1 - erase from start to active position inclusive
        !          80328: /              2 - erase entire line
        !          80329: /
        !          80330: ////////
        !          80331: 
        !          80332: mm_el: movb    al, MM_N1(bp)
        !          80333:        movb    bl, ROW
        !          80334:        cmpb    al, $0
        !          80335:        je      mm_e0
        !          80336:        cmpb    al, $1
        !          80337:        je      mm_e1
        !          80338:        shlb    bl, $1
        !          80339:        mov     POS, ss:rowtab(bx)
        !          80340:        subb    COL, COL
        !          80341:        subb    bl, bl
        !          80342: /      jmp     mm_e2
        !          80343: 
        !          80344: mm_e2: push    cx
        !          80345:        movb    al, $SPACE
        !          80346: 0:     mov     cx, MM_NCOL(bp)
        !          80347:        rep
        !          80348:        stosw
        !          80349:        decb    bl
        !          80350:        jge     0b
        !          80351:        pop     cx
        !          80352:        jmp     repos
        !          80353: 
        !          80354: mm_e1: push    cx
        !          80355:        mov     cx, POS
        !          80356:        shlb    bl, $1
        !          80357:        mov     POS, ss:rowtab(bx)
        !          80358:        sub     cx, POS
        !          80359:        jl      0f
        !          80360:        movb    al, $SPACE
        !          80361:        shr     cx, $1
        !          80362:        rep
        !          80363:        stosw
        !          80364: 0:     pop     cx
        !          80365:        jmp     repos
        !          80366: 
        !          80367: mm_e0: push    cx
        !          80368:        shlb    bl, $1
        !          80369:        mov     cx, ss:rowtab+2(bx)
        !          80370:        sub     cx, POS
        !          80371:        jl      0f
        !          80372:        movb    al, $SPACE
        !          80373:        shr     cx, $1
        !          80374:        rep
        !          80375:        stosw
        !          80376: 0:     pop     cx
        !          80377:        jmp     repos
        !          80378: 
        !          80379: ////////
        !          80380: /
        !          80381: / mm_emi - enable manual input
        !          80382: /
        !          80383: /      Clear flag preventing keyboard input.
        !          80384: /
        !          80385: ////////
        !          80386: 
        !          80387: mm_emi:
        !          80388:        mov     ss:islock_, $0
        !          80389:        jmp     eval
        !          80390: 
        !          80391: ////////
        !          80392: /
        !          80393: / mm_il - insert line
        !          80394: /
        !          80395: /      Insert a erased line at the active line by shifting the contents
        !          80396: /      of the active line and all following lines away from the active line.
        !          80397: /      The contents of the last line in the scrolling region are removed.
        !          80398: /
        !          80399: ////////
        !          80400: 
        !          80401: scrolldown:
        !          80402: mm_il: push    ds
        !          80403:        push    si
        !          80404:        push    cx
        !          80405:        mov     ds, MM_BASE(bp)
        !          80406:        movb    bl, MM_EROW(bp)
        !          80407:        shlb    bl, $1
        !          80408:        mov     si, ss:rowtab(bx)
        !          80409:        mov     cx, si
        !          80410:        sub     si, $2
        !          80411:        mov     di, ss:rowtab+2(bx)
        !          80412:        sub     di, $2
        !          80413:        movb    bl, ROW
        !          80414:        shlb    bl, $1
        !          80415:        sub     cx, ss:rowtab(bx)
        !          80416:        jle     0f
        !          80417:        shr     cx, $1
        !          80418:        std
        !          80419:        rep
        !          80420:        movsw
        !          80421:        mov     di, ss:rowtab(bx)
        !          80422:        mov     cx, MM_NCOL(bp)
        !          80423:        movb    al, $SPACE
        !          80424:        cld
        !          80425:        rep
        !          80426:        stosw
        !          80427:        subb    COL, COL
        !          80428:        movb    bl, ROW
        !          80429:        shlb    bl, $1
        !          80430:        mov     di, ss:rowtab(bx)
        !          80431: 0:     pop     cx
        !          80432:        pop     si
        !          80433:        pop     ds
        !          80434:        call    exit
        !          80435:        jmp     eval
        !          80436: 
        !          80437: ////////
        !          80438: /
        !          80439: / mm_hpa - horizontal position absolute
        !          80440: /
        !          80441: /      Moves the active position within the active line to the position
        !          80442: /      specified by the parameter.  A parameter value of zero or one
        !          80443: /      moves the active position to the first position of the active line.
        !          80444: /
        !          80445: ////////
        !          80446: 
        !          80447: mm_hpa:        movb    COL, MM_N1(bp)
        !          80448:        orb     COL, COL
        !          80449:        je      0f
        !          80450:        decb    COL
        !          80451: 0:     cmpb    COL, MM_NCOL(bp)
        !          80452:        jb      0f
        !          80453:        movb    COL, MM_NCOL(bp)
        !          80454:        decb    COL
        !          80455: 0:     jmp     repos                   / reposition cursor
        !          80456: 
        !          80457: ////////
        !          80458: /
        !          80459: / mm_hpr - horizontal position relative
        !          80460: /
        !          80461: /      Moves the active position forward the number of positions specified
        !          80462: /      by the parameter.  A parameter value of zero or one indicates a
        !          80463: /      single-position move.
        !          80464: /
        !          80465: ////////
        !          80466: 
        !          80467: mm_hpr:        movb    al, MM_N1(bp)
        !          80468:        orb     al, al
        !          80469:        jne     0f
        !          80470:        incb    al
        !          80471: 0:     addb    COL, al
        !          80472:        cmpb    COL, MM_NCOL(bp)
        !          80473:        jb      0f
        !          80474:        movb    COL, MM_NCOL(bp)
        !          80475:        decb    COL
        !          80476: 0:     jmp     repos                   / reposition cursor
        !          80477: 
        !          80478: ////////
        !          80479: /
        !          80480: / mm_hvp - horizontal and vertical position
        !          80481: /
        !          80482: /      Moves the active position to the position specified by two parameters.
        !          80483: /      The first parameter specifies the vertical position (MM_ROW(bp)).
        !          80484: /      The second parameter specifies the horizontal position (MM_COL(bp)).
        !          80485: /      A parameter value of zero or one moves the active position to the
        !          80486: /      first line or column in the display.
        !          80487: /
        !          80488: ////////
        !          80489: 
        !          80490: mm_hvp:        movb    ROW, MM_N1(bp)
        !          80491:        orb     ROW, ROW
        !          80492:        je      0f
        !          80493:        decb    ROW
        !          80494: 0:     cmpb    ROW, MM_LROW(bp)
        !          80495:        jna     0f
        !          80496:        movb    ROW, MM_LROW(bp)
        !          80497: 0:     movb    COL, MM_N2(bp)
        !          80498:        orb     COL, COL
        !          80499:        je      0f
        !          80500:        decb    COL
        !          80501: 0:     cmpb    COL, MM_NCOL(bp)
        !          80502:        jb      0f
        !          80503:        movb    COL, MM_NCOL(bp)
        !          80504:        decb    COL
        !          80505: 0:     jmp     repos                   / reposition cursor
        !          80506: 
        !          80507: ////////
        !          80508: /
        !          80509: / mm_ind - index
        !          80510: /
        !          80511: /      Causes the active position to move downward one line without changing
        !          80512: /      the horizontal position.  Scrolling occurs if below scrolling region.
        !          80513: /
        !          80514: ////////
        !          80515: 
        !          80516: mm_ind:        incb    ROW
        !          80517:        cmpb    ROW, MM_EROW(bp)
        !          80518:        jg      0f
        !          80519:        jmp     repos
        !          80520: 0:     movb    ROW, MM_EROW(bp)
        !          80521:        jmp     scrollup
        !          80522: 
        !          80523: ////////
        !          80524: /
        !          80525: / mm_new - save cursor position
        !          80526: /
        !          80527: ////////
        !          80528: 
        !          80529: mm_new:        movb    MM_SCOL(bp), COL
        !          80530:        movb    MM_SROW(bp), ROW
        !          80531:        jmp     eval
        !          80532: 
        !          80533: ////////
        !          80534: /
        !          80535: / mm_old - restore old cursor position
        !          80536: /
        !          80537: ////////
        !          80538: 
        !          80539: mm_old:        movb    COL, MM_SCOL(bp)
        !          80540:        movb    ROW, MM_SROW(bp)
        !          80541:        jmp     repos
        !          80542: 
        !          80543: ////////
        !          80544: /
        !          80545: / mm_ri - reverse index
        !          80546: /
        !          80547: /      Moves the active position to the same horizontal position on the
        !          80548: /      preceding line.  Scrolling occurs if above scrolling region.
        !          80549: /
        !          80550: ////////
        !          80551: 
        !          80552: mm_ri: decb    ROW
        !          80553:        cmpb    ROW, MM_BROW(bp)
        !          80554:        jge     0f
        !          80555:        movb    ROW, MM_BROW(bp)
        !          80556:        jmp     scrolldown
        !          80557: 0:     jmp     repos
        !          80558: 
        !          80559: ////////
        !          80560: /
        !          80561: / mm_scr - select cursor rendition
        !          80562: /
        !          80563: /      Invokes the cursor rendition specified by the parameter.
        !          80564: /
        !          80565: /      Recognized renditions are:      0 - cursor visible
        !          80566: /                                      1 - cursor invisible
        !          80567: ////////
        !          80568: 
        !          80569: mm_scr:        decb     MM_N1(bp)
        !          80570:        je      0f
        !          80571:        jg      1f
        !          80572:        mov     MM_INVIS(bp), $0
        !          80573:        jmp     eval
        !          80574: 
        !          80575: 0:     mov     MM_INVIS(bp), $-1
        !          80576: 1:     jmp     eval
        !          80577: 
        !          80578: ////////
        !          80579: /
        !          80580: / mm_sgr - select graphic rendition
        !          80581: /
        !          80582: /      Invokes the graphic rendition specified by the parameter.
        !          80583: /      All following characters in the data stream are rendered
        !          80584: /      according to the parameters until the next occurrence of
        !          80585: /      SGR in the data stream.
        !          80586: /
        !          80587: /      Recognized renditions are:      1 - high intensity
        !          80588: /                                      4 - underline
        !          80589: /                                      5 - slow blink
        !          80590: /                                      7 - reverse video
        !          80591: /                                      30-37 - foreground color
        !          80592: /                                      40-47 - background color
        !          80593: /                                      50-57 - border color
        !          80594: /
        !          80595: ////////
        !          80596: 
        !          80597: mm_sgr:        movb    al, MM_N1(bp)
        !          80598:        cmpb    al, $0
        !          80599:        jne     0f
        !          80600:        movb    ATTR, $0x07
        !          80601: 1:     jmp     eval
        !          80602: 0:     cmpb    al, $1          / bold
        !          80603:        jne     0f
        !          80604:        orb     ATTR, $INTENSE
        !          80605:        jmp     1b
        !          80606: 0:     cmpb    al, $4          / underline
        !          80607:        jne     0f
        !          80608:        cmp     MM_PORT(bp), $0x03D4    / color card?
        !          80609:        je      1b                      / yes, ignore underline
        !          80610:        andb    ATTR, $~0x77
        !          80611:        orb     ATTR, $0x01
        !          80612:        jmp     1b
        !          80613: 0:     cmpb    al, $5          / blinking
        !          80614:        jne     0f
        !          80615:        orb     ATTR, $BLINK
        !          80616:        jmp     1b
        !          80617: 0:     cmpb    al, $7          / reverse video
        !          80618:        jne     0f
        !          80619:        movb    al, $0x70
        !          80620:        cmp     MM_PORT(bp), $0x3D4     / color card?
        !          80621:        jne     2f
        !          80622:        movb    al, ah                  / yes, exchange foreground/background
        !          80623:        andb    al, $0x77
        !          80624:        rolb    al, $1
        !          80625:        rolb    al, $1
        !          80626:        rolb    al, $1
        !          80627:        rolb    al, $1
        !          80628: 2:     andb    ATTR, $~0x77
        !          80629:        orb     ATTR, al
        !          80630:        jmp     1b
        !          80631: 0:     cmp     MM_PORT(bp), $0x03D4    / color card?
        !          80632:        jne     1b                      / no, ignore remaining options
        !          80633: 0:     subb    al, $30         / foreground color
        !          80634:        jl      1f
        !          80635:        cmpb    al, $7
        !          80636:        jg      0f
        !          80637:        movb    bl, al
        !          80638:        andb    ATTR, $~0x07
        !          80639:        orb     ATTR, cs:fcolor(bx)
        !          80640:        jmp     1f
        !          80641: 0:     subb    al, $10
        !          80642:        jl      1f
        !          80643:        cmpb    al, $7
        !          80644:        jg      0f
        !          80645:        movb    bl, al
        !          80646:        andb    ATTR, $~0x70
        !          80647:        orb     ATTR, cs:bcolor(bx)
        !          80648:        jmp     1f
        !          80649: 0:     subb    al, $10
        !          80650:        jl      1f
        !          80651:        cmpb    al, $7
        !          80652:        jg      0f
        !          80653:        movb    bl, al
        !          80654:        movb    al, cs:fcolor(bx)
        !          80655:        push    dx
        !          80656:        mov     dx, MM_PORT(bp)
        !          80657:        add     dx, $5
        !          80658:        outb    dx, al
        !          80659:        pop     dx
        !          80660: /      jmp     1f
        !          80661: 0:
        !          80662: 1:     jmp     eval
        !          80663: 
        !          80664: ////////
        !          80665: /
        !          80666: / mm_ssr - set scrolling region
        !          80667: /
        !          80668: ////////
        !          80669: 
        !          80670: mm_ssr:        movb    al, MM_N1(bp)
        !          80671:        decb    al
        !          80672:        jge     0f
        !          80673:        subb    al, al
        !          80674: 0:     cmpb    al, MM_LROW(bp)
        !          80675:        ja      1f
        !          80676:        movb    bl, MM_N2(bp)
        !          80677:        decb    bl
        !          80678:        jge     0f
        !          80679:        subb    bl, bl
        !          80680: 0:     cmpb    bl, MM_LROW(bp)
        !          80681:        ja      1f
        !          80682:        cmpb    al, bl
        !          80683:        ja      1f
        !          80684:        movb    MM_BROW(bp), al
        !          80685:        movb    MM_EROW(bp), bl
        !          80686:        movb    ROW, al
        !          80687:        subb    COL, COL
        !          80688: 1:     jmp     repos
        !          80689: 
        !          80690: ////////
        !          80691: /
        !          80692: / mm_vpa - vertical position absolute
        !          80693: /
        !          80694: /      Moves the active position to the line specified by the parameter
        !          80695: /      without changing the horizontal position.
        !          80696: /      A parameter value of 0 or 1 moves the active position vertically
        !          80697: /      to the first line.
        !          80698: /
        !          80699: ////////
        !          80700: 
        !          80701: mm_vpa:        movb    ROW, MM_N1(bp)
        !          80702:        decb    ROW
        !          80703:        jg      0f
        !          80704:        subb    ROW, ROW
        !          80705: 0:     cmpb    ROW, MM_LROW(bp)
        !          80706:        jna     0f
        !          80707:        movb    ROW, MM_LROW(bp)
        !          80708: 0:     jmp     repos                   / reposition cursor
        !          80709: 
        !          80710: ////////
        !          80711: /
        !          80712: / mm_vpr - vertical position relative
        !          80713: /
        !          80714: /      Moves the active position downward the number of lines specified
        !          80715: /      by the parameter without changing the horizontal position.
        !          80716: /      A parameter value of zero or one moves the active position
        !          80717: /      one line downward.
        !          80718: /
        !          80719: ////////
        !          80720: 
        !          80721: mm_vpr:        movb    al, MM_N1(bp)
        !          80722:        orb     al, al
        !          80723:        jne     0f
        !          80724:        incb    al
        !          80725: 0:     addb    ROW, al
        !          80726:        cmpb    ROW, MM_LROW(bp)
        !          80727:        jb      0f
        !          80728:        movb    ROW, MM_LROW(bp)
        !          80729: 0:     jmp     repos                   / reposition cursor
        !          80730: 
        !          80731: ////////
        !          80732: /
        !          80733: / asctab - table of functions indexed by ascii characters
        !          80734: /
        !          80735: ////////
        !          80736: 
        !          80737: asctab:        .word   eval,   eval,   eval,   eval    /       NUL  SOH  STX  ETX
        !          80738:        .word   eval,   eval,   eval,   mmbell  /       EOT  ENQ  ACK  BEL
        !          80739:        .word   mm_cub, mm_cht, mm_cnl, mm_ind  /       BS   HT   LF   VT
        !          80740:        .word   eval,   mm_cr,  mm_so,  mm_si   /       FF   CR   SO   SI
        !          80741:        .word   eval,   eval,   eval,   eval    /       DLE  DC1  DC2  DC3
        !          80742: / DEBUG: mm_132 is only inserted temporarily, for testing - 86/05/26
        !          80743:        .word   eval,   eval,   eval,   mm_132  /       DC4  NAK  SYN  ETB
        !          80744:        .word   eval,   eval,   eval,   mm_esc  /       CAN  EM   SUB  ESC
        !          80745:        .word   eval,   eval,   eval,   eval    /       FS   GS   RS   US
        !          80746:        .word   mmputc, mmputc, mmputc, mmputc  /         ! dquote # \040 - \043
        !          80747:        .word   mmputc, mmputc, mmputc, mmputc  /       $ % & quote \044 - \047
        !          80748:        .word   mmputc, mmputc, mmputc, mmputc  /       ( ) * + \050 - \053
        !          80749:        .word   mmputc, mmputc, mmputc, mmputc  /       , - . / \054 - \057
        !          80750:        .word   mmputc, mmputc, mmputc, mmputc  /       0 1 2 3 \060 - \063
        !          80751:        .word   mmputc, mmputc, mmputc, mmputc  /       4 5 6 7 \064 - \067
        !          80752:        .word   mmputc, mmputc, mmputc, mmputc  /       8 9 : ; \070 - \073
        !          80753:        .word   mmputc, mmputc, mmputc, mmputc  /       < = > ? \074 - \077
        !          80754:        .word   mmputc, mmputc, mmputc, mmputc  /       @@ A B C \100 - \103
        !          80755:        .word   mmputc, mmputc, mmputc, mmputc  /       D E F G \104 - \107
        !          80756:        .word   mmputc, mmputc, mmputc, mmputc  /       H I J K \110 - \113
        !          80757:        .word   mmputc, mmputc, mmputc, mmputc  /       L M N O \114 - \117
        !          80758:        .word   mmputc, mmputc, mmputc, mmputc  /       P Q R S \120 - \123
        !          80759:        .word   mmputc, mmputc, mmputc, mmputc  /       T U V W \124 - \127
        !          80760:        .word   mmputc, mmputc, mmputc, mmputc  /       X Y Z [ \130 - \133
        !          80761:        .word   mmputc, mmputc, mmputc, mmputc  /       \ ] ^ _ \134 - \137
        !          80762:        .word   mmputc, mmputc, mmputc, mmputc  /       ` a b c \140 - \143
        !          80763:        .word   mmputc, mmputc, mmputc, mmputc  /       d e f g \144 - \147
        !          80764:        .word   mmputc, mmputc, mmputc, mmputc  /       h i j k \150 - \153
        !          80765:        .word   mmputc, mmputc, mmputc, mmputc  /       l m n o \154 - \157
        !          80766:        .word   mmputc, mmputc, mmputc, mmputc  /       p q r s \160 - \163
        !          80767:        .word   mmputc, mmputc, mmputc, mmputc  /       t u v w \164 - \167
        !          80768:        .word   mmputc, mmputc, mmputc, mmputc  /       x y z { \170 - \173
        !          80769:        .word   mmputc, mmputc, mmputc, mmputc  /       | } ~ ? \174 - \177
        !          80770: 
        !          80771: ////////
        !          80772: /
        !          80773: / esctab - table of functions indexed by escape characters.
        !          80774: /
        !          80775: ////////
        !          80776: 
        !          80777: esctab:        .word   mmputc, mmputc, mmputc, mmputc  /       NUL  SOH  STX  ETX
        !          80778:        .word   mmputc, mmputc, mmputc, mmputc  /       EOT  ENQ  ACK  BEL
        !          80779:        .word   mmputc, mmputc, mmputc, mmputc  /       BS   HT   LF   VT
        !          80780:        .word   mmputc, mmputc, mmputc, mmputc  /       FF   CR   SO   SI
        !          80781:        .word   mmputc, mmputc, mmputc, mmputc  /       DLE  DC1  DC2  DC3
        !          80782:        .word   mmputc, mmputc, mmputc, mmputc  /       DC4  NAK  SYN  ETB
        !          80783:        .word   mmputc, mmputc, mmputc, mmputc  /       CAN  EM   SUB  ESC
        !          80784:        .word   mmputc, mmputc, mmputc, mmputc  /       FS   GS   RS   US
        !          80785:        .word   eval,   eval,   eval,   eval    /         ! dquote # \040 - \043
        !          80786:        .word   eval,   eval,   eval,   eval    /       $ % & quote \044 - \047
        !          80787:        .word   eval,   eval,   eval,   eval    /       ( ) * + \050 - \053
        !          80788:        .word   eval,   eval,   eval,   eval    /       , - . / \054 - \057
        !          80789:        .word   eval,   eval,   eval,   eval    /       0 1 2 3 \060 - \063
        !          80790:        .word   eval,   eval,   eval,   mm_new  /       4 5 6 7 \064 - \067
        !          80791:        .word   mm_old, eval,   eval,   eval    /       8 9 : ; \070 - \073
        !          80792:        .word   eval,   mmspec, mmspec, eval    /       < = > ? \074 - \077
        !          80793:        .word   eval,   eval,   eval,   eval    /       @@ A B C \100 - \103
        !          80794:        .word   mm_ind, mm_cnl, eval,   eval    /       D E F G \104 - \107
        !          80795:        .word   eval,   eval,   eval,   eval    /       H I J K \110 - \113
        !          80796:        .word   eval,   mm_ri,  eval,   eval    /       L M N O \114 - \117
        !          80797:        .word   eval,   eval,   eval,   eval    /       P Q R S \120 - \123
        !          80798:        .word   eval,   eval,   eval,   eval    /       T U V W \124 - \127
        !          80799:        .word   eval,   eval,   eval,   csi_n1  /       X Y Z [ \130 - \133
        !          80800:        .word   eval,   eval,   eval,   eval    /       \ ] ^ _ \134 - \137
        !          80801:        .word   mm_dmi, eval,   mm_emi, mminit  /       ` a b c \140 - \143
        !          80802:        .word   eval,   eval,   eval,   eval    /       d e f g \144 - \147
        !          80803:        .word   eval,   eval,   eval,   eval    /       h i j k \150 - \153
        !          80804:        .word   eval,   eval,   eval,   eval    /       l m n o \154 - \157
        !          80805:        .word   eval,   eval,   eval,   eval    /       p q r s \160 - \163
        !          80806:        .word   mmspec, mmspec, eval,   eval    /       t u v w \164 - \167
        !          80807:        .word   eval,   eval,   eval,   eval    /       x y z { \170 - \173
        !          80808:        .word   eval,   eval,   eval,   eval    /       | } ~ ? \174 - \177
        !          80809: 
        !          80810: ////////
        !          80811: /
        !          80812: / csitab - table of functions indexed by ESC [ characters.
        !          80813: /
        !          80814: ////////
        !          80815: 
        !          80816: csitab:        .word   eval,   eval,   eval,   eval    /       NUL  SOH  STX  ETX
        !          80817:        .word   eval,   eval,   eval,   eval    /       EOT  ENQ  ACK  BEL
        !          80818:        .word   eval,   eval,   eval,   eval    /       BS   HT   LF   VT
        !          80819:        .word   eval,   eval,   eval,   eval    /       FF   CR   SO   SI
        !          80820:        .word   eval,   eval,   eval,   eval    /       DLE  DC1  DC2  DC3
        !          80821:        .word   eval,   eval,   eval,   eval    /       DC4  NAK  SYN  ETB
        !          80822:        .word   eval,   eval,   eval,   eval    /       CAN  EM   SUB  ESC
        !          80823:        .word   eval,   eval,   eval,   eval    /       FS   GS   RS   US
        !          80824:        .word   eval,   eval,   eval,   eval    /         ! dquote # \040 - \043
        !          80825:        .word   eval,   eval,   eval,   eval    /       $ % & quote \044 - \047
        !          80826:        .word   eval,   eval,   eval,   eval    /       ( ) * + \050 - \053
        !          80827:        .word   eval,   eval,   eval,   eval    /       , - . / \054 - \057
        !          80828:        .word   eval,   eval,   eval,   eval    /       0 1 2 3 \060 - \063
        !          80829:        .word   eval,   eval,   eval,   eval    /       4 5 6 7 \064 - \067
        !          80830:        .word   eval,   eval,   eval,   eval    /       8 9 : ; \070 - \073
        !          80831:        .word   eval,   eval,   csi_gt, eval    /       < = > ? \074 - \077
        !          80832:        .word   eval,   mm_cuu, mm_cud, mm_cuf  /       @@ A B C \100 - \103
        !          80833:        .word   mm_cub, mm_cnl, mm_cpl, mm_cha  /       D E F G \104 - \107
        !          80834:        .word   mm_cup, mm_cht, mm_ed,  mm_el   /       H I J K \110 - \113
        !          80835:        .word   mm_il,  mm_dl,  eval,   mm_ea   /       L M N O \114 - \117
        !          80836:        .word   eval,   eval,   eval,   mm_ind  /       P Q R S \120 - \123
        !          80837:        .word   mm_ri,  eval,   eval,   eval    /       T U V W \124 - \127
        !          80838:        .word   eval,   eval,   mm_cbt, eval    /       X Y Z [ \130 - \133
        !          80839:        .word   eval,   eval,   eval,   eval    /       \ ] ^ _ \134 - \137
        !          80840:        .word   mm_hpa, mm_hpr, eval,   eval    /       ` a b c \140 - \143
        !          80841:        .word   mm_vpa, mm_vpr, mm_hvp, mm_cup  /       d e f g \144 - \147
        !          80842:        .word   eval,   eval,   eval,   eval    /       h i j k \150 - \153
        !          80843:        .word   eval,   mm_sgr, eval,   eval    /       l m n o \154 - \157
        !          80844:        .word   eval,   eval,   mm_ssr, eval    /       p q r s \160 - \163
        !          80845:        .word   eval,   eval,   mm_scr, eval    /       t u v w \164 - \167
        !          80846:        .word   eval,   eval,   eval,   eval    /       x y z { \170 - \173
        !          80847:        .word   eval,   eval,   eval,   eval    /       | } ~ ? \174 - \177
        !          80848: 
        !          80849: ////////
        !          80850: /
        !          80851: / csgtab - table of functions indexed by ESC [ > characters.
        !          80852: /
        !          80853: ////////
        !          80854: 
        !          80855: csgtab:        .word   eval,   eval,   eval,   eval    /       NUL  SOH  STX  ETX
        !          80856:        .word   eval,   eval,   eval,   eval    /       EOT  ENQ  ACK  BEL
        !          80857:        .word   eval,   eval,   eval,   eval    /       BS   HT   LF   VT
        !          80858:        .word   eval,   eval,   eval,   eval    /       FF   CR   SO   SI
        !          80859:        .word   eval,   eval,   eval,   eval    /       DLE  DC1  DC2  DC3
        !          80860:        .word   eval,   eval,   eval,   eval    /       DC4  NAK  SYN  ETB
        !          80861:        .word   eval,   eval,   eval,   eval    /       CAN  EM   SUB  ESC
        !          80862:        .word   eval,   eval,   eval,   eval    /       FS   GS   RS   US
        !          80863:        .word   eval,   eval,   eval,   eval    /         ! dquote # \040 - \043
        !          80864:        .word   eval,   eval,   eval,   eval    /       $ % & quote \044 - \047
        !          80865:        .word   eval,   eval,   eval,   eval    /       ( ) * + \050 - \053
        !          80866:        .word   eval,   eval,   eval,   eval    /       , - . / \054 - \057
        !          80867:        .word   eval,   eval,   eval,   eval    /       0 1 2 3 \060 - \063
        !          80868:        .word   eval,   eval,   eval,   eval    /       4 5 6 7 \064 - \067
        !          80869:        .word   eval,   eval,   eval,   eval    /       8 9 : ; \070 - \073
        !          80870:        .word   eval,   eval,   eval,   eval    /       < = > ? \074 - \077
        !          80871:        .word   eval,   eval,   eval,   eval    /       @@ A B C \100 - \103
        !          80872:        .word   eval,   eval,   eval,   eval    /       D E F G \104 - \107
        !          80873:        .word   eval,   eval,   eval,   eval    /       H I J K \110 - \113
        !          80874:        .word   eval,   eval,   eval,   eval    /       L M N O \114 - \117
        !          80875:        .word   eval,   eval,   eval,   eval    /       P Q R S \120 - \123
        !          80876:        .word   eval,   eval,   eval,   eval    /       T U V W \124 - \127
        !          80877:        .word   eval,   eval,   eval,   eval    /       X Y Z [ \130 - \133
        !          80878:        .word   eval,   eval,   eval,   eval    /       \ ] ^ _ \134 - \137
        !          80879:        .word   eval,   eval,   eval,   eval    /       ` a b c \140 - \143
        !          80880:        .word   eval,   eval,   eval,   eval    /       d e f g \144 - \147
        !          80881:        .word   mm_cgh, eval,   eval,   eval    /       h i j k \150 - \153
        !          80882:        .word   mm_cgl, eval,   eval,   eval    /       l m n o \154 - \157
        !          80883:        .word   eval,   eval,   eval,   eval    /       p q r s \160 - \163
        !          80884:        .word   eval,   eval,   eval,   eval    /       t u v w \164 - \167
        !          80885:        .word   eval,   eval,   eval,   eval    /       x y z { \170 - \173
        !          80886:        .word   eval,   eval,   eval,   eval    /       | } ~ ? \174 - \177
        !          80887: 
        !          80888: ////////
        !          80889: /
        !          80890: / coltab - integer array of offsets to each column - up to 132 columns
        !          80891: /
        !          80892: ////////
        !          80893: 
        !          80894: coltab:        .word     0*NCB,   1*NCB,   2*NCB,   3*NCB
        !          80895:        .word     4*NCB,   5*NCB,   6*NCB,   7*NCB
        !          80896:        .word     8*NCB,   9*NCB,  10*NCB,  11*NCB
        !          80897:        .word    12*NCB,  13*NCB,  14*NCB,  15*NCB
        !          80898:        .word    16*NCB,  17*NCB,  18*NCB,  19*NCB
        !          80899:        .word    20*NCB,  21*NCB,  22*NCB,  23*NCB
        !          80900:        .word    24*NCB,  25*NCB,  26*NCB,  27*NCB
        !          80901:        .word    28*NCB,  29*NCB,  30*NCB,  31*NCB
        !          80902:        .word    32*NCB,  33*NCB,  34*NCB,  35*NCB
        !          80903:        .word    36*NCB,  37*NCB,  38*NCB,  39*NCB
        !          80904:        .word    40*NCB,  41*NCB,  42*NCB,  43*NCB
        !          80905:        .word    44*NCB,  45*NCB,  46*NCB,  47*NCB
        !          80906:        .word    48*NCB,  49*NCB,  50*NCB,  51*NCB
        !          80907:        .word    52*NCB,  53*NCB,  54*NCB,  55*NCB
        !          80908:        .word    56*NCB,  57*NCB,  58*NCB,  59*NCB
        !          80909:        .word    60*NCB,  61*NCB,  62*NCB,  63*NCB
        !          80910:        .word    64*NCB,  65*NCB,  66*NCB,  67*NCB
        !          80911:        .word    68*NCB,  69*NCB,  70*NCB,  71*NCB
        !          80912:        .word    72*NCB,  73*NCB,  74*NCB,  75*NCB
        !          80913:        .word    76*NCB,  77*NCB,  78*NCB,  79*NCB
        !          80914:        .word    80*NCB,  81*NCB,  82*NCB,  83*NCB
        !          80915:        .word    84*NCB,  85*NCB,  86*NCB,  87*NCB
        !          80916:        .word    88*NCB,  89*NCB,  90*NCB,  91*NCB
        !          80917:        .word    92*NCB,  93*NCB,  94*NCB,  95*NCB
        !          80918:        .word    96*NCB,  97*NCB,  98*NCB,  99*NCB
        !          80919:        .word   100*NCB, 101*NCB, 102*NCB, 103*NCB
        !          80920:        .word   104*NCB, 105*NCB, 106*NCB, 107*NCB
        !          80921:        .word   108*NCB, 109*NCB, 110*NCB, 111*NCB
        !          80922:        .word   112*NCB, 113*NCB, 114*NCB, 115*NCB
        !          80923:        .word   116*NCB, 117*NCB, 118*NCB, 119*NCB
        !          80924:        .word   120*NCB, 121*NCB, 122*NCB, 123*NCB
        !          80925:        .word   124*NCB, 125*NCB, 126*NCB, 127*NCB
        !          80926:        .word   128*NCB, 129*NCB, 130*NCB, 131*NCB
        !          80927: 
        !          80928: ////////
        !          80929: /
        !          80930: / rowtab - array of offsets to each row - up to 44 rows
        !          80931: /         automatically regenerated by reinit().
        !          80932: /
        !          80933: /      NOTE: In kernel data space to allow modification in protected mode.
        !          80934: /
        !          80935: ////////
        !          80936: 
        !          80937:        .shrd
        !          80938: rowtab:        .word    0*NRB,  1*NRB,  2*NRB,  3*NRB
        !          80939:        .word    4*NRB,  5*NRB,  6*NRB,  7*NRB
        !          80940:        .word    8*NRB,  9*NRB, 10*NRB, 11*NRB
        !          80941:        .word   12*NRB, 13*NRB, 14*NRB, 15*NRB
        !          80942:        .word   16*NRB, 17*NRB, 18*NRB, 19*NRB
        !          80943:        .word   20*NRB, 21*NRB, 22*NRB, 23*NRB
        !          80944:        .word   24*NRB, 25*NRB, 26*NRB, 27*NRB
        !          80945:        .word   28*NRB, 29*NRB, 30*NRB, 31*NRB
        !          80946:        .word   32*NRB, 33*NRB, 34*NRB, 35*NRB
        !          80947:        .word   36*NRB, 37*NRB, 38*NRB, 39*NRB
        !          80948:        .word   40*NRB, 41*NRB, 42*NRB, 43*NRB
        !          80949: rowend:
        !          80950:        .shri
        !          80951: 
        !          80952: ////////
        !          80953: /
        !          80954: / fcolor - foreground color
        !          80955: / bcolor - background color
        !          80956: /
        !          80957: /      indexed by ansi color (black,red,green,brown,blue,magenta,cyan,white)
        !          80958: /      yields graphics color (black,blue,green,cyan,red,magenta,brown,white)
        !          80959: /              which is properly shifted for installation in attribute byte.
        !          80960: /
        !          80961: ////////
        !          80962: 
        !          80963: fcolor:        .byte   0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07
        !          80964: bcolor:        .byte   0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70
        !          80965: 
        !          80966: ////////
        !          80967: /
        !          80968: / mm_voff()    -- Disable video display.
        !          80969: /
        !          80970: ////////
        !          80971:        .globl  mm_voff_
        !          80972: mm_voff_:
        !          80973:        mov     dx, mmdata+MM_PORT
        !          80974:        add     dx, $4
        !          80975:        movb    al, mmdata+MM_MODE
        !          80976:        outb    dx, al
        !          80977:        ret
        !          80978: 
        !          80979: ////////
        !          80980: /
        !          80981: / mm_von()     -- Enable video display
        !          80982: /
        !          80983: ////////
        !          80984:        .globl  mm_von_
        !          80985: mm_von_:
        !          80986:        mov     dx, mmdata+MM_PORT      / enable video display
        !          80987:        add     dx, $4
        !          80988:        movb    al, mmdata+MM_MODE
        !          80989:        orb     al, $0x08
        !          80990:        outb    dx, al
        !          80991:        mov     mmvcnt_, $300           / 300 seconds before video disabled
        !          80992:        ret
        !          80993: @
        !          80994: 0707070064030147531004440000000000000000011777770507310707100005600000114157/newbits/kernel/USRSRC/i8086/drv/RCS/gras.m,vhead     1.1;
        !          80995: branch   ;
        !          80996: access   ;
        !          80997: symbols  ;
        !          80998: locks    bin:1.1; strict;
        !          80999: comment  @@;
        !          81000: 
        !          81001: 
        !          81002: 1.1
        !          81003: date     91.07.24.08.12.22;  author bin;  state Exp;
        !          81004: branches ;
        !          81005: next     ;
        !          81006: 
        !          81007: 
        !          81008: desc
        !          81009: @prov by hal, replaced gras.s
        !          81010: @
        !          81011: 
        !          81012: 
        !          81013: 
        !          81014: 1.1
        !          81015: log
        !          81016: @Initial revision
        !          81017: @
        !          81018: text
        !          81019: @/ (lgl-
        !          81020: /      COHERENT Driver Kit Version 1.0.0
        !          81021: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          81022: /      All rights reserved. May not be copied without permission.
        !          81023: / -lgl)
        !          81024:        .globl  grread_
        !          81025:        .globl  grwrite_
        !          81026:        .globl  mmgo_
        !          81027: 
        !          81028: ////////
        !          81029: /
        !          81030: / State driven code
        !          81031: /
        !          81032: /      Input:  DS:SI - input string
        !          81033: /              ES:DI - current screen location
        !          81034: /              SS:BP - terminal attributes
        !          81035: /              CX    - input count
        !          81036: /              BP    - references terminal information
        !          81037: /              AL    - character
        !          81038: /              BH    - (usually) kept zeroed for efficiency
        !          81039: /              DH    - current row
        !          81040: /              DL    - current column
        !          81041: /
        !          81042: ////////
        !          81043: 
        !          81044: #ifdef HERCULES
        !          81045:        VSEG    = 0xB000        / Video Display Segment
        !          81046:        BANKSZ  = 8192          / Size of Display Banks
        !          81047:        LROW    = 24            / Last legal row
        !          81048:        NCR     = 8             / number of horizontal lines per char
        !          81049:        NCR2    = 4             / number of horizontal lines per char / 2
        !          81050:        NCR4    = 2             / number of horizontal lines per char / 4
        !          81051:        NHB     = 90            / number of horizontal bytes per line
        !          81052: #else
        !          81053: #ifdef TECMAR
        !          81054:        VSEG    = 0xA000        / Video Display Segment
        !          81055:        BANKSZ  = 32768         / Size of Display Banks
        !          81056:        LROW    = 24            / Last legal row
        !          81057:        NCR     = 16            / number of horizontal lines per char
        !          81058:        NCR2    = 8             / number of horizontal lines per char / 2
        !          81059:        NCR4    = 4             / number of horizontal lines per char / 4
        !          81060:        NHB     = 80            / number of horizontal bytes per line
        !          81061: #else
        !          81062:        VSEG    = 0xB800        / Video Display Segment
        !          81063:        BANKSZ  = 8192          / Size of Display Banks
        !          81064:        LROW    = 24            / Last legal row
        !          81065:        NCR     = 8             / number of horizontal lines per char
        !          81066:        NCR2    = 4             / number of horizontal lines per char / 2
        !          81067:        NCR4    = 2             / number of horizontal lines per char / 4
        !          81068:        NHB     = 80            / number of horizontal bytes per line
        !          81069: #endif
        !          81070: #endif
        !          81071: 
        !          81072:        NRB     = NHB*NCR       / number of bytes per character row
        !          81073:        NRB2    = NHB*NCR2      / number of bytes per character row / 2
        !          81074:        NRB4    = NHB*NCR4      / number of bytes per character row / 4
        !          81075: 
        !          81076: 
        !          81077:        ZERO    = bh            / (almost) always zero
        !          81078:        ROW     = dh            / currently active vertical position
        !          81079:        COL     = dl            / currently active horizontal position
        !          81080:        POS     = di            / currently active display address
        !          81081: 
        !          81082:        CSR     = 0x3D9         / Color Select Register
        !          81083:        MSR     = 0x3D8         / Mode Select Register
        !          81084:        XMSR    = 0x3DA         / Extended Mode Select Register
        !          81085: 
        !          81086: 
        !          81087: ////////
        !          81088: /
        !          81089: / Magic constants from <sys/io.h>
        !          81090: /
        !          81091: ////////
        !          81092: 
        !          81093:        IO_SEG  = 0
        !          81094:        IO_IOC  = 2
        !          81095:        IO_SEEK = 4
        !          81096:        IO_BASE = 8
        !          81097: 
        !          81098:        IOSYS   = 0
        !          81099: 
        !          81100: ////////
        !          81101: /
        !          81102: / Data
        !          81103: /
        !          81104: ////////
        !          81105: 
        !          81106: MM_FUNC                = 0             / current state
        !          81107: MM_PORT                = 2             / adapter base i/o port
        !          81108: MM_BASE                = 4             / adapter base memory address
        !          81109: MM_ROW         = 6             / screen row
        !          81110: MM_COL         = 7             / screen column
        !          81111: MM_POS         = 8             / screen position
        !          81112: MM_ATTR                = 10            / attributes
        !          81113: MM_N1          = 11            / numeric argument 1
        !          81114: MM_N2          = 12            / numeric argument 2
        !          81115: MM_BROW                = 13            / base row
        !          81116: MM_EROW                = 14            / end row
        !          81117: MM_LROW                = 15            / legal row limit
        !          81118: MM_SROW                = 16            / saved cursor row
        !          81119: MM_SCOL                = 17            / saved cursor column
        !          81120: MM_IBROW       = 18            / initial base row
        !          81121: MM_IEROW       = 19            / initial end row
        !          81122: MM_FLIP                = 20
        !          81123: MM_MASK                = 22
        !          81124: MM_ULINE       = 24
        !          81125: MM_CURSE       = 26
        !          81126: MM_VIS         = 28            / set to -1 to make cursor visible
        !          81127: MM_NCOL                = 30
        !          81128: MM_WRAP                = 31
        !          81129: 
        !          81130: / ASCII characters
        !          81131: AZERO          = 0x30
        !          81132: CLOWER         = 0x63
        !          81133: HLOWER         = 0x68
        !          81134: LLOWER         = 0x6C
        !          81135: SEMIC          = 0x3B
        !          81136: 
        !          81137:        .prvd
        !          81138: mmdata:        .word   mminit, 0x03D4, VSEG
        !          81139:        .byte   0, 0
        !          81140:        .word   0
        !          81141:        .byte   0x7, 0, 0, 0, LROW-1, LROW, 0, 0, 0, LROW-1
        !          81142:        .word   0, -1, 0, 0xff
        !          81143:        .word   0
        !          81144:        .byte   80
        !          81145:        .byte   1
        !          81146: 
        !          81147:        .shri
        !          81148: #ifdef HERCULES
        !          81149: crtdata:.byte   54,  45,  45,   8,  91,   1,  86,  88
        !          81150:        .byte     2,   3,  32,   0,   0,   0,   0,   0
        !          81151: #else
        !          81152: #ifdef TECMAR
        !          81153: crtdata:.byte   56,  40,  43,   8, 127,   6, 100, 112
        !          81154:        .byte     3,   1,  32,   0,   0,   0,   0,   0
        !          81155: #else
        !          81156: crtdata:.byte   56,  40,  43,   8, 127,   6, 100, 112
        !          81157:        .byte     2,   1,  32,   0,   0,   0,   0,   0
        !          81158: #endif
        !          81159: #endif
        !          81160:        .shri
        !          81161: 
        !          81162: ////////
        !          81163: /
        !          81164: / mmgo( iop )          - Entry point for text stream output
        !          81165: / IO *iop;
        !          81166: /
        !          81167: ////////
        !          81168: 
        !          81169: mmgo_:
        !          81170:        push    si
        !          81171:        push    di
        !          81172:        push    bp
        !          81173:        mov     bp, sp
        !          81174:        push    ds
        !          81175:        push    es
        !          81176:        cld
        !          81177:        mov     bx, 8(bp)               / iop
        !          81178:        mov     si, IO_BASE(bx)         / iop->io_base
        !          81179:        mov     cx, IO_IOC(bx)          / iop->io_ioc
        !          81180:        cmp     IO_SEG(bx), $IOSYS
        !          81181:        je      0f
        !          81182:        mov     bx, uds_
        !          81183:        mov     ds, bx
        !          81184: 0:     mov     bp, $mmdata
        !          81185:        movb    ROW, MM_ROW(bp)
        !          81186:        movb    COL, MM_COL(bp)
        !          81187:        mov     es,  MM_BASE(bp)
        !          81188:        mov     POS, MM_POS(bp)
        !          81189:        mov     ax, MM_CURSE(bp)
        !          81190:        and     ax, MM_VIS(bp)
        !          81191: #ifdef TECMAR
        !          81192:        xor     es:[NHB*6](POS), ax
        !          81193:        xor     es:[NHB*6]+BANKSZ(POS), ax
        !          81194:        xor     es:[NHB*7](POS), ax
        !          81195:        xor     es:[NHB*7]+BANKSZ(POS), ax
        !          81196: #else
        !          81197:        xor     es:[NHB*3](POS), ax     / turn cursor off
        !          81198:        xor     es:[NHB*3]+BANKSZ(POS), ax
        !          81199: #endif
        !          81200:        sub     bx, bx
        !          81201:        ijmp    MM_FUNC(bp)
        !          81202: 
        !          81203: exit:  movb    bl, ROW                 / reposition to ROW and COL
        !          81204:        shlb    bl, $1
        !          81205:        mov     POS, cs:rowtab(bx)
        !          81206:        movb    bl, COL
        !          81207:        cmpb    MM_NCOL(bp), $40
        !          81208:        jne     0f
        !          81209:        shlb    bl, $1
        !          81210: 0:     add     POS, bx
        !          81211:        mov     ax, MM_CURSE(bp)
        !          81212:        and     ax, MM_VIS(bp)
        !          81213: #ifdef TECMAR
        !          81214:        xor     es:[NHB*6](POS), ax     / turn cursor on
        !          81215:        xor     es:[NHB*6]+BANKSZ(POS), ax
        !          81216:        xor     es:[NHB*7](POS), ax
        !          81217:        xor     es:[NHB*7]+BANKSZ(POS), ax
        !          81218: #else
        !          81219:        xor     es:[NHB*3](POS), ax     / turn cursor on
        !          81220:        xor     es:[NHB*3]+BANKSZ(POS), ax
        !          81221: #endif
        !          81222:        pop     bx
        !          81223:        pop     es
        !          81224:        pop     ds
        !          81225:        mov     MM_FUNC(bp), bx
        !          81226:        movb    MM_ROW(bp), ROW         / save row,column
        !          81227:        movb    MM_COL(bp), COL
        !          81228:        mov     MM_POS(bp), POS         / save position
        !          81229: 
        !          81230:        mov     dx, $MSR                / enable video display
        !          81231:        movb    al, $0x1A
        !          81232:        outb    dx, al
        !          81233:        mov     mmvcnt_, $480           / 480 seconds before video disabled
        !          81234: 
        !          81235:        mov     bp, sp
        !          81236:        mov     bx, 8(bp)
        !          81237:        mov     ax, cx                  / Return the residual count.
        !          81238:        xchg    cx, IO_IOC(bx)
        !          81239:        sub     cx, IO_IOC(bx)
        !          81240:        add     IO_BASE(bx), cx
        !          81241:        pop     bp
        !          81242:        pop     di
        !          81243:        pop     si
        !          81244:        ret
        !          81245: 
        !          81246: ////////
        !          81247: /
        !          81248: / mminit - initialize screen
        !          81249: /
        !          81250: ////////
        !          81251: 
        !          81252: mminit:        movb    ss:mmesc_, $CLOWER              / schedule keyboard initialization
        !          81253:        mov     dx, $MSR                / disable video display
        !          81254:        movb    al, $0x12
        !          81255:        outb    dx, al
        !          81256: 
        !          81257:        push    cx                      / program registers, last to first
        !          81258:        mov     bx, $15
        !          81259:        mov     dx, MM_PORT(bp)
        !          81260: 0:     movb    al, bl
        !          81261:        outb    dx, al
        !          81262:        inc     dx
        !          81263:        movb    al, cs:crtdata(bx)
        !          81264:        outb    dx, al
        !          81265:        dec     dx
        !          81266:        dec     bx
        !          81267:        jge     0b
        !          81268:        pop     cx
        !          81269: 
        !          81270:        mov     dx, $CSR
        !          81271:        movb    al, $0x0F
        !          81272:        outb    dx, al
        !          81273: 
        !          81274:        mov     dx, $XMSR
        !          81275: #ifdef TECMAR
        !          81276:        movb    al, $31
        !          81277: #else
        !          81278:        movb    al, $0
        !          81279: #endif
        !          81280:        outb    dx, al
        !          81281: 
        !          81282: /      mov     dx, $XMSR
        !          81283: 0:     inb     al, dx          / wait for vertical retrace
        !          81284:        andb    al, $8
        !          81285:        je      0b
        !          81286: 
        !          81287:        mov     dx, $MSR
        !          81288:        movb    al, $0x1A       / video display on
        !          81289:        outb    dx, al
        !          81290: 
        !          81291:        mov     MM_VIS(bp), $-1
        !          81292:        mov     MM_MASK(bp), $0xAAAA
        !          81293:        mov     MM_FLIP(bp), $0
        !          81294:        mov     MM_ULINE(bp), $0
        !          81295:        mov     MM_CURSE(bp), $0x00ff
        !          81296:        movb    MM_WRAP(bp), $1
        !          81297:        movb    MM_NCOL(bp), $80
        !          81298:        subb    COL, COL
        !          81299:        movb    ROW, MM_IBROW(bp)
        !          81300:        movb    MM_BROW(bp), ROW
        !          81301:        movb    bl, MM_IEROW(bp)
        !          81302:        movb    MM_EROW(bp), bl
        !          81303:        sub     bx, bx
        !          81304:        movb    MM_N1(bp), $2
        !          81305:        jmp     mm_ed
        !          81306: 
        !          81307: ////////
        !          81308: /
        !          81309: / mmbell - schedule beep
        !          81310: /
        !          81311: ////////
        !          81312: 
        !          81313: mmbell:        movb    ss:mmbeeps_, $-1
        !          81314:        jmp     eval
        !          81315: 
        !          81316: ////////
        !          81317: /
        !          81318: / mmspec - pass special characters on to keyboard routine(s).
        !          81319: /
        !          81320: ////////
        !          81321: 
        !          81322: mmspec:        movb    ss:mmesc_, al
        !          81323:        jmp     eval
        !          81324: 
        !          81325: ////////
        !          81326: /
        !          81327: / mm_cnl - cursor next line
        !          81328: /
        !          81329: /      Moves the active position to the first column of the next display line.
        !          81330: /      Scrolls the active display if necessary.
        !          81331: /      Returns to mmwrite() to allow flow control on each output line.
        !          81332: /
        !          81333: ////////
        !          81334: 
        !          81335: mm_cnl:        subb    COL, COL
        !          81336:        incb    ROW
        !          81337:        cmpb    ROW, MM_EROW(bp)
        !          81338:        jle     repos
        !          81339:        movb    ROW, MM_EROW(bp)
        !          81340: /      jmp     scrollup
        !          81341: 
        !          81342: ////////
        !          81343: /
        !          81344: / scrollup - scroll display upwards
        !          81345: /
        !          81346: ////////
        !          81347: 
        !          81348: scrollup:
        !          81349:        push    ds
        !          81350:        push    si
        !          81351:        push    cx
        !          81352:        mov     ds, MM_BASE(bp)
        !          81353:        movb    bl, MM_BROW(bp)
        !          81354:        shlb    bl, $1
        !          81355:        mov     di, cs:rowtab(bx)
        !          81356:        mov     si, cs:rowtab+2(bx)
        !          81357:        movb    bl, ROW
        !          81358:        shlb    bl, $1
        !          81359:        mov     cx, cs:rowtab(bx)
        !          81360:        push    cx
        !          81361:        sub     cx, di
        !          81362:        shr     cx, $1
        !          81363:        push    si
        !          81364:        push    di
        !          81365:        push    cx
        !          81366:        rep
        !          81367:        movsw
        !          81368:        pop     cx
        !          81369:        pop     di
        !          81370:        pop     si
        !          81371:        add     si, $BANKSZ
        !          81372:        add     di, $BANKSZ
        !          81373:        rep
        !          81374:        movsw
        !          81375:        mov     ax, MM_FLIP(bp)
        !          81376:        and     ax, MM_MASK(bp)
        !          81377:        pop     di
        !          81378:        push    di
        !          81379:        mov     cx, $NRB4
        !          81380:        rep
        !          81381:        stosw
        !          81382:        pop     di
        !          81383:        add     di, $BANKSZ
        !          81384:        mov     cx, $NRB4
        !          81385:        rep
        !          81386:        stosw
        !          81387:        pop     cx
        !          81388:        pop     si
        !          81389:        pop     ds
        !          81390:        jmp     ewait
        !          81391: 
        !          81392: ////////
        !          81393: /
        !          81394: / repos - reposition cursor
        !          81395: /
        !          81396: ////////
        !          81397: 
        !          81398: repos: movb    bl, ROW                 / reposition to ROW and COL
        !          81399:        shlb    bl, $1
        !          81400:        mov     POS, cs:rowtab(bx)
        !          81401:        movb    bl, COL
        !          81402:        cmpb    MM_NCOL(bp), $40
        !          81403:        jne     0f
        !          81404:        shlb    bl, $1
        !          81405: 0:     add     POS, bx
        !          81406: /      jmp     eval
        !          81407: 
        !          81408: ////////
        !          81409: /
        !          81410: / eval - evaluate input character
        !          81411: /
        !          81412: ////////
        !          81413: 
        !          81414: eval:  jcxz    ewait0
        !          81415:        dec     cx                              / evaluate next char
        !          81416:        lodsb
        !          81417:        movb    bl, al
        !          81418:        shlb    bl, $1
        !          81419:        ijmp    cs:asctab(bx)
        !          81420: 
        !          81421: ewait0:        call    exit
        !          81422:        jcxz    0b
        !          81423:        dec     cx
        !          81424:        lodsb
        !          81425:        movb    bl, al
        !          81426:        shlb    bl, $1
        !          81427:        ijmp    cs:asctab(bx)
        !          81428: 
        !          81429: ////////
        !          81430: /
        !          81431: / mmputc - put character on screen
        !          81432: /
        !          81433: ////////
        !          81434: 
        !          81435: mmputc:        cmpb    MM_NCOL(bp), $40
        !          81436:        jne     putc8
        !          81437: 
        !          81438: 
        !          81439: putc16:        push    ds
        !          81440:        push    si
        !          81441:        subb    ah, ah
        !          81442:        shlb    al, $1
        !          81443:        shl     ax, $1
        !          81444:        shl     ax, $1
        !          81445:        shl     ax, $1
        !          81446:        add     ax, $fontw_
        !          81447:        mov     si, ax
        !          81448:        mov     ax, cs
        !          81449:        mov     ds, ax
        !          81450:        mov     bx, $BANKSZ-2
        !          81451: 
        !          81452:        lodsw                           / row 0
        !          81453:        xor     ax, MM_FLIP(bp)
        !          81454:        and     ax, MM_MASK(bp)
        !          81455:        stosw
        !          81456:        push    di                      / save position for next char
        !          81457: #ifdef TECMAR
        !          81458:        mov     es:(bx,di), ax
        !          81459:        add     di, $78
        !          81460: #endif
        !          81461:        lodsw                           / row 1
        !          81462:        xor     ax, MM_FLIP(bp)
        !          81463:        and     ax, MM_MASK(bp)
        !          81464: #ifdef TECMAR
        !          81465:        stosw
        !          81466: #endif
        !          81467:        mov     es:(bx,di), ax
        !          81468:        add     di, $78
        !          81469: 
        !          81470:        lodsw                           / row 2
        !          81471:        xor     ax, MM_FLIP(bp)
        !          81472:        and     ax, MM_MASK(bp)
        !          81473:        stosw
        !          81474: #ifdef TECMAR
        !          81475:        mov     es:(bx,di), ax
        !          81476:        add     di, $78
        !          81477: #endif
        !          81478: 
        !          81479:        lodsw                           / row 3
        !          81480:        xor     ax, MM_FLIP(bp)
        !          81481:        and     ax, MM_MASK(bp)
        !          81482: #ifdef TECMAR
        !          81483:        stosw
        !          81484: #endif
        !          81485:        mov     es:(bx,di), ax
        !          81486:        add     di, $78
        !          81487: 
        !          81488:        lodsw                           / row 4
        !          81489:        xor     ax, MM_FLIP(bp)
        !          81490:        and     ax, MM_MASK(bp)
        !          81491:        stosw
        !          81492: #ifdef TECMAR
        !          81493:        mov     es:(bx,di), ax
        !          81494:        add     di, $78
        !          81495: #endif
        !          81496: 
        !          81497:        lodsw                           / row 5
        !          81498:        xor     ax, MM_FLIP(bp)
        !          81499:        and     ax, MM_MASK(bp)
        !          81500: #ifdef TECMAR
        !          81501:        stosw
        !          81502: #endif
        !          81503:        mov     es:(bx,di), ax
        !          81504:        add     di, $78
        !          81505: 
        !          81506:        lodsw                           / row 6
        !          81507:        xor     ax, MM_FLIP(bp)
        !          81508:        and     ax, MM_MASK(bp)
        !          81509:        stosw
        !          81510: #ifdef TECMAR
        !          81511:        mov     es:(bx,di), ax
        !          81512:        add     di, $78
        !          81513: #endif
        !          81514:        lodsw                           / row 7
        !          81515:        or      ax, MM_ULINE(bp)
        !          81516:        xor     ax, MM_FLIP(bp)
        !          81517:        and     ax, MM_MASK(bp)
        !          81518: #ifdef TECMAR
        !          81519:        stosw
        !          81520: #endif
        !          81521:        mov     es:(bx,di), ax
        !          81522: 
        !          81523: 
        !          81524:        pop     di                      / restore position for next char
        !          81525:        pop     si
        !          81526:        pop     ds
        !          81527: 
        !          81528:        sub     bx, bx
        !          81529:        incb    COL
        !          81530:        cmpb    COL, MM_NCOL(bp)
        !          81531:        jge     0f
        !          81532:        jcxz    ewait1
        !          81533:        dec     cx
        !          81534:        lodsb
        !          81535:        movb    bl, al
        !          81536:        shlb    bl, $1
        !          81537:        ijmp    cs:asctab(bx)
        !          81538: 
        !          81539: 0:     subb    COL, COL
        !          81540:        incb    ROW
        !          81541:        cmpb    ROW, MM_EROW(bp)
        !          81542:        jg      0f
        !          81543:        jmp     repos
        !          81544: 
        !          81545: 0:     movb    ROW, MM_EROW(bp)
        !          81546:        jmp     scrollup
        !          81547: 
        !          81548: ewait1:        jmp     ewait
        !          81549: 
        !          81550: putc8: push    ds
        !          81551:        push    si
        !          81552:        subb    ah, ah
        !          81553:        shlb    al, $1
        !          81554:        shl     ax, $1
        !          81555:        shl     ax, $1
        !          81556:        add     ax, $0xFA6E
        !          81557:        mov     si, ax
        !          81558:        mov     ax, $0xF000
        !          81559:        mov     ds, ax
        !          81560:        mov     bx, $BANKSZ-1
        !          81561: 
        !          81562:        lodsw
        !          81563:        xor     ax, MM_FLIP(bp)
        !          81564:        stosb                           / row 0
        !          81565:        push    di                      / save position for next char
        !          81566: #ifdef TECMAR
        !          81567:        movb    es:(bx,di), al
        !          81568:        movb    es:79(di), ah           / row 1
        !          81569:        movb    es:80(bx,di), ah
        !          81570:        add     di, $79+80
        !          81571: #else
        !          81572:        movb    es:(bx,di), ah          / row 1
        !          81573:        add     di, $79
        !          81574: #endif
        !          81575: 
        !          81576:        lodsw
        !          81577:        xor     ax, MM_FLIP(bp)
        !          81578:        stosb                           / row 2
        !          81579: #ifdef TECMAR
        !          81580:        movb    es:(bx,di), al
        !          81581:        movb    es:79(di), ah
        !          81582:        movb    es:80(bx,di), ah        / row 3
        !          81583:        add     di, $79+80
        !          81584: #else
        !          81585:        movb    es:(bx,di), ah          / row 3
        !          81586:        add     di, $79
        !          81587: #endif
        !          81588: 
        !          81589:        lodsw
        !          81590:        xor     ax, MM_FLIP(bp)
        !          81591:        stosb                           / row 4
        !          81592: #ifdef TECMAR
        !          81593:        movb    es:(bx,di), al
        !          81594:        movb    es:79(di), ah           / row 5
        !          81595:        movb    es:80(bx,di), ah
        !          81596:        add     di, $79+80
        !          81597: #else
        !          81598:        movb    es:(bx,di), ah          / row 5
        !          81599:        add     di, $79
        !          81600: #endif
        !          81601: 
        !          81602:        lodsw
        !          81603:        orb     ah, MM_ULINE(bp)
        !          81604:        xor     ax, MM_FLIP(bp)
        !          81605:        stosb                           / row 6
        !          81606: #ifdef TECMAR
        !          81607:        movb    es:(bx,di), al
        !          81608:        movb    es:79(di), ah
        !          81609:        movb    es:80(bx,di), ah
        !          81610: #else
        !          81611:        movb    es:(bx,di), ah          / row 7
        !          81612: #endif
        !          81613: 
        !          81614:        pop     di                      / restore position for next char
        !          81615:        pop     si
        !          81616:        pop     ds
        !          81617: 
        !          81618:        sub     bx, bx
        !          81619:        incb    COL
        !          81620:        cmpb    COL, MM_NCOL(bp)
        !          81621:        jge     0f
        !          81622:        jcxz    ewait
        !          81623:        dec     cx
        !          81624:        lodsb
        !          81625:        movb    bl, al
        !          81626:        shlb    bl, $1
        !          81627:        ijmp    cs:asctab(bx)
        !          81628: 
        !          81629: 0:     subb    COL, COL
        !          81630:        incb    ROW
        !          81631:        cmpb    ROW, MM_EROW(bp)
        !          81632:        jg      0f
        !          81633:        jmp     repos
        !          81634: 
        !          81635: 0:     movb    ROW, MM_EROW(bp)
        !          81636:        jmp     scrollup
        !          81637: 
        !          81638: ////////
        !          81639: /
        !          81640: / Ewait - wait for next input char to evaluate
        !          81641: /
        !          81642: ////////
        !          81643: 
        !          81644: ewait: call    exit
        !          81645:        jcxz    ewait
        !          81646:        dec     cx
        !          81647:        lodsb
        !          81648:        movb    bl, al
        !          81649:        shlb    bl, $1
        !          81650:        ijmp    cs:asctab(bx)
        !          81651: 
        !          81652: ////////
        !          81653: /
        !          81654: / mm_cr - carriage return
        !          81655: /
        !          81656: /      Moves the active position to first position of current display line.
        !          81657: /
        !          81658: ////////
        !          81659: 
        !          81660: mm_cr: subb    COL, COL
        !          81661:        movb    bl, ROW
        !          81662:        shlb    bl, $1
        !          81663:        mov     POS, cs:rowtab(bx)
        !          81664:        jcxz    ewait
        !          81665:        dec     cx
        !          81666:        lodsb
        !          81667:        movb    bl, al
        !          81668:        shlb    bl, $1
        !          81669:        ijmp    cs:asctab(bx)
        !          81670: 
        !          81671: ////////
        !          81672: /
        !          81673: / mm_cub - cursor backwards
        !          81674: /
        !          81675: ////////
        !          81676: 
        !          81677: mm_cub:        decb    COL
        !          81678:        jge     0f
        !          81679:        movb    COL, MM_NCOL(bp)
        !          81680:        decb    COL
        !          81681:        decb    ROW
        !          81682:        cmpb    ROW, MM_BROW(bp)
        !          81683:        jge     0f
        !          81684:        subb    COL, COL
        !          81685:        movb    ROW, MM_BROW(bp)
        !          81686: 0:     jmp     repos
        !          81687: 
        !          81688: ////////
        !          81689: /
        !          81690: / Esc state - entered when last char was ESC - transient state.
        !          81691: /
        !          81692: ////////
        !          81693: 
        !          81694: 0:     call    exit
        !          81695: mm_esc:        jcxz    0b
        !          81696:        dec     cx
        !          81697:        lodsb
        !          81698:        movb    MM_N1(bp), ZERO
        !          81699:        movb    MM_N2(bp), ZERO
        !          81700:        movb    bl, al
        !          81701:        shlb    bl, $1
        !          81702:        ijmp    cs:esctab(bx)
        !          81703: 
        !          81704: ////////
        !          81705: /
        !          81706: / Csi_n1 state - entered when last two chars were ESC [
        !          81707: /
        !          81708: /      Action: Evaluates numeric chars as numeric parameter 1.
        !          81709: /
        !          81710: ////////
        !          81711: 
        !          81712: 0:     call    exit
        !          81713: csi_n1:        jcxz    0b
        !          81714:        dec     cx
        !          81715:        lodsb
        !          81716:        cmpb    al, $SEMIC
        !          81717:        je      csi_n2
        !          81718:        movb    bl, al
        !          81719:        subb    bl, $AZERO
        !          81720:        cmpb    bl, $9
        !          81721:        ja      csival
        !          81722:        shlb    MM_N1(bp), $1   / n1 * 2
        !          81723:        movb    al, MM_N1(bp)   / n1 * 2
        !          81724:        shlb    al, $1          / n1 * 4
        !          81725:        shlb    al, $1          / n1 * 8
        !          81726:        addb    al, MM_N1(bp)   / n1 * 10
        !          81727:        addb    al, bl          / n1 * 10 + digit
        !          81728:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          81729:        jmp     csi_n1
        !          81730: 
        !          81731: ////////
        !          81732: /
        !          81733: / Csi_n2 state - entered after input sequence ESC [ n ;
        !          81734: /
        !          81735: ////////
        !          81736: 
        !          81737: 0:     call    exit
        !          81738: csi_n2:        jcxz    0b
        !          81739:        dec     cx
        !          81740:        lodsb
        !          81741:        movb    bl, al
        !          81742:        subb    bl, $AZERO
        !          81743:        cmpb    bl, $9
        !          81744:        ja      csival
        !          81745:        shlb    MM_N2(bp), $1   / n2 * 2
        !          81746:        movb    al, MM_N2(bp)   / n2 * 2
        !          81747:        shlb    al, $1          / n2 * 4
        !          81748:        shlb    al, $1          / n2 * 8
        !          81749:        addb    al, MM_N2(bp)   / n2 * 10
        !          81750:        addb    al, bl          / n2 * 10 + digit
        !          81751:        movb    MM_N2(bp), al   / n2 = (n2 * 10) + digit
        !          81752:        jmp     csi_n2
        !          81753: 
        !          81754: csival:        movb    bl, al
        !          81755:        shlb    bl, $1
        !          81756:        ijmp    cs:csitab(bx)
        !          81757: 
        !          81758: ////////
        !          81759: /
        !          81760: / Csi_gt state - entered after input sequence ESC [ >
        !          81761: /      
        !          81762: ////////
        !          81763: 
        !          81764: 0:     call    exit
        !          81765: csi_gt:        jcxz    0b
        !          81766:        dec     cx
        !          81767:        lodsb
        !          81768:        movb    bl, al
        !          81769:        subb    bl, $AZERO
        !          81770:        cmpb    bl, $9
        !          81771:        ja      0f
        !          81772:        shlb    MM_N1(bp), $1   / n1 * 2
        !          81773:        movb    al, MM_N1(bp)   / n1 * 2
        !          81774:        shlb    al, $1          / n1 * 4
        !          81775:        shlb    al, $1          / n1 * 8
        !          81776:        addb    al, MM_N1(bp)   / n1 * 10
        !          81777:        addb    al, bl          / n1 * 10 + digit
        !          81778:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          81779:        jmp     csi_gt
        !          81780: 
        !          81781: 0:     cmpb    al, $HLOWER
        !          81782:        je      mm_cgh
        !          81783:        cmpb    al, $LLOWER
        !          81784:        je      mm_cgl
        !          81785:        jmp     eval
        !          81786: 
        !          81787: ////////
        !          81788: /
        !          81789: / Csi_q state - entered after input sequence ESC [ ?
        !          81790: /      
        !          81791: ////////
        !          81792: 
        !          81793: 0:     call    exit
        !          81794: csi_q: jcxz    0b
        !          81795:        dec     cx
        !          81796:        lodsb
        !          81797:        movb    bl, al
        !          81798:        subb    bl, $AZERO
        !          81799:        cmpb    bl, $9
        !          81800:        ja      0f
        !          81801:        shlb    MM_N1(bp), $1   / n1 * 2
        !          81802:        movb    al, MM_N1(bp)   / n1 * 2
        !          81803:        shlb    al, $1          / n1 * 4
        !          81804:        shlb    al, $1          / n1 * 8
        !          81805:        addb    al, MM_N1(bp)   / n1 * 10
        !          81806:        addb    al, bl          / n1 * 10 + digit
        !          81807:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          81808:        jmp     csi_q
        !          81809: 
        !          81810: 0:     cmpb    al, $HLOWER
        !          81811:        je      mm_cqh
        !          81812:        cmpb    al, $LLOWER
        !          81813:        je      mm_cql
        !          81814:        jmp     eval
        !          81815: 
        !          81816: ////////
        !          81817: /
        !          81818: / mm_cbt - cursor backward tabulation
        !          81819: /
        !          81820: /      Moves the active position horizontally in the backward direction
        !          81821: /      to the preceding in a series of predetermined positions.
        !          81822: /
        !          81823: ////////
        !          81824: 
        !          81825: mm_cbt:        orb     COL, $7                 / calculate next tab stop
        !          81826:        incb    COL
        !          81827:        subb    COL, $16                / step back two tab positions
        !          81828:        jg      0f
        !          81829:        subb    COL, COL                / cannot step past column 0
        !          81830: 0:     jmp     repos                   / reposition cursor
        !          81831: 
        !          81832: ////////
        !          81833: /
        !          81834: / mm_cgh - process ESC [ > N1 h escape sequence
        !          81835: /
        !          81836: /      Recognized sequences:   ESC [ > 13 h    -- Set CRT saver enabled.
        !          81837: /
        !          81838: ////////
        !          81839: 
        !          81840: mm_cgh:        cmpb    MM_N1(bp), $13
        !          81841:        jne     0f
        !          81842:        mov     ss:mmcrtsav_, $1
        !          81843: 0:     jmp     eval
        !          81844: 
        !          81845: ////////
        !          81846: /
        !          81847: / mm_cgl - process ESC [ > N1 l escape sequence
        !          81848: /
        !          81849: /      Recognized sequences:   ESC [ > 13 l    -- Reset CRT saver.
        !          81850: /
        !          81851: ////////
        !          81852: 
        !          81853: mm_cgl:        cmpb    MM_N1(bp), $13
        !          81854:        jne     0f
        !          81855:        mov     ss:mmcrtsav_, $0
        !          81856: 0:     jmp     eval
        !          81857: 
        !          81858: ////////
        !          81859: /
        !          81860: / mm_cha - cursor horizontal absolute
        !          81861: /
        !          81862: /      Advances the active position forward or backward along the active line
        !          81863: /      to the character position specified by the parameter.
        !          81864: /      A parameter value of zero or one moves the active position to the
        !          81865: /      first character position of the active line.
        !          81866: /      A parameter value of N moves the active position to character position
        !          81867: /      N of the active line.
        !          81868: /
        !          81869: ////////
        !          81870: 
        !          81871: mm_cha:        movb    COL, MM_N1(bp)
        !          81872:        decb    COL
        !          81873:        jge     0f
        !          81874:        subb    COL, COL
        !          81875: 0:     cmpb    COL, MM_NCOL(bp)
        !          81876:        jb      0f
        !          81877:        movb    COL, MM_NCOL(bp)
        !          81878:        decb    COL
        !          81879: 0:     jmp     repos                   / reposition cursor
        !          81880: 
        !          81881: 
        !          81882: ////////
        !          81883: /
        !          81884: / mm_cht - cursor horizontal tabulation
        !          81885: /
        !          81886: /      Advances the active position horizontally to the next or following
        !          81887: /      in a series of predetermined positions.
        !          81888: /
        !          81889: ////////
        !          81890: 
        !          81891: mm_cht:        mov     bx, $BANKSZ
        !          81892:        push    cx
        !          81893:        push    si
        !          81894:        sub     cx, cx
        !          81895:        movb    cl, COL
        !          81896:        orb     cl, $7
        !          81897:        incb    cl
        !          81898:        subb    cl, COL
        !          81899:        addb    COL, cl
        !          81900: 
        !          81901:        mov     si, MM_MASK(bp)
        !          81902:        cmpb    MM_NCOL(bp), $80
        !          81903:        jne     0f
        !          81904:        mov     si, $-1
        !          81905:        inc     cx
        !          81906:        shr     cx, $1
        !          81907: 
        !          81908: 0:     mov     ax, MM_FLIP(bp)
        !          81909:        and     ax, si
        !          81910: #ifdef TECMAR
        !          81911:        stosw                           / row 0
        !          81912:        mov     es:[NHB*0]-2(di,bx), ax
        !          81913:        mov     es:[NHB*1]-2(di), ax    / row 1
        !          81914:        mov     es:[NHB*1]-2(di,bx), ax
        !          81915:        mov     es:[NHB*2]-2(di), ax    / row 2
        !          81916:        mov     es:[NHB*2]-2(di,bx), ax
        !          81917:        mov     es:[NHB*3]-2(di), ax    / row 3
        !          81918:        mov     es:[NHB*3]-2(di,bx), ax
        !          81919:        mov     es:[NHB*4]-2(di), ax    / row 4
        !          81920:        mov     es:[NHB*4]-2(di,bx), ax
        !          81921:        mov     es:[NHB*5]-2(di), ax    / row 5
        !          81922:        mov     es:[NHB*5]-2(di,bx), ax
        !          81923:        mov     es:[NHB*6]-2(di), ax    / row 6
        !          81924:        mov     es:[NHB*6]-2(di,bx), ax
        !          81925:        or      ax, MM_ULINE(bp)
        !          81926:        and     ax, si
        !          81927:        mov     es:[NHB*7]-2(di), ax    / row 7
        !          81928:        mov     es:[NHB*7]-2(di,bx), ax
        !          81929: #else
        !          81930:        stosw                           / row 0
        !          81931:        mov     es:[NHB*0]-2(di,bx), ax / row 1
        !          81932:        mov     es:[NHB*1]-2(di), ax    / row 2
        !          81933:        mov     es:[NHB*1]-2(di,bx), ax / row 3
        !          81934:        mov     es:[NHB*2]-2(di), ax    / row 4
        !          81935:        mov     es:[NHB*2]-2(di,bx), ax / row 5
        !          81936:        mov     es:[NHB*3]-2(di), ax    / row 6
        !          81937:        or      ax, MM_ULINE(bp)
        !          81938:        and     ax, si
        !          81939:        mov     es:[NHB*3]-2(di,bx), ax / row 7
        !          81940: #endif
        !          81941:        loop    0b
        !          81942:        sub     bx, bx
        !          81943:        pop     si
        !          81944:        pop     cx
        !          81945:        cmpb    COL, MM_NCOL(bp)
        !          81946:        jl      0f
        !          81947:        subb    COL, MM_NCOL(bp)
        !          81948:        incb    ROW
        !          81949:        cmpb    ROW, MM_EROW(bp)
        !          81950:        jle     0f
        !          81951:        movb    ROW, MM_EROW(bp)
        !          81952:        jmp     scrollup
        !          81953: 0:     jmp     repos
        !          81954: 
        !          81955: ////////
        !          81956: /
        !          81957: / mm_cpl - cursor preceding line
        !          81958: /
        !          81959: /      Moves the active position to the first position of the preceding
        !          81960: /      display line.
        !          81961: /
        !          81962: ////////
        !          81963: 
        !          81964: mm_cpl:        subb    COL, COL
        !          81965:        decb    ROW
        !          81966:        cmpb    ROW, MM_BROW(bp)
        !          81967:        jnb     0f
        !          81968:        movb    ROW, MM_BROW(bp)
        !          81969:        jmp     scrolldown
        !          81970: 0:     jmp     repos                   / reposition cursor
        !          81971: 
        !          81972: ////////
        !          81973: /
        !          81974: / mm_cqh - process ESC [ ? N1 h escape sequence
        !          81975: /
        !          81976: /      Recognized sequences:   ESC [ ? 7 h     -- Set wraparound.
        !          81977: /
        !          81978: ////////
        !          81979: 
        !          81980: mm_cqh:
        !          81981:        cmpb    MM_N1(bp), $7           / Wraparound.
        !          81982:        jne     0f
        !          81983:        movb    MM_WRAP(bp), $1
        !          81984: 0:     jmp     eval
        !          81985: 
        !          81986: ////////
        !          81987: /
        !          81988: / mm_cql - process ESC [ ? N1 l escape sequence
        !          81989: /
        !          81990: /      Recognized sequences:   ESC [ ? 7 l     -- Reset wraparound.
        !          81991: /
        !          81992: ////////
        !          81993: 
        !          81994: mm_cql:
        !          81995:        cmpb    MM_N1(bp), $7           / No wraparound.
        !          81996:        jne     0f
        !          81997:        movb    MM_WRAP(bp), $0
        !          81998: 0:     jmp     eval
        !          81999: 
        !          82000: ////////
        !          82001: /
        !          82002: / mm_cud - cursor down
        !          82003: /
        !          82004: /      Moves the active position downward without altering the
        !          82005: /      horizontal position.
        !          82006: /
        !          82007: ////////
        !          82008: 
        !          82009: mm_cud:        incb    ROW
        !          82010:        cmpb    ROW, MM_EROW(bp)
        !          82011:        jna     0f
        !          82012:        movb    ROW, MM_EROW(bp)
        !          82013: 0:     jmp     repos                   / reposition cursor
        !          82014: 
        !          82015: ////////
        !          82016: /
        !          82017: / mm_cuf - cursor forward
        !          82018: /
        !          82019: /      Moves the active position in the forward direction.
        !          82020: /
        !          82021: ////////
        !          82022: 
        !          82023: mm_cuf:        incb    COL
        !          82024:        cmpb    COL, MM_NCOL(bp)
        !          82025:        jb      0f
        !          82026:        subb    COL, MM_NCOL(bp)
        !          82027:        incb    ROW
        !          82028:        cmpb    ROW, MM_EROW(bp)
        !          82029:        jna     0f
        !          82030:        movb    ROW, MM_EROW(bp)
        !          82031:        movb    COL, MM_NCOL(bp)
        !          82032:        decb    COL
        !          82033: 0:     jmp     repos
        !          82034: 
        !          82035: ////////
        !          82036: /
        !          82037: / mm_cup - cursor position
        !          82038: /
        !          82039: /      Moves the active position to the position specified by two parameters.
        !          82040: /      The first parameter (mm_n1) specifies the vertical position (MM_ROW(bp)).
        !          82041: /      The second parameter (mm_n2) specifies the horizontal position (MM_COL(bp)).
        !          82042: /      A parameter value of 0 or 1 for the first or second parameter
        !          82043: /      moves the active position to the first line or column in the
        !          82044: /      display respectively.
        !          82045: /
        !          82046: ////////
        !          82047: 
        !          82048: mm_cup:        movb    ROW, MM_N1(bp)
        !          82049:        decb    ROW
        !          82050:        jg      0f
        !          82051:        subb    ROW, ROW
        !          82052: 0:     addb    ROW, MM_BROW(bp)
        !          82053:        cmpb    ROW, MM_EROW(bp)
        !          82054:        jb      0f
        !          82055:        movb    ROW, MM_EROW(bp)
        !          82056: 0:     movb    COL, MM_N2(bp)
        !          82057:        decb    COL
        !          82058:        jg      0f
        !          82059:        subb    COL, COL
        !          82060: 0:     cmpb    COL, MM_NCOL(bp)
        !          82061:        jb      0f
        !          82062:        movb    COL, MM_NCOL(bp)
        !          82063:        decb    COL
        !          82064: 0:     jmp     repos                   / reposition cursor
        !          82065: 
        !          82066: ////////
        !          82067: /
        !          82068: / mm_cuu - cursor up
        !          82069: /
        !          82070: /      Moves the active position upward without altering the horizontal
        !          82071: /      position.
        !          82072: /
        !          82073: ////////
        !          82074: 
        !          82075: mm_cuu:        decb    ROW
        !          82076:        cmpb    ROW, MM_BROW(bp)
        !          82077:        jge     0f
        !          82078:        movb    ROW, MM_BROW(bp)
        !          82079: 0:     jmp     repos                   / reposition cursor
        !          82080: 
        !          82081: ////////
        !          82082: /
        !          82083: / mm_dl - delete line
        !          82084: /
        !          82085: /      Removes the contents of the active line.
        !          82086: /      The contents of all following lines are shifted in a block
        !          82087: /      toward the active line.
        !          82088: /
        !          82089: ////////
        !          82090: 
        !          82091: mm_dl: push    ds
        !          82092:        push    si
        !          82093:        push    cx
        !          82094:        mov     ds, MM_BASE(bp)
        !          82095:        movb    bl, ROW
        !          82096:        shlb    bl, $1
        !          82097:        mov     di, cs:rowtab(bx)
        !          82098:        mov     si, cs:rowtab+2(bx)
        !          82099:        movb    bl, MM_EROW(bp)
        !          82100:        shlb    bl, $1
        !          82101:        mov     cx, cs:rowtab(bx)
        !          82102:        sub     cx, di
        !          82103:        jle     0f
        !          82104:        shr     cx, $1
        !          82105:        push    si
        !          82106:        push    di
        !          82107:        push    cx
        !          82108:        rep
        !          82109:        movsw
        !          82110:        pop     cx
        !          82111:        pop     di
        !          82112:        pop     si
        !          82113:        add     si, $BANKSZ
        !          82114:        add     di, $BANKSZ
        !          82115:        rep
        !          82116:        movsw
        !          82117:        mov     di, cs:rowtab(bx)
        !          82118:        push    di
        !          82119:        mov     cx, $NRB4
        !          82120:        mov     ax, MM_FLIP(bp)
        !          82121:        and     ax, MM_MASK(bp)
        !          82122:        rep
        !          82123:        stosw
        !          82124:        pop     di
        !          82125:        add     di, $BANKSZ
        !          82126:        mov     cx, $NRB4
        !          82127:        rep
        !          82128:        stosw
        !          82129:        subb    COL, COL
        !          82130: 0:     pop     cx
        !          82131:        pop     si
        !          82132:        pop     ds
        !          82133:        jmp     repos
        !          82134: 
        !          82135: ////////
        !          82136: /
        !          82137: / mm_dmi - disable manual input
        !          82138: /
        !          82139: /      Set flag preventing keyboard input.
        !          82140: /
        !          82141: ////////
        !          82142: 
        !          82143: mm_dmi:
        !          82144:        mov     ss:islock_, $1
        !          82145:        jmp     eval
        !          82146: 
        !          82147: ////////
        !          82148: /
        !          82149: / mm_ea - erase in area
        !          82150: /
        !          82151: /      Erase some or all of the characters in the currently active area
        !          82152: /      according to the parameter:
        !          82153: /              0 - erase from active position to end inclusive (default)
        !          82154: /              1 - erase from start to active position inclusive
        !          82155: /              2 - erase all of active area
        !          82156: /
        !          82157: ////////
        !          82158: 
        !          82159: mm_ea: movb    al, MM_N1(bp)
        !          82160:        cmpb    al, $0
        !          82161:        jne     0f
        !          82162:        movb    bl, MM_EROW(bp)
        !          82163:        jmp     mm_e0
        !          82164: 0:     cmpb    al, $1
        !          82165:        jne     0f
        !          82166:        movb    bl, MM_BROW(bp)
        !          82167:        jmp     mm_e1
        !          82168: 0:     subb    COL, COL
        !          82169:        movb    ROW, MM_BROW(bp)
        !          82170:        movb    bl, ROW
        !          82171:        shlb    bl, $1
        !          82172:        mov     POS, cs:rowtab(bx)
        !          82173:        movb    bl, MM_EROW(bp)
        !          82174:        subb    bl, ROW
        !          82175:        jmp     mm_e2
        !          82176: 
        !          82177: ////////
        !          82178: /
        !          82179: / mm_ed - erase in display
        !          82180: /
        !          82181: /      Erase some or all of the characters in the display according to the
        !          82182: /      parameter
        !          82183: /              0 - erase from active position to end inclusive (default)
        !          82184: /              1 - erase from start to active position inclusive
        !          82185: /              2 - erase all of display
        !          82186: /
        !          82187: ////////
        !          82188: 
        !          82189: mm_ed: movb    al, MM_N1(bp)
        !          82190:        cmpb    al, $0
        !          82191:        jne     0f
        !          82192:        movb    bl, MM_LROW(bp)
        !          82193:        jmp     mm_e0
        !          82194: 0:     cmpb    al, $1
        !          82195:        jne     0f
        !          82196:        subb    bl, bl
        !          82197:        jmp     mm_e1
        !          82198: 0:     subb    COL, COL
        !          82199:        movb    ROW, MM_BROW(bp)
        !          82200:        sub     POS, POS
        !          82201:        movb    bl, MM_LROW(bp)
        !          82202:        jmp     mm_e2
        !          82203: 
        !          82204: ////////
        !          82205: /
        !          82206: / mm_el - erase in line
        !          82207: /
        !          82208: /      Erase some or all of the characters in the line according to the
        !          82209: /      parameter:
        !          82210: /              0 - erase from active position to end inclusive (default)
        !          82211: /              1 - erase from start to active position inclusive
        !          82212: /              2 - erase entire line
        !          82213: /
        !          82214: ////////
        !          82215: 
        !          82216: mm_el: movb    al, MM_N1(bp)
        !          82217:        movb    bl, ROW
        !          82218:        cmpb    al, $0
        !          82219:        je      mm_e0
        !          82220:        cmpb    al, $1
        !          82221:        je      mm_e1
        !          82222:        shlb    bl, $1
        !          82223:        mov     POS, cs:rowtab(bx)
        !          82224:        subb    COL, COL
        !          82225:        subb    bl, bl
        !          82226: /      jmp     mm_e2
        !          82227: 
        !          82228: ////////
        !          82229: /
        !          82230: / mm_e2 - erase from POS for BL rows (minimum 1 row)
        !          82231: /
        !          82232: ////////
        !          82233: 
        !          82234: mm_e2: push    cx
        !          82235:        mov     ax, MM_FLIP(bp)
        !          82236:        and     ax, MM_MASK(bp)
        !          82237: 0:     mov     cx, $NRB4
        !          82238:        rep
        !          82239:        stosw
        !          82240:        add     di, $BANKSZ-NRB2
        !          82241:        mov     cx, $NRB4
        !          82242:        rep
        !          82243:        stosw
        !          82244:        sub     di, $BANKSZ
        !          82245:        decb    bl
        !          82246:        jge     0b
        !          82247:        pop     cx
        !          82248:        jmp     repos
        !          82249: 
        !          82250: ////////
        !          82251: /
        !          82252: / mm_e1 - erase from row BL to current cursor position.
        !          82253: /
        !          82254: ////////
        !          82255: 
        !          82256: mm_e1: push    dx
        !          82257:        push    cx
        !          82258:        push    di
        !          82259:        mov     ax, MM_FLIP(bp)
        !          82260:        and     ax, MM_MASK(bp)
        !          82261:        shlb    bl, $1
        !          82262:        mov     di, cs:rowtab(bx)
        !          82263:        movb    bl, ROW
        !          82264:        shlb    bl, $1
        !          82265:        mov     cx, cs:rowtab(bx)
        !          82266:        sub     cx, di
        !          82267:        jle     0f
        !          82268:        shr     cx, $1
        !          82269:        push    di
        !          82270:        push    cx
        !          82271:        rep
        !          82272:        stosw
        !          82273:        pop     cx
        !          82274:        pop     di
        !          82275:        add     di, $BANKSZ
        !          82276:        rep
        !          82277:        stosw
        !          82278: 0:     pop     cx
        !          82279:        movb    bl, ROW
        !          82280:        shlb    bl, $1
        !          82281:        mov     di, cs:rowtab(bx)
        !          82282:        sub     cx, di
        !          82283:        jle     0f
        !          82284: 
        !          82285:        mov     dx, di
        !          82286:        mov     bx, cx
        !          82287:        rep                     / erase row 0
        !          82288:        stosb
        !          82289:        add     dx, $80
        !          82290:        mov     di, dx
        !          82291:        mov     cx, bx
        !          82292: #ifdef TECMAR
        !          82293:        rep                     / erase row 1
        !          82294:        stosb
        !          82295:        add     dx, $80
        !          82296:        mov     di, dx
        !          82297:        mov     cx, bx
        !          82298: #endif
        !          82299:        rep                     / erase row 2
        !          82300:        stosb
        !          82301:        add     dx, $80
        !          82302:        mov     di, dx
        !          82303:        mov     cx, bx
        !          82304: #ifdef TECMAR
        !          82305:        rep                     / erase row 3
        !          82306:        stosb
        !          82307:        add     dx, $80
        !          82308:        mov     di, dx
        !          82309:        mov     cx, bx
        !          82310: #endif
        !          82311:        rep                     / erase row 4
        !          82312:        stosb
        !          82313:        add     dx, $80
        !          82314:        mov     di, dx
        !          82315:        mov     cx, bx
        !          82316: #ifdef TECMAR
        !          82317:        rep                     / erase row 5
        !          82318:        stosb
        !          82319:        add     dx, $80
        !          82320:        mov     di, dx
        !          82321:        mov     cx, bx
        !          82322: #endif
        !          82323:        rep                     / erase row 6
        !          82324:        stosb
        !          82325: #ifdef TECMAR
        !          82326:        add     dx, $80
        !          82327:        mov     di, dx
        !          82328:        mov     cx, bx
        !          82329:        rep                     / erase row 7
        !          82330:        stosb
        !          82331:        add     dx, $BANKSZ-560
        !          82332: #else
        !          82333:        add     dx, $BANKSZ-240
        !          82334: #endif
        !          82335:        mov     di, dx
        !          82336:        mov     cx, bx
        !          82337: #ifdef TECMAR
        !          82338:        rep                     / erase row 0
        !          82339:        stosb
        !          82340:        add     dx, $80
        !          82341:        mov     di, dx
        !          82342:        mov     cx, bx
        !          82343: #endif
        !          82344:        rep                     / erase row 1
        !          82345:        stosb
        !          82346:        add     dx, $80
        !          82347:        mov     di, dx
        !          82348:        mov     cx, bx
        !          82349: #ifdef TECMAR
        !          82350:        rep                     / erase row 2
        !          82351:        stosb
        !          82352:        add     dx, $80
        !          82353:        mov     di, dx
        !          82354:        mov     cx, bx
        !          82355: #endif
        !          82356:        rep                     / erase row 3
        !          82357:        stosb
        !          82358:        add     dx, $80
        !          82359:        mov     di, dx
        !          82360:        mov     cx, bx
        !          82361: #ifdef TECMAR
        !          82362:        rep                     / erase row 4
        !          82363:        stosb
        !          82364:        add     dx, $80
        !          82365:        mov     di, dx
        !          82366:        mov     cx, bx
        !          82367: #endif
        !          82368:        rep                     / erase row 5
        !          82369:        stosb
        !          82370:        add     dx, $80
        !          82371:        mov     di, dx
        !          82372:        mov     cx, bx
        !          82373: #ifdef TECMAR
        !          82374:        rep                     / erase row 6
        !          82375:        stosb
        !          82376:        add     dx, $80
        !          82377:        mov     di, dx
        !          82378:        mov     cx, bx
        !          82379: #endif
        !          82380:        rep                     / erase row 7
        !          82381:        stosb
        !          82382: 1:     sub     bx, bx
        !          82383:        pop     cx
        !          82384:        pop     dx
        !          82385:        jmp     repos
        !          82386: 
        !          82387: ////////
        !          82388: /
        !          82389: / mm_e0 - erase from current cursor position to row BL inclusive.
        !          82390: /
        !          82391: ////////
        !          82392: 
        !          82393: mm_e0: push    dx
        !          82394:        push    cx
        !          82395:        push    di
        !          82396:        mov     ax, MM_FLIP(bp)
        !          82397:        and     ax, MM_MASK(bp)
        !          82398:        shlb    bl, $1
        !          82399:        mov     cx, cs:rowtab+2(bx)
        !          82400:        movb    bl, ROW
        !          82401:        shlb    bl, $1
        !          82402:        mov     di, cs:rowtab+2(bx)
        !          82403:        sub     cx, di
        !          82404:        jle     0f
        !          82405:        shr     cx, $1
        !          82406:        push    di
        !          82407:        push    cx
        !          82408:        rep
        !          82409:        stosw
        !          82410:        pop     cx
        !          82411:        pop     di
        !          82412:        add     di, $BANKSZ
        !          82413:        rep
        !          82414:        stosw
        !          82415: 0:     pop     di
        !          82416:        sub     cx, cx
        !          82417:        movb    cl, MM_NCOL(bp)
        !          82418:        subb    cl, COL
        !          82419:        cmpb    MM_NCOL(bp), $40
        !          82420:        jne     0f
        !          82421:        shlb    cl, $1
        !          82422: 0:     mov     dx, di
        !          82423:        mov     bx, cx
        !          82424:        rep                     / erase row 0
        !          82425:        stosb
        !          82426:        add     dx, $80
        !          82427:        mov     di, dx
        !          82428:        mov     cx, bx
        !          82429: #ifdef TECMAR
        !          82430:        rep                     / erase row 1
        !          82431:        stosb
        !          82432:        add     dx, $80
        !          82433:        mov     di, dx
        !          82434:        mov     cx, bx
        !          82435: #endif
        !          82436:        rep                     / erase row 2
        !          82437:        stosb
        !          82438:        add     dx, $80
        !          82439:        mov     di, dx
        !          82440:        mov     cx, bx
        !          82441: #ifdef TECMAR
        !          82442:        rep                     / erase row 3
        !          82443:        stosb
        !          82444:        add     dx, $80
        !          82445:        mov     di, dx
        !          82446:        mov     cx, bx
        !          82447: #endif
        !          82448:        rep                     / erase row 4
        !          82449:        stosb
        !          82450:        add     dx, $80
        !          82451:        mov     di, dx
        !          82452:        mov     cx, bx
        !          82453: #ifdef TECMAR
        !          82454:        rep                     / erase row 5
        !          82455:        stosb
        !          82456:        add     dx, $80
        !          82457:        mov     di, dx
        !          82458:        mov     cx, bx
        !          82459: #endif
        !          82460:        rep                     / erase row 6
        !          82461:        stosb
        !          82462: #ifdef TECMAR
        !          82463:        add     dx, $80
        !          82464:        mov     di, dx
        !          82465:        mov     cx, bx
        !          82466:        rep                     / erase row 7
        !          82467:        stosb
        !          82468:        add     dx, $BANKSZ-560
        !          82469: #else
        !          82470:        add     dx, $BANKSZ-240
        !          82471: #endif
        !          82472:        mov     di, dx
        !          82473:        mov     cx, bx
        !          82474: #ifdef TECMAR
        !          82475:        rep                     / erase row 0
        !          82476:        stosb
        !          82477:        add     dx, $80
        !          82478:        mov     di, dx
        !          82479:        mov     cx, bx
        !          82480: #endif
        !          82481:        rep                     / erase row 1
        !          82482:        stosb
        !          82483:        add     dx, $80
        !          82484:        mov     di, dx
        !          82485:        mov     cx, bx
        !          82486: #ifdef TECMAR
        !          82487:        rep                     / erase row 2
        !          82488:        stosb
        !          82489:        add     dx, $80
        !          82490:        mov     di, dx
        !          82491:        mov     cx, bx
        !          82492: #endif
        !          82493:        rep                     / erase row 3
        !          82494:        stosb
        !          82495:        add     dx, $80
        !          82496:        mov     di, dx
        !          82497:        mov     cx, bx
        !          82498: #ifdef TECMAR
        !          82499:        rep                     / erase row 4
        !          82500:        stosb
        !          82501:        add     dx, $80
        !          82502:        mov     di, dx
        !          82503:        mov     cx, bx
        !          82504: #endif
        !          82505:        rep                     / erase row 5
        !          82506:        stosb
        !          82507:        add     dx, $80
        !          82508:        mov     di, dx
        !          82509:        mov     cx, bx
        !          82510: #ifdef TECMAR
        !          82511:        rep                     / erase row 6
        !          82512:        stosb
        !          82513:        add     dx, $80
        !          82514:        mov     di, dx
        !          82515:        mov     cx, bx
        !          82516: #endif
        !          82517:        rep                     / erase row 7
        !          82518:        stosb
        !          82519: 1:     sub     bx, bx
        !          82520:        pop     cx
        !          82521:        pop     dx
        !          82522:        jmp     repos
        !          82523: 
        !          82524: ////////
        !          82525: /
        !          82526: / mm_emi - enable manual input
        !          82527: /
        !          82528: /      Clear flag preventing keyboard input.
        !          82529: /
        !          82530: ////////
        !          82531: 
        !          82532: mm_emi:
        !          82533:        mov     ss:islock_, $0
        !          82534:        jmp     eval
        !          82535: 
        !          82536: ////////
        !          82537: /
        !          82538: / mm_il - insert line
        !          82539: /
        !          82540: /      Insert a erased line at the active line by shifting the contents
        !          82541: /      of the active line and all following lines away from the active line.
        !          82542: /      The contents of the last line in the scrolling region are removed.
        !          82543: /
        !          82544: ////////
        !          82545: 
        !          82546: scrolldown:
        !          82547: mm_il: push    ds
        !          82548:        push    si
        !          82549:        push    cx
        !          82550:        mov     ds, MM_BASE(bp)
        !          82551:        movb    bl, MM_EROW(bp)
        !          82552:        shlb    bl, $1
        !          82553:        mov     si, cs:rowtab(bx)
        !          82554:        mov     cx, si
        !          82555:        sub     si, $2
        !          82556:        mov     di, cs:rowtab+2(bx)
        !          82557:        sub     di, $2
        !          82558:        movb    bl, ROW
        !          82559:        shlb    bl, $1
        !          82560:        sub     cx, cs:rowtab(bx)
        !          82561:        jle     0f
        !          82562:        shr     cx, $1
        !          82563:        push    si
        !          82564:        push    di
        !          82565:        push    cx
        !          82566:        std
        !          82567:        rep
        !          82568:        movsw
        !          82569:        pop     cx
        !          82570:        pop     di
        !          82571:        pop     si
        !          82572:        add     si, $BANKSZ
        !          82573:        add     di, $BANKSZ
        !          82574:        rep
        !          82575:        movsw
        !          82576:        mov     di, cs:rowtab(bx)
        !          82577:        push    di
        !          82578:        mov     cx, $NRB4
        !          82579:        mov     ax, MM_FLIP(bp)
        !          82580:        and     ax, MM_MASK(bp)
        !          82581:        cld
        !          82582:        rep
        !          82583:        stosw
        !          82584:        pop     di
        !          82585:        add     di, $BANKSZ
        !          82586:        mov     cx, $NRB4
        !          82587:        rep
        !          82588:        stosw
        !          82589:        subb    COL, COL
        !          82590: 0:     pop     cx
        !          82591:        pop     si
        !          82592:        pop     ds
        !          82593:        jmp     repos
        !          82594: 
        !          82595: ////////
        !          82596: /
        !          82597: / mm_hpa - horizontal position absolute
        !          82598: /
        !          82599: /      Moves the active position within the active line to the position
        !          82600: /      specified by the parameter.  A parameter value of zero or one
        !          82601: /      moves the active position to the first position of the active line.
        !          82602: /
        !          82603: ////////
        !          82604: 
        !          82605: mm_hpa:        movb    COL, MM_N1(bp)
        !          82606:        decb    COL
        !          82607:        jg      0f
        !          82608:        subb    COL, COL
        !          82609: 0:     cmpb    COL, MM_NCOL(bp)
        !          82610:        jb      0f
        !          82611:        movb    COL, MM_NCOL(bp)
        !          82612:        decb    COL
        !          82613: 0:     jmp     repos                   / reposition cursor
        !          82614: 
        !          82615: ////////
        !          82616: /
        !          82617: / mm_hpr - horizontal position relative
        !          82618: /
        !          82619: /      Moves the active position forward the number of positions specified
        !          82620: /      by the parameter.  A parameter value of zero or one indicates a
        !          82621: /      single-position move.
        !          82622: /
        !          82623: ////////
        !          82624: 
        !          82625: mm_hpr:        movb    al, MM_N1(bp)
        !          82626:        orb     al, al
        !          82627:        jne     0f
        !          82628:        incb    al
        !          82629: 0:     addb    COL, al
        !          82630:        cmpb    COL, MM_NCOL(bp)
        !          82631:        jb      0f
        !          82632:        movb    COL, MM_NCOL(bp)
        !          82633:        decb    COL
        !          82634: 0:     jmp     repos                   / reposition cursor
        !          82635: 
        !          82636: ////////
        !          82637: /
        !          82638: / mm_hvp - horizontal and vertical position
        !          82639: /
        !          82640: /      Moves the active position to the position specified by two parameters.
        !          82641: /      The first parameter specifies the vertical position (MM_ROW(bp)).
        !          82642: /      The second parameter specifies the horizontal position (MM_COL(bp)).
        !          82643: /      A parameter value of zero or one moves the active position to the
        !          82644: /      first line or column in the display.
        !          82645: /
        !          82646: ////////
        !          82647: 
        !          82648: mm_hvp:        movb    ROW, MM_N1(bp)
        !          82649:        decb    ROW
        !          82650:        jg      0f
        !          82651:        subb    ROW, ROW
        !          82652: 0:     cmpb    ROW, MM_LROW(bp)
        !          82653:        jna     0f
        !          82654:        movb    ROW, MM_LROW(bp)
        !          82655: 0:     movb    COL, MM_N2(bp)
        !          82656:        decb    COL
        !          82657:        jg      0f
        !          82658:        subb    COL, COL
        !          82659: 0:     cmpb    COL, MM_NCOL(bp)
        !          82660:        jb      0f
        !          82661:        movb    COL, MM_NCOL(bp)
        !          82662:        decb    COL
        !          82663: 0:     jmp     repos                   / reposition cursor
        !          82664: 
        !          82665: ////////
        !          82666: /
        !          82667: / mm_ind - index
        !          82668: /
        !          82669: /      Causes the active position to move downward one line without changing
        !          82670: /      the horizontal position.  Scrolling occurs if below scrolling region.
        !          82671: /
        !          82672: ////////
        !          82673: 
        !          82674: mm_ind:        incb    ROW
        !          82675:        cmpb    ROW, MM_EROW(bp)
        !          82676:        jg      0f
        !          82677:        jmp     repos
        !          82678: 0:     movb    ROW, MM_EROW(bp)
        !          82679:        jmp     scrollup
        !          82680: 
        !          82681: ////////
        !          82682: /
        !          82683: / mm_new - save cursor position
        !          82684: /
        !          82685: ////////
        !          82686: 
        !          82687: mm_new:        movb    MM_SCOL(bp), COL
        !          82688:        movb    MM_SROW(bp), ROW
        !          82689:        jmp     eval
        !          82690: 
        !          82691: ////////
        !          82692: /
        !          82693: / mm_old - restore old cursor position
        !          82694: /
        !          82695: ////////
        !          82696: 
        !          82697: mm_old:        movb    COL, MM_SCOL(bp)
        !          82698:        movb    ROW, MM_SROW(bp)
        !          82699:        jmp     repos
        !          82700: 
        !          82701: ////////
        !          82702: /
        !          82703: / mm_ri - reverse index
        !          82704: /
        !          82705: /      Moves the active position to the same horizontal position on the
        !          82706: /      preceding line.  Scrolling occurs if above scrolling region.
        !          82707: /
        !          82708: ////////
        !          82709: 
        !          82710: mm_ri: decb    ROW
        !          82711:        cmpb    ROW, MM_BROW(bp)
        !          82712:        jge     0f
        !          82713:        movb    ROW, MM_BROW(bp)
        !          82714:        jmp     scrolldown
        !          82715: 0:     jmp     repos
        !          82716: 
        !          82717: ////////
        !          82718: /
        !          82719: / mm_scr - select cursor rendition
        !          82720: /
        !          82721: /      Invokes the cursor rendition specified by the parameter.
        !          82722: /
        !          82723: /      Recognized renditions are:      0 - cursor visible
        !          82724: /                                      1 - cursor invisible
        !          82725: ////////
        !          82726: 
        !          82727: mm_scr:        decb    MM_N1(bp)
        !          82728:        je      0f
        !          82729:        jg      1f
        !          82730:        mov     MM_VIS(bp), $-1
        !          82731:        jmp     eval
        !          82732: 
        !          82733: 0:     mov     MM_VIS(bp), $0
        !          82734: 1:     jmp     eval
        !          82735: 
        !          82736: ////////
        !          82737: /
        !          82738: / mm_sgr - select graphic rendition
        !          82739: /
        !          82740: /      Invokes the graphic rendition specified by the parameter.
        !          82741: /      All following characters in the data stream are rendered
        !          82742: /      according to the parameters until the next occurrence of
        !          82743: /      SGR in the data stream.
        !          82744: /
        !          82745: /      Recognized renditions are:      1 - high intensity
        !          82746: /                                      4 - underline
        !          82747: /                                      7 - reverse video
        !          82748: /
        !          82749: ////////
        !          82750: 
        !          82751: mm_sgr:        movb    al, MM_N1(bp)
        !          82752:        cmpb    al, $0
        !          82753:        jne     0f
        !          82754:        mov     MM_MASK(bp), $0xAAAA
        !          82755:        mov     MM_FLIP(bp), $0
        !          82756:        mov     MM_ULINE(bp), $0
        !          82757:        jmp     1f
        !          82758: 0:     cmpb    al, $1          / bold
        !          82759:        jne     0f
        !          82760:        mov     MM_MASK(bp), $-1
        !          82761:        jmp     1f
        !          82762: 0:     cmpb    al, $4          / underline
        !          82763:        jne     0f
        !          82764:        mov     MM_ULINE(bp), $0xFFFF
        !          82765:        jmp     1f
        !          82766: 0:     cmpb    al, $7          / reverse video
        !          82767:        jne     0f
        !          82768:        mov     MM_FLIP(bp), $-1
        !          82769:        jmp     1f
        !          82770: 0:
        !          82771: 1:     jmp     eval
        !          82772: 
        !          82773: ////////
        !          82774: /
        !          82775: / mm_so - stand out - enter 40 column mode
        !          82776: /
        !          82777: ////////
        !          82778: 
        !          82779: mm_so: cmpb    MM_NCOL(bp), $80
        !          82780:        jne     0f
        !          82781:        movb    MM_NCOL(bp), $40
        !          82782:        incb    COL
        !          82783:        shrb    COL, $1
        !          82784: 0:     mov     MM_CURSE(bp), $0xffff
        !          82785:        jmp     repos
        !          82786: 
        !          82787: ////////
        !          82788: /
        !          82789: / mm_si - stand in - enter 80 column mode
        !          82790: /
        !          82791: ////////
        !          82792: 
        !          82793: mm_si: cmpb    MM_NCOL(bp), $40
        !          82794:        jne     0f
        !          82795:        movb    MM_NCOL(bp), $80
        !          82796:        shlb    COL, $1
        !          82797: 0:     mov     MM_CURSE(bp), $0x00ff
        !          82798:        jmp     repos
        !          82799: 
        !          82800: ////////
        !          82801: /
        !          82802: / mm_ssr - set scrolling region
        !          82803: /
        !          82804: ////////
        !          82805: 
        !          82806: mm_ssr:        movb    al, MM_N1(bp)
        !          82807:        decb    al
        !          82808:        jge     0f
        !          82809:        subb    al, al
        !          82810: 0:     cmpb    al, MM_LROW(bp)
        !          82811:        ja      1f
        !          82812:        movb    bl, MM_N2(bp)
        !          82813:        decb    bl
        !          82814:        jge     0f
        !          82815:        subb    bl, bl
        !          82816: 0:     cmpb    bl, MM_LROW(bp)
        !          82817:        ja      1f
        !          82818:        cmpb    al, bl
        !          82819:        ja      1f
        !          82820:        movb    MM_BROW(bp), al
        !          82821:        movb    MM_EROW(bp), bl
        !          82822:        movb    ROW, al
        !          82823:        subb    COL, COL
        !          82824: 1:     jmp     repos
        !          82825: 
        !          82826: ////////
        !          82827: /
        !          82828: / mm_vpa - vertical position absolute
        !          82829: /
        !          82830: /      Moves the active position to the line specified by the parameter
        !          82831: /      without changing the horizontal position.
        !          82832: /      A parameter value of 0 or 1 moves the active position vertically
        !          82833: /      to the first line.
        !          82834: /
        !          82835: ////////
        !          82836: 
        !          82837: mm_vpa:        movb    ROW, MM_N1(bp)
        !          82838:        decb    ROW
        !          82839:        jg      0f
        !          82840:        subb    ROW, ROW
        !          82841: 0:     cmpb    ROW, MM_LROW(bp)
        !          82842:        jna     0f
        !          82843:        movb    ROW, MM_LROW(bp)
        !          82844: 0:     jmp     repos                   / reposition cursor
        !          82845: 
        !          82846: ////////
        !          82847: /
        !          82848: / mm_vpr - vertical position relative
        !          82849: /
        !          82850: /      Moves the active position downward the number of lines specified
        !          82851: /      by the parameter without changing the horizontal position.
        !          82852: /      A parameter value of zero or one moves the active position
        !          82853: /      one line downward.
        !          82854: /
        !          82855: ////////
        !          82856: 
        !          82857: mm_vpr:        movb    al, MM_N1(bp)
        !          82858:        orb     al, al
        !          82859:        jne     0f
        !          82860:        incb    al
        !          82861: 0:     addb    ROW, al
        !          82862:        cmpb    ROW, MM_LROW(bp)
        !          82863:        jb      0f
        !          82864:        movb    ROW, MM_LROW(bp)
        !          82865: 0:     jmp     repos                   / reposition cursor
        !          82866: 
        !          82867: ////////
        !          82868: /
        !          82869: / asctab - table of functions indexed by ascii characters
        !          82870: /
        !          82871: ////////
        !          82872: 
        !          82873: asctab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          82874:        .word   eval,   eval,   eval,   mmbell  /* EOT  ENQ  ACK  BEL  */
        !          82875:        .word   mm_cub, mm_cht, mm_cnl, mm_ind  /* BS   HT   LF   VT  */
        !          82876:        .word   eval,   mm_cr,  mm_so,  mm_si   /* FF   CR   SO   SI  */
        !          82877:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3 */
        !          82878:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          82879:        .word   eval,   eval,   eval,   mm_esc  /* CAN  EM   SUB  ESC  */
        !          82880:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          82881:        .word   mmputc, mmputc, mmputc, mmputc  /*   ! " # \040 - \043 */
        !          82882:        .word   mmputc, mmputc, mmputc, mmputc  /* $ % & quote \044 - \047 */
        !          82883:        .word   mmputc, mmputc, mmputc, mmputc  /* ( ) * + \050 - \053 */
        !          82884:        .word   mmputc, mmputc, mmputc, mmputc  /* , - . / \054 - \057 */
        !          82885:        .word   mmputc, mmputc, mmputc, mmputc  /* 0 1 2 3 \060 - \063 */
        !          82886:        .word   mmputc, mmputc, mmputc, mmputc  /* 4 5 6 7 \064 - \067 */
        !          82887:        .word   mmputc, mmputc, mmputc, mmputc  /* 8 9 : ; \070 - \073 */
        !          82888:        .word   mmputc, mmputc, mmputc, mmputc  /* < = > ? \074 - \077 */
        !          82889:        .word   mmputc, mmputc, mmputc, mmputc  /* @@ A B C \100 - \103 */
        !          82890:        .word   mmputc, mmputc, mmputc, mmputc  /* D E F G \104 - \107 */
        !          82891:        .word   mmputc, mmputc, mmputc, mmputc  /* H I J K \110 - \113 */
        !          82892:        .word   mmputc, mmputc, mmputc, mmputc  /* L M N O \114 - \117 */
        !          82893:        .word   mmputc, mmputc, mmputc, mmputc  /* P Q R S \120 - \123 */
        !          82894:        .word   mmputc, mmputc, mmputc, mmputc  /* T U V W \124 - \127 */
        !          82895:        .word   mmputc, mmputc, mmputc, mmputc  /* X Y Z [ \130 - \133 */
        !          82896:        .word   mmputc, mmputc, mmputc, mmputc  /* \ ] ^ _ \134 - \137 */
        !          82897:        .word   mmputc, mmputc, mmputc, mmputc  /* ` a b c \140 - \143 */
        !          82898:        .word   mmputc, mmputc, mmputc, mmputc  /* d e f g \144 - \147 */
        !          82899:        .word   mmputc, mmputc, mmputc, mmputc  /* h i j k \150 - \153 */
        !          82900:        .word   mmputc, mmputc, mmputc, mmputc  /* l m n o \154 - \157 */
        !          82901:        .word   mmputc, mmputc, mmputc, mmputc  /* p q r s \160 - \163 */
        !          82902:        .word   mmputc, mmputc, mmputc, mmputc  /* t u v w \164 - \167 */
        !          82903:        .word   mmputc, mmputc, mmputc, mmputc  /* x y z { \170 - \173 */
        !          82904:        .word   mmputc, mmputc, mmputc, mmputc  /* | } ~ ? \174 - \177 */
        !          82905: 
        !          82906: ////////
        !          82907: /
        !          82908: / esctab - table of functions indexed by escape characters.
        !          82909: /
        !          82910: ////////
        !          82911: 
        !          82912: esctab:        .word   mmputc, mmputc, mmputc, mmputc  /* NUL  SOH  STX  ETX  */
        !          82913:        .word   mmputc, mmputc, mmputc, mmputc  /* EOT  ENQ  ACK  BEL  */
        !          82914:        .word   mmputc, mmputc, mmputc, mmputc  /* BS   HT   LF   VT  */
        !          82915:        .word   mmputc, mmputc, mmputc, mmputc  /* FF   CR   SO   SI  */
        !          82916:        .word   mmputc, mmputc, mmputc, mmputc  /* DLE  DC1  DC2  DC3 */
        !          82917:        .word   mmputc, mmputc, mmputc, mmputc  /* DC4  NAK  SYN  ETB  */
        !          82918:        .word   mmputc, mmputc, mmputc, mmputc  /* CAN  EM   SUB  ESC  */
        !          82919:        .word   mmputc, mmputc, mmputc, mmputc  /* FS   GS   RS   US   */
        !          82920:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          82921:        .word   eval,   eval,   eval,   eval    /* $ % & quote \044 - \047 */
        !          82922:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          82923:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          82924:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          82925:        .word   eval,   eval,   eval,   mm_new  /* 4 5 6 7 \064 - \067 */
        !          82926:        .word   mm_old, eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          82927:        .word   eval,   mmspec, mmspec, eval    /* < = > ? \074 - \077 */
        !          82928:        .word   eval,   eval,   eval,   eval    /* @@ A B C \100 - \103 */
        !          82929:        .word   mm_ind, mm_cnl, eval,   eval    /* D E F G \104 - \107 */
        !          82930:        .word   eval,   eval,   eval,   eval    /* H I J K \110 - \113 */
        !          82931:        .word   eval,   mm_ri,  eval,   eval    /* L M N O \114 - \117 */
        !          82932:        .word   eval,   eval,   eval,   eval    /* P Q R S \120 - \123 */
        !          82933:        .word   eval,   eval,   eval,   eval    /* T U V W \124 - \127 */
        !          82934:        .word   eval,   eval,   eval,   csi_n1  /* X Y Z [ \130 - \133 */
        !          82935:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          82936:        .word   mm_dmi, eval,   mm_emi, mminit  /* ` a b c \140 - \143 */
        !          82937:        .word   eval,   eval,   eval,   eval    /* d e f g \144 - \147 */
        !          82938:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          82939:        .word   eval,   eval,   eval,   eval    /* l m n o \154 - \157 */
        !          82940:        .word   eval,   eval,   eval,   eval    /* p q r s \160 - \163 */
        !          82941:        .word   mmspec, mmspec, eval,   eval    /* t u v w \164 - \167 */
        !          82942:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          82943:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          82944: 
        !          82945: ////////
        !          82946: /
        !          82947: / csitab - table of functions indexed by ESC [ characters.
        !          82948: /
        !          82949: ////////
        !          82950: 
        !          82951: csitab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          82952:        .word   eval,   eval,   eval,   eval    /* EOT  ENQ  ACK  BEL  */
        !          82953:        .word   eval,   eval,   eval,   eval    /* BS   HT   LF   VT  */
        !          82954:        .word   eval,   eval,   eval,   eval    /* FF   CR   SO   SI  */
        !          82955:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3 */
        !          82956:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          82957:        .word   eval,   eval,   eval,   eval    /* CAN  EM   SUB  ESC  */
        !          82958:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          82959:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          82960:        .word   eval,   eval,   eval,   eval    /* $ % & quote \044 - \047 */
        !          82961:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          82962:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          82963:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          82964:        .word   eval,   eval,   eval,   eval    /* 4 5 6 7 \064 - \067 */
        !          82965:        .word   eval,   eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          82966:        .word   eval,   eval,   csi_gt, eval    /* < = > ? \074 - \077 */
        !          82967:        .word   eval,   mm_cuu, mm_cud, mm_cuf  /* @@ A B C \100 - \103 */
        !          82968:        .word   mm_cub, mm_cnl, mm_cpl, mm_cha  /* D E F G \104 - \107 */
        !          82969:        .word   mm_cup, mm_cht, mm_ed,  mm_el   /* H I J K \110 - \113 */
        !          82970:        .word   mm_il,  mm_dl,  eval,   mm_ea   /* L M N O \114 - \117 */
        !          82971:        .word   eval,   eval,   eval,   mm_ind  /* P Q R S \120 - \123 */
        !          82972:        .word   mm_ri,  eval,   eval,   eval    /* T U V W \124 - \127 */
        !          82973:        .word   eval,   eval,   mm_cbt, eval    /* X Y Z [ \130 - \133 */
        !          82974:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          82975:        .word   mm_hpa, mm_hpr, eval,   eval    /* ` a b c \140 - \143 */
        !          82976:        .word   mm_vpa, mm_vpr, mm_hvp, mm_cup  /* d e f g \144 - \147 */
        !          82977:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          82978:        .word   eval,   mm_sgr, eval,   eval    /* l m n o \154 - \157 */
        !          82979:        .word   eval,   eval,   mm_ssr, eval    /* p q r s \160 - \163 */
        !          82980:        .word   eval,   eval,   mm_scr, eval    /* t u v w \164 - \167 */
        !          82981:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          82982:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          82983: 
        !          82984: ////////
        !          82985: /
        !          82986: / rowtab - array of offsets to each row
        !          82987: /
        !          82988: ////////
        !          82989: 
        !          82990: rowtab:        .word    0*NRB2,         1*NRB2,         2*NRB2,         3*NRB2
        !          82991:        .word    4*NRB2,         5*NRB2,         6*NRB2,         7*NRB2
        !          82992:        .word    8*NRB2,         9*NRB2,        10*NRB2,        11*NRB2
        !          82993:        .word   12*NRB2,        13*NRB2,        14*NRB2,        15*NRB2
        !          82994:        .word   16*NRB2,        17*NRB2,        18*NRB2,        19*NRB2
        !          82995:        .word   20*NRB2,        21*NRB2,        22*NRB2,        23*NRB2
        !          82996:        .word   24*NRB2,        25*NRB2,        26*NRB2,        27*NRB2
        !          82997:        .word   28*NRB2,        29*NRB2,        30*NRB2,        31*NRB2
        !          82998:        .word   32*NRB2,        33*NRB2,        34*NRB2,        35*NRB2
        !          82999:        .word   36*NRB2,        37*NRB2,        38*NRB2,        39*NRB2
        !          83000:        .word   40*NRB2,        41*NRB2,        42*NRB2,        43*NRB2
        !          83001:        .word   44*NRB2,        45*NRB2,        46*NRB2,        47*NRB2
        !          83002:        .word   48*NRB2,        49*NRB2,        50*NRB2,        51*NRB2
        !          83003: 
        !          83004: ////////
        !          83005: /
        !          83006: / grread( dev, iop ) - read graphics display memory
        !          83007: /
        !          83008: ////////
        !          83009: 
        !          83010: grread_:
        !          83011:        push    si
        !          83012:        push    di
        !          83013:        push    bp
        !          83014:        mov     bp, sp
        !          83015:        mov     bp, 10(bp)
        !          83016:        push    ds
        !          83017:        push    es
        !          83018:        cmp     IO_SEG(bp), $IOSYS
        !          83019:        je      0f
        !          83020:        mov     ax, uds_
        !          83021:        mov     es, ax
        !          83022: 0:     mov     di, IO_BASE(bp)
        !          83023:        mov     ax, $VSEG
        !          83024:        mov     ds, ax
        !          83025: 
        !          83026: #ifndef TECMAR
        !          83027:        mov     ax, IO_SEEK(bp)
        !          83028:        add     ax, IO_IOC(bp)
        !          83029:        cmp     ax, $BANKSZ*2
        !          83030:        ja      done
        !          83031: #endif
        !          83032: 
        !          83033:        mov     ax, IO_SEEK(bp)
        !          83034:        sub     dx, dx
        !          83035:        mov     cx, $NHB
        !          83036:        div     cx
        !          83037:        mov     si, dx
        !          83038:        mov     bx, ax
        !          83039:        shr     ax, $1
        !          83040:        mul     cx
        !          83041:        mov     dx, si
        !          83042:        add     si, ax
        !          83043:        testb   bl, $1
        !          83044:        jne     read2
        !          83045: 
        !          83046: read1: mov     cx, $NHB
        !          83047:        sub     cx, dx
        !          83048:        cmp     cx, IO_IOC(bp)
        !          83049:        jle     0f
        !          83050:        mov     cx, IO_IOC(bp)
        !          83051:        jcxz    done
        !          83052: 0:     sub     IO_IOC(bp), cx
        !          83053:        add     IO_BASE(bp), cx
        !          83054:        push    si
        !          83055:        rep
        !          83056:        movsb
        !          83057:        pop     si
        !          83058: read2: add     si, $BANKSZ
        !          83059:        mov     cx, $NHB
        !          83060:        sub     cx, dx
        !          83061:        cmp     cx, IO_IOC(bp)
        !          83062:        jle     0f
        !          83063:        mov     cx, IO_IOC(bp)
        !          83064:        jcxz    done
        !          83065: 0:     sub     IO_IOC(bp), cx
        !          83066:        add     IO_BASE(bp), cx
        !          83067:        rep
        !          83068:        movsb
        !          83069:        sub     si, $BANKSZ
        !          83070:        sub     dx, dx
        !          83071:        jmp     read1
        !          83072: 
        !          83073: done:  pop     es
        !          83074:        pop     ds
        !          83075:        pop     bp
        !          83076:        pop     di
        !          83077:        pop     si
        !          83078:        ret
        !          83079: 
        !          83080: ////////
        !          83081: /
        !          83082: / grwrite( dev, iop ) - write graphics display memory
        !          83083: /
        !          83084: ////////
        !          83085: 
        !          83086: grwrite_:
        !          83087:        push    si
        !          83088:        push    di
        !          83089:        push    bp
        !          83090:        mov     bp, sp
        !          83091:        mov     bp, 10(bp)
        !          83092:        push    ds
        !          83093:        push    es
        !          83094:        cmp     IO_SEG(bp), $IOSYS
        !          83095:        je      0f
        !          83096:        mov     ax, uds_
        !          83097:        mov     ds, ax
        !          83098: 0:     mov     si, IO_BASE(bp)
        !          83099:        mov     ax, $VSEG
        !          83100:        mov     es, ax
        !          83101: 
        !          83102: #ifndef TECMAR
        !          83103:        mov     ax, IO_SEEK(bp)
        !          83104:        add     ax, IO_IOC(bp)
        !          83105:        cmp     ax, $BANKSZ*2
        !          83106:        ja      done
        !          83107: #endif
        !          83108: 
        !          83109:        mov     ax, IO_SEEK(bp)
        !          83110:        sub     dx, dx
        !          83111:        mov     cx, $NHB
        !          83112:        div     cx
        !          83113:        mov     di, dx
        !          83114:        mov     bx, ax
        !          83115:        shr     ax, $1
        !          83116:        mul     cx
        !          83117:        mov     dx, di
        !          83118:        add     di, ax
        !          83119:        testb   bl, $1
        !          83120:        jne     page2
        !          83121: 
        !          83122: page1: mov     cx, $NHB
        !          83123:        sub     cx, dx
        !          83124:        cmp     cx, IO_IOC(bp)
        !          83125:        jle     0f
        !          83126:        mov     cx, IO_IOC(bp)
        !          83127:        jcxz    done
        !          83128: 0:     sub     IO_IOC(bp), cx
        !          83129:        add     IO_BASE(bp), cx
        !          83130:        push    di
        !          83131:        rep
        !          83132:        movsb
        !          83133:        pop     di
        !          83134: page2: add     di, $BANKSZ
        !          83135:        mov     cx, $NHB
        !          83136:        sub     cx, dx
        !          83137:        cmp     cx, IO_IOC(bp)
        !          83138:        jle     0f
        !          83139:        mov     cx, IO_IOC(bp)
        !          83140:        jcxz    done
        !          83141: 0:     sub     IO_IOC(bp), cx
        !          83142:        add     IO_BASE(bp), cx
        !          83143:        rep
        !          83144:        movsb
        !          83145:        sub     di, $BANKSZ
        !          83146:        sub     dx, dx
        !          83147:        jmp     page1
        !          83148: 
        !          83149: ////////
        !          83150: /
        !          83151: / mm_voff()    -- Disable video display
        !          83152: /
        !          83153: ////////
        !          83154:        .globl  mm_voff_
        !          83155: mm_voff_:
        !          83156:        mov     dx, $MSR
        !          83157:        movb    al, $0x12
        !          83158:        outb    dx, al
        !          83159:        ret
        !          83160: 
        !          83161: ////////
        !          83162: /
        !          83163: / mm_von()     -- Enable video display
        !          83164: /
        !          83165: ////////
        !          83166:        .globl  mm_von_
        !          83167: mm_von_:
        !          83168:        mov     dx, $MSR                / enable video display
        !          83169:        movb    al, $0x1A
        !          83170:        outb    dx, al
        !          83171:        mov     ss:mmvcnt_, $480        / 480 seconds before video disabled
        !          83172:        ret
        !          83173: @
        !          83174: 0707070064030114141004440000000000000000011777770507310710300005600000032530/newbits/kernel/USRSRC/i8086/drv/RCS/Mf.mwc,vhead     1.1;
        !          83175: branch   ;
        !          83176: access   ;
        !          83177: symbols  ;
        !          83178: locks    root:1.1; strict;
        !          83179: comment  @@;
        !          83180: 
        !          83181: 
        !          83182: 1.1
        !          83183: date     91.07.24.11.44.31;  author root;  state Exp;
        !          83184: branches ;
        !          83185: next     ;
        !          83186: 
        !          83187: 
        !          83188: desc
        !          83189: @init ver prov by hal
        !          83190: @
        !          83191: 
        !          83192: 
        !          83193: 
        !          83194: 1.1
        !          83195: log
        !          83196: @Initial revision
        !          83197: @
        !          83198: text
        !          83199: @# Makefile for AT specific Coherent drivers
        !          83200: # Environment variable USRSYS must be defined!  Try /usr/sys ...
        !          83201: # Environment variable KOBJ must be defined!  Try /usr/kobj ...
        !          83202: 
        !          83203: # Include directories
        !          83204: USRINC=/usr/include
        !          83205: SYSINC=/usr/include/sys
        !          83206: 
        !          83207: DEBUG=0
        !          83208: 
        !          83209: # Loadable driver directory
        !          83210: LDRV=$(USRSYS)/ldrv
        !          83211: 
        !          83212: ARCHIVES=$(USRSYS)/lib/aha154x.a \
        !          83213:        $(USRSYS)/lib/al.a \
        !          83214:        $(USRSYS)/lib/at.a \
        !          83215:        $(USRSYS)/lib/ati.a \
        !          83216:        $(USRSYS)/lib/fl.a \
        !          83217:        $(USRSYS)/lib/gkb.a \
        !          83218:        $(USRSYS)/lib/gr.a \
        !          83219:        $(USRSYS)/lib/hs.a \
        !          83220:        $(USRSYS)/lib/kb.a \
        !          83221:        $(USRSYS)/lib/lp.a \
        !          83222:        $(USRSYS)/lib/mm.a \
        !          83223:        $(USRSYS)/lib/ms.a \
        !          83224:        $(USRSYS)/lib/nkb.a \
        !          83225:        $(USRSYS)/lib/rm.a \
        !          83226:        $(USRSYS)/lib/rs.a \
        !          83227:        $(USRSYS)/lib/st.a \
        !          83228:        $(USRSYS)/lib/tn.a \
        !          83229: 
        !          83230: DRVOBJ=        $(KOBJ)/aha.o \
        !          83231:        $(KOBJ)/alx.o \
        !          83232:        $(KOBJ)/at.o \
        !          83233:        $(KOBJ)/atas.o \
        !          83234:        $(KOBJ)/bufq.o \
        !          83235:        $(KOBJ)/ms.o \
        !          83236:        $(KOBJ)/ati.o \
        !          83237:        $(KOBJ)/com1.o $(KOBJ)/com2.o \
        !          83238:        $(KOBJ)/fdisk.o \
        !          83239:        $(KOBJ)/fl.o \
        !          83240:        $(KOBJ)/fontw.o \
        !          83241:        $(KOBJ)/gr.o $(KOBJ)/gras.o \
        !          83242:        $(KOBJ)/hs.o \
        !          83243:        $(KOBJ)/nkb.o \
        !          83244:        $(KOBJ)/gkb.o \
        !          83245:        $(KOBJ)/kb.o \
        !          83246:        $(KOBJ)/mm.o \
        !          83247:        $(KOBJ)/lp.o \
        !          83248:        $(KOBJ)/mmas.o \
        !          83249:        $(KOBJ)/rm.o \
        !          83250:        $(KOBJ)/rs0.o $(KOBJ)/rs1.o $(KOBJ)/rsas.o \
        !          83251:        $(KOBJ)/scsi.o \
        !          83252:        $(KOBJ)/ss.o \
        !          83253:        $(KOBJ)/ssas.o \
        !          83254:        $(KOBJ)/st.o \
        !          83255:        $(KOBJ)/tn.o $(KOBJ)/tnas.o \
        !          83256: 
        !          83257: DRIVERS=$(LDRV)/aha154x \
        !          83258:        $(LDRV)/al0 \
        !          83259:        $(LDRV)/al1 \
        !          83260:        $(LDRV)/at \
        !          83261:        $(LDRV)/fl \
        !          83262:        $(LDRV)/gr \
        !          83263:        $(LDRV)/hs \
        !          83264:        $(LDRV)/lp \
        !          83265:        $(LDRV)/mm \
        !          83266:        $(LDRV)/ms \
        !          83267:        $(LDRV)/rm \
        !          83268:        $(LDRV)/ss \
        !          83269: 
        !          83270: install: $(ARCHIVES) $(DRIVERS)
        !          83271:        @@exec /bin/sync
        !          83272: 
        !          83273: all:   $(DRVOBJ)
        !          83274:        @@exec /bin/sync
        !          83275: 
        !          83276: $(USRSYS)/lib/aha154x.a: $(KOBJ)/scsi.o $(KOBJ)/aha.o $(KOBJ)/fdisk.o
        !          83277:        rm -f $@@
        !          83278:        ar rc $@@ $<
        !          83279: $(USRSYS)/lib/al.a: $(KOBJ)/com1.o $(KOBJ)/com2.o $(KOBJ)/alx.o
        !          83280:        rm -f $@@
        !          83281:        ar rc $@@ $<
        !          83282: $(USRSYS)/lib/at.a: $(KOBJ)/at.o $(KOBJ)/atas.o $(KOBJ)/fdisk.o
        !          83283:        rm -f $@@
        !          83284:        ar rc $@@ $<
        !          83285: $(USRSYS)/lib/ati.a: $(KOBJ)/mm.o $(KOBJ)/ati.o
        !          83286:        rm -f $@@
        !          83287:        ar rc $@@ $<
        !          83288: $(USRSYS)/lib/fl.a: $(KOBJ)/fl.o
        !          83289:        rm -f $(USRSYS)/lib/fl.a
        !          83290:        ar rc $(USRSYS)/lib/fl.a $(KOBJ)/fl.o
        !          83291: $(USRSYS)/lib/gkb.a: $(KOBJ)/gkb.o
        !          83292:        rm -f $@@
        !          83293:        ar rc $@@ $<
        !          83294: $(USRSYS)/lib/gr.a: $(KOBJ)/mm.o $(KOBJ)/gr.o $(KOBJ)/gras.o \
        !          83295:                                $(KOBJ)/fontw.o
        !          83296:        rm -f $@@
        !          83297:        ar rc $@@ $<
        !          83298: $(USRSYS)/lib/hs.a: $(KOBJ)/hs.o
        !          83299:        rm -f $@@
        !          83300:        ar rc $@@ $<
        !          83301: $(USRSYS)/lib/kb.a: $(KOBJ)/kb.o
        !          83302:        rm -f $@@
        !          83303:        ar rc $@@ $<
        !          83304: $(USRSYS)/lib/lp.a: $(KOBJ)/lp.o
        !          83305:        rm -f $@@
        !          83306:        ar rc $@@ $<
        !          83307: $(USRSYS)/lib/mm.a: $(KOBJ)/mm.o $(KOBJ)/mmas.o
        !          83308:        rm -f $@@
        !          83309:        ar rc $@@ $<
        !          83310: $(USRSYS)/lib/ms.a: $(KOBJ)/ms.o
        !          83311:        rm -f $@@
        !          83312:        ar rc $@@ $<
        !          83313: $(USRSYS)/lib/nkb.a: $(KOBJ)/nkb.o
        !          83314:        rm -f $@@
        !          83315:        ar rc $@@ $<
        !          83316: $(USRSYS)/lib/rm.a: $(KOBJ)/rm.o
        !          83317:        rm -f $@@
        !          83318:        ar rc $@@ $<
        !          83319: $(USRSYS)/lib/rs.a: $(KOBJ)/rs0.o $(KOBJ)/rs1.o $(KOBJ)/rsas.o
        !          83320:        rm -f $@@
        !          83321:        ar rc $@@ $<
        !          83322: $(USRSYS)/lib/ss.a: $(KOBJ)/ss.o $(KOBJ)/ssas.o $(KOBJ)/bufq.o $(KOBJ)/fdisk.o
        !          83323:        rm -f $@@
        !          83324:        ar rc $@@ $<
        !          83325: $(USRSYS)/lib/st.a: $(KOBJ)/st.o
        !          83326:        rm -f $@@
        !          83327:        ar rc $@@ $<
        !          83328: $(USRSYS)/lib/tn.a: $(KOBJ)/tn.o $(KOBJ)/tnas.o
        !          83329:        rm -f $@@
        !          83330:        ar rc $@@ $<
        !          83331: 
        !          83332: $(KOBJ)/aha.o:                         \
        !          83333:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83334:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83335:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          83336:                $(SYSINC)/buf.h         \
        !          83337:                $(SYSINC)/sched.h               \
        !          83338:                $(SYSINC)/scsiwork.h    \
        !          83339:                $(SYSINC)/aha154x.h     \
        !          83340:                aha.c
        !          83341:        $(CC) $(CFLAGS) -c -o $@@ aha.c
        !          83342: 
        !          83343: $(KOBJ)/alx.o:                         \
        !          83344:                $(SYSINC)/clist.h       \
        !          83345:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83346:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83347:                                        $(SYSINC)/fun.h \
        !          83348:                $(SYSINC)/con.h         \
        !          83349:                $(USRINC)/errno.h       \
        !          83350:                $(SYSINC)/i8086.h       \
        !          83351:                $(SYSINC)/ins8250.h     \
        !          83352:                $(SYSINC)/sched.h       \
        !          83353:                $(SYSINC)/stat.h        \
        !          83354:                $(SYSINC)/timeout.h     \
        !          83355:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          83356:                $(SYSINC)/uproc.h       \
        !          83357:                alx.c
        !          83358:        $(CC) $(CFLAGS) -c -o $@@ alx.c
        !          83359: 
        !          83360: $(KOBJ)/at.o: at.c                     \
        !          83361:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83362:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83363:                                        $(SYSINC)/fun.h \
        !          83364:                $(SYSINC)/fdisk.h       \
        !          83365:                $(SYSINC)/hdioctl.h     \
        !          83366:                $(SYSINC)/buf.h         \
        !          83367:                $(SYSINC)/con.h         \
        !          83368:                $(SYSINC)/devices.h     \
        !          83369:                $(SYSINC)/stat.h        \
        !          83370:                $(SYSINC)/uproc.h       \
        !          83371:                $(USRINC)/errno.h
        !          83372:        $(CC) $(CFLAGS) -DVERBOSE=1 -c -o $@@ at.c
        !          83373: 
        !          83374: $(KOBJ)/atas.o: atas.s
        !          83375:        $(AS) -go $@@ $<
        !          83376: 
        !          83377: $(KOBJ)/ati.o: ati.m
        !          83378:        $(CC) $(CFLAGS) -DATI_132=1 -c -o $@@ ati.m
        !          83379: 
        !          83380: $(KOBJ)/bufq.o:                        \
        !          83381:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83382:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83383:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          83384:                $(SYSINC)/buf.h         \
        !          83385:                bufq.c
        !          83386:        $(CC) $(CFLAGS) -DDEBUG=$(DEBUG) -c -o $@@ bufq.c
        !          83387: 
        !          83388: $(KOBJ)/com1.o:                        \
        !          83389:                $(SYSINC)/al.h          \
        !          83390:                $(SYSINC)/clist.h       \
        !          83391:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83392:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83393:                                        $(SYSINC)/fun.h \
        !          83394:                $(SYSINC)/con.h         \
        !          83395:                $(SYSINC)/devices.h     \
        !          83396:                $(USRINC)/errno.h       \
        !          83397:                $(SYSINC)/i8086.h       \
        !          83398:                $(SYSINC)/ins8250.h     \
        !          83399:                $(SYSINC)/sched.h       \
        !          83400:                $(SYSINC)/stat.h        \
        !          83401:                $(SYSINC)/timeout.h     \
        !          83402:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          83403:                $(SYSINC)/uproc.h       \
        !          83404:                al.c
        !          83405:        $(CC) $(CFLAGS) -DALCOM1=1 -c -o $@@ al.c
        !          83406: 
        !          83407: $(KOBJ)/com2.o:                        \
        !          83408:                $(SYSINC)/al.h          \
        !          83409:                $(SYSINC)/clist.h       \
        !          83410:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83411:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83412:                                        $(SYSINC)/fun.h \
        !          83413:                $(SYSINC)/con.h         \
        !          83414:                $(SYSINC)/devices.h     \
        !          83415:                $(USRINC)/errno.h       \
        !          83416:                $(SYSINC)/i8086.h       \
        !          83417:                $(SYSINC)/ins8250.h     \
        !          83418:                $(SYSINC)/sched.h       \
        !          83419:                $(SYSINC)/stat.h        \
        !          83420:                $(SYSINC)/timeout.h     \
        !          83421:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          83422:                $(SYSINC)/uproc.h       \
        !          83423:                al.c
        !          83424:        $(CC) $(CFLAGS) -DALCOM2=1 -c -o $@@ al.c
        !          83425: 
        !          83426: $(KOBJ)/fdisk.o:                       \
        !          83427:                $(SYSINC)/buf.h         \
        !          83428:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83429:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83430:                                        $(SYSINC)/fun.h \
        !          83431:                $(SYSINC)/con.h         \
        !          83432:                $(USRINC)/errno.h       \
        !          83433:                $(SYSINC)/fdisk.h       \
        !          83434:                $(SYSINC)/inode.h       \
        !          83435:                $(SYSINC)/uproc.h       \
        !          83436:                fdisk.c
        !          83437:        $(CC) $(CFLAGS) -c -o $@@ fdisk.c
        !          83438: 
        !          83439: $(KOBJ)/fl.o:                          \
        !          83440:                $(SYSINC)/buf.h         \
        !          83441:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83442:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83443:                                        $(SYSINC)/fun.h \
        !          83444:                $(SYSINC)/con.h         \
        !          83445:                $(SYSINC)/devices.h     \
        !          83446:                $(SYSINC)/dmac.h        \
        !          83447:                $(USRINC)/errno.h       \
        !          83448:                $(SYSINC)/fdioctl.h     \
        !          83449:                $(SYSINC)/i8086.h       \
        !          83450:                $(SYSINC)/sched.h       \
        !          83451:                $(SYSINC)/stat.h        \
        !          83452:                $(SYSINC)/timeout.h     \
        !          83453:                $(SYSINC)/uproc.h       \
        !          83454:                fl.c
        !          83455:        $(CC) $(CFLAGS) -c -o $@@ fl.c
        !          83456: 
        !          83457: $(KOBJ)/fontw.o: tools/fontgen.c
        !          83458:        $(CC) -o tools/fontgen tools/fontgen.c
        !          83459:        exec tools/fontgen > fontw.s
        !          83460:        exec /bin/rm tools/fontgen
        !          83461:        $(AS) -gxo $(KOBJ)/fontw.o fontw.s
        !          83462:        exec /bin/rm fontw.s
        !          83463: 
        !          83464: $(KOBJ)/gr.o:                          \
        !          83465:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83466:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83467:                                        $(SYSINC)/fun.h \
        !          83468:                $(SYSINC)/con.h         \
        !          83469:                $(SYSINC)/devices.h     \
        !          83470:                $(USRINC)/errno.h       \
        !          83471:                $(SYSINC)/sched.h       \
        !          83472:                $(SYSINC)/timeout.h     \
        !          83473:                $(SYSINC)/types.h       \
        !          83474:                $(SYSINC)/uproc.h       \
        !          83475:                gr.c
        !          83476:        $(CC) $(CFLAGS) -c -o $@@ gr.c
        !          83477: 
        !          83478: $(KOBJ)/gras.o: gras.m
        !          83479:        $(CC) $(CFLAGS) -c -o $@@ gras.m
        !          83480: 
        !          83481: $(KOBJ)/hgas.o: gras.s
        !          83482:        $(CC) $(CFLAGS) -c -o $@@ -DHERCULES gras.m
        !          83483: 
        !          83484: $(KOBJ)/hd.o: hd.c
        !          83485:        $(CC) $(CFLAGS) -c -o $@@ hd.c
        !          83486: 
        !          83487: $(KOBJ)/hs.o:                          \
        !          83488:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83489:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83490:                                        $(SYSINC)/fun.h \
        !          83491:                $(SYSINC)/con.h         \
        !          83492:                $(SYSINC)/devices.h     \
        !          83493:                $(USRINC)/errno.h       \
        !          83494:                $(SYSINC)/ins8250.h     \
        !          83495:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          83496:                $(SYSINC)/stat.h        \
        !          83497:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          83498:                $(SYSINC)/uproc.h       \
        !          83499:                hs.c
        !          83500:        $(CC) $(CFLAGS) -c -o $@@ hs.c
        !          83501: 
        !          83502: $(KOBJ)/kb.o:                          \
        !          83503:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83504:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83505:                                        $(SYSINC)/fun.h \
        !          83506:                $(SYSINC)/con.h         \
        !          83507:                $(SYSINC)/devices.h     \
        !          83508:                $(USRINC)/errno.h       \
        !          83509:                $(SYSINC)/i8086.h       \
        !          83510:                $(SYSINC)/sched.h       \
        !          83511:                $(USRINC)/signal.h      \
        !          83512:                $(SYSINC)/stat.h        \
        !          83513:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          83514:                $(SYSINC)/uproc.h       \
        !          83515:                kb.c
        !          83516:        $(CC) $(CFLAGS) -c -o $@@ kb.c
        !          83517: 
        !          83518: $(KOBJ)/gkb.o:                         \
        !          83519:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83520:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83521:                                        $(SYSINC)/fun.h \
        !          83522:                $(SYSINC)/con.h         \
        !          83523:                $(USRINC)/errno.h       \
        !          83524:                $(SYSINC)/i8086.h       \
        !          83525:                $(SYSINC)/sched.h       \
        !          83526:                $(USRINC)/signal.h      \
        !          83527:                $(SYSINC)/stat.h        \
        !          83528:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          83529:                $(SYSINC)/uproc.h       \
        !          83530:                gkb.c
        !          83531:        $(CC) $(CFLAGS) -c -o $@@ gkb.c
        !          83532: 
        !          83533: $(KOBJ)/nkb.o:                         \
        !          83534:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83535:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83536:                                        $(SYSINC)/fun.h \
        !          83537:                $(SYSINC)/con.h         \
        !          83538:                $(USRINC)/errno.h       \
        !          83539:                $(SYSINC)/i8086.h       \
        !          83540:                $(SYSINC)/sched.h       \
        !          83541:                $(SYSINC)/seg.h         \
        !          83542:                $(USRINC)/signal.h      \
        !          83543:                $(SYSINC)/stat.h        \
        !          83544:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          83545:                $(SYSINC)/uproc.h       \
        !          83546:                $(SYSINC)/kb.h          \
        !          83547:                nkb.c
        !          83548:        $(CC) $(CFLAGS) -c -o $@@ nkb.c
        !          83549: 
        !          83550: $(KOBJ)/lp.o:                          \
        !          83551:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83552:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83553:                                        $(SYSINC)/fun.h \
        !          83554:                $(SYSINC)/con.h         \
        !          83555:                $(SYSINC)/devices.h     \
        !          83556:                $(USRINC)/errno.h       \
        !          83557:                $(SYSINC)/i8086.h       \
        !          83558:                $(SYSINC)/io.h          \
        !          83559:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          83560:                $(SYSINC)/stat.h        \
        !          83561:                $(SYSINC)/timeout.h     \
        !          83562:                $(SYSINC)/uproc.h       \
        !          83563:                lp.c
        !          83564:        $(CC) $(CFLAGS) -c -o $@@ lp.c
        !          83565: 
        !          83566: $(KOBJ)/mm.o:                          \
        !          83567:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83568:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83569:                                        $(SYSINC)/fun.h \
        !          83570:                $(SYSINC)/sched.h       \
        !          83571:                $(USRINC)/errno.h       \
        !          83572:                $(SYSINC)/stat.h        \
        !          83573:                $(SYSINC)/io.h          \
        !          83574:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          83575:                $(SYSINC)/uproc.h       \
        !          83576:                $(SYSINC)/timeout.h     \
        !          83577:                mm.c
        !          83578:        $(CC) $(CFLAGS) -c -o $@@ mm.c
        !          83579: 
        !          83580: $(KOBJ)/mmas.o: mmas.m
        !          83581:        $(CC) $(CFLAGS) -c -o $@@ mmas.m
        !          83582: 
        !          83583: $(KOBJ)/ms.o:                          \
        !          83584:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83585:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83586:                                        $(SYSINC)/fun.h \
        !          83587:                $(SYSINC)/uproc.h       \
        !          83588:                $(SYSINC)/con.h         \
        !          83589:                $(SYSINC)/devices.h     \
        !          83590:                $(SYSINC)/ms.h          \
        !          83591:                $(USRINC)/errno.h       \
        !          83592:                ms.c
        !          83593:        $(CC) $(CFLAGS) -c -o $@@ ms.c
        !          83594: 
        !          83595: $(KOBJ)/rm.o: rm.c                     \
        !          83596:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83597:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83598:                                        $(SYSINC)/fun.h \
        !          83599:                $(SYSINC)/buf.h         \
        !          83600:                $(USRINC)/errno.h       \
        !          83601:                $(SYSINC)/uproc.h       \
        !          83602:                $(SYSINC)/seg.h         \
        !          83603:                $(SYSINC)/con.h         \
        !          83604:                $(SYSINC)/devices.h     \
        !          83605:                $(SYSINC)/inode.h       \
        !          83606:                $(SYSINC)/stat.h
        !          83607:        $(CC) $(CFLAGS) -c -o $@@ rm.c
        !          83608: 
        !          83609: $(KOBJ)/rs0.o:                         \
        !          83610:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83611:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83612:                                        $(SYSINC)/fun.h \
        !          83613:                $(SYSINC)/con.h         \
        !          83614:                $(SYSINC)/devices.h     \
        !          83615:                $(USRINC)/errno.h       \
        !          83616:                $(SYSINC)/ins8250.h     \
        !          83617:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          83618:                $(SYSINC)/sched.h       \
        !          83619:                $(SYSINC)/stat.h        \
        !          83620:                $(USRINC)/termio.h      \
        !          83621:                $(SYSINC)/uproc.h       \
        !          83622:                rs.c
        !          83623:        $(CC) $(CFLAGS) -DRS0 -c -o $@@ rs.c
        !          83624: 
        !          83625: $(KOBJ)/rs1.o:                                 \
        !          83626:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83627:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83628:                                        $(SYSINC)/fun.h \
        !          83629:                $(SYSINC)/con.h         \
        !          83630:                $(SYSINC)/devices.h     \
        !          83631:                $(USRINC)/errno.h       \
        !          83632:                $(SYSINC)/ins8250.h     \
        !          83633:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          83634:                $(SYSINC)/sched.h       \
        !          83635:                $(SYSINC)/stat.h        \
        !          83636:                $(USRINC)/termio.h      \
        !          83637:                $(SYSINC)/uproc.h       \
        !          83638:                rs.c
        !          83639:        $(CC) $(CFLAGS) -DRS1 -c -o $@@ rs.c
        !          83640: 
        !          83641: $(KOBJ)/rsas.o: rsas.s
        !          83642:        $(AS) -gxo $@@ rsas.s
        !          83643: 
        !          83644: $(KOBJ)/scsi.o:                                \
        !          83645:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83646:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83647:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          83648:                $(SYSINC)/fdisk.h       \
        !          83649:                $(SYSINC)/hdioctl.h     \
        !          83650:                $(SYSINC)/sdioctl.h     \
        !          83651:                $(SYSINC)/buf.h         \
        !          83652:                $(SYSINC)/con.h         \
        !          83653:                $(SYSINC)/stat.h        \
        !          83654:                $(SYSINC)/uproc.h       \
        !          83655:                $(USRINC)/errno.h       \
        !          83656:                $(SYSINC)/scsiwork.h    \
        !          83657:                scsi.c
        !          83658:        $(CC) $(CFLAGS) -c -o $(KOBJ)/scsi.o scsi.c
        !          83659: 
        !          83660: $(KOBJ)/ss.o:                          \
        !          83661:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83662:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83663:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          83664:                $(SYSINC)/io.h          \
        !          83665:                $(SYSINC)/sched.h       \
        !          83666:                $(SYSINC)/uproc.h       \
        !          83667:                $(SYSINC)/proc.h        \
        !          83668:                $(SYSINC)/con.h         \
        !          83669:                $(SYSINC)/stat.h        \
        !          83670:                $(SYSINC)/devices.h     \
        !          83671:                $(USRINC)/errno.h       \
        !          83672:                $(SYSINC)/ss.h          \
        !          83673:                $(SYSINC)/fdisk.h       \
        !          83674:                $(SYSINC)/hdioctl.h     \
        !          83675:                $(SYSINC)/buf.h         \
        !          83676:                $(SYSINC)/scsiwork.h    \
        !          83677:                ss.c
        !          83678:        $(CC) $(CFLAGS) -DDEBUG=$(DEBUG) -c -o $(KOBJ)/ss.o ss.c
        !          83679: 
        !          83680: $(KOBJ)/ssas.o:                                \
        !          83681:                ssas.s
        !          83682:        $(AS) -go $@@ $<
        !          83683: 
        !          83684: $(KOBJ)/st.o:                          \
        !          83685:                $(SYSINC)/buf.h         \
        !          83686:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83687:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83688:                                        $(SYSINC)/fun.h \
        !          83689:                $(SYSINC)/con.h         \
        !          83690:                $(SYSINC)/devices.h     \
        !          83691:                $(SYSINC)/const.h       \
        !          83692:                $(USRINC)/errno.h       \
        !          83693:                $(SYSINC)/inode.h       \
        !          83694:                $(SYSINC)/mtioctl.h     \
        !          83695:                $(SYSINC)/sched.h       \
        !          83696:                $(SYSINC)/seg.h         \
        !          83697:                $(SYSINC)/stat.h        \
        !          83698:                $(SYSINC)/uproc.h       \
        !          83699:                st.c
        !          83700:        $(CC) $(CFLAGS) -c -o $@@ st.c
        !          83701: 
        !          83702: $(KOBJ)/tn.o:                          \
        !          83703:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          83704:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          83705:                                        $(SYSINC)/fun.h \
        !          83706:                $(SYSINC)/con.h         \
        !          83707:                $(SYSINC)/devices.h     \
        !          83708:                $(USRINC)/errno.h       \
        !          83709:                $(SYSINC)/sched.h       \
        !          83710:                $(SYSINC)/timeout.h     \
        !          83711:                $(SYSINC)/types.h       \
        !          83712:                $(SYSINC)/uproc.h       \
        !          83713:                tn.c
        !          83714:        $(CC) $(CFLAGS) -c -o $@@ tn.c
        !          83715: 
        !          83716: $(KOBJ)/tnas.o: tnas.s
        !          83717:        $(AS) -gxo $@@ tnas.s
        !          83718: 
        !          83719: # How to make loadable drivers.
        !          83720: 
        !          83721: $(LDRV)/aha154x:       $(USRSYS)/lib/aha154x.a
        !          83722:        ( cd $(USRSYS); ldconfig aha154x )
        !          83723: 
        !          83724: $(LDRV)/al0:   $(USRSYS)/lib/al.a
        !          83725:        ( cd $(USRSYS); ldconfig al0 )
        !          83726: 
        !          83727: $(LDRV)/al1:   $(USRSYS)/lib/al.a
        !          83728:        ( cd $(USRSYS); ldconfig al1 )
        !          83729: 
        !          83730: $(LDRV)/at:    $(USRSYS)/lib/at.a
        !          83731:        ( cd $(USRSYS); ldconfig at )
        !          83732: 
        !          83733: $(LDRV)/fl:    $(USRSYS)/lib/fl.a
        !          83734:        ( cd $(USRSYS); ldconfig fl )
        !          83735: 
        !          83736: $(LDRV)/gr:    $(USRSYS)/lib/gr.a
        !          83737:        ( cd $(USRSYS); ldconfig gr )
        !          83738: 
        !          83739: $(LDRV)/hs:    $(USRSYS)/lib/hs.a
        !          83740:        ( cd $(USRSYS); ldconfig hs )
        !          83741: 
        !          83742: $(LDRV)/lp:    $(USRSYS)/lib/lp.a
        !          83743:        ( cd $(USRSYS); ldconfig lp )
        !          83744: 
        !          83745: $(LDRV)/mm:    $(USRSYS)/lib/mm.a
        !          83746:        ( cd $(USRSYS); ldconfig mm )
        !          83747: 
        !          83748: $(LDRV)/ms:    $(USRSYS)/lib/ms.a
        !          83749:        ( cd $(USRSYS); ldconfig ms )
        !          83750: 
        !          83751: $(LDRV)/rm:    $(USRSYS)/lib/rm.a
        !          83752:        ( cd $(USRSYS); ldconfig rm )
        !          83753: 
        !          83754: $(LDRV)/ss:    $(USRSYS)/lib/ss.a
        !          83755:        ( cd $(USRSYS); ldconfig ss )
        !          83756: @
        !          83757: 0707070064030141331006440000030000030000011777770507310710600005200000012516/newbits/kernel/USRSRC/i8086/drv/kbmain.c/*
        !          83758:  * driver routine for loadable keyboard tables.
        !          83759:  *
        !          83760:  * prior to firing off the ioctl() which loads the new keyboard tables,
        !          83761:  * permform some simple validity checks on the table.
        !          83762:  * if errors are found, bail out without setting the new table.
        !          83763:  *
        !          83764:  * Version 1.0, 6/8/91
        !          83765:  */
        !          83766: #include <stdio.h>
        !          83767: #include <sgtty.h>
        !          83768: #include <sys/kb.h>
        !          83769: #include <sys/kbscan.h>
        !          83770: #include <errno.h>
        !          83771: 
        !          83772: #define        VERSION "1.0"
        !          83773: #define        FALSE   (0 != 0)
        !          83774: #define        TRUE    (0 == 0)
        !          83775: 
        !          83776: /*
        !          83777:  * globals
        !          83778:  */
        !          83779: char   *argv0;                         /* name of this executable */
        !          83780: int    errors;                         /* for exit status */
        !          83781: char   verbose;                        /* step-by-step details */
        !          83782: char   debug;                          /* print out cooked table & exit */
        !          83783: KBTBL  table[MAX_KEYS];                /* cooked table for ioctl() */
        !          83784: FNKEY  *arena;                         /* function key arena */
        !          83785: 
        !          83786: unsigned char  keyval[] = {            /* code set 3 mapped value */
        !          83787: none, K_1, K_2, K_3, K_4, K_5, K_6, K_7,
        !          83788: K_8, K_9, K_10, K_11, K_12, K_13, none, K_15,
        !          83789: K_16, K_17, K_18, K_19, K_20, K_21, K_22, K_23,
        !          83790: K_24, K_25, K_26, K_27, K_28, K_29, K_30, K_31,
        !          83791: K_32, K_33, K_34, K_35, K_36, K_37, K_38, K_39,
        !          83792: K_40, K_41, K_42, K_43, K_44, K_45, K_46, K_47,
        !          83793: K_48, K_49, K_50, K_51, K_52, K_53, K_54, K_55,
        !          83794: none, K_57, K_58, none, K_60, K_61, K_62, none,
        !          83795: K_64, none, none, none, none, none, none, none,
        !          83796: none, none, none, K_75, K_76, none, none, K_79,
        !          83797: K_80, K_81, none, K_83, K_84, K_85, K_86, none,
        !          83798: none, K_89, K_90, K_91, K_92, K_93, none, K_95,
        !          83799: K_96, K_97, K_98, K_99, K_100, K_101, K_102, K_103,
        !          83800: K_104, K_105, K_106, none, K_108, none, K_110, none,
        !          83801: K_112, K_113, K_114, K_115, K_116, K_117, K_118, K_119,
        !          83802: K_120, K_121, K_122, K_123, K_124, K_125, K_126
        !          83803: };
        !          83804: 
        !          83805: /*
        !          83806:  * externs from user-defined keyboard table
        !          83807:  */
        !          83808: extern KBTBL   kbtbl[];                        /* actual table */
        !          83809: extern char    tbl_name[];                     /* name of table as text */
        !          83810: extern unsigned char *funkey[];                /* function key definitions */
        !          83811: extern int     numfun;                         /* # of function keys in tbl */
        !          83812: extern int     numkey;                         /* number of keys in kbtbl[] */
        !          83813: 
        !          83814: main(argc, argv)
        !          83815: char *argv[];
        !          83816: {
        !          83817:        unsigned char *cp, *ncp;
        !          83818:        int i, j;
        !          83819:        int fd;                                 /* console file descriptor */
        !          83820: 
        !          83821:        argv0 = argv[0];
        !          83822:        if ((arena = (FNKEY *)malloc(sizeof(FNKEY) + MAX_FCHAR)) == NULL) {
        !          83823:                err("out of memory");
        !          83824:                exit(errors);
        !          83825:        }
        !          83826:        if (argc > 1) {
        !          83827:                if (strcmp(argv[1], "-V") == 0)
        !          83828:                        printf("Version %s\n", VERSION);
        !          83829:                else if (strcmp(argv[1], "-D") == 0)
        !          83830:                        ++debug;
        !          83831:                else
        !          83832:                        usage();
        !          83833:        }
        !          83834: 
        !          83835:        if ((fd = open("/dev/console", 2)) < 0) {
        !          83836:                err("unable to access console");
        !          83837:                exit(errors);
        !          83838:        }
        !          83839: 
        !          83840:        /*
        !          83841:         * loop through the user's keyboard table validating each entry.
        !          83842:         * if the entry is good, copy it to the destination table.
        !          83843:         */
        !          83844:        for (i = 0; i < numkey; ++i) {          /* loop thru user's keys */
        !          83845:                if (ok_entry(i)) {
        !          83846:                        j = kbtbl[i].k_key;             /* map key */
        !          83847:                        table[j] = kbtbl[i];            /* copy entry */
        !          83848:                } else
        !          83849:                        ++errors;
        !          83850:        }
        !          83851: 
        !          83852:        if (errors)
        !          83853:                exit(errors);
        !          83854:        /*
        !          83855:         * build a function key arena consisting of the user defined
        !          83856:         * special and function keys.
        !          83857:         */
        !          83858:        ncp = arena->k_fnval;
        !          83859:        for (i = 0; i < numfun; ++i) {
        !          83860:                cp = funkey[i];
        !          83861:                do {
        !          83862:                        if (ncp >= &arena->k_fnval[MAX_FCHAR]) {
        !          83863:                                err("function key table overflow");
        !          83864:                                exit(errors);
        !          83865:                        }
        !          83866:                        *ncp++ = *cp;
        !          83867:                } while (*cp++ != DELIM);
        !          83868:        }
        !          83869:        arena->k_nfkeys = numfun;
        !          83870: 
        !          83871:        if (debug) {
        !          83872:                dump();                         /* print out cooked table */
        !          83873:                exit(0);
        !          83874:        }
        !          83875: 
        !          83876:        /*
        !          83877:         * load the cooked keyboard table into the driver via a
        !          83878:         * special ioctl() call.
        !          83879:         */
        !          83880:        ioctl(fd, TIOCSETKBT, table);
        !          83881:        if (errno) {
        !          83882:                perror("keyboard table ioctl() failed");
        !          83883:                exit(++errors);
        !          83884:        }
        !          83885: 
        !          83886:        /*
        !          83887:         * load the cooked function key table into the driver via a
        !          83888:         * special ioctl() call.
        !          83889:         */
        !          83890:        ioctl(fd, TIOCSETF, arena);
        !          83891:        if (errno) {
        !          83892:                perror("function key ioctl() failed");
        !          83893:                exit(++errors);
        !          83894:        }
        !          83895: 
        !          83896:        printf("Loaded %s\n", tbl_name);
        !          83897:        close(fd);
        !          83898:        exit(errors);
        !          83899: }
        !          83900: 
        !          83901: /*
        !          83902:  * validate a table entry
        !          83903:  */
        !          83904: ok_entry(n)
        !          83905: register int n;
        !          83906: {
        !          83907:        int i;
        !          83908:        int key = lookup(kbtbl[n].k_key);
        !          83909: 
        !          83910:        if (!key) {
        !          83911:                err("invalid key #0x%x in kbtbl[%d]", kbtbl[n].k_key, n);
        !          83912:                return FALSE;
        !          83913:        }
        !          83914:        if ((kbtbl[n].k_flags & (S|F)) == (S|F)) {
        !          83915:                err("invalid flag field for key K_%d", key);
        !          83916:                return FALSE;
        !          83917:        }
        !          83918:        if (kbtbl[n].k_flags & S) {
        !          83919:                for (i = BASE; i <= ALT_GR; ++i) {
        !          83920:                        if (kbtbl[n].k_val[i] != kbtbl[n].k_val[BASE]) {
        !          83921:                                err("inconsistent shift key entry for K_%d",
        !          83922:                                    key);
        !          83923:                                return FALSE;
        !          83924:                        }
        !          83925:                        if (kbtbl[n].k_val[i] < scroll
        !          83926:                           || kbtbl[n].k_val[i] > altgr) {
        !          83927:                                err("bad shift key entry for K_%d",
        !          83928:                                    key);
        !          83929:                                return FALSE;
        !          83930:                        }
        !          83931:                } /* for */
        !          83932:        } else if (kbtbl[n].k_flags & F) {
        !          83933:                for (i = BASE; i <= ALT_GR; ++i) {
        !          83934:                        if (kbtbl[n].k_val[i] != none)
        !          83935:                                if (kbtbl[n].k_val[i] >= numfun) {
        !          83936:                                        err("bad function key entry for K_%d",
        !          83937:                                            key);
        !          83938:                                        return FALSE;
        !          83939:                                }
        !          83940:                } /* for */
        !          83941:        } /* flag key */
        !          83942: 
        !          83943:        key = kbtbl[n].k_key;
        !          83944:        if (table[key].k_key != 0) {
        !          83945:                err("multiple entries for K_%d", key);
        !          83946:                return FALSE;
        !          83947:        }
        !          83948:        return TRUE;
        !          83949: }
        !          83950: 
        !          83951: /*
        !          83952:  * lookup the physical key number associated with a given
        !          83953:  * code set 3 scan code.
        !          83954:  *
        !          83955:  * return 0 if not found.
        !          83956:  */
        !          83957: lookup(sc)
        !          83958: unsigned sc;
        !          83959: {
        !          83960:        register int i;
        !          83961: 
        !          83962:        if (sc == none)
        !          83963:                return 0;
        !          83964:        for (i = 0; i < sizeof(keyval)/sizeof(keyval[0]); ++i)
        !          83965:                if (keyval[i] == (unsigned char)sc)
        !          83966:                        return (i);
        !          83967:        return 0;
        !          83968: }
        !          83969: 
        !          83970: usage()
        !          83971: {
        !          83972:        fprintf(stderr, "usage:\t%s [-V]\n", argv0);
        !          83973:        exit(1);
        !          83974: }
        !          83975: 
        !          83976: err(msg)
        !          83977: char *msg;
        !          83978: {
        !          83979:        fprintf(stderr, "%s: ERROR: %r\n", argv0, &msg);
        !          83980:        ++errors;
        !          83981: }
        !          83982: 
        !          83983: /*
        !          83984:  * dump the cooked keyboard table to stdout
        !          83985:  */
        !          83986: dump()
        !          83987: {
        !          83988:        int i, j;
        !          83989: 
        !          83990:        for (i = 0; i < MAX_KEYS; ++i) {
        !          83991:                printf("%02x: %02x ", i, table[i].k_key);
        !          83992:                for (j = 0; j < 9; ++j)
        !          83993:                        printf("%02x ", table[i].k_val[j]);
        !          83994:                printf("(%02x)\n", table[i].k_flags);
        !          83995:        }
        !          83996: }
        !          83997: 0707070064030143450407550000000000000000011777770507310711000005100000000000/newbits/kernel/USRSRC/i8086/drv/objects0707070064030107500407550000030000030000011777770507310711000004700000000000/newbits/kernel/USRSRC/i8086/drv/tools0707070064030112621004440000030000030000011777770507310711000006100000003706/newbits/kernel/USRSRC/i8086/drv/tools/fontgen.c/* (-lgl
        !          83998:  *     COHERENT Driver Kit Version 1.1.0
        !          83999:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          84000:  *     All rights reserved. May not be copied without permission.
        !          84001:  -lgl) */
        !          84002: /*
        !          84003:  * fontgen - generate 16x8 font assembler source on stdout.
        !          84004:  */
        !          84005: 
        !          84006: #define        BIT(n)  (1 << (n))
        !          84007: #define        BITS(n) (((n) >= 4) ? (3 << (((n) - 4) * 2)) : (3 << (((n) + 4) * 2)))
        !          84008: 
        !          84009: unsigned char ibuf[1024];
        !          84010: unsigned char odef[] = "\tB________ = 0000000\n";
        !          84011: unsigned char obuf[] = "\t.word\tB________\n";
        !          84012: 
        !          84013: main()
        !          84014: {
        !          84015:        register unsigned s;
        !          84016:        register unsigned j;
        !          84017:        register unsigned i;
        !          84018:        extern long lseek();
        !          84019: 
        !          84020:        /*
        !          84021:         * Read fonts from /dev/mem at offset 0xFFA6E.
        !          84022:         */
        !          84023:        close(0);
        !          84024:        if (open("/dev/mem", 0) != 0)
        !          84025:                fatal("/dev/mem: can't open\n");
        !          84026:        if (lseek( 0, 0xFFA6EL, 0) != 0xFFA6EL)
        !          84027:                fatal("/dev/mem: can't seek to fonts");
        !          84028:        if (read( 0, ibuf, sizeof ibuf ) != sizeof ibuf)
        !          84029:                fatal("/dev/mem: can't read fonts");
        !          84030: 
        !          84031:        /*
        !          84032:         * Define symbolic constants.
        !          84033:         */
        !          84034:        for (i=0; i < 256; ++i) {
        !          84035:                /* Generate constant's name. */
        !          84036:                s = i;
        !          84037:                for (j=10; --j >= 2; s>>=1)
        !          84038:                        odef[j] = (s&1) ? 'X' : '_';
        !          84039: 
        !          84040:                /* Convert 8 pixel width to 16 pixels */
        !          84041:                s = 0;
        !          84042:                for (j=0; j < 8; ++j)
        !          84043:                        if (i & BIT(j))
        !          84044:                                s |= BITS(j);
        !          84045: 
        !          84046:                /* Generate constant's value */
        !          84047:                for (j=19; j >= 14; --j) {
        !          84048:                        odef[j] = (s & 7) + '0';
        !          84049:                        s >>= 3;
        !          84050:                }
        !          84051: 
        !          84052:                /* Print constant's name and value */
        !          84053:                send( odef );
        !          84054:        }
        !          84055:        send( "\n\t.globl\tfontw_\nfontw_:" );
        !          84056: 
        !          84057:        /*
        !          84058:         * Define fonts for 128 characters.
        !          84059:         */
        !          84060:        for (i=0; i < sizeof ibuf; ++i) {
        !          84061: 
        !          84062:                /* Format and print one pixel line */
        !          84063:                j = 16;
        !          84064:                s = ibuf[i];
        !          84065:                while ( --j >= 8 ) {
        !          84066:                        obuf[j] = (s&1) ? 'X' : '_' ;
        !          84067:                        s >>= 1;
        !          84068:                }
        !          84069:                send( obuf );
        !          84070: 
        !          84071:                /* Insert blank line between characters for readability */
        !          84072:                if ( (i & 7) == 7 )
        !          84073:                        send( "\n" );
        !          84074:        }
        !          84075:        exit( 0 );
        !          84076: }
        !          84077: 
        !          84078: /*
        !          84079:  * Fatal( msg ) - report error, and abort.
        !          84080:  */
        !          84081: 
        !          84082: fatal( msg )
        !          84083: register char *msg;
        !          84084: {
        !          84085:        write( 2, msg, strlen(msg) );
        !          84086:        exit( 1 );
        !          84087: }
        !          84088: 
        !          84089: /*
        !          84090:  * send( s ) - write null-terminated string to standard output.
        !          84091:  */
        !          84092: 
        !          84093: send( s )
        !          84094: register char *s;
        !          84095: {
        !          84096:        write( 1, s, strlen(s) );
        !          84097: }
        !          84098: 0707070064030127070407550000030000030000011777770507310711000005300000000000/newbits/kernel/USRSRC/i8086/drv/tools/RCS0707070064030046021004440000030000030000011777770507310711000006700000004266/newbits/kernel/USRSRC/i8086/drv/tools/RCS/fontgen.c,vhead     1.1;
        !          84099: branch   ;
        !          84100: access   ;
        !          84101: symbols  ;
        !          84102: locks    bin:1.1; strict;
        !          84103: comment  @ * @;
        !          84104: 
        !          84105: 
        !          84106: 1.1
        !          84107: date     91.07.02.09.23.11;  author bin;  state Exp;
        !          84108: branches ;
        !          84109: next     ;
        !          84110: 
        !          84111: 
        !          84112: desc
        !          84113: @init ver prov by hel
        !          84114: @
        !          84115: 
        !          84116: 
        !          84117: 
        !          84118: 1.1
        !          84119: log
        !          84120: @Initial revision
        !          84121: @
        !          84122: text
        !          84123: @/* (-lgl
        !          84124:  *     COHERENT Driver Kit Version 1.1.0
        !          84125:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          84126:  *     All rights reserved. May not be copied without permission.
        !          84127:  -lgl) */
        !          84128: /*
        !          84129:  * fontgen - generate 16x8 font assembler source on stdout.
        !          84130:  */
        !          84131: 
        !          84132: #define        BIT(n)  (1 << (n))
        !          84133: #define        BITS(n) (((n) >= 4) ? (3 << (((n) - 4) * 2)) : (3 << (((n) + 4) * 2)))
        !          84134: 
        !          84135: unsigned char ibuf[1024];
        !          84136: unsigned char odef[] = "\tB________ = 0000000\n";
        !          84137: unsigned char obuf[] = "\t.word\tB________\n";
        !          84138: 
        !          84139: main()
        !          84140: {
        !          84141:        register unsigned s;
        !          84142:        register unsigned j;
        !          84143:        register unsigned i;
        !          84144:        extern long lseek();
        !          84145: 
        !          84146:        /*
        !          84147:         * Read fonts from /dev/mem at offset 0xFFA6E.
        !          84148:         */
        !          84149:        close(0);
        !          84150:        if (open("/dev/mem", 0) != 0)
        !          84151:                fatal("/dev/mem: can't open\n");
        !          84152:        if (lseek( 0, 0xFFA6EL, 0) != 0xFFA6EL)
        !          84153:                fatal("/dev/mem: can't seek to fonts");
        !          84154:        if (read( 0, ibuf, sizeof ibuf ) != sizeof ibuf)
        !          84155:                fatal("/dev/mem: can't read fonts");
        !          84156: 
        !          84157:        /*
        !          84158:         * Define symbolic constants.
        !          84159:         */
        !          84160:        for (i=0; i < 256; ++i) {
        !          84161:                /* Generate constant's name. */
        !          84162:                s = i;
        !          84163:                for (j=10; --j >= 2; s>>=1)
        !          84164:                        odef[j] = (s&1) ? 'X' : '_';
        !          84165: 
        !          84166:                /* Convert 8 pixel width to 16 pixels */
        !          84167:                s = 0;
        !          84168:                for (j=0; j < 8; ++j)
        !          84169:                        if (i & BIT(j))
        !          84170:                                s |= BITS(j);
        !          84171: 
        !          84172:                /* Generate constant's value */
        !          84173:                for (j=19; j >= 14; --j) {
        !          84174:                        odef[j] = (s & 7) + '0';
        !          84175:                        s >>= 3;
        !          84176:                }
        !          84177: 
        !          84178:                /* Print constant's name and value */
        !          84179:                send( odef );
        !          84180:        }
        !          84181:        send( "\n\t.globl\tfontw_\nfontw_:" );
        !          84182: 
        !          84183:        /*
        !          84184:         * Define fonts for 128 characters.
        !          84185:         */
        !          84186:        for (i=0; i < sizeof ibuf; ++i) {
        !          84187: 
        !          84188:                /* Format and print one pixel line */
        !          84189:                j = 16;
        !          84190:                s = ibuf[i];
        !          84191:                while ( --j >= 8 ) {
        !          84192:                        obuf[j] = (s&1) ? 'X' : '_' ;
        !          84193:                        s >>= 1;
        !          84194:                }
        !          84195:                send( obuf );
        !          84196: 
        !          84197:                /* Insert blank line between characters for readability */
        !          84198:                if ( (i & 7) == 7 )
        !          84199:                        send( "\n" );
        !          84200:        }
        !          84201:        exit( 0 );
        !          84202: }
        !          84203: 
        !          84204: /*
        !          84205:  * Fatal( msg ) - report error, and abort.
        !          84206:  */
        !          84207: 
        !          84208: fatal( msg )
        !          84209: register char *msg;
        !          84210: {
        !          84211:        write( 2, msg, strlen(msg) );
        !          84212:        exit( 1 );
        !          84213: }
        !          84214: 
        !          84215: /*
        !          84216:  * send( s ) - write null-terminated string to standard output.
        !          84217:  */
        !          84218: 
        !          84219: send( s )
        !          84220: register char *s;
        !          84221: {
        !          84222:        write( 1, s, strlen(s) );
        !          84223: }
        !          84224: @
        !          84225: 0707070064030112631006440000030000030000011777770507310711100005700000004521/newbits/kernel/USRSRC/i8086/drv/tools/parms.c/* parms.c - display hard drive parameters per "atparm" in kernel */
        !          84226: 
        !          84227: #include <stdio.h>
        !          84228: #include <l.out.h>
        !          84229: 
        !          84230: /*
        !          84231:  * For easy referencing.
        !          84232:  */
        !          84233: #define        at_table                nl[0].n_value
        !          84234: #define        plowner         nl[1].n_value
        !          84235: #define NDRIVE         2
        !          84236: 
        !          84237: struct dparm_s {
        !          84238:        unsigned short  d_ncyl;         /* number of cylinders */
        !          84239:        unsigned char   d_nhead;        /* number of heads */
        !          84240:        unsigned short  d_rwcc;         /* reduced write current cyl */
        !          84241:        unsigned short  d_wpcc;         /* write pre-compensation cyl */
        !          84242:        unsigned char   d_eccl;         /* max ecc data length */
        !          84243:        unsigned char   d_ctrl;         /* control byte */
        !          84244:        unsigned char   d_fill2[3];
        !          84245:        unsigned short  d_landc;        /* landing zone cylinder */
        !          84246:        unsigned char   d_nspt;         /* number of sectors per track */
        !          84247:        unsigned char   d_fill3;
        !          84248: 
        !          84249: }      atparm[ NDRIVE ] = {
        !          84250:        0                               /* Initialized to allow patching */
        !          84251: };
        !          84252: 
        !          84253: /*
        !          84254:  * Table for namelist.
        !          84255:  */
        !          84256: struct nlist nl[] ={
        !          84257:        "atparm_",              0,      0,
        !          84258:        ""
        !          84259: };
        !          84260: 
        !          84261: /*
        !          84262:  * Symbols.
        !          84263:  */
        !          84264: char    *kfile;                        /* Kernel data memory file */
        !          84265: char    *nfile;                        /* Namelist file */
        !          84266: int     kfd;                           /* Kernel memory file descriptor */
        !          84267: 
        !          84268: main(argc, argv)
        !          84269: char *argv[];
        !          84270: {
        !          84271:        register int i;
        !          84272:        register char *cp;
        !          84273: 
        !          84274:        initialise();
        !          84275:        for (i=1; i<argc; i++) {
        !          84276:                for (cp=&argv[i][0]; *cp; cp++) {
        !          84277:                        switch (*cp) {
        !          84278:                        case '-':
        !          84279:                                continue;
        !          84280:                        case 'c':
        !          84281:                                if (++i >= argc)
        !          84282:                                        usage();
        !          84283:                                nfile = argv[i];
        !          84284:                                continue;
        !          84285:                        default:
        !          84286:                                usage();
        !          84287:                        }
        !          84288:                }
        !          84289:        }
        !          84290:        execute();
        !          84291:        exit(0);
        !          84292: }
        !          84293: 
        !          84294: /*
        !          84295:  * Initialise.
        !          84296:  */
        !          84297: initialise()
        !          84298: {
        !          84299:        nfile = "/coherent";
        !          84300:        kfile = "/dev/kmem";
        !          84301: }
        !          84302: 
        !          84303: /*
        !          84304:  * Print out usage.
        !          84305:  */
        !          84306: usage()
        !          84307: {
        !          84308:        panic("Usage: parms [-][c kernel_file]");
        !          84309: }
        !          84310: 
        !          84311: /*
        !          84312:  * Display parameters
        !          84313:  */
        !          84314: execute()
        !          84315: {
        !          84316:        int dr;
        !          84317: 
        !          84318:        nlist(nfile, nl);
        !          84319:        if (nl[0].n_type == 0)
        !          84320:                panic("Bad namelist file %s", nfile);
        !          84321:        if ((kfd = open(kfile, 0)) < 0)
        !          84322:                panic("Cannot open %s", kfile);
        !          84323: 
        !          84324:        kread((long)at_table, atparm, sizeof(atparm));
        !          84325:        printf("Hard drive parameters as stored in \"at\" driver:\n");
        !          84326:        for (dr = 0;  dr < NDRIVE;  dr++) {
        !          84327:                printf("drive %d  cyl=%4d  hd=%2d  spt=%2d  ctrl=%02x\n",
        !          84328:                        dr, atparm[dr].d_ncyl, atparm[dr].d_nhead,
        !          84329:                        atparm[dr].d_nspt, atparm[dr].d_ctrl);
        !          84330:        }
        !          84331: }
        !          84332: 
        !          84333: /*
        !          84334:  * Read `n' bytes into the buffer `bp' from kernel memory
        !          84335:  * starting at seek position `s'.
        !          84336:  */
        !          84337: kread(s, bp, n)
        !          84338: long s;
        !          84339: {
        !          84340:        lseek(kfd, (long)s, 0);
        !          84341:        if (read(kfd, bp, n) != n)
        !          84342:                panic("Kernel memory read error");
        !          84343: }
        !          84344: 
        !          84345: /*
        !          84346:  * Print out an error message and exit.
        !          84347:  */
        !          84348: panic(a1)
        !          84349: char *a1;
        !          84350: {
        !          84351:        fflush(stdout);
        !          84352:        fprintf(stderr, "%r", &a1);
        !          84353:        fprintf(stderr, "\n");
        !          84354:        exit(1);
        !          84355: }
        !          84356: 0707070064030112641004440000030000030000011777770507310711100005700000003746/newbits/kernel/USRSRC/i8086/drv/tools/prate.c/* (-lgl
        !          84357:  *     COHERENT Driver Kit Version 1.1.0
        !          84358:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !          84359:  *     All rights reserved. May not be copied without permission.
        !          84360:  -lgl) */
        !          84361: /*
        !          84362:  * prate.c - display polling rate of com[1-4] drivers
        !          84363:  */
        !          84364: 
        !          84365: #include <stdio.h>
        !          84366: #include <l.out.h>
        !          84367: #include <poll_clk.h>
        !          84368: 
        !          84369: /*
        !          84370:  * For easy referencing.
        !          84371:  */
        !          84372: #define        plrate          nl[0].n_value
        !          84373: #define        plowner         nl[1].n_value
        !          84374: 
        !          84375: /*
        !          84376:  * Table for namelist.
        !          84377:  */
        !          84378: struct nlist nl[] ={
        !          84379:        "poll_rate_",           0,      0,
        !          84380:        "poll_owner_",          0,      0,
        !          84381:        ""
        !          84382: };
        !          84383: 
        !          84384: /*
        !          84385:  * Symbols.
        !          84386:  */
        !          84387: char    *kfile;                        /* Kernel data memory file */
        !          84388: char    *nfile;                        /* Namelist file */
        !          84389: int     kfd;                           /* Kernel memory file descriptor */
        !          84390: 
        !          84391: main(argc, argv)
        !          84392: char *argv[];
        !          84393: {
        !          84394:        register int i;
        !          84395:        register char *cp;
        !          84396: 
        !          84397:        initialise();
        !          84398:        for (i=1; i<argc; i++) {
        !          84399:                for (cp=&argv[i][0]; *cp; cp++) {
        !          84400:                        switch (*cp) {
        !          84401:                        case '-':
        !          84402:                                continue;
        !          84403:                        case 'c':
        !          84404:                                if (++i >= argc)
        !          84405:                                        usage();
        !          84406:                                nfile = argv[i];
        !          84407:                                continue;
        !          84408:                        default:
        !          84409:                                usage();
        !          84410:                        }
        !          84411:                }
        !          84412:        }
        !          84413:        execute();
        !          84414:        exit(0);
        !          84415: }
        !          84416: 
        !          84417: /*
        !          84418:  * Initialise.
        !          84419:  */
        !          84420: initialise()
        !          84421: {
        !          84422:        nfile = "/coherent";
        !          84423:        kfile = "/dev/kmem";
        !          84424: }
        !          84425: 
        !          84426: /*
        !          84427:  * Print out usage.
        !          84428:  */
        !          84429: usage()
        !          84430: {
        !          84431:        panic("Usage: prate [-][c kernel_file]");
        !          84432: }
        !          84433: 
        !          84434: /*
        !          84435:  * Display polling rate
        !          84436:  */
        !          84437: execute()
        !          84438: {
        !          84439:        int rate, owner;
        !          84440: 
        !          84441:        nlist(nfile, nl);
        !          84442:        if (nl[0].n_type == 0)
        !          84443:                panic("Bad namelist file %s", nfile);
        !          84444:        if ((kfd = open(kfile, 0)) < 0)
        !          84445:                panic("Cannot open %s", kfile);
        !          84446: 
        !          84447:        kread((long)plrate, &rate, sizeof(rate));
        !          84448:        kread((long)plowner, &owner, sizeof(owner));
        !          84449:        if (rate) {
        !          84450:                if (owner & POLL_AL)
        !          84451:                        printf("al driver is ");
        !          84452:                else if (owner & POLL_HS)
        !          84453:                        printf("hs driver is ");
        !          84454:                printf("polling at %d Hz\n", rate);
        !          84455:        } else
        !          84456:                printf("polling is OFF\n");
        !          84457: }
        !          84458: 
        !          84459: /*
        !          84460:  * Read `n' bytes into the buffer `bp' from kernel memory
        !          84461:  * starting at seek position `s'.
        !          84462:  */
        !          84463: kread(s, bp, n)
        !          84464: long s;
        !          84465: {
        !          84466:        lseek(kfd, (long)s, 0);
        !          84467:        if (read(kfd, bp, n) != n)
        !          84468:                panic("Kernel memory read error");
        !          84469: }
        !          84470: 
        !          84471: /*
        !          84472:  * Print out an error message and exit.
        !          84473:  */
        !          84474: panic(a1)
        !          84475: char *a1;
        !          84476: {
        !          84477:        fflush(stdout);
        !          84478:        fprintf(stderr, "%r", &a1);
        !          84479:        fprintf(stderr, "\n");
        !          84480:        exit(1);
        !          84481: }
        !          84482: 0707070064030107730407550000030000030000011777770507310711200004700000000000/newbits/kernel/USRSRC/i8086/drv/stuff0707070064030050661006440000030000030000011777770507310711200004700000046137/newbits/kernel/USRSRC/i8086/drv/gkb.c/*
        !          84483:  * Keyboard/display driver for German keyboard.
        !          84484:  * Coherent, IBM PC/XT and AT (in XT mode).
        !          84485:  */
        !          84486: #include <sys/coherent.h>
        !          84487: #include <sys/i8086.h>
        !          84488: #include <sys/con.h>
        !          84489: #include <errno.h>
        !          84490: #include <sys/stat.h>
        !          84491: #include <sys/tty.h>
        !          84492: #include <sys/uproc.h>
        !          84493: #include <signal.h>
        !          84494: #include <sys/sched.h>
        !          84495: 
        !          84496: #define        ISMAJ   2                       /* Keyboard major device */
        !          84497: 
        !          84498: #define        SPC     0376                    /* Special encoding */
        !          84499: #define XXX    0377                    /* Non-character */
        !          84500: #define        KBDATA  0x60                    /* Keyboard data */
        !          84501: #define        KBCTRL  0x61                    /* Keyboard control */
        !          84502: #define        KBFLAG  0x80                    /* Keyboard reset flag */
        !          84503: #define        LEDCMD  0xED                    /* status indicator command */
        !          84504: #define        KBACK   0xFA                    /* status indicator acknowledge */
        !          84505: #define        EXTENDED0 0xE0                  /* extended key seq initiator */
        !          84506: #define        EXTENDED1 0xE1                  /* extended key seq initiator */
        !          84507: 
        !          84508: #define        KEYUP   0x80                    /* Key up change */
        !          84509: #define        KEYSC   0x7F                    /* Key scan code mask */
        !          84510: #define        LSHIFT  0x2A-1                  /* Left shift key */
        !          84511: #define LSHIFTA 0x2B-1                 /* Alternate left-shift key */
        !          84512: #define        RSHIFT  0x36-1                  /* Right shift key */
        !          84513: #define        CTRL    0x1D-1                  /* Control key */
        !          84514: /*-- #define   CAPLOCK 0x1D-1  --*/            /* Control key */
        !          84515: #define        ALT     0x38-1                  /* ALT key or ALT GR */
        !          84516: #define        CAPLOCK 0x3A-1                  /* Caps lock key */
        !          84517: /*-- #define   CTRL    0x3A-1  --*/            /* Caps lock key */
        !          84518: #define        NUMLOCK 0x45-1                  /* Numeric lock key */
        !          84519: #define        DELETE  0x53-1                  /* Del, as in CTRL-ALT-DEL */
        !          84520: #define BACKSP 0x0E-1                  /* Back space */
        !          84521: #define SCRLOCK        0x46-1                  /* Scroll lock */
        !          84522: 
        !          84523: /* Shift flags */
        !          84524: #define        SRS     0x01                    /* Right shift key on */
        !          84525: #define        SLS     0x02                    /* Left shift key on */
        !          84526: #define CTS    0x04                    /* Ctrl key on */
        !          84527: #define ALS    0x08                    /* Alt key on */
        !          84528: #define CPLS   0x10                    /* Caps lock on */
        !          84529: #define NMLS   0x20                    /* Num lock on */
        !          84530: #define AKPS   0x40                    /* Alternate keypad shift */
        !          84531: #define SHFT   0x80                    /* Shift key flag */
        !          84532: #define        AGS     0x100                   /* Alt Graphics on */
        !          84533: 
        !          84534: /* Function key information */
        !          84535: #define        NFKEY   20                      /* Number of settable functions */
        !          84536: #define        NFCHAR  150                     /* Number of characters settable */
        !          84537: #define        NFBUF   (NFKEY*2+NFCHAR+1)      /* Size of buffer */
        !          84538: 
        !          84539: /*
        !          84540:  * Functions.
        !          84541:  */
        !          84542: int    isrint();
        !          84543: int    istime();
        !          84544: void   isbatch();
        !          84545: int    mmstart();
        !          84546: int    isopen();
        !          84547: int    isclose();
        !          84548: int    isread();
        !          84549: int    mmwrite();
        !          84550: int    isioctl();
        !          84551: void   mmwatch();
        !          84552: int    isload();
        !          84553: int    isuload();
        !          84554: int    ispoll();
        !          84555: int    nulldev();
        !          84556: int    nonedev();
        !          84557: 
        !          84558: /*
        !          84559:  * Configuration table.
        !          84560:  */
        !          84561: CON iscon ={
        !          84562:        DFCHR|DFPOL,                    /* Flags */
        !          84563:        ISMAJ,                          /* Major index */
        !          84564:        isopen,                         /* Open */
        !          84565:        isclose,                        /* Close */
        !          84566:        nulldev,                        /* Block */
        !          84567:        isread,                         /* Read */
        !          84568:        mmwrite,                        /* Write */
        !          84569:        isioctl,                        /* Ioctl */
        !          84570:        nulldev,                        /* Powerfail */
        !          84571:        mmwatch,                        /* Timeout */
        !          84572:        isload,                         /* Load */
        !          84573:        isuload,                        /* Unload */
        !          84574:        ispoll                          /* Poll */
        !          84575: };
        !          84576: 
        !          84577: /*
        !          84578:  * Flag indicating turbo machine.
        !          84579:  */
        !          84580: int isturbo = 0;
        !          84581: 
        !          84582: /*
        !          84583:  * Terminal structure.
        !          84584:  */
        !          84585: TTY    istty = {
        !          84586:        {0}, {0}, 0, mmstart, NULL, 0, 0
        !          84587: };
        !          84588: 
        !          84589: /*
        !          84590:  * State variables.
        !          84591:  */
        !          84592: int            islock;                 /* Keyboard locked flag */
        !          84593: int            isbusy;                 /* Raw input conversion busy */
        !          84594: static int     shift;                  /* Overall shift state */
        !          84595: static char    scroll;                 /* Scroll lock state */
        !          84596: static  char   lshift = LSHIFT;        /* Left shift alternate state */
        !          84597: static char    isfbuf[NFBUF];          /* Function key values */
        !          84598: static char    *isfval[NFKEY];         /* Function key string pointers */
        !          84599: static int     ledcmd;                 /* LED update command flag */
        !          84600: static char    extended;               /* extended key scan count */
        !          84601: static char    extmode;                /* use extended mode for this key */
        !          84602: static char    ext0seen;               /* 0xE0 prefix seen */
        !          84603: 
        !          84604: /*
        !          84605:  * Tables for converting key code to ASCII.
        !          84606:  * lmaptab specifies unshifted conversion,
        !          84607:  * umaptab specifies shifted conversion,
        !          84608:  * smaptab specifies the shift states which are active.
        !          84609:  * An entry of XXX says the key is dead.
        !          84610:  * An entry of SPC requires further processing.
        !          84611:  *
        !          84612:  * Key codes:
        !          84613:  *     ESC .. <- == 1 .. 14
        !          84614:  *     -> .. \n == 15 .. 28
        !          84615:  *     CTRL .. ` == 29 .. 41
        !          84616:  *     ^Shift .. PrtSc == 42 .. 55
        !          84617:  *     ALT .. CapsLock == 56 .. 58
        !          84618:  *     F1 .. F10 == 59 .. 68
        !          84619:  *     NumLock .. Del == 69 .. 83
        !          84620:  *     ISO, F11, F12 == 86 .. 88
        !          84621:  */
        !          84622: unsigned char agmaptab[] ={                                    /* Alt Gr */
        !          84623:               XXX,  XXX,'\375','\374',XXX,  XXX,  XXX,         /* 1 - 7 */
        !          84624:         '{',  '[',  ']',  '}', '\\',  XXX,  XXX,  XXX,         /* 8 - 15 */
        !          84625:         '@',  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 16 - 23 */
        !          84626:         XXX,  XXX,  XXX,  '~',  XXX,  XXX,  XXX,  XXX,         /* 24 - 31 */
        !          84627:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 32 - 39 */
        !          84628:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 40 - 47 */
        !          84629:         XXX,  XXX,'\346', XXX,  XXX,  XXX,  XXX,  XXX,         /* 48 - 55 */
        !          84630:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 56 - 63 */
        !          84631:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 64 - 71 */
        !          84632:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  XXX,         /* 72 - 79 */
        !          84633:         XXX,  XXX,  XXX,  XXX,  XXX,  XXX,  '|',  XXX,         /* 80 - 87 */
        !          84634:         XXX                                                    /* 88 */
        !          84635: };
        !          84636: 
        !          84637: static unsigned char lmaptab[] ={
        !          84638:             '\33',  '1',  '2',  '3',  '4',  '5',  '6',         /* 1 - 7 */
        !          84639:         '7',  '8',  '9',  '0','\341','\'', '\b', '\t',         /* 8 - 15 */
        !          84640:         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',         /* 16 - 23 */
        !          84641:         'o',  'p','\201', '+', '\r',  XXX,  'a',  's',         /* 24 - 31 */
        !          84642:         'd',  'f',  'g',  'h',  'j',  'k',  'l','\224',        /* 32 - 39 */
        !          84643:        '\204','^',  XXX,  '#',  'y', 'x',  'c',  'v',          /* 40 - 47 */
        !          84644:         'b',  'n',  'm',  ',',  '.',  SPC,  XXX,  SPC,         /* 48 - 55 */
        !          84645:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
        !          84646:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
        !          84647:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
        !          84648:         SPC,  SPC,  SPC,  SPC,  XXX,  XXX,  '<',  XXX,         /* 80 - 87 */
        !          84649:         XXX                                                    /* 88 */
        !          84650: };
        !          84651: 
        !          84652: static unsigned char umaptab[] ={
        !          84653:             '\33',  '!',  '"','\025', '$',  '%',  '&',         /* 1 - 7 */
        !          84654:         '/',  '(',  ')',  '=',  '?',  '`', '\b',  SPC,         /* 8 - 15 */
        !          84655:         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',         /* 16 - 23 */
        !          84656:         'O',  'P','\232',  '*', '\r',  XXX,  'A',  'S',        /* 24 - 31 */
        !          84657:         'D',  'F',  'G',  'H',  'J',  'K',  'L','\231',        /* 32 - 39 */
        !          84658:        '\216','\370',XXX,'\'',  'Y',  'X',  'C',  'V',         /* 40 - 47 */
        !          84659:         'B',  'N',  'M',  ';',  ':',  SPC,  XXX,  SPC,         /* 48 - 55 */
        !          84660:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
        !          84661:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
        !          84662:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
        !          84663:         SPC,  SPC,  SPC,  SPC,  XXX,  XXX,  '>',  XXX,         /* 80 - 87 */
        !          84664:         XXX                                                    /* 88 */
        !          84665: };
        !          84666: 
        !          84667: #define SS0    0                       /* No shift */
        !          84668: #define SS1    (SLS|SRS|CTS)           /* Shift, Ctrl */
        !          84669: #define SES    (SLS|SRS)               /* Shift */
        !          84670: #define LET    (SLS|SRS|CPLS|CTS)      /* Shift, Caps, Ctrl */
        !          84671: #define KEY    (SLS|SRS|NMLS|AKPS)     /* Shift, Num, Alt keypad */
        !          84672: 
        !          84673: static unsigned char smaptab[] ={
        !          84674:               SS0,  SES,  SS1,  SES,  SES,  SES,  SS1,         /* 1 - 7 */
        !          84675:         SES,  SES,  SES,  SES,  SS1,  SES,  CTS,  SES,         /* 8 - 15 */
        !          84676:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  LET,         /* 16 - 23 */
        !          84677:         LET,  LET,  SS1,  SS1,  CTS, SHFT,  LET,  LET,         /* 24 - 31 */
        !          84678:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  SES,         /* 32 - 39 */
        !          84679:         SES,  SS1, SHFT,  SS1,  LET,  LET,  LET,  LET,         /* 40 - 47 */
        !          84680:         LET,  LET,  LET,  SES,  SES,  SES, SHFT,  SES,         /* 48 - 55 */
        !          84681:        SHFT,  SS1, SHFT,  SS0,  SS0,  SS0,  SS0,  SS0,         /* 56 - 63 */
        !          84682:         SS0,  SS0,  SS0,  SS0,  SS0, SHFT,  KEY,  KEY,         /* 64 - 71 */
        !          84683:         KEY,  KEY,  SS0,  KEY,  KEY,  KEY,  SS0,  KEY,         /* 72 - 79 */
        !          84684:         KEY,  KEY,  KEY,  KEY,  SS0,  SS0,  SES,  SS0,         /* 80 - 87 */
        !          84685:         SS0
        !          84686: };
        !          84687: 
        !          84688: /*
        !          84689:  * Load entry point.
        !          84690:  *  Do reset the keyboard because it gets terribly munged
        !          84691:  *  if you type during the boot.
        !          84692:  */
        !          84693: isload()
        !          84694: {
        !          84695:        register int i;
        !          84696: 
        !          84697:        /*
        !          84698:         * Reset keyboard if NOT an XT turbo.
        !          84699:         */
        !          84700:        if ( ! isturbo ) {
        !          84701:                outb(KBCTRL, 0x0C);             /* Clock low */
        !          84702:                for (i = 10582; --i >= 0; );    /* For 20ms */
        !          84703:                outb(KBCTRL, 0xCC);             /* Clock high */
        !          84704:                for (i = 0; --i != 0; )
        !          84705:                        ;
        !          84706:                i = inb(KBDATA);
        !          84707:                outb(KBCTRL, 0xCC);                     /* Clear keyboard */
        !          84708:                outb(KBCTRL, 0x4D);                     /* Enable keyboard */
        !          84709:        }
        !          84710: 
        !          84711:        /*
        !          84712:         * Enable mmwatch() invocation every second.
        !          84713:         */
        !          84714:        drvl[ISMAJ].d_time = 1;
        !          84715: 
        !          84716:        /*
        !          84717:         * Seize keyboard interrupt.
        !          84718:         */
        !          84719:        setivec(1, isrint);
        !          84720: 
        !          84721:        /*
        !          84722:         * Initiailize video display.
        !          84723:         */
        !          84724:        mmstart( &istty );
        !          84725: }
        !          84726: 
        !          84727: /*
        !          84728:  * Unload entry point.
        !          84729:  */
        !          84730: isuload()
        !          84731: {
        !          84732:        clrivec(1);
        !          84733: }
        !          84734: 
        !          84735: /*
        !          84736:  * Default function key strings (terminated by -1 [\377])
        !          84737:  */
        !          84738: static char *deffuncs[] = {
        !          84739:        "\33[1x\377",   /* F1 */
        !          84740:        "\33[2x\377",   /* F2 */
        !          84741:        "\33[3x\377",   /* F3 */
        !          84742:        "\33[4x\377",   /* F4 */
        !          84743:        "\33[5x\377",   /* F5 */
        !          84744:        "\33[6x\377",   /* F6 */
        !          84745:        "\33[7x\377",   /* F7 */
        !          84746:        "\33[8x\377",   /* F8 */
        !          84747:        "\33[9x\377",   /* F9 */
        !          84748:        "\33[0x\377",   /* F10 - historical value */
        !          84749:        "\33[1y\377",   /* F11 */
        !          84750:        "\33[2y\377",   /* F12 */
        !          84751:        "\33[3y\377",   /* F13 */
        !          84752:        "\33[4y\377",   /* F14 */
        !          84753:        "\33[5y\377",   /* F15 */
        !          84754:        "\33[6y\377",   /* F16 */
        !          84755:        "\33[7y\377",   /* F17 */
        !          84756:        "\33[8y\377",   /* F18 */
        !          84757:        "\33[9y\377",   /* F19 */
        !          84758:        "\33[0y\377"    /* F20 */
        !          84759: };
        !          84760: 
        !          84761: /*
        !          84762:  * Open routine.
        !          84763:  */
        !          84764: isopen(dev)
        !          84765: dev_t dev;
        !          84766: {
        !          84767:        register int s;
        !          84768: 
        !          84769:        if (minor(dev) != 0) {
        !          84770:                u.u_error = ENXIO;
        !          84771:                return;
        !          84772:        }
        !          84773:        if ((istty.t_flags&T_EXCL)!=0 && super()==0) {
        !          84774:                u.u_error = ENODEV;
        !          84775:                return;
        !          84776:        }
        !          84777:        ttsetgrp(&istty, dev);
        !          84778: 
        !          84779:        s = sphi();
        !          84780:        if (istty.t_open++ == 0)
        !          84781:        {  initkeys();   /* init function keys */
        !          84782:           istty.t_flags = T_CARR;  /* indicate "carrier" */
        !          84783:           ttopen(&istty);
        !          84784:        }
        !          84785:        spl(s);
        !          84786:        updleds();                      /* update keyboard status LEDS */
        !          84787: }
        !          84788: 
        !          84789: /* Init function keys */
        !          84790: initkeys()
        !          84791: {      register int i;
        !          84792:        register char *cp1, *cp2;
        !          84793: 
        !          84794:        for (i=0; i<NFKEY; i++)
        !          84795:            isfval[i] = 0;          /* clear function key buffer */
        !          84796:        cp2 = isfbuf;               /* pointer to key buffer */   
        !          84797:        for (i=0; i<NFKEY; i++)
        !          84798:        {  isfval[i] = cp2;         /* save pointer to key string */
        !          84799:           cp1 = deffuncs[i];       /* get init string pointer */
        !          84800:           while ((*cp2++ = *cp1++) != -1)  /* copy key data */
        !          84801:             if (cp2 >= &isfbuf[NFBUF-3])   /* overflow? */
        !          84802:                return;
        !          84803:        }
        !          84804: }
        !          84805: 
        !          84806: /*
        !          84807:  * Close a tty.
        !          84808:  */
        !          84809: isclose(dev)
        !          84810: {
        !          84811:        register int s;
        !          84812: 
        !          84813:        s = sphi();
        !          84814:        if (--istty.t_open == 0)
        !          84815:        {       s = sphi();
        !          84816:                ttclose(&istty);
        !          84817:                spl(s);
        !          84818:        }
        !          84819: }
        !          84820: 
        !          84821: /*
        !          84822:  * Read routine.
        !          84823:  */
        !          84824: isread(dev, iop)
        !          84825: dev_t dev;
        !          84826: IO *iop;
        !          84827: {
        !          84828:        ttread(&istty, iop, 0);
        !          84829:        if (istty.t_oq.cq_cc)
        !          84830:                mmtime(&istty);
        !          84831: }
        !          84832: 
        !          84833: /*
        !          84834:  * Ioctl routine.
        !          84835:  */
        !          84836: isioctl(dev, com, vec)
        !          84837: dev_t dev;
        !          84838: struct sgttyb *vec;
        !          84839: {
        !          84840:        register int s;
        !          84841: 
        !          84842:        switch(com) {
        !          84843:        case TIOCSETF:
        !          84844:        case TIOCGETF:
        !          84845:                isfunction(com, (char *)vec);
        !          84846:                return;
        !          84847:        case TIOCSHIFT:   /* switch left-SHIFT and "\" */
        !          84848:                lshift = LSHIFTA;    /* alternate values */
        !          84849:                lmaptab[41] = '\\';
        !          84850:                lmaptab[42] = XXX;
        !          84851:                umaptab[41] = '|';
        !          84852:                umaptab[42] = XXX;
        !          84853:                smaptab[41] = SS1;
        !          84854:                smaptab[42] = SHFT;
        !          84855:                return;
        !          84856:        case TIOCCSHIFT:  /* normal (default) left-SHIFT and "\" */
        !          84857:                lshift = LSHIFT;     /* normal values */
        !          84858:                lmaptab[41] = XXX;
        !          84859:                lmaptab[42] = '\\';
        !          84860:                umaptab[41] = XXX;
        !          84861:                umaptab[42] = '|';
        !          84862:                smaptab[41] = SHFT;
        !          84863:                smaptab[42] = SS1;
        !          84864:                return;
        !          84865:        }
        !          84866:        s = sphi();
        !          84867:        ttioctl(&istty, com, vec);
        !          84868:        spl(s);
        !          84869: }
        !          84870: 
        !          84871: /*
        !          84872:  * Set and receive the function keys.
        !          84873:  */
        !          84874: isfunction(c, v)
        !          84875: int c;
        !          84876: char *v;
        !          84877: {
        !          84878:        register char *cp;
        !          84879:        register int i;
        !          84880: 
        !          84881:        if (c == TIOCGETF) {
        !          84882:                for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++)
        !          84883:                    putubd(v++, *cp);
        !          84884:        } else {
        !          84885:                for (i=0; i<NFKEY; i++)         /* zap current settings */
        !          84886:                        isfval[i] = 0;
        !          84887:                cp = isfbuf;                    /* pointer to key buffer */
        !          84888:                for (i=0; i<NFKEY; i++) {
        !          84889:                        isfval[i] = cp;         /* save pointer to key string */
        !          84890:                        while ((*cp++ = getubd(v++)) != -1)  /* copy key data */
        !          84891:                                if (cp >= &isfbuf[NFBUF-3])  /* overflow? */
        !          84892:                                        return;
        !          84893:                }
        !          84894:        }
        !          84895: }
        !          84896: 
        !          84897: 
        !          84898: /*
        !          84899:  * Poll routine.
        !          84900:  */
        !          84901: ispoll( dev, ev, msec )
        !          84902: dev_t dev;
        !          84903: int ev;
        !          84904: int msec;
        !          84905: {
        !          84906:        /*
        !          84907:         * Priority polls not supported.
        !          84908:         */
        !          84909:        ev &= ~POLLPRI;
        !          84910: 
        !          84911:        /*
        !          84912:         * Input poll failure.
        !          84913:         */
        !          84914:        if ( (ev & POLLIN) && (istty.t_iq.cq_cc == 0) ) {
        !          84915: 
        !          84916:                if ( msec != 0 )
        !          84917:                        pollopen( &istty.t_ipolls );
        !          84918: 
        !          84919:                /*
        !          84920:                 * Second look AFTER enabling monitor, avoiding interrupt race.
        !          84921:                 */
        !          84922:                if ( istty.t_iq.cq_cc == 0 )
        !          84923:                        ev &= ~POLLIN;
        !          84924:        }
        !          84925: 
        !          84926:        return ev;
        !          84927: }
        !          84928: 
        !          84929: /*
        !          84930:  * Receive interrupt.
        !          84931:  */
        !          84932: isrint()
        !          84933: {
        !          84934:        register int    c;
        !          84935:        register int    s;
        !          84936:        register int    r;
        !          84937:        int     savests;
        !          84938:        int     update_leds = 0;
        !          84939: 
        !          84940:        /*
        !          84941:         * Schedule raw input handler if not already active.
        !          84942:         */
        !          84943:        if ( isbusy == 0 ) {
        !          84944:                defer( isbatch, &istty );
        !          84945:                isbusy = 1;
        !          84946:        }
        !          84947: 
        !          84948:        /*
        !          84949:         * Pull character from the data
        !          84950:         * port. Pulse the KBFLAG in the control
        !          84951:         * port to reset the data buffer.
        !          84952:         */
        !          84953:        r = inb(KBDATA) & 0xFF;
        !          84954:        c = inb(KBCTRL);
        !          84955:        outb(KBCTRL, c|KBFLAG);
        !          84956:        outb(KBCTRL, c);
        !          84957: #if    0
        !          84958:        printf("kbd: %x %s\n", r&0x7F, (r&KEYUP) ? "up" : "down");
        !          84959: #endif
        !          84960:        if (ledcmd) {
        !          84961:                ledcmd = 0;
        !          84962:                if (r == KBACK) {               /* output to status LEDS */
        !          84963:                        c = scroll & 1;
        !          84964:                        if (shift & NMLS)
        !          84965:                                c |= 2;
        !          84966:                        if (shift & CPLS)
        !          84967:                                c |= 4;
        !          84968:                        outb(KBDATA, c);
        !          84969:                }
        !          84970:                return;
        !          84971:        }
        !          84972:        if (extended > 0) {                     /* if multi-character seq, */
        !          84973:                --extended;                     /* ... ignore this char */
        !          84974:                return;
        !          84975:        }
        !          84976: 
        !          84977:        switch (r) {
        !          84978:        case EXTENDED0:                         /* 0xE0 prefix found */
        !          84979:                ext0seen = 1;
        !          84980:                return;
        !          84981:        case EXTENDED1:                         /* ignore extended sequences */
        !          84982:                extended = 5;
        !          84983:                return;
        !          84984:        case 0xFF:                              /* Overrun */
        !          84985:                return;
        !          84986:        }
        !          84987: 
        !          84988:        if (ext0seen) {
        !          84989:                ext0seen = 0;
        !          84990:                extmode = 1;
        !          84991:        } else 
        !          84992:                extmode = 0;
        !          84993: 
        !          84994:        c = (r & KEYSC) - 1;                    /* bias to internal format */
        !          84995: 
        !          84996:        /*
        !          84997:         * Check for reset.
        !          84998:         */
        !          84999:        if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS))
        !          85000:                boot();
        !          85001: 
        !          85002:        /*
        !          85003:         * Track "shift" keys.
        !          85004:         */
        !          85005:        s = smaptab[c];
        !          85006:        if (s&SHFT) {
        !          85007:                if (r&KEYUP) {                  /* "shift" released */
        !          85008:                        if (c == RSHIFT)
        !          85009:                                shift &= ~SRS;
        !          85010:                        else if (c == lshift)
        !          85011:                                shift &= ~SLS;
        !          85012:                        else if (c == CTRL)
        !          85013:                                shift &= ~CTS;
        !          85014:                        else if (c == ALT)
        !          85015:                                shift &= extmode ? ~AGS : ~ALS;
        !          85016:                } else {                        /* "shift" pressed */
        !          85017:                        if (c == lshift)
        !          85018:                                shift |= SLS;
        !          85019:                        else if (c == RSHIFT)
        !          85020:                                shift |= SRS;
        !          85021:                        else if (c == CTRL)
        !          85022:                                shift |= CTS;
        !          85023:                        else if (c == ALT)
        !          85024:                                shift |= extmode ? AGS : ALS;
        !          85025:                        else if (c == CAPLOCK) {
        !          85026:                                shift ^= CPLS;  /* toggle cap lock */
        !          85027:                                updleds();
        !          85028:                        } else if (c == NUMLOCK) {
        !          85029:                                shift ^= NMLS;  /* toggle num lock */
        !          85030:                                updleds();
        !          85031:                        }
        !          85032:                }
        !          85033:                return;
        !          85034:        }
        !          85035: 
        !          85036:        /*
        !          85037:         * No other key up codes of interest.
        !          85038:         */
        !          85039:        if (r&KEYUP)
        !          85040:                return;
        !          85041: 
        !          85042:        /*
        !          85043:         * If the tty is not open the character is
        !          85044:         * just tossed away.
        !          85045:         */
        !          85046:        if (istty.t_open == 0)
        !          85047:                return;
        !          85048: 
        !          85049:        /*
        !          85050:         * Map character, based on the
        !          85051:         * current state of the shift, control, alt graphics,
        !          85052:         * meta (ALT) and lock flags.
        !          85053:         */
        !          85054:        if (shift & AGS)                        /* Alt Graphics ? */
        !          85055:                c = agmaptab[c];
        !          85056:        else if (shift & CTS) {
        !          85057:                if (s == CTS)                   /* Map Ctrl (BS | NL) */
        !          85058:                        c = (c == BACKSP) ? 0x7F : 0x0A;  
        !          85059:                else if (s==SS1 || s==LET)      /* Normal Ctrl map */
        !          85060:                        c = umaptab[c]&0x1F;    /* Clear bits 5-6 */
        !          85061:                else                            
        !          85062:                        return;                 /* Ignore this char */
        !          85063:        } else if (s &= shift) {
        !          85064:                if (shift & SES) {               /* if shift on */
        !          85065:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
        !          85066:                                c = lmaptab[c];  /* use unshifted */
        !          85067:                        else
        !          85068:                                c = umaptab[c];  /* use shifted */
        !          85069:                } else {                         /* if shift not on */
        !          85070:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
        !          85071:                                c = umaptab[c];  /* use shifted */
        !          85072:                        else
        !          85073:                                c = lmaptab[c];  /* use unshifted */
        !          85074:                }
        !          85075:        } else                                   
        !          85076:                c = lmaptab[c];                  /* use unshifted */
        !          85077: 
        !          85078:        /*
        !          85079:         * Act on character.
        !          85080:         */
        !          85081:        if (c == XXX)                           
        !          85082:                return;                          /* char to ignore */
        !          85083: 
        !          85084:        if (c != SPC) {                  /* not special char? */
        !          85085:                if (shift & ALS)         /* ALT (meta bit)? */
        !          85086:                        c |= 0x80;       /* set meta */
        !          85087:                isin(c);                 /* send the char */
        !          85088:        } else
        !          85089:                update_leds += isspecial(r);     /* special chars */
        !          85090:        if (update_leds) {
        !          85091:                savests = sphi();
        !          85092:                outb(KBDATA, LEDCMD);
        !          85093:                ledcmd = 1;
        !          85094:                spl(savests);
        !          85095:        }
        !          85096: }
        !          85097: 
        !          85098: /*
        !          85099:  * Handle special input sequences.
        !          85100:  * The character passed is the key number.
        !          85101:  *
        !          85102:  * The keypad is translated by the following table,
        !          85103:  * the first entry is the normal sequence, the second the shifted,
        !          85104:  * and the third the alternate keypad sequence.
        !          85105:  */
        !          85106: static char *keypad[][3] = {
        !          85107:        { "\33[H",  "7", "\33?w" },     /* 71 */
        !          85108:        { "\33[A",  "8", "\33?x" },     /* 72 */
        !          85109:        { "\33[V",  "9", "\33?y" },     /* 73 */
        !          85110:        { "\33[D",  "4", "\33?t" },     /* 75 */
        !          85111:        { "\0337",  "5", "\33?u" },     /* 76 */
        !          85112:        { "\33[C",  "6", "\33?v" },     /* 77 */
        !          85113:        { "\33[24H","1", "\33?q" },     /* 79 */
        !          85114:        { "\33[B",  "2", "\33?r" },     /* 80 */
        !          85115:        { "\33[U",  "3", "\33?s" },     /* 81 */
        !          85116:        { "\33[@",  "0", "\33?p" },     /* 82 */
        !          85117:        { "\33[P", ".",  "\33?n" }      /* 83 */
        !          85118: };
        !          85119: 
        !          85120: isspecial(c)
        !          85121: int c;
        !          85122: {
        !          85123:        register char *cp;
        !          85124:        register int s;
        !          85125:        int     update_leds = 0;
        !          85126: 
        !          85127:        cp = 0;
        !          85128: 
        !          85129:        switch (c) {
        !          85130:        case 15:                                        /* cursor back tab */
        !          85131:                cp = "\033[Z";
        !          85132:                break;
        !          85133:        case 53:
        !          85134:                if (extmode)
        !          85135:                        cp = "/";
        !          85136:                else if (shift & SES)
        !          85137:                        cp = "_";
        !          85138:                else
        !          85139:                        cp = "-";
        !          85140:                break;
        !          85141:        case 55:                                        /* ignore PrtScr */
        !          85142:                if (!extmode)
        !          85143:                        cp = "*";
        !          85144:                break;
        !          85145:        case 59: case 60: case 61: case 62: case 63:    /* Function keys */
        !          85146:        case 64: case 65: case 66: case 67: case 68:
        !          85147:                /* offset to function string */
        !          85148:                if ( shift & ALS )
        !          85149:                        cp = isfval[c-49];
        !          85150:                else
        !          85151:                        cp = isfval[c-59];
        !          85152:                break;
        !          85153: 
        !          85154:        case 70:                /* Scroll Lock -- stop/start output */
        !          85155:        {
        !          85156:                static char cbuf[2];
        !          85157: 
        !          85158:                cp = &cbuf[0];  /* working buffer */
        !          85159:                if (!(istty.t_sgttyb.sg_flags&RAWIN)) { /* not if in RAW mode */
        !          85160:                        ++update_leds;
        !          85161:                        if (istty.t_flags & T_STOP) {   /* output stopped? */
        !          85162:                           cbuf[0] = istty.t_tchars.t_startc;  /* start it */
        !          85163:                           scroll = 0;
        !          85164:                        } else {
        !          85165:                           cbuf[0] = istty.t_tchars.t_stopc;   /* stop output */
        !          85166:                           scroll = 1;
        !          85167:                        }
        !          85168:                }
        !          85169:                break;
        !          85170:        }
        !          85171: 
        !          85172:        case 79:                /* 1/End */
        !          85173:        case 80:                /* 2/DOWN */
        !          85174:        case 81:                /* 3/PgDn */
        !          85175:        case 82:                /* 0/Ins */
        !          85176:        case 83:                /* ./Del */
        !          85177:                --c;            /* adjust code */
        !          85178:        case 75:                /* 4/LEFT */
        !          85179:        case 76:                /* 5 */
        !          85180:        case 77:                /* 6/RIGHT */
        !          85181:                --c;            /* adjust code */
        !          85182:        case 71:                /* 7/Home/Clear */
        !          85183:        case 72:                /* 8/UP */
        !          85184:        case 73:                /* 9/PgUp */
        !          85185:                s = 0;                  /* start off with normal keypad */
        !          85186:                if (shift & NMLS)       /* num lock? */
        !          85187:                        s = 1;          /* set shift pad */
        !          85188:                if (shift & SES)        /* shift? */
        !          85189:                        s ^= 1;         /* toggle shift pad */
        !          85190:                if (shift & AKPS)       /* alternate pad? */
        !          85191:                        s = 2;          /* set alternate pad */         
        !          85192:                if (extmode)            /* not from keypad? */
        !          85193:                        s = 0;          /* force normal sequence */
        !          85194:                cp = keypad[c-71][s];   /* get keypad value */
        !          85195:                break;
        !          85196:        }
        !          85197:        if (cp)                                 /* send string */
        !          85198:                while ((*cp != 0) && (*cp != -1))
        !          85199:                        isin( *cp++ & 0377 );
        !          85200:        return update_leds;
        !          85201: }
        !          85202: 
        !          85203: /**
        !          85204:  *
        !          85205:  * void
        !          85206:  * ismmfunc( c )       -- process keyboard related output escape sequences
        !          85207:  * char c;
        !          85208:  */
        !          85209: void
        !          85210: ismmfunc(c)
        !          85211: register int c;
        !          85212: {
        !          85213:        switch (c) {
        !          85214:        case 't':       /* Enter numlock */
        !          85215:                shift |= NMLS;
        !          85216:                updleds();                      /* update LED status */
        !          85217:                break;
        !          85218:        case 'u':       /* Leave numlock */
        !          85219:                shift &= ~NMLS;
        !          85220:                updleds();                      /* update LED status */
        !          85221:                break;
        !          85222:        case '=':       /* Enter alternate keypad */
        !          85223:                shift |= AKPS;
        !          85224:                break;
        !          85225:        case '>':       /* Exit alternate keypad */
        !          85226:                shift &= ~AKPS;
        !          85227:                break;
        !          85228:        case 'c':       /* Reset terminal */
        !          85229:                islock = 0;
        !          85230:                shift  = 0;
        !          85231:                initkeys();
        !          85232:                updleds();                      /* update LED status */
        !          85233:                break;
        !          85234:        }
        !          85235: }
        !          85236: 
        !          85237: /**
        !          85238:  *
        !          85239:  * void
        !          85240:  * isin( c )   -- append character to raw input silo
        !          85241:  * char c;
        !          85242:  */
        !          85243: static
        !          85244: isin( c )
        !          85245: register int c;
        !          85246: {
        !          85247:        /*
        !          85248:         * Cache received character.
        !          85249:         */
        !          85250:        istty.t_rawin.si_buf[ istty.t_rawin.si_ix ] = c;
        !          85251: 
        !          85252:        if ( ++istty.t_rawin.si_ix >= sizeof(istty.t_rawin.si_buf) )
        !          85253:                istty.t_rawin.si_ix = 0;
        !          85254: }
        !          85255: 
        !          85256: /**
        !          85257:  *
        !          85258:  * void
        !          85259:  * isbatch()   -- raw input conversion routine
        !          85260:  *
        !          85261:  *     Action: Enable the video display.
        !          85262:  *             Canonize the raw input silo.
        !          85263:  *
        !          85264:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
        !          85265:  */
        !          85266: static void
        !          85267: isbatch( tp )
        !          85268: register TTY * tp;
        !          85269: {
        !          85270:        register int c;
        !          85271:        static int lastc;
        !          85272: 
        !          85273:        /*
        !          85274:         * Ensure video display is enabled.
        !          85275:         */
        !          85276:        mm_von();
        !          85277: 
        !          85278:        isbusy = 0;
        !          85279: 
        !          85280:        /*
        !          85281:         * Process all cached characters.
        !          85282:         */
        !          85283:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
        !          85284: 
        !          85285:                /*
        !          85286:                 * Get next cached char.
        !          85287:                 */
        !          85288:                c = tp->t_rawin.si_buf[ tp->t_rawin.si_ox ];
        !          85289: 
        !          85290:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
        !          85291:                        tp->t_rawin.si_ox = 0;
        !          85292:                else
        !          85293:                        tp->t_rawin.si_ox++;
        !          85294: 
        !          85295:                if ( (islock == 0) || ISINTR || ISQUIT ) {
        !          85296:                        ttin( tp, c );
        !          85297:                }
        !          85298: 
        !          85299:                else if ( (c == 'b') && (lastc == '\033') ) {
        !          85300:                        islock = 0;
        !          85301:                        ttin( tp, lastc );
        !          85302:                        ttin( tp, c );
        !          85303:                }
        !          85304: 
        !          85305:                else if ( (c == 'c') && (lastc == '\033') ) {
        !          85306:                        ttin( tp, lastc );
        !          85307:                        ttin( tp, c );
        !          85308:                }
        !          85309: 
        !          85310:                else
        !          85311:                        putchar('\007');
        !          85312: 
        !          85313:                lastc = c;
        !          85314:        }
        !          85315: }
        !          85316: 
        !          85317: /*
        !          85318:  * update the keyboard status LEDS
        !          85319:  */
        !          85320: updleds()
        !          85321: {
        !          85322:        int     s;
        !          85323: 
        !          85324:        s = sphi();
        !          85325:        outb(KBDATA, LEDCMD);
        !          85326:        ledcmd = 1;
        !          85327:        spl(s);
        !          85328: }
        !          85329: 
        !          85330: /*
        !          85331:  * unlock the scroll in case an interrupt character is received
        !          85332:  */
        !          85333: kbunscroll()
        !          85334: {
        !          85335:        scroll = 0;
        !          85336:        updleds();
        !          85337: }
        !          85338: 0707070064030112151006440000000000000000011777770507310711600005000000032047/newbits/kernel/USRSRC/i8086/drv/Mf.mwc# Makefile for AT specific Coherent drivers
        !          85339: # Environment variable USRSYS must be defined!  Try /usr/sys ...
        !          85340: # Environment variable KOBJ must be defined!  Try /usr/kobj ...
        !          85341: 
        !          85342: # Include directories
        !          85343: USRINC=/usr/include
        !          85344: SYSINC=/usr/include/sys
        !          85345: 
        !          85346: DEBUG=0
        !          85347: 
        !          85348: # Loadable driver directory
        !          85349: LDRV=$(USRSYS)/ldrv
        !          85350: 
        !          85351: ARCHIVES=$(USRSYS)/lib/aha154x.a \
        !          85352:        $(USRSYS)/lib/al.a \
        !          85353:        $(USRSYS)/lib/at.a \
        !          85354:        $(USRSYS)/lib/ati.a \
        !          85355:        $(USRSYS)/lib/fl.a \
        !          85356:        $(USRSYS)/lib/gkb.a \
        !          85357:        $(USRSYS)/lib/gr.a \
        !          85358:        $(USRSYS)/lib/hs.a \
        !          85359:        $(USRSYS)/lib/kb.a \
        !          85360:        $(USRSYS)/lib/lp.a \
        !          85361:        $(USRSYS)/lib/mm.a \
        !          85362:        $(USRSYS)/lib/ms.a \
        !          85363:        $(USRSYS)/lib/nkb.a \
        !          85364:        $(USRSYS)/lib/rm.a \
        !          85365:        $(USRSYS)/lib/rs.a \
        !          85366:        $(USRSYS)/lib/st.a \
        !          85367:        $(USRSYS)/lib/tn.a \
        !          85368: 
        !          85369: DRVOBJ=        $(KOBJ)/aha.o \
        !          85370:        $(KOBJ)/alx.o \
        !          85371:        $(KOBJ)/at.o \
        !          85372:        $(KOBJ)/atas.o \
        !          85373:        $(KOBJ)/bufq.o \
        !          85374:        $(KOBJ)/ms.o \
        !          85375:        $(KOBJ)/ati.o \
        !          85376:        $(KOBJ)/com1.o $(KOBJ)/com2.o \
        !          85377:        $(KOBJ)/fdisk.o \
        !          85378:        $(KOBJ)/fl.o \
        !          85379:        $(KOBJ)/fontw.o \
        !          85380:        $(KOBJ)/gr.o $(KOBJ)/gras.o \
        !          85381:        $(KOBJ)/hs.o \
        !          85382:        $(KOBJ)/nkb.o \
        !          85383:        $(KOBJ)/gkb.o \
        !          85384:        $(KOBJ)/kb.o \
        !          85385:        $(KOBJ)/mm.o \
        !          85386:        $(KOBJ)/lp.o \
        !          85387:        $(KOBJ)/mmas.o \
        !          85388:        $(KOBJ)/rm.o \
        !          85389:        $(KOBJ)/rs0.o $(KOBJ)/rs1.o $(KOBJ)/rsas.o \
        !          85390:        $(KOBJ)/scsi.o \
        !          85391:        $(KOBJ)/ss.o \
        !          85392:        $(KOBJ)/ssas.o \
        !          85393:        $(KOBJ)/st.o \
        !          85394:        $(KOBJ)/tn.o $(KOBJ)/tnas.o \
        !          85395: 
        !          85396: DRIVERS=$(LDRV)/aha154x \
        !          85397:        $(LDRV)/al0 \
        !          85398:        $(LDRV)/al1 \
        !          85399:        $(LDRV)/at \
        !          85400:        $(LDRV)/fl \
        !          85401:        $(LDRV)/gr \
        !          85402:        $(LDRV)/hs \
        !          85403:        $(LDRV)/lp \
        !          85404:        $(LDRV)/mm \
        !          85405:        $(LDRV)/ms \
        !          85406:        $(LDRV)/rm \
        !          85407:        $(LDRV)/ss \
        !          85408: 
        !          85409: install: $(ARCHIVES) $(DRIVERS)
        !          85410:        @exec /bin/sync
        !          85411: 
        !          85412: all:   $(DRVOBJ)
        !          85413:        @exec /bin/sync
        !          85414: 
        !          85415: $(USRSYS)/lib/aha154x.a: $(KOBJ)/scsi.o $(KOBJ)/aha.o $(KOBJ)/fdisk.o
        !          85416:        rm -f $@
        !          85417:        ar rc $@ $<
        !          85418: $(USRSYS)/lib/al.a: $(KOBJ)/com1.o $(KOBJ)/com2.o $(KOBJ)/alx.o
        !          85419:        rm -f $@
        !          85420:        ar rc $@ $<
        !          85421: $(USRSYS)/lib/at.a: $(KOBJ)/at.o $(KOBJ)/atas.o $(KOBJ)/fdisk.o
        !          85422:        rm -f $@
        !          85423:        ar rc $@ $<
        !          85424: $(USRSYS)/lib/ati.a: $(KOBJ)/mm.o $(KOBJ)/ati.o
        !          85425:        rm -f $@
        !          85426:        ar rc $@ $<
        !          85427: $(USRSYS)/lib/fl.a: $(KOBJ)/fl.o
        !          85428:        rm -f $(USRSYS)/lib/fl.a
        !          85429:        ar rc $(USRSYS)/lib/fl.a $(KOBJ)/fl.o
        !          85430: $(USRSYS)/lib/gkb.a: $(KOBJ)/gkb.o
        !          85431:        rm -f $@
        !          85432:        ar rc $@ $<
        !          85433: $(USRSYS)/lib/gr.a: $(KOBJ)/mm.o $(KOBJ)/gr.o $(KOBJ)/gras.o \
        !          85434:                                $(KOBJ)/fontw.o
        !          85435:        rm -f $@
        !          85436:        ar rc $@ $<
        !          85437: $(USRSYS)/lib/hs.a: $(KOBJ)/hs.o
        !          85438:        rm -f $@
        !          85439:        ar rc $@ $<
        !          85440: $(USRSYS)/lib/kb.a: $(KOBJ)/kb.o
        !          85441:        rm -f $@
        !          85442:        ar rc $@ $<
        !          85443: $(USRSYS)/lib/lp.a: $(KOBJ)/lp.o
        !          85444:        rm -f $@
        !          85445:        ar rc $@ $<
        !          85446: $(USRSYS)/lib/mm.a: $(KOBJ)/mm.o $(KOBJ)/mmas.o
        !          85447:        rm -f $@
        !          85448:        ar rc $@ $<
        !          85449: $(USRSYS)/lib/ms.a: $(KOBJ)/ms.o
        !          85450:        rm -f $@
        !          85451:        ar rc $@ $<
        !          85452: $(USRSYS)/lib/nkb.a: $(KOBJ)/nkb.o
        !          85453:        rm -f $@
        !          85454:        ar rc $@ $<
        !          85455: $(USRSYS)/lib/rm.a: $(KOBJ)/rm.o
        !          85456:        rm -f $@
        !          85457:        ar rc $@ $<
        !          85458: $(USRSYS)/lib/rs.a: $(KOBJ)/rs0.o $(KOBJ)/rs1.o $(KOBJ)/rsas.o
        !          85459:        rm -f $@
        !          85460:        ar rc $@ $<
        !          85461: $(USRSYS)/lib/ss.a: $(KOBJ)/ss.o $(KOBJ)/ssas.o $(KOBJ)/bufq.o $(KOBJ)/fdisk.o
        !          85462:        rm -f $@
        !          85463:        ar rc $@ $<
        !          85464: $(USRSYS)/lib/st.a: $(KOBJ)/st.o
        !          85465:        rm -f $@
        !          85466:        ar rc $@ $<
        !          85467: $(USRSYS)/lib/tn.a: $(KOBJ)/tn.o $(KOBJ)/tnas.o
        !          85468:        rm -f $@
        !          85469:        ar rc $@ $<
        !          85470: 
        !          85471: $(KOBJ)/aha.o:                         \
        !          85472:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85473:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85474:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          85475:                $(SYSINC)/buf.h         \
        !          85476:                $(SYSINC)/sched.h               \
        !          85477:                $(SYSINC)/scsiwork.h    \
        !          85478:                $(SYSINC)/aha154x.h     \
        !          85479:                aha.c
        !          85480:        $(CC) $(CFLAGS) -c -o $@ aha.c
        !          85481: 
        !          85482: $(KOBJ)/alx.o:                         \
        !          85483:                $(SYSINC)/clist.h       \
        !          85484:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85485:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85486:                                        $(SYSINC)/fun.h \
        !          85487:                $(SYSINC)/con.h         \
        !          85488:                $(USRINC)/errno.h       \
        !          85489:                $(SYSINC)/i8086.h       \
        !          85490:                $(SYSINC)/ins8250.h     \
        !          85491:                $(SYSINC)/sched.h       \
        !          85492:                $(SYSINC)/stat.h        \
        !          85493:                $(SYSINC)/timeout.h     \
        !          85494:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          85495:                $(SYSINC)/uproc.h       \
        !          85496:                alx.c
        !          85497:        $(CC) $(CFLAGS) -c -o $@ alx.c
        !          85498: 
        !          85499: $(KOBJ)/at.o: at.c                     \
        !          85500:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85501:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85502:                                        $(SYSINC)/fun.h \
        !          85503:                $(SYSINC)/fdisk.h       \
        !          85504:                $(SYSINC)/hdioctl.h     \
        !          85505:                $(SYSINC)/buf.h         \
        !          85506:                $(SYSINC)/con.h         \
        !          85507:                $(SYSINC)/devices.h     \
        !          85508:                $(SYSINC)/stat.h        \
        !          85509:                $(SYSINC)/uproc.h       \
        !          85510:                $(USRINC)/errno.h
        !          85511:        $(CC) $(CFLAGS) -DVERBOSE=1 -c -o $@ at.c
        !          85512: 
        !          85513: $(KOBJ)/atas.o: atas.s
        !          85514:        $(AS) -go $@ $<
        !          85515: 
        !          85516: $(KOBJ)/ati.o: ati.m
        !          85517:        $(CC) $(CFLAGS) -DATI_132=1 -c -o $@ ati.m
        !          85518: 
        !          85519: $(KOBJ)/bufq.o:                        \
        !          85520:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85521:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85522:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          85523:                $(SYSINC)/buf.h         \
        !          85524:                bufq.c
        !          85525:        $(CC) $(CFLAGS) -DDEBUG=$(DEBUG) -c -o $@ bufq.c
        !          85526: 
        !          85527: $(KOBJ)/com1.o:                        \
        !          85528:                $(SYSINC)/al.h          \
        !          85529:                $(SYSINC)/clist.h       \
        !          85530:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85531:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85532:                                        $(SYSINC)/fun.h \
        !          85533:                $(SYSINC)/con.h         \
        !          85534:                $(SYSINC)/devices.h     \
        !          85535:                $(USRINC)/errno.h       \
        !          85536:                $(SYSINC)/i8086.h       \
        !          85537:                $(SYSINC)/ins8250.h     \
        !          85538:                $(SYSINC)/sched.h       \
        !          85539:                $(SYSINC)/stat.h        \
        !          85540:                $(SYSINC)/timeout.h     \
        !          85541:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          85542:                $(SYSINC)/uproc.h       \
        !          85543:                al.c
        !          85544:        $(CC) $(CFLAGS) -DALCOM1=1 -c -o $@ al.c
        !          85545: 
        !          85546: $(KOBJ)/com2.o:                        \
        !          85547:                $(SYSINC)/al.h          \
        !          85548:                $(SYSINC)/clist.h       \
        !          85549:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85550:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85551:                                        $(SYSINC)/fun.h \
        !          85552:                $(SYSINC)/con.h         \
        !          85553:                $(SYSINC)/devices.h     \
        !          85554:                $(USRINC)/errno.h       \
        !          85555:                $(SYSINC)/i8086.h       \
        !          85556:                $(SYSINC)/ins8250.h     \
        !          85557:                $(SYSINC)/sched.h       \
        !          85558:                $(SYSINC)/stat.h        \
        !          85559:                $(SYSINC)/timeout.h     \
        !          85560:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          85561:                $(SYSINC)/uproc.h       \
        !          85562:                al.c
        !          85563:        $(CC) $(CFLAGS) -DALCOM2=1 -c -o $@ al.c
        !          85564: 
        !          85565: $(KOBJ)/fdisk.o:                       \
        !          85566:                $(SYSINC)/buf.h         \
        !          85567:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85568:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85569:                                        $(SYSINC)/fun.h \
        !          85570:                $(SYSINC)/con.h         \
        !          85571:                $(USRINC)/errno.h       \
        !          85572:                $(SYSINC)/fdisk.h       \
        !          85573:                $(SYSINC)/inode.h       \
        !          85574:                $(SYSINC)/uproc.h       \
        !          85575:                fdisk.c
        !          85576:        $(CC) $(CFLAGS) -c -o $@ fdisk.c
        !          85577: 
        !          85578: $(KOBJ)/fl.o:                          \
        !          85579:                $(SYSINC)/buf.h         \
        !          85580:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85581:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85582:                                        $(SYSINC)/fun.h \
        !          85583:                $(SYSINC)/con.h         \
        !          85584:                $(SYSINC)/devices.h     \
        !          85585:                $(SYSINC)/dmac.h        \
        !          85586:                $(USRINC)/errno.h       \
        !          85587:                $(SYSINC)/fdioctl.h     \
        !          85588:                $(SYSINC)/i8086.h       \
        !          85589:                $(SYSINC)/sched.h       \
        !          85590:                $(SYSINC)/stat.h        \
        !          85591:                $(SYSINC)/timeout.h     \
        !          85592:                $(SYSINC)/uproc.h       \
        !          85593:                fl.c
        !          85594:        $(CC) $(CFLAGS) -c -o $@ fl.c
        !          85595: 
        !          85596: $(KOBJ)/fontw.o: tools/fontgen.c
        !          85597:        $(CC) -o tools/fontgen tools/fontgen.c
        !          85598:        exec tools/fontgen > fontw.s
        !          85599:        exec /bin/rm tools/fontgen
        !          85600:        $(AS) -gxo $(KOBJ)/fontw.o fontw.s
        !          85601:        exec /bin/rm fontw.s
        !          85602: 
        !          85603: $(KOBJ)/gr.o:                          \
        !          85604:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85605:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85606:                                        $(SYSINC)/fun.h \
        !          85607:                $(SYSINC)/con.h         \
        !          85608:                $(SYSINC)/devices.h     \
        !          85609:                $(USRINC)/errno.h       \
        !          85610:                $(SYSINC)/sched.h       \
        !          85611:                $(SYSINC)/timeout.h     \
        !          85612:                $(SYSINC)/types.h       \
        !          85613:                $(SYSINC)/uproc.h       \
        !          85614:                gr.c
        !          85615:        $(CC) $(CFLAGS) -c -o $@ gr.c
        !          85616: 
        !          85617: $(KOBJ)/gras.o: gras.m
        !          85618:        $(CC) $(CFLAGS) -c -o $@ gras.m
        !          85619: 
        !          85620: $(KOBJ)/hgas.o: gras.s
        !          85621:        $(CC) $(CFLAGS) -c -o $@ -DHERCULES gras.m
        !          85622: 
        !          85623: $(KOBJ)/hd.o: hd.c
        !          85624:        $(CC) $(CFLAGS) -c -o $@ hd.c
        !          85625: 
        !          85626: $(KOBJ)/hs.o:                          \
        !          85627:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85628:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85629:                                        $(SYSINC)/fun.h \
        !          85630:                $(SYSINC)/con.h         \
        !          85631:                $(SYSINC)/devices.h     \
        !          85632:                $(USRINC)/errno.h       \
        !          85633:                $(SYSINC)/ins8250.h     \
        !          85634:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          85635:                $(SYSINC)/stat.h        \
        !          85636:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          85637:                $(SYSINC)/uproc.h       \
        !          85638:                hs.c
        !          85639:        $(CC) $(CFLAGS) -c -o $@ hs.c
        !          85640: 
        !          85641: $(KOBJ)/kb.o:                          \
        !          85642:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85643:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85644:                                        $(SYSINC)/fun.h \
        !          85645:                $(SYSINC)/con.h         \
        !          85646:                $(SYSINC)/devices.h     \
        !          85647:                $(USRINC)/errno.h       \
        !          85648:                $(SYSINC)/i8086.h       \
        !          85649:                $(SYSINC)/sched.h       \
        !          85650:                $(USRINC)/signal.h      \
        !          85651:                $(SYSINC)/stat.h        \
        !          85652:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          85653:                $(SYSINC)/uproc.h       \
        !          85654:                kb.c
        !          85655:        $(CC) $(CFLAGS) -c -o $@ kb.c
        !          85656: 
        !          85657: $(KOBJ)/gkb.o:                         \
        !          85658:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85659:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85660:                                        $(SYSINC)/fun.h \
        !          85661:                $(SYSINC)/con.h         \
        !          85662:                $(USRINC)/errno.h       \
        !          85663:                $(SYSINC)/i8086.h       \
        !          85664:                $(SYSINC)/sched.h       \
        !          85665:                $(USRINC)/signal.h      \
        !          85666:                $(SYSINC)/stat.h        \
        !          85667:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          85668:                $(SYSINC)/uproc.h       \
        !          85669:                gkb.c
        !          85670:        $(CC) $(CFLAGS) -c -o $@ gkb.c
        !          85671: 
        !          85672: $(KOBJ)/nkb.o:                         \
        !          85673:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85674:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85675:                                        $(SYSINC)/fun.h \
        !          85676:                $(SYSINC)/con.h         \
        !          85677:                $(USRINC)/errno.h       \
        !          85678:                $(SYSINC)/i8086.h       \
        !          85679:                $(SYSINC)/sched.h       \
        !          85680:                $(SYSINC)/seg.h         \
        !          85681:                $(USRINC)/signal.h      \
        !          85682:                $(SYSINC)/stat.h        \
        !          85683:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          85684:                $(SYSINC)/uproc.h       \
        !          85685:                $(SYSINC)/kb.h          \
        !          85686:                nkb.c
        !          85687:        $(CC) $(CFLAGS) -c -o $@ nkb.c
        !          85688: 
        !          85689: $(KOBJ)/lp.o:                          \
        !          85690:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85691:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85692:                                        $(SYSINC)/fun.h \
        !          85693:                $(SYSINC)/con.h         \
        !          85694:                $(SYSINC)/devices.h     \
        !          85695:                $(USRINC)/errno.h       \
        !          85696:                $(SYSINC)/i8086.h       \
        !          85697:                $(SYSINC)/io.h          \
        !          85698:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          85699:                $(SYSINC)/stat.h        \
        !          85700:                $(SYSINC)/timeout.h     \
        !          85701:                $(SYSINC)/uproc.h       \
        !          85702:                lp.c
        !          85703:        $(CC) $(CFLAGS) -c -o $@ lp.c
        !          85704: 
        !          85705: $(KOBJ)/mm.o:                          \
        !          85706:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85707:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85708:                                        $(SYSINC)/fun.h \
        !          85709:                $(SYSINC)/sched.h       \
        !          85710:                $(USRINC)/errno.h       \
        !          85711:                $(SYSINC)/stat.h        \
        !          85712:                $(SYSINC)/io.h          \
        !          85713:                $(SYSINC)/tty.h         $(SYSINC)/ktty.h \
        !          85714:                $(SYSINC)/uproc.h       \
        !          85715:                $(SYSINC)/timeout.h     \
        !          85716:                mm.c
        !          85717:        $(CC) $(CFLAGS) -c -o $@ mm.c
        !          85718: 
        !          85719: $(KOBJ)/mmas.o: mmas.m
        !          85720:        $(CC) $(CFLAGS) -c -o $@ mmas.m
        !          85721: 
        !          85722: $(KOBJ)/ms.o:                          \
        !          85723:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85724:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85725:                                        $(SYSINC)/fun.h \
        !          85726:                $(SYSINC)/uproc.h       \
        !          85727:                $(SYSINC)/con.h         \
        !          85728:                $(SYSINC)/devices.h     \
        !          85729:                $(SYSINC)/ms.h          \
        !          85730:                $(USRINC)/errno.h       \
        !          85731:                ms.c
        !          85732:        $(CC) $(CFLAGS) -c -o $@ ms.c
        !          85733: 
        !          85734: $(KOBJ)/rm.o: rm.c                     \
        !          85735:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85736:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85737:                                        $(SYSINC)/fun.h \
        !          85738:                $(SYSINC)/buf.h         \
        !          85739:                $(USRINC)/errno.h       \
        !          85740:                $(SYSINC)/uproc.h       \
        !          85741:                $(SYSINC)/seg.h         \
        !          85742:                $(SYSINC)/con.h         \
        !          85743:                $(SYSINC)/devices.h     \
        !          85744:                $(SYSINC)/inode.h       \
        !          85745:                $(SYSINC)/stat.h
        !          85746:        $(CC) $(CFLAGS) -c -o $@ rm.c
        !          85747: 
        !          85748: $(KOBJ)/rs0.o:                         \
        !          85749:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85750:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85751:                                        $(SYSINC)/fun.h \
        !          85752:                $(SYSINC)/con.h         \
        !          85753:                $(SYSINC)/devices.h     \
        !          85754:                $(USRINC)/errno.h       \
        !          85755:                $(SYSINC)/ins8250.h     \
        !          85756:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          85757:                $(SYSINC)/sched.h       \
        !          85758:                $(SYSINC)/stat.h        \
        !          85759:                $(USRINC)/termio.h      \
        !          85760:                $(SYSINC)/uproc.h       \
        !          85761:                rs.c
        !          85762:        $(CC) $(CFLAGS) -DRS0 -c -o $@ rs.c
        !          85763: 
        !          85764: $(KOBJ)/rs1.o:                                 \
        !          85765:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85766:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85767:                                        $(SYSINC)/fun.h \
        !          85768:                $(SYSINC)/con.h         \
        !          85769:                $(SYSINC)/devices.h     \
        !          85770:                $(USRINC)/errno.h       \
        !          85771:                $(SYSINC)/ins8250.h     \
        !          85772:                $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          85773:                $(SYSINC)/sched.h       \
        !          85774:                $(SYSINC)/stat.h        \
        !          85775:                $(USRINC)/termio.h      \
        !          85776:                $(SYSINC)/uproc.h       \
        !          85777:                rs.c
        !          85778:        $(CC) $(CFLAGS) -DRS1 -c -o $@ rs.c
        !          85779: 
        !          85780: $(KOBJ)/rsas.o: rsas.s
        !          85781:        $(AS) -gxo $@ rsas.s
        !          85782: 
        !          85783: $(KOBJ)/scsi.o:                                \
        !          85784:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85785:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85786:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          85787:                $(SYSINC)/fdisk.h       \
        !          85788:                $(SYSINC)/hdioctl.h     \
        !          85789:                $(SYSINC)/sdioctl.h     \
        !          85790:                $(SYSINC)/buf.h         \
        !          85791:                $(SYSINC)/con.h         \
        !          85792:                $(SYSINC)/stat.h        \
        !          85793:                $(SYSINC)/uproc.h       \
        !          85794:                $(USRINC)/errno.h       \
        !          85795:                $(SYSINC)/scsiwork.h    \
        !          85796:                scsi.c
        !          85797:        $(CC) $(CFLAGS) -c -o $(KOBJ)/scsi.o scsi.c
        !          85798: 
        !          85799: $(KOBJ)/ss.o:                          \
        !          85800:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85801:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85802:                                        $(SYSINC)/fun.h $(SYSINC)/mmu.h \
        !          85803:                $(SYSINC)/io.h          \
        !          85804:                $(SYSINC)/sched.h       \
        !          85805:                $(SYSINC)/uproc.h       \
        !          85806:                $(SYSINC)/proc.h        \
        !          85807:                $(SYSINC)/con.h         \
        !          85808:                $(SYSINC)/stat.h        \
        !          85809:                $(SYSINC)/devices.h     \
        !          85810:                $(USRINC)/errno.h       \
        !          85811:                $(SYSINC)/ss.h          \
        !          85812:                $(SYSINC)/fdisk.h       \
        !          85813:                $(SYSINC)/hdioctl.h     \
        !          85814:                $(SYSINC)/buf.h         \
        !          85815:                $(SYSINC)/scsiwork.h    \
        !          85816:                ss.c
        !          85817:        $(CC) $(CFLAGS) -DDEBUG=$(DEBUG) -c -o $(KOBJ)/ss.o ss.c
        !          85818: 
        !          85819: $(KOBJ)/ssas.o:                                \
        !          85820:                ssas.s
        !          85821:        $(AS) -go $@ $<
        !          85822: 
        !          85823: $(KOBJ)/st.o:                          \
        !          85824:                $(SYSINC)/buf.h         \
        !          85825:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85826:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85827:                                        $(SYSINC)/fun.h \
        !          85828:                $(SYSINC)/con.h         \
        !          85829:                $(SYSINC)/devices.h     \
        !          85830:                $(SYSINC)/const.h       \
        !          85831:                $(USRINC)/errno.h       \
        !          85832:                $(SYSINC)/inode.h       \
        !          85833:                $(SYSINC)/mtioctl.h     \
        !          85834:                $(SYSINC)/sched.h       \
        !          85835:                $(SYSINC)/seg.h         \
        !          85836:                $(SYSINC)/stat.h        \
        !          85837:                $(SYSINC)/uproc.h       \
        !          85838:                st.c
        !          85839:        $(CC) $(CFLAGS) -c -o $@ st.c
        !          85840: 
        !          85841: $(KOBJ)/tn.o:                          \
        !          85842:                $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          85843:                                        $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          85844:                                        $(SYSINC)/fun.h \
        !          85845:                $(SYSINC)/con.h         \
        !          85846:                $(SYSINC)/devices.h     \
        !          85847:                $(USRINC)/errno.h       \
        !          85848:                $(SYSINC)/sched.h       \
        !          85849:                $(SYSINC)/timeout.h     \
        !          85850:                $(SYSINC)/types.h       \
        !          85851:                $(SYSINC)/uproc.h       \
        !          85852:                tn.c
        !          85853:        $(CC) $(CFLAGS) -c -o $@ tn.c
        !          85854: 
        !          85855: $(KOBJ)/tnas.o: tnas.s
        !          85856:        $(AS) -gxo $@ tnas.s
        !          85857: 
        !          85858: # How to make loadable drivers.
        !          85859: 
        !          85860: $(LDRV)/aha154x:       $(USRSYS)/lib/aha154x.a
        !          85861:        ( cd $(USRSYS); ldconfig aha154x )
        !          85862: 
        !          85863: $(LDRV)/al0:   $(USRSYS)/lib/al.a
        !          85864:        ( cd $(USRSYS); ldconfig al0 )
        !          85865: 
        !          85866: $(LDRV)/al1:   $(USRSYS)/lib/al.a
        !          85867:        ( cd $(USRSYS); ldconfig al1 )
        !          85868: 
        !          85869: $(LDRV)/at:    $(USRSYS)/lib/at.a
        !          85870:        ( cd $(USRSYS); ldconfig at )
        !          85871: 
        !          85872: $(LDRV)/fl:    $(USRSYS)/lib/fl.a
        !          85873:        ( cd $(USRSYS); ldconfig fl )
        !          85874: 
        !          85875: $(LDRV)/gr:    $(USRSYS)/lib/gr.a
        !          85876:        ( cd $(USRSYS); ldconfig gr )
        !          85877: 
        !          85878: $(LDRV)/hs:    $(USRSYS)/lib/hs.a
        !          85879:        ( cd $(USRSYS); ldconfig hs )
        !          85880: 
        !          85881: $(LDRV)/lp:    $(USRSYS)/lib/lp.a
        !          85882:        ( cd $(USRSYS); ldconfig lp )
        !          85883: 
        !          85884: $(LDRV)/mm:    $(USRSYS)/lib/mm.a
        !          85885:        ( cd $(USRSYS); ldconfig mm )
        !          85886: 
        !          85887: $(LDRV)/ms:    $(USRSYS)/lib/ms.a
        !          85888:        ( cd $(USRSYS); ldconfig ms )
        !          85889: 
        !          85890: $(LDRV)/rm:    $(USRSYS)/lib/rm.a
        !          85891:        ( cd $(USRSYS); ldconfig rm )
        !          85892: 
        !          85893: $(LDRV)/ss:    $(USRSYS)/lib/ss.a
        !          85894:        ( cd $(USRSYS); ldconfig ss )
        !          85895: 0707070064030106231006440000000000000000011777770507310712200005000000113567/newbits/kernel/USRSRC/i8086/drv/gras.m/ (lgl-
        !          85896: /      COHERENT Driver Kit Version 1.0.0
        !          85897: /      Copyright (c) 1982, 1990 by Mark Williams Company.
        !          85898: /      All rights reserved. May not be copied without permission.
        !          85899: / -lgl)
        !          85900:        .globl  grread_
        !          85901:        .globl  grwrite_
        !          85902:        .globl  mmgo_
        !          85903: 
        !          85904: ////////
        !          85905: /
        !          85906: / State driven code
        !          85907: /
        !          85908: /      Input:  DS:SI - input string
        !          85909: /              ES:DI - current screen location
        !          85910: /              SS:BP - terminal attributes
        !          85911: /              CX    - input count
        !          85912: /              BP    - references terminal information
        !          85913: /              AL    - character
        !          85914: /              BH    - (usually) kept zeroed for efficiency
        !          85915: /              DH    - current row
        !          85916: /              DL    - current column
        !          85917: /
        !          85918: ////////
        !          85919: 
        !          85920: #ifdef HERCULES
        !          85921:        VSEG    = 0xB000        / Video Display Segment
        !          85922:        BANKSZ  = 8192          / Size of Display Banks
        !          85923:        LROW    = 24            / Last legal row
        !          85924:        NCR     = 8             / number of horizontal lines per char
        !          85925:        NCR2    = 4             / number of horizontal lines per char / 2
        !          85926:        NCR4    = 2             / number of horizontal lines per char / 4
        !          85927:        NHB     = 90            / number of horizontal bytes per line
        !          85928: #else
        !          85929: #ifdef TECMAR
        !          85930:        VSEG    = 0xA000        / Video Display Segment
        !          85931:        BANKSZ  = 32768         / Size of Display Banks
        !          85932:        LROW    = 24            / Last legal row
        !          85933:        NCR     = 16            / number of horizontal lines per char
        !          85934:        NCR2    = 8             / number of horizontal lines per char / 2
        !          85935:        NCR4    = 4             / number of horizontal lines per char / 4
        !          85936:        NHB     = 80            / number of horizontal bytes per line
        !          85937: #else
        !          85938:        VSEG    = 0xB800        / Video Display Segment
        !          85939:        BANKSZ  = 8192          / Size of Display Banks
        !          85940:        LROW    = 24            / Last legal row
        !          85941:        NCR     = 8             / number of horizontal lines per char
        !          85942:        NCR2    = 4             / number of horizontal lines per char / 2
        !          85943:        NCR4    = 2             / number of horizontal lines per char / 4
        !          85944:        NHB     = 80            / number of horizontal bytes per line
        !          85945: #endif
        !          85946: #endif
        !          85947: 
        !          85948:        NRB     = NHB*NCR       / number of bytes per character row
        !          85949:        NRB2    = NHB*NCR2      / number of bytes per character row / 2
        !          85950:        NRB4    = NHB*NCR4      / number of bytes per character row / 4
        !          85951: 
        !          85952: 
        !          85953:        ZERO    = bh            / (almost) always zero
        !          85954:        ROW     = dh            / currently active vertical position
        !          85955:        COL     = dl            / currently active horizontal position
        !          85956:        POS     = di            / currently active display address
        !          85957: 
        !          85958:        CSR     = 0x3D9         / Color Select Register
        !          85959:        MSR     = 0x3D8         / Mode Select Register
        !          85960:        XMSR    = 0x3DA         / Extended Mode Select Register
        !          85961: 
        !          85962: 
        !          85963: ////////
        !          85964: /
        !          85965: / Magic constants from <sys/io.h>
        !          85966: /
        !          85967: ////////
        !          85968: 
        !          85969:        IO_SEG  = 0
        !          85970:        IO_IOC  = 2
        !          85971:        IO_SEEK = 4
        !          85972:        IO_BASE = 8
        !          85973: 
        !          85974:        IOSYS   = 0
        !          85975: 
        !          85976: ////////
        !          85977: /
        !          85978: / Data
        !          85979: /
        !          85980: ////////
        !          85981: 
        !          85982: MM_FUNC                = 0             / current state
        !          85983: MM_PORT                = 2             / adapter base i/o port
        !          85984: MM_BASE                = 4             / adapter base memory address
        !          85985: MM_ROW         = 6             / screen row
        !          85986: MM_COL         = 7             / screen column
        !          85987: MM_POS         = 8             / screen position
        !          85988: MM_ATTR                = 10            / attributes
        !          85989: MM_N1          = 11            / numeric argument 1
        !          85990: MM_N2          = 12            / numeric argument 2
        !          85991: MM_BROW                = 13            / base row
        !          85992: MM_EROW                = 14            / end row
        !          85993: MM_LROW                = 15            / legal row limit
        !          85994: MM_SROW                = 16            / saved cursor row
        !          85995: MM_SCOL                = 17            / saved cursor column
        !          85996: MM_IBROW       = 18            / initial base row
        !          85997: MM_IEROW       = 19            / initial end row
        !          85998: MM_FLIP                = 20
        !          85999: MM_MASK                = 22
        !          86000: MM_ULINE       = 24
        !          86001: MM_CURSE       = 26
        !          86002: MM_VIS         = 28            / set to -1 to make cursor visible
        !          86003: MM_NCOL                = 30
        !          86004: MM_WRAP                = 31
        !          86005: 
        !          86006: / ASCII characters
        !          86007: AZERO          = 0x30
        !          86008: CLOWER         = 0x63
        !          86009: HLOWER         = 0x68
        !          86010: LLOWER         = 0x6C
        !          86011: SEMIC          = 0x3B
        !          86012: 
        !          86013:        .prvd
        !          86014: mmdata:        .word   mminit, 0x03D4, VSEG
        !          86015:        .byte   0, 0
        !          86016:        .word   0
        !          86017:        .byte   0x7, 0, 0, 0, LROW-1, LROW, 0, 0, 0, LROW-1
        !          86018:        .word   0, -1, 0, 0xff
        !          86019:        .word   0
        !          86020:        .byte   80
        !          86021:        .byte   1
        !          86022: 
        !          86023:        .shri
        !          86024: #ifdef HERCULES
        !          86025: crtdata:.byte   54,  45,  45,   8,  91,   1,  86,  88
        !          86026:        .byte     2,   3,  32,   0,   0,   0,   0,   0
        !          86027: #else
        !          86028: #ifdef TECMAR
        !          86029: crtdata:.byte   56,  40,  43,   8, 127,   6, 100, 112
        !          86030:        .byte     3,   1,  32,   0,   0,   0,   0,   0
        !          86031: #else
        !          86032: crtdata:.byte   56,  40,  43,   8, 127,   6, 100, 112
        !          86033:        .byte     2,   1,  32,   0,   0,   0,   0,   0
        !          86034: #endif
        !          86035: #endif
        !          86036:        .shri
        !          86037: 
        !          86038: ////////
        !          86039: /
        !          86040: / mmgo( iop )          - Entry point for text stream output
        !          86041: / IO *iop;
        !          86042: /
        !          86043: ////////
        !          86044: 
        !          86045: mmgo_:
        !          86046:        push    si
        !          86047:        push    di
        !          86048:        push    bp
        !          86049:        mov     bp, sp
        !          86050:        push    ds
        !          86051:        push    es
        !          86052:        cld
        !          86053:        mov     bx, 8(bp)               / iop
        !          86054:        mov     si, IO_BASE(bx)         / iop->io_base
        !          86055:        mov     cx, IO_IOC(bx)          / iop->io_ioc
        !          86056:        cmp     IO_SEG(bx), $IOSYS
        !          86057:        je      0f
        !          86058:        mov     bx, uds_
        !          86059:        mov     ds, bx
        !          86060: 0:     mov     bp, $mmdata
        !          86061:        movb    ROW, MM_ROW(bp)
        !          86062:        movb    COL, MM_COL(bp)
        !          86063:        mov     es,  MM_BASE(bp)
        !          86064:        mov     POS, MM_POS(bp)
        !          86065:        mov     ax, MM_CURSE(bp)
        !          86066:        and     ax, MM_VIS(bp)
        !          86067: #ifdef TECMAR
        !          86068:        xor     es:[NHB*6](POS), ax
        !          86069:        xor     es:[NHB*6]+BANKSZ(POS), ax
        !          86070:        xor     es:[NHB*7](POS), ax
        !          86071:        xor     es:[NHB*7]+BANKSZ(POS), ax
        !          86072: #else
        !          86073:        xor     es:[NHB*3](POS), ax     / turn cursor off
        !          86074:        xor     es:[NHB*3]+BANKSZ(POS), ax
        !          86075: #endif
        !          86076:        sub     bx, bx
        !          86077:        ijmp    MM_FUNC(bp)
        !          86078: 
        !          86079: exit:  movb    bl, ROW                 / reposition to ROW and COL
        !          86080:        shlb    bl, $1
        !          86081:        mov     POS, cs:rowtab(bx)
        !          86082:        movb    bl, COL
        !          86083:        cmpb    MM_NCOL(bp), $40
        !          86084:        jne     0f
        !          86085:        shlb    bl, $1
        !          86086: 0:     add     POS, bx
        !          86087:        mov     ax, MM_CURSE(bp)
        !          86088:        and     ax, MM_VIS(bp)
        !          86089: #ifdef TECMAR
        !          86090:        xor     es:[NHB*6](POS), ax     / turn cursor on
        !          86091:        xor     es:[NHB*6]+BANKSZ(POS), ax
        !          86092:        xor     es:[NHB*7](POS), ax
        !          86093:        xor     es:[NHB*7]+BANKSZ(POS), ax
        !          86094: #else
        !          86095:        xor     es:[NHB*3](POS), ax     / turn cursor on
        !          86096:        xor     es:[NHB*3]+BANKSZ(POS), ax
        !          86097: #endif
        !          86098:        pop     bx
        !          86099:        pop     es
        !          86100:        pop     ds
        !          86101:        mov     MM_FUNC(bp), bx
        !          86102:        movb    MM_ROW(bp), ROW         / save row,column
        !          86103:        movb    MM_COL(bp), COL
        !          86104:        mov     MM_POS(bp), POS         / save position
        !          86105: 
        !          86106:        mov     dx, $MSR                / enable video display
        !          86107:        movb    al, $0x1A
        !          86108:        outb    dx, al
        !          86109:        mov     mmvcnt_, $480           / 480 seconds before video disabled
        !          86110: 
        !          86111:        mov     bp, sp
        !          86112:        mov     bx, 8(bp)
        !          86113:        mov     ax, cx                  / Return the residual count.
        !          86114:        xchg    cx, IO_IOC(bx)
        !          86115:        sub     cx, IO_IOC(bx)
        !          86116:        add     IO_BASE(bx), cx
        !          86117:        pop     bp
        !          86118:        pop     di
        !          86119:        pop     si
        !          86120:        ret
        !          86121: 
        !          86122: ////////
        !          86123: /
        !          86124: / mminit - initialize screen
        !          86125: /
        !          86126: ////////
        !          86127: 
        !          86128: mminit:        movb    ss:mmesc_, $CLOWER              / schedule keyboard initialization
        !          86129:        mov     dx, $MSR                / disable video display
        !          86130:        movb    al, $0x12
        !          86131:        outb    dx, al
        !          86132: 
        !          86133:        push    cx                      / program registers, last to first
        !          86134:        mov     bx, $15
        !          86135:        mov     dx, MM_PORT(bp)
        !          86136: 0:     movb    al, bl
        !          86137:        outb    dx, al
        !          86138:        inc     dx
        !          86139:        movb    al, cs:crtdata(bx)
        !          86140:        outb    dx, al
        !          86141:        dec     dx
        !          86142:        dec     bx
        !          86143:        jge     0b
        !          86144:        pop     cx
        !          86145: 
        !          86146:        mov     dx, $CSR
        !          86147:        movb    al, $0x0F
        !          86148:        outb    dx, al
        !          86149: 
        !          86150:        mov     dx, $XMSR
        !          86151: #ifdef TECMAR
        !          86152:        movb    al, $31
        !          86153: #else
        !          86154:        movb    al, $0
        !          86155: #endif
        !          86156:        outb    dx, al
        !          86157: 
        !          86158: /      mov     dx, $XMSR
        !          86159: 0:     inb     al, dx          / wait for vertical retrace
        !          86160:        andb    al, $8
        !          86161:        je      0b
        !          86162: 
        !          86163:        mov     dx, $MSR
        !          86164:        movb    al, $0x1A       / video display on
        !          86165:        outb    dx, al
        !          86166: 
        !          86167:        mov     MM_VIS(bp), $-1
        !          86168:        mov     MM_MASK(bp), $0xAAAA
        !          86169:        mov     MM_FLIP(bp), $0
        !          86170:        mov     MM_ULINE(bp), $0
        !          86171:        mov     MM_CURSE(bp), $0x00ff
        !          86172:        movb    MM_WRAP(bp), $1
        !          86173:        movb    MM_NCOL(bp), $80
        !          86174:        subb    COL, COL
        !          86175:        movb    ROW, MM_IBROW(bp)
        !          86176:        movb    MM_BROW(bp), ROW
        !          86177:        movb    bl, MM_IEROW(bp)
        !          86178:        movb    MM_EROW(bp), bl
        !          86179:        sub     bx, bx
        !          86180:        movb    MM_N1(bp), $2
        !          86181:        jmp     mm_ed
        !          86182: 
        !          86183: ////////
        !          86184: /
        !          86185: / mmbell - schedule beep
        !          86186: /
        !          86187: ////////
        !          86188: 
        !          86189: mmbell:        movb    ss:mmbeeps_, $-1
        !          86190:        jmp     eval
        !          86191: 
        !          86192: ////////
        !          86193: /
        !          86194: / mmspec - pass special characters on to keyboard routine(s).
        !          86195: /
        !          86196: ////////
        !          86197: 
        !          86198: mmspec:        movb    ss:mmesc_, al
        !          86199:        jmp     eval
        !          86200: 
        !          86201: ////////
        !          86202: /
        !          86203: / mm_cnl - cursor next line
        !          86204: /
        !          86205: /      Moves the active position to the first column of the next display line.
        !          86206: /      Scrolls the active display if necessary.
        !          86207: /      Returns to mmwrite() to allow flow control on each output line.
        !          86208: /
        !          86209: ////////
        !          86210: 
        !          86211: mm_cnl:        subb    COL, COL
        !          86212:        incb    ROW
        !          86213:        cmpb    ROW, MM_EROW(bp)
        !          86214:        jle     repos
        !          86215:        movb    ROW, MM_EROW(bp)
        !          86216: /      jmp     scrollup
        !          86217: 
        !          86218: ////////
        !          86219: /
        !          86220: / scrollup - scroll display upwards
        !          86221: /
        !          86222: ////////
        !          86223: 
        !          86224: scrollup:
        !          86225:        push    ds
        !          86226:        push    si
        !          86227:        push    cx
        !          86228:        mov     ds, MM_BASE(bp)
        !          86229:        movb    bl, MM_BROW(bp)
        !          86230:        shlb    bl, $1
        !          86231:        mov     di, cs:rowtab(bx)
        !          86232:        mov     si, cs:rowtab+2(bx)
        !          86233:        movb    bl, ROW
        !          86234:        shlb    bl, $1
        !          86235:        mov     cx, cs:rowtab(bx)
        !          86236:        push    cx
        !          86237:        sub     cx, di
        !          86238:        shr     cx, $1
        !          86239:        push    si
        !          86240:        push    di
        !          86241:        push    cx
        !          86242:        rep
        !          86243:        movsw
        !          86244:        pop     cx
        !          86245:        pop     di
        !          86246:        pop     si
        !          86247:        add     si, $BANKSZ
        !          86248:        add     di, $BANKSZ
        !          86249:        rep
        !          86250:        movsw
        !          86251:        mov     ax, MM_FLIP(bp)
        !          86252:        and     ax, MM_MASK(bp)
        !          86253:        pop     di
        !          86254:        push    di
        !          86255:        mov     cx, $NRB4
        !          86256:        rep
        !          86257:        stosw
        !          86258:        pop     di
        !          86259:        add     di, $BANKSZ
        !          86260:        mov     cx, $NRB4
        !          86261:        rep
        !          86262:        stosw
        !          86263:        pop     cx
        !          86264:        pop     si
        !          86265:        pop     ds
        !          86266:        jmp     ewait
        !          86267: 
        !          86268: ////////
        !          86269: /
        !          86270: / repos - reposition cursor
        !          86271: /
        !          86272: ////////
        !          86273: 
        !          86274: repos: movb    bl, ROW                 / reposition to ROW and COL
        !          86275:        shlb    bl, $1
        !          86276:        mov     POS, cs:rowtab(bx)
        !          86277:        movb    bl, COL
        !          86278:        cmpb    MM_NCOL(bp), $40
        !          86279:        jne     0f
        !          86280:        shlb    bl, $1
        !          86281: 0:     add     POS, bx
        !          86282: /      jmp     eval
        !          86283: 
        !          86284: ////////
        !          86285: /
        !          86286: / eval - evaluate input character
        !          86287: /
        !          86288: ////////
        !          86289: 
        !          86290: eval:  jcxz    ewait0
        !          86291:        dec     cx                              / evaluate next char
        !          86292:        lodsb
        !          86293:        movb    bl, al
        !          86294:        shlb    bl, $1
        !          86295:        ijmp    cs:asctab(bx)
        !          86296: 
        !          86297: ewait0:        call    exit
        !          86298:        jcxz    0b
        !          86299:        dec     cx
        !          86300:        lodsb
        !          86301:        movb    bl, al
        !          86302:        shlb    bl, $1
        !          86303:        ijmp    cs:asctab(bx)
        !          86304: 
        !          86305: ////////
        !          86306: /
        !          86307: / mmputc - put character on screen
        !          86308: /
        !          86309: ////////
        !          86310: 
        !          86311: mmputc:        cmpb    MM_NCOL(bp), $40
        !          86312:        jne     putc8
        !          86313: 
        !          86314: 
        !          86315: putc16:        push    ds
        !          86316:        push    si
        !          86317:        subb    ah, ah
        !          86318:        shlb    al, $1
        !          86319:        shl     ax, $1
        !          86320:        shl     ax, $1
        !          86321:        shl     ax, $1
        !          86322:        add     ax, $fontw_
        !          86323:        mov     si, ax
        !          86324:        mov     ax, cs
        !          86325:        mov     ds, ax
        !          86326:        mov     bx, $BANKSZ-2
        !          86327: 
        !          86328:        lodsw                           / row 0
        !          86329:        xor     ax, MM_FLIP(bp)
        !          86330:        and     ax, MM_MASK(bp)
        !          86331:        stosw
        !          86332:        push    di                      / save position for next char
        !          86333: #ifdef TECMAR
        !          86334:        mov     es:(bx,di), ax
        !          86335:        add     di, $78
        !          86336: #endif
        !          86337:        lodsw                           / row 1
        !          86338:        xor     ax, MM_FLIP(bp)
        !          86339:        and     ax, MM_MASK(bp)
        !          86340: #ifdef TECMAR
        !          86341:        stosw
        !          86342: #endif
        !          86343:        mov     es:(bx,di), ax
        !          86344:        add     di, $78
        !          86345: 
        !          86346:        lodsw                           / row 2
        !          86347:        xor     ax, MM_FLIP(bp)
        !          86348:        and     ax, MM_MASK(bp)
        !          86349:        stosw
        !          86350: #ifdef TECMAR
        !          86351:        mov     es:(bx,di), ax
        !          86352:        add     di, $78
        !          86353: #endif
        !          86354: 
        !          86355:        lodsw                           / row 3
        !          86356:        xor     ax, MM_FLIP(bp)
        !          86357:        and     ax, MM_MASK(bp)
        !          86358: #ifdef TECMAR
        !          86359:        stosw
        !          86360: #endif
        !          86361:        mov     es:(bx,di), ax
        !          86362:        add     di, $78
        !          86363: 
        !          86364:        lodsw                           / row 4
        !          86365:        xor     ax, MM_FLIP(bp)
        !          86366:        and     ax, MM_MASK(bp)
        !          86367:        stosw
        !          86368: #ifdef TECMAR
        !          86369:        mov     es:(bx,di), ax
        !          86370:        add     di, $78
        !          86371: #endif
        !          86372: 
        !          86373:        lodsw                           / row 5
        !          86374:        xor     ax, MM_FLIP(bp)
        !          86375:        and     ax, MM_MASK(bp)
        !          86376: #ifdef TECMAR
        !          86377:        stosw
        !          86378: #endif
        !          86379:        mov     es:(bx,di), ax
        !          86380:        add     di, $78
        !          86381: 
        !          86382:        lodsw                           / row 6
        !          86383:        xor     ax, MM_FLIP(bp)
        !          86384:        and     ax, MM_MASK(bp)
        !          86385:        stosw
        !          86386: #ifdef TECMAR
        !          86387:        mov     es:(bx,di), ax
        !          86388:        add     di, $78
        !          86389: #endif
        !          86390:        lodsw                           / row 7
        !          86391:        or      ax, MM_ULINE(bp)
        !          86392:        xor     ax, MM_FLIP(bp)
        !          86393:        and     ax, MM_MASK(bp)
        !          86394: #ifdef TECMAR
        !          86395:        stosw
        !          86396: #endif
        !          86397:        mov     es:(bx,di), ax
        !          86398: 
        !          86399: 
        !          86400:        pop     di                      / restore position for next char
        !          86401:        pop     si
        !          86402:        pop     ds
        !          86403: 
        !          86404:        sub     bx, bx
        !          86405:        incb    COL
        !          86406:        cmpb    COL, MM_NCOL(bp)
        !          86407:        jge     0f
        !          86408:        jcxz    ewait1
        !          86409:        dec     cx
        !          86410:        lodsb
        !          86411:        movb    bl, al
        !          86412:        shlb    bl, $1
        !          86413:        ijmp    cs:asctab(bx)
        !          86414: 
        !          86415: 0:     subb    COL, COL
        !          86416:        incb    ROW
        !          86417:        cmpb    ROW, MM_EROW(bp)
        !          86418:        jg      0f
        !          86419:        jmp     repos
        !          86420: 
        !          86421: 0:     movb    ROW, MM_EROW(bp)
        !          86422:        jmp     scrollup
        !          86423: 
        !          86424: ewait1:        jmp     ewait
        !          86425: 
        !          86426: putc8: push    ds
        !          86427:        push    si
        !          86428:        subb    ah, ah
        !          86429:        shlb    al, $1
        !          86430:        shl     ax, $1
        !          86431:        shl     ax, $1
        !          86432:        add     ax, $0xFA6E
        !          86433:        mov     si, ax
        !          86434:        mov     ax, $0xF000
        !          86435:        mov     ds, ax
        !          86436:        mov     bx, $BANKSZ-1
        !          86437: 
        !          86438:        lodsw
        !          86439:        xor     ax, MM_FLIP(bp)
        !          86440:        stosb                           / row 0
        !          86441:        push    di                      / save position for next char
        !          86442: #ifdef TECMAR
        !          86443:        movb    es:(bx,di), al
        !          86444:        movb    es:79(di), ah           / row 1
        !          86445:        movb    es:80(bx,di), ah
        !          86446:        add     di, $79+80
        !          86447: #else
        !          86448:        movb    es:(bx,di), ah          / row 1
        !          86449:        add     di, $79
        !          86450: #endif
        !          86451: 
        !          86452:        lodsw
        !          86453:        xor     ax, MM_FLIP(bp)
        !          86454:        stosb                           / row 2
        !          86455: #ifdef TECMAR
        !          86456:        movb    es:(bx,di), al
        !          86457:        movb    es:79(di), ah
        !          86458:        movb    es:80(bx,di), ah        / row 3
        !          86459:        add     di, $79+80
        !          86460: #else
        !          86461:        movb    es:(bx,di), ah          / row 3
        !          86462:        add     di, $79
        !          86463: #endif
        !          86464: 
        !          86465:        lodsw
        !          86466:        xor     ax, MM_FLIP(bp)
        !          86467:        stosb                           / row 4
        !          86468: #ifdef TECMAR
        !          86469:        movb    es:(bx,di), al
        !          86470:        movb    es:79(di), ah           / row 5
        !          86471:        movb    es:80(bx,di), ah
        !          86472:        add     di, $79+80
        !          86473: #else
        !          86474:        movb    es:(bx,di), ah          / row 5
        !          86475:        add     di, $79
        !          86476: #endif
        !          86477: 
        !          86478:        lodsw
        !          86479:        orb     ah, MM_ULINE(bp)
        !          86480:        xor     ax, MM_FLIP(bp)
        !          86481:        stosb                           / row 6
        !          86482: #ifdef TECMAR
        !          86483:        movb    es:(bx,di), al
        !          86484:        movb    es:79(di), ah
        !          86485:        movb    es:80(bx,di), ah
        !          86486: #else
        !          86487:        movb    es:(bx,di), ah          / row 7
        !          86488: #endif
        !          86489: 
        !          86490:        pop     di                      / restore position for next char
        !          86491:        pop     si
        !          86492:        pop     ds
        !          86493: 
        !          86494:        sub     bx, bx
        !          86495:        incb    COL
        !          86496:        cmpb    COL, MM_NCOL(bp)
        !          86497:        jge     0f
        !          86498:        jcxz    ewait
        !          86499:        dec     cx
        !          86500:        lodsb
        !          86501:        movb    bl, al
        !          86502:        shlb    bl, $1
        !          86503:        ijmp    cs:asctab(bx)
        !          86504: 
        !          86505: 0:     subb    COL, COL
        !          86506:        incb    ROW
        !          86507:        cmpb    ROW, MM_EROW(bp)
        !          86508:        jg      0f
        !          86509:        jmp     repos
        !          86510: 
        !          86511: 0:     movb    ROW, MM_EROW(bp)
        !          86512:        jmp     scrollup
        !          86513: 
        !          86514: ////////
        !          86515: /
        !          86516: / Ewait - wait for next input char to evaluate
        !          86517: /
        !          86518: ////////
        !          86519: 
        !          86520: ewait: call    exit
        !          86521:        jcxz    ewait
        !          86522:        dec     cx
        !          86523:        lodsb
        !          86524:        movb    bl, al
        !          86525:        shlb    bl, $1
        !          86526:        ijmp    cs:asctab(bx)
        !          86527: 
        !          86528: ////////
        !          86529: /
        !          86530: / mm_cr - carriage return
        !          86531: /
        !          86532: /      Moves the active position to first position of current display line.
        !          86533: /
        !          86534: ////////
        !          86535: 
        !          86536: mm_cr: subb    COL, COL
        !          86537:        movb    bl, ROW
        !          86538:        shlb    bl, $1
        !          86539:        mov     POS, cs:rowtab(bx)
        !          86540:        jcxz    ewait
        !          86541:        dec     cx
        !          86542:        lodsb
        !          86543:        movb    bl, al
        !          86544:        shlb    bl, $1
        !          86545:        ijmp    cs:asctab(bx)
        !          86546: 
        !          86547: ////////
        !          86548: /
        !          86549: / mm_cub - cursor backwards
        !          86550: /
        !          86551: ////////
        !          86552: 
        !          86553: mm_cub:        decb    COL
        !          86554:        jge     0f
        !          86555:        movb    COL, MM_NCOL(bp)
        !          86556:        decb    COL
        !          86557:        decb    ROW
        !          86558:        cmpb    ROW, MM_BROW(bp)
        !          86559:        jge     0f
        !          86560:        subb    COL, COL
        !          86561:        movb    ROW, MM_BROW(bp)
        !          86562: 0:     jmp     repos
        !          86563: 
        !          86564: ////////
        !          86565: /
        !          86566: / Esc state - entered when last char was ESC - transient state.
        !          86567: /
        !          86568: ////////
        !          86569: 
        !          86570: 0:     call    exit
        !          86571: mm_esc:        jcxz    0b
        !          86572:        dec     cx
        !          86573:        lodsb
        !          86574:        movb    MM_N1(bp), ZERO
        !          86575:        movb    MM_N2(bp), ZERO
        !          86576:        movb    bl, al
        !          86577:        shlb    bl, $1
        !          86578:        ijmp    cs:esctab(bx)
        !          86579: 
        !          86580: ////////
        !          86581: /
        !          86582: / Csi_n1 state - entered when last two chars were ESC [
        !          86583: /
        !          86584: /      Action: Evaluates numeric chars as numeric parameter 1.
        !          86585: /
        !          86586: ////////
        !          86587: 
        !          86588: 0:     call    exit
        !          86589: csi_n1:        jcxz    0b
        !          86590:        dec     cx
        !          86591:        lodsb
        !          86592:        cmpb    al, $SEMIC
        !          86593:        je      csi_n2
        !          86594:        movb    bl, al
        !          86595:        subb    bl, $AZERO
        !          86596:        cmpb    bl, $9
        !          86597:        ja      csival
        !          86598:        shlb    MM_N1(bp), $1   / n1 * 2
        !          86599:        movb    al, MM_N1(bp)   / n1 * 2
        !          86600:        shlb    al, $1          / n1 * 4
        !          86601:        shlb    al, $1          / n1 * 8
        !          86602:        addb    al, MM_N1(bp)   / n1 * 10
        !          86603:        addb    al, bl          / n1 * 10 + digit
        !          86604:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          86605:        jmp     csi_n1
        !          86606: 
        !          86607: ////////
        !          86608: /
        !          86609: / Csi_n2 state - entered after input sequence ESC [ n ;
        !          86610: /
        !          86611: ////////
        !          86612: 
        !          86613: 0:     call    exit
        !          86614: csi_n2:        jcxz    0b
        !          86615:        dec     cx
        !          86616:        lodsb
        !          86617:        movb    bl, al
        !          86618:        subb    bl, $AZERO
        !          86619:        cmpb    bl, $9
        !          86620:        ja      csival
        !          86621:        shlb    MM_N2(bp), $1   / n2 * 2
        !          86622:        movb    al, MM_N2(bp)   / n2 * 2
        !          86623:        shlb    al, $1          / n2 * 4
        !          86624:        shlb    al, $1          / n2 * 8
        !          86625:        addb    al, MM_N2(bp)   / n2 * 10
        !          86626:        addb    al, bl          / n2 * 10 + digit
        !          86627:        movb    MM_N2(bp), al   / n2 = (n2 * 10) + digit
        !          86628:        jmp     csi_n2
        !          86629: 
        !          86630: csival:        movb    bl, al
        !          86631:        shlb    bl, $1
        !          86632:        ijmp    cs:csitab(bx)
        !          86633: 
        !          86634: ////////
        !          86635: /
        !          86636: / Csi_gt state - entered after input sequence ESC [ >
        !          86637: /      
        !          86638: ////////
        !          86639: 
        !          86640: 0:     call    exit
        !          86641: csi_gt:        jcxz    0b
        !          86642:        dec     cx
        !          86643:        lodsb
        !          86644:        movb    bl, al
        !          86645:        subb    bl, $AZERO
        !          86646:        cmpb    bl, $9
        !          86647:        ja      0f
        !          86648:        shlb    MM_N1(bp), $1   / n1 * 2
        !          86649:        movb    al, MM_N1(bp)   / n1 * 2
        !          86650:        shlb    al, $1          / n1 * 4
        !          86651:        shlb    al, $1          / n1 * 8
        !          86652:        addb    al, MM_N1(bp)   / n1 * 10
        !          86653:        addb    al, bl          / n1 * 10 + digit
        !          86654:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          86655:        jmp     csi_gt
        !          86656: 
        !          86657: 0:     cmpb    al, $HLOWER
        !          86658:        je      mm_cgh
        !          86659:        cmpb    al, $LLOWER
        !          86660:        je      mm_cgl
        !          86661:        jmp     eval
        !          86662: 
        !          86663: ////////
        !          86664: /
        !          86665: / Csi_q state - entered after input sequence ESC [ ?
        !          86666: /      
        !          86667: ////////
        !          86668: 
        !          86669: 0:     call    exit
        !          86670: csi_q: jcxz    0b
        !          86671:        dec     cx
        !          86672:        lodsb
        !          86673:        movb    bl, al
        !          86674:        subb    bl, $AZERO
        !          86675:        cmpb    bl, $9
        !          86676:        ja      0f
        !          86677:        shlb    MM_N1(bp), $1   / n1 * 2
        !          86678:        movb    al, MM_N1(bp)   / n1 * 2
        !          86679:        shlb    al, $1          / n1 * 4
        !          86680:        shlb    al, $1          / n1 * 8
        !          86681:        addb    al, MM_N1(bp)   / n1 * 10
        !          86682:        addb    al, bl          / n1 * 10 + digit
        !          86683:        movb    MM_N1(bp), al   / n1 = (n1 * 10) + digit
        !          86684:        jmp     csi_q
        !          86685: 
        !          86686: 0:     cmpb    al, $HLOWER
        !          86687:        je      mm_cqh
        !          86688:        cmpb    al, $LLOWER
        !          86689:        je      mm_cql
        !          86690:        jmp     eval
        !          86691: 
        !          86692: ////////
        !          86693: /
        !          86694: / mm_cbt - cursor backward tabulation
        !          86695: /
        !          86696: /      Moves the active position horizontally in the backward direction
        !          86697: /      to the preceding in a series of predetermined positions.
        !          86698: /
        !          86699: ////////
        !          86700: 
        !          86701: mm_cbt:        orb     COL, $7                 / calculate next tab stop
        !          86702:        incb    COL
        !          86703:        subb    COL, $16                / step back two tab positions
        !          86704:        jg      0f
        !          86705:        subb    COL, COL                / cannot step past column 0
        !          86706: 0:     jmp     repos                   / reposition cursor
        !          86707: 
        !          86708: ////////
        !          86709: /
        !          86710: / mm_cgh - process ESC [ > N1 h escape sequence
        !          86711: /
        !          86712: /      Recognized sequences:   ESC [ > 13 h    -- Set CRT saver enabled.
        !          86713: /
        !          86714: ////////
        !          86715: 
        !          86716: mm_cgh:        cmpb    MM_N1(bp), $13
        !          86717:        jne     0f
        !          86718:        mov     ss:mmcrtsav_, $1
        !          86719: 0:     jmp     eval
        !          86720: 
        !          86721: ////////
        !          86722: /
        !          86723: / mm_cgl - process ESC [ > N1 l escape sequence
        !          86724: /
        !          86725: /      Recognized sequences:   ESC [ > 13 l    -- Reset CRT saver.
        !          86726: /
        !          86727: ////////
        !          86728: 
        !          86729: mm_cgl:        cmpb    MM_N1(bp), $13
        !          86730:        jne     0f
        !          86731:        mov     ss:mmcrtsav_, $0
        !          86732: 0:     jmp     eval
        !          86733: 
        !          86734: ////////
        !          86735: /
        !          86736: / mm_cha - cursor horizontal absolute
        !          86737: /
        !          86738: /      Advances the active position forward or backward along the active line
        !          86739: /      to the character position specified by the parameter.
        !          86740: /      A parameter value of zero or one moves the active position to the
        !          86741: /      first character position of the active line.
        !          86742: /      A parameter value of N moves the active position to character position
        !          86743: /      N of the active line.
        !          86744: /
        !          86745: ////////
        !          86746: 
        !          86747: mm_cha:        movb    COL, MM_N1(bp)
        !          86748:        decb    COL
        !          86749:        jge     0f
        !          86750:        subb    COL, COL
        !          86751: 0:     cmpb    COL, MM_NCOL(bp)
        !          86752:        jb      0f
        !          86753:        movb    COL, MM_NCOL(bp)
        !          86754:        decb    COL
        !          86755: 0:     jmp     repos                   / reposition cursor
        !          86756: 
        !          86757: 
        !          86758: ////////
        !          86759: /
        !          86760: / mm_cht - cursor horizontal tabulation
        !          86761: /
        !          86762: /      Advances the active position horizontally to the next or following
        !          86763: /      in a series of predetermined positions.
        !          86764: /
        !          86765: ////////
        !          86766: 
        !          86767: mm_cht:        mov     bx, $BANKSZ
        !          86768:        push    cx
        !          86769:        push    si
        !          86770:        sub     cx, cx
        !          86771:        movb    cl, COL
        !          86772:        orb     cl, $7
        !          86773:        incb    cl
        !          86774:        subb    cl, COL
        !          86775:        addb    COL, cl
        !          86776: 
        !          86777:        mov     si, MM_MASK(bp)
        !          86778:        cmpb    MM_NCOL(bp), $80
        !          86779:        jne     0f
        !          86780:        mov     si, $-1
        !          86781:        inc     cx
        !          86782:        shr     cx, $1
        !          86783: 
        !          86784: 0:     mov     ax, MM_FLIP(bp)
        !          86785:        and     ax, si
        !          86786: #ifdef TECMAR
        !          86787:        stosw                           / row 0
        !          86788:        mov     es:[NHB*0]-2(di,bx), ax
        !          86789:        mov     es:[NHB*1]-2(di), ax    / row 1
        !          86790:        mov     es:[NHB*1]-2(di,bx), ax
        !          86791:        mov     es:[NHB*2]-2(di), ax    / row 2
        !          86792:        mov     es:[NHB*2]-2(di,bx), ax
        !          86793:        mov     es:[NHB*3]-2(di), ax    / row 3
        !          86794:        mov     es:[NHB*3]-2(di,bx), ax
        !          86795:        mov     es:[NHB*4]-2(di), ax    / row 4
        !          86796:        mov     es:[NHB*4]-2(di,bx), ax
        !          86797:        mov     es:[NHB*5]-2(di), ax    / row 5
        !          86798:        mov     es:[NHB*5]-2(di,bx), ax
        !          86799:        mov     es:[NHB*6]-2(di), ax    / row 6
        !          86800:        mov     es:[NHB*6]-2(di,bx), ax
        !          86801:        or      ax, MM_ULINE(bp)
        !          86802:        and     ax, si
        !          86803:        mov     es:[NHB*7]-2(di), ax    / row 7
        !          86804:        mov     es:[NHB*7]-2(di,bx), ax
        !          86805: #else
        !          86806:        stosw                           / row 0
        !          86807:        mov     es:[NHB*0]-2(di,bx), ax / row 1
        !          86808:        mov     es:[NHB*1]-2(di), ax    / row 2
        !          86809:        mov     es:[NHB*1]-2(di,bx), ax / row 3
        !          86810:        mov     es:[NHB*2]-2(di), ax    / row 4
        !          86811:        mov     es:[NHB*2]-2(di,bx), ax / row 5
        !          86812:        mov     es:[NHB*3]-2(di), ax    / row 6
        !          86813:        or      ax, MM_ULINE(bp)
        !          86814:        and     ax, si
        !          86815:        mov     es:[NHB*3]-2(di,bx), ax / row 7
        !          86816: #endif
        !          86817:        loop    0b
        !          86818:        sub     bx, bx
        !          86819:        pop     si
        !          86820:        pop     cx
        !          86821:        cmpb    COL, MM_NCOL(bp)
        !          86822:        jl      0f
        !          86823:        subb    COL, MM_NCOL(bp)
        !          86824:        incb    ROW
        !          86825:        cmpb    ROW, MM_EROW(bp)
        !          86826:        jle     0f
        !          86827:        movb    ROW, MM_EROW(bp)
        !          86828:        jmp     scrollup
        !          86829: 0:     jmp     repos
        !          86830: 
        !          86831: ////////
        !          86832: /
        !          86833: / mm_cpl - cursor preceding line
        !          86834: /
        !          86835: /      Moves the active position to the first position of the preceding
        !          86836: /      display line.
        !          86837: /
        !          86838: ////////
        !          86839: 
        !          86840: mm_cpl:        subb    COL, COL
        !          86841:        decb    ROW
        !          86842:        cmpb    ROW, MM_BROW(bp)
        !          86843:        jnb     0f
        !          86844:        movb    ROW, MM_BROW(bp)
        !          86845:        jmp     scrolldown
        !          86846: 0:     jmp     repos                   / reposition cursor
        !          86847: 
        !          86848: ////////
        !          86849: /
        !          86850: / mm_cqh - process ESC [ ? N1 h escape sequence
        !          86851: /
        !          86852: /      Recognized sequences:   ESC [ ? 7 h     -- Set wraparound.
        !          86853: /
        !          86854: ////////
        !          86855: 
        !          86856: mm_cqh:
        !          86857:        cmpb    MM_N1(bp), $7           / Wraparound.
        !          86858:        jne     0f
        !          86859:        movb    MM_WRAP(bp), $1
        !          86860: 0:     jmp     eval
        !          86861: 
        !          86862: ////////
        !          86863: /
        !          86864: / mm_cql - process ESC [ ? N1 l escape sequence
        !          86865: /
        !          86866: /      Recognized sequences:   ESC [ ? 7 l     -- Reset wraparound.
        !          86867: /
        !          86868: ////////
        !          86869: 
        !          86870: mm_cql:
        !          86871:        cmpb    MM_N1(bp), $7           / No wraparound.
        !          86872:        jne     0f
        !          86873:        movb    MM_WRAP(bp), $0
        !          86874: 0:     jmp     eval
        !          86875: 
        !          86876: ////////
        !          86877: /
        !          86878: / mm_cud - cursor down
        !          86879: /
        !          86880: /      Moves the active position downward without altering the
        !          86881: /      horizontal position.
        !          86882: /
        !          86883: ////////
        !          86884: 
        !          86885: mm_cud:        incb    ROW
        !          86886:        cmpb    ROW, MM_EROW(bp)
        !          86887:        jna     0f
        !          86888:        movb    ROW, MM_EROW(bp)
        !          86889: 0:     jmp     repos                   / reposition cursor
        !          86890: 
        !          86891: ////////
        !          86892: /
        !          86893: / mm_cuf - cursor forward
        !          86894: /
        !          86895: /      Moves the active position in the forward direction.
        !          86896: /
        !          86897: ////////
        !          86898: 
        !          86899: mm_cuf:        incb    COL
        !          86900:        cmpb    COL, MM_NCOL(bp)
        !          86901:        jb      0f
        !          86902:        subb    COL, MM_NCOL(bp)
        !          86903:        incb    ROW
        !          86904:        cmpb    ROW, MM_EROW(bp)
        !          86905:        jna     0f
        !          86906:        movb    ROW, MM_EROW(bp)
        !          86907:        movb    COL, MM_NCOL(bp)
        !          86908:        decb    COL
        !          86909: 0:     jmp     repos
        !          86910: 
        !          86911: ////////
        !          86912: /
        !          86913: / mm_cup - cursor position
        !          86914: /
        !          86915: /      Moves the active position to the position specified by two parameters.
        !          86916: /      The first parameter (mm_n1) specifies the vertical position (MM_ROW(bp)).
        !          86917: /      The second parameter (mm_n2) specifies the horizontal position (MM_COL(bp)).
        !          86918: /      A parameter value of 0 or 1 for the first or second parameter
        !          86919: /      moves the active position to the first line or column in the
        !          86920: /      display respectively.
        !          86921: /
        !          86922: ////////
        !          86923: 
        !          86924: mm_cup:        movb    ROW, MM_N1(bp)
        !          86925:        decb    ROW
        !          86926:        jg      0f
        !          86927:        subb    ROW, ROW
        !          86928: 0:     addb    ROW, MM_BROW(bp)
        !          86929:        cmpb    ROW, MM_EROW(bp)
        !          86930:        jb      0f
        !          86931:        movb    ROW, MM_EROW(bp)
        !          86932: 0:     movb    COL, MM_N2(bp)
        !          86933:        decb    COL
        !          86934:        jg      0f
        !          86935:        subb    COL, COL
        !          86936: 0:     cmpb    COL, MM_NCOL(bp)
        !          86937:        jb      0f
        !          86938:        movb    COL, MM_NCOL(bp)
        !          86939:        decb    COL
        !          86940: 0:     jmp     repos                   / reposition cursor
        !          86941: 
        !          86942: ////////
        !          86943: /
        !          86944: / mm_cuu - cursor up
        !          86945: /
        !          86946: /      Moves the active position upward without altering the horizontal
        !          86947: /      position.
        !          86948: /
        !          86949: ////////
        !          86950: 
        !          86951: mm_cuu:        decb    ROW
        !          86952:        cmpb    ROW, MM_BROW(bp)
        !          86953:        jge     0f
        !          86954:        movb    ROW, MM_BROW(bp)
        !          86955: 0:     jmp     repos                   / reposition cursor
        !          86956: 
        !          86957: ////////
        !          86958: /
        !          86959: / mm_dl - delete line
        !          86960: /
        !          86961: /      Removes the contents of the active line.
        !          86962: /      The contents of all following lines are shifted in a block
        !          86963: /      toward the active line.
        !          86964: /
        !          86965: ////////
        !          86966: 
        !          86967: mm_dl: push    ds
        !          86968:        push    si
        !          86969:        push    cx
        !          86970:        mov     ds, MM_BASE(bp)
        !          86971:        movb    bl, ROW
        !          86972:        shlb    bl, $1
        !          86973:        mov     di, cs:rowtab(bx)
        !          86974:        mov     si, cs:rowtab+2(bx)
        !          86975:        movb    bl, MM_EROW(bp)
        !          86976:        shlb    bl, $1
        !          86977:        mov     cx, cs:rowtab(bx)
        !          86978:        sub     cx, di
        !          86979:        jle     0f
        !          86980:        shr     cx, $1
        !          86981:        push    si
        !          86982:        push    di
        !          86983:        push    cx
        !          86984:        rep
        !          86985:        movsw
        !          86986:        pop     cx
        !          86987:        pop     di
        !          86988:        pop     si
        !          86989:        add     si, $BANKSZ
        !          86990:        add     di, $BANKSZ
        !          86991:        rep
        !          86992:        movsw
        !          86993:        mov     di, cs:rowtab(bx)
        !          86994:        push    di
        !          86995:        mov     cx, $NRB4
        !          86996:        mov     ax, MM_FLIP(bp)
        !          86997:        and     ax, MM_MASK(bp)
        !          86998:        rep
        !          86999:        stosw
        !          87000:        pop     di
        !          87001:        add     di, $BANKSZ
        !          87002:        mov     cx, $NRB4
        !          87003:        rep
        !          87004:        stosw
        !          87005:        subb    COL, COL
        !          87006: 0:     pop     cx
        !          87007:        pop     si
        !          87008:        pop     ds
        !          87009:        jmp     repos
        !          87010: 
        !          87011: ////////
        !          87012: /
        !          87013: / mm_dmi - disable manual input
        !          87014: /
        !          87015: /      Set flag preventing keyboard input.
        !          87016: /
        !          87017: ////////
        !          87018: 
        !          87019: mm_dmi:
        !          87020:        mov     ss:islock_, $1
        !          87021:        jmp     eval
        !          87022: 
        !          87023: ////////
        !          87024: /
        !          87025: / mm_ea - erase in area
        !          87026: /
        !          87027: /      Erase some or all of the characters in the currently active area
        !          87028: /      according to the parameter:
        !          87029: /              0 - erase from active position to end inclusive (default)
        !          87030: /              1 - erase from start to active position inclusive
        !          87031: /              2 - erase all of active area
        !          87032: /
        !          87033: ////////
        !          87034: 
        !          87035: mm_ea: movb    al, MM_N1(bp)
        !          87036:        cmpb    al, $0
        !          87037:        jne     0f
        !          87038:        movb    bl, MM_EROW(bp)
        !          87039:        jmp     mm_e0
        !          87040: 0:     cmpb    al, $1
        !          87041:        jne     0f
        !          87042:        movb    bl, MM_BROW(bp)
        !          87043:        jmp     mm_e1
        !          87044: 0:     subb    COL, COL
        !          87045:        movb    ROW, MM_BROW(bp)
        !          87046:        movb    bl, ROW
        !          87047:        shlb    bl, $1
        !          87048:        mov     POS, cs:rowtab(bx)
        !          87049:        movb    bl, MM_EROW(bp)
        !          87050:        subb    bl, ROW
        !          87051:        jmp     mm_e2
        !          87052: 
        !          87053: ////////
        !          87054: /
        !          87055: / mm_ed - erase in display
        !          87056: /
        !          87057: /      Erase some or all of the characters in the display according to the
        !          87058: /      parameter
        !          87059: /              0 - erase from active position to end inclusive (default)
        !          87060: /              1 - erase from start to active position inclusive
        !          87061: /              2 - erase all of display
        !          87062: /
        !          87063: ////////
        !          87064: 
        !          87065: mm_ed: movb    al, MM_N1(bp)
        !          87066:        cmpb    al, $0
        !          87067:        jne     0f
        !          87068:        movb    bl, MM_LROW(bp)
        !          87069:        jmp     mm_e0
        !          87070: 0:     cmpb    al, $1
        !          87071:        jne     0f
        !          87072:        subb    bl, bl
        !          87073:        jmp     mm_e1
        !          87074: 0:     subb    COL, COL
        !          87075:        movb    ROW, MM_BROW(bp)
        !          87076:        sub     POS, POS
        !          87077:        movb    bl, MM_LROW(bp)
        !          87078:        jmp     mm_e2
        !          87079: 
        !          87080: ////////
        !          87081: /
        !          87082: / mm_el - erase in line
        !          87083: /
        !          87084: /      Erase some or all of the characters in the line according to the
        !          87085: /      parameter:
        !          87086: /              0 - erase from active position to end inclusive (default)
        !          87087: /              1 - erase from start to active position inclusive
        !          87088: /              2 - erase entire line
        !          87089: /
        !          87090: ////////
        !          87091: 
        !          87092: mm_el: movb    al, MM_N1(bp)
        !          87093:        movb    bl, ROW
        !          87094:        cmpb    al, $0
        !          87095:        je      mm_e0
        !          87096:        cmpb    al, $1
        !          87097:        je      mm_e1
        !          87098:        shlb    bl, $1
        !          87099:        mov     POS, cs:rowtab(bx)
        !          87100:        subb    COL, COL
        !          87101:        subb    bl, bl
        !          87102: /      jmp     mm_e2
        !          87103: 
        !          87104: ////////
        !          87105: /
        !          87106: / mm_e2 - erase from POS for BL rows (minimum 1 row)
        !          87107: /
        !          87108: ////////
        !          87109: 
        !          87110: mm_e2: push    cx
        !          87111:        mov     ax, MM_FLIP(bp)
        !          87112:        and     ax, MM_MASK(bp)
        !          87113: 0:     mov     cx, $NRB4
        !          87114:        rep
        !          87115:        stosw
        !          87116:        add     di, $BANKSZ-NRB2
        !          87117:        mov     cx, $NRB4
        !          87118:        rep
        !          87119:        stosw
        !          87120:        sub     di, $BANKSZ
        !          87121:        decb    bl
        !          87122:        jge     0b
        !          87123:        pop     cx
        !          87124:        jmp     repos
        !          87125: 
        !          87126: ////////
        !          87127: /
        !          87128: / mm_e1 - erase from row BL to current cursor position.
        !          87129: /
        !          87130: ////////
        !          87131: 
        !          87132: mm_e1: push    dx
        !          87133:        push    cx
        !          87134:        push    di
        !          87135:        mov     ax, MM_FLIP(bp)
        !          87136:        and     ax, MM_MASK(bp)
        !          87137:        shlb    bl, $1
        !          87138:        mov     di, cs:rowtab(bx)
        !          87139:        movb    bl, ROW
        !          87140:        shlb    bl, $1
        !          87141:        mov     cx, cs:rowtab(bx)
        !          87142:        sub     cx, di
        !          87143:        jle     0f
        !          87144:        shr     cx, $1
        !          87145:        push    di
        !          87146:        push    cx
        !          87147:        rep
        !          87148:        stosw
        !          87149:        pop     cx
        !          87150:        pop     di
        !          87151:        add     di, $BANKSZ
        !          87152:        rep
        !          87153:        stosw
        !          87154: 0:     pop     cx
        !          87155:        movb    bl, ROW
        !          87156:        shlb    bl, $1
        !          87157:        mov     di, cs:rowtab(bx)
        !          87158:        sub     cx, di
        !          87159:        jle     0f
        !          87160: 
        !          87161:        mov     dx, di
        !          87162:        mov     bx, cx
        !          87163:        rep                     / erase row 0
        !          87164:        stosb
        !          87165:        add     dx, $80
        !          87166:        mov     di, dx
        !          87167:        mov     cx, bx
        !          87168: #ifdef TECMAR
        !          87169:        rep                     / erase row 1
        !          87170:        stosb
        !          87171:        add     dx, $80
        !          87172:        mov     di, dx
        !          87173:        mov     cx, bx
        !          87174: #endif
        !          87175:        rep                     / erase row 2
        !          87176:        stosb
        !          87177:        add     dx, $80
        !          87178:        mov     di, dx
        !          87179:        mov     cx, bx
        !          87180: #ifdef TECMAR
        !          87181:        rep                     / erase row 3
        !          87182:        stosb
        !          87183:        add     dx, $80
        !          87184:        mov     di, dx
        !          87185:        mov     cx, bx
        !          87186: #endif
        !          87187:        rep                     / erase row 4
        !          87188:        stosb
        !          87189:        add     dx, $80
        !          87190:        mov     di, dx
        !          87191:        mov     cx, bx
        !          87192: #ifdef TECMAR
        !          87193:        rep                     / erase row 5
        !          87194:        stosb
        !          87195:        add     dx, $80
        !          87196:        mov     di, dx
        !          87197:        mov     cx, bx
        !          87198: #endif
        !          87199:        rep                     / erase row 6
        !          87200:        stosb
        !          87201: #ifdef TECMAR
        !          87202:        add     dx, $80
        !          87203:        mov     di, dx
        !          87204:        mov     cx, bx
        !          87205:        rep                     / erase row 7
        !          87206:        stosb
        !          87207:        add     dx, $BANKSZ-560
        !          87208: #else
        !          87209:        add     dx, $BANKSZ-240
        !          87210: #endif
        !          87211:        mov     di, dx
        !          87212:        mov     cx, bx
        !          87213: #ifdef TECMAR
        !          87214:        rep                     / erase row 0
        !          87215:        stosb
        !          87216:        add     dx, $80
        !          87217:        mov     di, dx
        !          87218:        mov     cx, bx
        !          87219: #endif
        !          87220:        rep                     / erase row 1
        !          87221:        stosb
        !          87222:        add     dx, $80
        !          87223:        mov     di, dx
        !          87224:        mov     cx, bx
        !          87225: #ifdef TECMAR
        !          87226:        rep                     / erase row 2
        !          87227:        stosb
        !          87228:        add     dx, $80
        !          87229:        mov     di, dx
        !          87230:        mov     cx, bx
        !          87231: #endif
        !          87232:        rep                     / erase row 3
        !          87233:        stosb
        !          87234:        add     dx, $80
        !          87235:        mov     di, dx
        !          87236:        mov     cx, bx
        !          87237: #ifdef TECMAR
        !          87238:        rep                     / erase row 4
        !          87239:        stosb
        !          87240:        add     dx, $80
        !          87241:        mov     di, dx
        !          87242:        mov     cx, bx
        !          87243: #endif
        !          87244:        rep                     / erase row 5
        !          87245:        stosb
        !          87246:        add     dx, $80
        !          87247:        mov     di, dx
        !          87248:        mov     cx, bx
        !          87249: #ifdef TECMAR
        !          87250:        rep                     / erase row 6
        !          87251:        stosb
        !          87252:        add     dx, $80
        !          87253:        mov     di, dx
        !          87254:        mov     cx, bx
        !          87255: #endif
        !          87256:        rep                     / erase row 7
        !          87257:        stosb
        !          87258: 1:     sub     bx, bx
        !          87259:        pop     cx
        !          87260:        pop     dx
        !          87261:        jmp     repos
        !          87262: 
        !          87263: ////////
        !          87264: /
        !          87265: / mm_e0 - erase from current cursor position to row BL inclusive.
        !          87266: /
        !          87267: ////////
        !          87268: 
        !          87269: mm_e0: push    dx
        !          87270:        push    cx
        !          87271:        push    di
        !          87272:        mov     ax, MM_FLIP(bp)
        !          87273:        and     ax, MM_MASK(bp)
        !          87274:        shlb    bl, $1
        !          87275:        mov     cx, cs:rowtab+2(bx)
        !          87276:        movb    bl, ROW
        !          87277:        shlb    bl, $1
        !          87278:        mov     di, cs:rowtab+2(bx)
        !          87279:        sub     cx, di
        !          87280:        jle     0f
        !          87281:        shr     cx, $1
        !          87282:        push    di
        !          87283:        push    cx
        !          87284:        rep
        !          87285:        stosw
        !          87286:        pop     cx
        !          87287:        pop     di
        !          87288:        add     di, $BANKSZ
        !          87289:        rep
        !          87290:        stosw
        !          87291: 0:     pop     di
        !          87292:        sub     cx, cx
        !          87293:        movb    cl, MM_NCOL(bp)
        !          87294:        subb    cl, COL
        !          87295:        cmpb    MM_NCOL(bp), $40
        !          87296:        jne     0f
        !          87297:        shlb    cl, $1
        !          87298: 0:     mov     dx, di
        !          87299:        mov     bx, cx
        !          87300:        rep                     / erase row 0
        !          87301:        stosb
        !          87302:        add     dx, $80
        !          87303:        mov     di, dx
        !          87304:        mov     cx, bx
        !          87305: #ifdef TECMAR
        !          87306:        rep                     / erase row 1
        !          87307:        stosb
        !          87308:        add     dx, $80
        !          87309:        mov     di, dx
        !          87310:        mov     cx, bx
        !          87311: #endif
        !          87312:        rep                     / erase row 2
        !          87313:        stosb
        !          87314:        add     dx, $80
        !          87315:        mov     di, dx
        !          87316:        mov     cx, bx
        !          87317: #ifdef TECMAR
        !          87318:        rep                     / erase row 3
        !          87319:        stosb
        !          87320:        add     dx, $80
        !          87321:        mov     di, dx
        !          87322:        mov     cx, bx
        !          87323: #endif
        !          87324:        rep                     / erase row 4
        !          87325:        stosb
        !          87326:        add     dx, $80
        !          87327:        mov     di, dx
        !          87328:        mov     cx, bx
        !          87329: #ifdef TECMAR
        !          87330:        rep                     / erase row 5
        !          87331:        stosb
        !          87332:        add     dx, $80
        !          87333:        mov     di, dx
        !          87334:        mov     cx, bx
        !          87335: #endif
        !          87336:        rep                     / erase row 6
        !          87337:        stosb
        !          87338: #ifdef TECMAR
        !          87339:        add     dx, $80
        !          87340:        mov     di, dx
        !          87341:        mov     cx, bx
        !          87342:        rep                     / erase row 7
        !          87343:        stosb
        !          87344:        add     dx, $BANKSZ-560
        !          87345: #else
        !          87346:        add     dx, $BANKSZ-240
        !          87347: #endif
        !          87348:        mov     di, dx
        !          87349:        mov     cx, bx
        !          87350: #ifdef TECMAR
        !          87351:        rep                     / erase row 0
        !          87352:        stosb
        !          87353:        add     dx, $80
        !          87354:        mov     di, dx
        !          87355:        mov     cx, bx
        !          87356: #endif
        !          87357:        rep                     / erase row 1
        !          87358:        stosb
        !          87359:        add     dx, $80
        !          87360:        mov     di, dx
        !          87361:        mov     cx, bx
        !          87362: #ifdef TECMAR
        !          87363:        rep                     / erase row 2
        !          87364:        stosb
        !          87365:        add     dx, $80
        !          87366:        mov     di, dx
        !          87367:        mov     cx, bx
        !          87368: #endif
        !          87369:        rep                     / erase row 3
        !          87370:        stosb
        !          87371:        add     dx, $80
        !          87372:        mov     di, dx
        !          87373:        mov     cx, bx
        !          87374: #ifdef TECMAR
        !          87375:        rep                     / erase row 4
        !          87376:        stosb
        !          87377:        add     dx, $80
        !          87378:        mov     di, dx
        !          87379:        mov     cx, bx
        !          87380: #endif
        !          87381:        rep                     / erase row 5
        !          87382:        stosb
        !          87383:        add     dx, $80
        !          87384:        mov     di, dx
        !          87385:        mov     cx, bx
        !          87386: #ifdef TECMAR
        !          87387:        rep                     / erase row 6
        !          87388:        stosb
        !          87389:        add     dx, $80
        !          87390:        mov     di, dx
        !          87391:        mov     cx, bx
        !          87392: #endif
        !          87393:        rep                     / erase row 7
        !          87394:        stosb
        !          87395: 1:     sub     bx, bx
        !          87396:        pop     cx
        !          87397:        pop     dx
        !          87398:        jmp     repos
        !          87399: 
        !          87400: ////////
        !          87401: /
        !          87402: / mm_emi - enable manual input
        !          87403: /
        !          87404: /      Clear flag preventing keyboard input.
        !          87405: /
        !          87406: ////////
        !          87407: 
        !          87408: mm_emi:
        !          87409:        mov     ss:islock_, $0
        !          87410:        jmp     eval
        !          87411: 
        !          87412: ////////
        !          87413: /
        !          87414: / mm_il - insert line
        !          87415: /
        !          87416: /      Insert a erased line at the active line by shifting the contents
        !          87417: /      of the active line and all following lines away from the active line.
        !          87418: /      The contents of the last line in the scrolling region are removed.
        !          87419: /
        !          87420: ////////
        !          87421: 
        !          87422: scrolldown:
        !          87423: mm_il: push    ds
        !          87424:        push    si
        !          87425:        push    cx
        !          87426:        mov     ds, MM_BASE(bp)
        !          87427:        movb    bl, MM_EROW(bp)
        !          87428:        shlb    bl, $1
        !          87429:        mov     si, cs:rowtab(bx)
        !          87430:        mov     cx, si
        !          87431:        sub     si, $2
        !          87432:        mov     di, cs:rowtab+2(bx)
        !          87433:        sub     di, $2
        !          87434:        movb    bl, ROW
        !          87435:        shlb    bl, $1
        !          87436:        sub     cx, cs:rowtab(bx)
        !          87437:        jle     0f
        !          87438:        shr     cx, $1
        !          87439:        push    si
        !          87440:        push    di
        !          87441:        push    cx
        !          87442:        std
        !          87443:        rep
        !          87444:        movsw
        !          87445:        pop     cx
        !          87446:        pop     di
        !          87447:        pop     si
        !          87448:        add     si, $BANKSZ
        !          87449:        add     di, $BANKSZ
        !          87450:        rep
        !          87451:        movsw
        !          87452:        mov     di, cs:rowtab(bx)
        !          87453:        push    di
        !          87454:        mov     cx, $NRB4
        !          87455:        mov     ax, MM_FLIP(bp)
        !          87456:        and     ax, MM_MASK(bp)
        !          87457:        cld
        !          87458:        rep
        !          87459:        stosw
        !          87460:        pop     di
        !          87461:        add     di, $BANKSZ
        !          87462:        mov     cx, $NRB4
        !          87463:        rep
        !          87464:        stosw
        !          87465:        subb    COL, COL
        !          87466: 0:     pop     cx
        !          87467:        pop     si
        !          87468:        pop     ds
        !          87469:        jmp     repos
        !          87470: 
        !          87471: ////////
        !          87472: /
        !          87473: / mm_hpa - horizontal position absolute
        !          87474: /
        !          87475: /      Moves the active position within the active line to the position
        !          87476: /      specified by the parameter.  A parameter value of zero or one
        !          87477: /      moves the active position to the first position of the active line.
        !          87478: /
        !          87479: ////////
        !          87480: 
        !          87481: mm_hpa:        movb    COL, MM_N1(bp)
        !          87482:        decb    COL
        !          87483:        jg      0f
        !          87484:        subb    COL, COL
        !          87485: 0:     cmpb    COL, MM_NCOL(bp)
        !          87486:        jb      0f
        !          87487:        movb    COL, MM_NCOL(bp)
        !          87488:        decb    COL
        !          87489: 0:     jmp     repos                   / reposition cursor
        !          87490: 
        !          87491: ////////
        !          87492: /
        !          87493: / mm_hpr - horizontal position relative
        !          87494: /
        !          87495: /      Moves the active position forward the number of positions specified
        !          87496: /      by the parameter.  A parameter value of zero or one indicates a
        !          87497: /      single-position move.
        !          87498: /
        !          87499: ////////
        !          87500: 
        !          87501: mm_hpr:        movb    al, MM_N1(bp)
        !          87502:        orb     al, al
        !          87503:        jne     0f
        !          87504:        incb    al
        !          87505: 0:     addb    COL, al
        !          87506:        cmpb    COL, MM_NCOL(bp)
        !          87507:        jb      0f
        !          87508:        movb    COL, MM_NCOL(bp)
        !          87509:        decb    COL
        !          87510: 0:     jmp     repos                   / reposition cursor
        !          87511: 
        !          87512: ////////
        !          87513: /
        !          87514: / mm_hvp - horizontal and vertical position
        !          87515: /
        !          87516: /      Moves the active position to the position specified by two parameters.
        !          87517: /      The first parameter specifies the vertical position (MM_ROW(bp)).
        !          87518: /      The second parameter specifies the horizontal position (MM_COL(bp)).
        !          87519: /      A parameter value of zero or one moves the active position to the
        !          87520: /      first line or column in the display.
        !          87521: /
        !          87522: ////////
        !          87523: 
        !          87524: mm_hvp:        movb    ROW, MM_N1(bp)
        !          87525:        decb    ROW
        !          87526:        jg      0f
        !          87527:        subb    ROW, ROW
        !          87528: 0:     cmpb    ROW, MM_LROW(bp)
        !          87529:        jna     0f
        !          87530:        movb    ROW, MM_LROW(bp)
        !          87531: 0:     movb    COL, MM_N2(bp)
        !          87532:        decb    COL
        !          87533:        jg      0f
        !          87534:        subb    COL, COL
        !          87535: 0:     cmpb    COL, MM_NCOL(bp)
        !          87536:        jb      0f
        !          87537:        movb    COL, MM_NCOL(bp)
        !          87538:        decb    COL
        !          87539: 0:     jmp     repos                   / reposition cursor
        !          87540: 
        !          87541: ////////
        !          87542: /
        !          87543: / mm_ind - index
        !          87544: /
        !          87545: /      Causes the active position to move downward one line without changing
        !          87546: /      the horizontal position.  Scrolling occurs if below scrolling region.
        !          87547: /
        !          87548: ////////
        !          87549: 
        !          87550: mm_ind:        incb    ROW
        !          87551:        cmpb    ROW, MM_EROW(bp)
        !          87552:        jg      0f
        !          87553:        jmp     repos
        !          87554: 0:     movb    ROW, MM_EROW(bp)
        !          87555:        jmp     scrollup
        !          87556: 
        !          87557: ////////
        !          87558: /
        !          87559: / mm_new - save cursor position
        !          87560: /
        !          87561: ////////
        !          87562: 
        !          87563: mm_new:        movb    MM_SCOL(bp), COL
        !          87564:        movb    MM_SROW(bp), ROW
        !          87565:        jmp     eval
        !          87566: 
        !          87567: ////////
        !          87568: /
        !          87569: / mm_old - restore old cursor position
        !          87570: /
        !          87571: ////////
        !          87572: 
        !          87573: mm_old:        movb    COL, MM_SCOL(bp)
        !          87574:        movb    ROW, MM_SROW(bp)
        !          87575:        jmp     repos
        !          87576: 
        !          87577: ////////
        !          87578: /
        !          87579: / mm_ri - reverse index
        !          87580: /
        !          87581: /      Moves the active position to the same horizontal position on the
        !          87582: /      preceding line.  Scrolling occurs if above scrolling region.
        !          87583: /
        !          87584: ////////
        !          87585: 
        !          87586: mm_ri: decb    ROW
        !          87587:        cmpb    ROW, MM_BROW(bp)
        !          87588:        jge     0f
        !          87589:        movb    ROW, MM_BROW(bp)
        !          87590:        jmp     scrolldown
        !          87591: 0:     jmp     repos
        !          87592: 
        !          87593: ////////
        !          87594: /
        !          87595: / mm_scr - select cursor rendition
        !          87596: /
        !          87597: /      Invokes the cursor rendition specified by the parameter.
        !          87598: /
        !          87599: /      Recognized renditions are:      0 - cursor visible
        !          87600: /                                      1 - cursor invisible
        !          87601: ////////
        !          87602: 
        !          87603: mm_scr:        decb    MM_N1(bp)
        !          87604:        je      0f
        !          87605:        jg      1f
        !          87606:        mov     MM_VIS(bp), $-1
        !          87607:        jmp     eval
        !          87608: 
        !          87609: 0:     mov     MM_VIS(bp), $0
        !          87610: 1:     jmp     eval
        !          87611: 
        !          87612: ////////
        !          87613: /
        !          87614: / mm_sgr - select graphic rendition
        !          87615: /
        !          87616: /      Invokes the graphic rendition specified by the parameter.
        !          87617: /      All following characters in the data stream are rendered
        !          87618: /      according to the parameters until the next occurrence of
        !          87619: /      SGR in the data stream.
        !          87620: /
        !          87621: /      Recognized renditions are:      1 - high intensity
        !          87622: /                                      4 - underline
        !          87623: /                                      7 - reverse video
        !          87624: /
        !          87625: ////////
        !          87626: 
        !          87627: mm_sgr:        movb    al, MM_N1(bp)
        !          87628:        cmpb    al, $0
        !          87629:        jne     0f
        !          87630:        mov     MM_MASK(bp), $0xAAAA
        !          87631:        mov     MM_FLIP(bp), $0
        !          87632:        mov     MM_ULINE(bp), $0
        !          87633:        jmp     1f
        !          87634: 0:     cmpb    al, $1          / bold
        !          87635:        jne     0f
        !          87636:        mov     MM_MASK(bp), $-1
        !          87637:        jmp     1f
        !          87638: 0:     cmpb    al, $4          / underline
        !          87639:        jne     0f
        !          87640:        mov     MM_ULINE(bp), $0xFFFF
        !          87641:        jmp     1f
        !          87642: 0:     cmpb    al, $7          / reverse video
        !          87643:        jne     0f
        !          87644:        mov     MM_FLIP(bp), $-1
        !          87645:        jmp     1f
        !          87646: 0:
        !          87647: 1:     jmp     eval
        !          87648: 
        !          87649: ////////
        !          87650: /
        !          87651: / mm_so - stand out - enter 40 column mode
        !          87652: /
        !          87653: ////////
        !          87654: 
        !          87655: mm_so: cmpb    MM_NCOL(bp), $80
        !          87656:        jne     0f
        !          87657:        movb    MM_NCOL(bp), $40
        !          87658:        incb    COL
        !          87659:        shrb    COL, $1
        !          87660: 0:     mov     MM_CURSE(bp), $0xffff
        !          87661:        jmp     repos
        !          87662: 
        !          87663: ////////
        !          87664: /
        !          87665: / mm_si - stand in - enter 80 column mode
        !          87666: /
        !          87667: ////////
        !          87668: 
        !          87669: mm_si: cmpb    MM_NCOL(bp), $40
        !          87670:        jne     0f
        !          87671:        movb    MM_NCOL(bp), $80
        !          87672:        shlb    COL, $1
        !          87673: 0:     mov     MM_CURSE(bp), $0x00ff
        !          87674:        jmp     repos
        !          87675: 
        !          87676: ////////
        !          87677: /
        !          87678: / mm_ssr - set scrolling region
        !          87679: /
        !          87680: ////////
        !          87681: 
        !          87682: mm_ssr:        movb    al, MM_N1(bp)
        !          87683:        decb    al
        !          87684:        jge     0f
        !          87685:        subb    al, al
        !          87686: 0:     cmpb    al, MM_LROW(bp)
        !          87687:        ja      1f
        !          87688:        movb    bl, MM_N2(bp)
        !          87689:        decb    bl
        !          87690:        jge     0f
        !          87691:        subb    bl, bl
        !          87692: 0:     cmpb    bl, MM_LROW(bp)
        !          87693:        ja      1f
        !          87694:        cmpb    al, bl
        !          87695:        ja      1f
        !          87696:        movb    MM_BROW(bp), al
        !          87697:        movb    MM_EROW(bp), bl
        !          87698:        movb    ROW, al
        !          87699:        subb    COL, COL
        !          87700: 1:     jmp     repos
        !          87701: 
        !          87702: ////////
        !          87703: /
        !          87704: / mm_vpa - vertical position absolute
        !          87705: /
        !          87706: /      Moves the active position to the line specified by the parameter
        !          87707: /      without changing the horizontal position.
        !          87708: /      A parameter value of 0 or 1 moves the active position vertically
        !          87709: /      to the first line.
        !          87710: /
        !          87711: ////////
        !          87712: 
        !          87713: mm_vpa:        movb    ROW, MM_N1(bp)
        !          87714:        decb    ROW
        !          87715:        jg      0f
        !          87716:        subb    ROW, ROW
        !          87717: 0:     cmpb    ROW, MM_LROW(bp)
        !          87718:        jna     0f
        !          87719:        movb    ROW, MM_LROW(bp)
        !          87720: 0:     jmp     repos                   / reposition cursor
        !          87721: 
        !          87722: ////////
        !          87723: /
        !          87724: / mm_vpr - vertical position relative
        !          87725: /
        !          87726: /      Moves the active position downward the number of lines specified
        !          87727: /      by the parameter without changing the horizontal position.
        !          87728: /      A parameter value of zero or one moves the active position
        !          87729: /      one line downward.
        !          87730: /
        !          87731: ////////
        !          87732: 
        !          87733: mm_vpr:        movb    al, MM_N1(bp)
        !          87734:        orb     al, al
        !          87735:        jne     0f
        !          87736:        incb    al
        !          87737: 0:     addb    ROW, al
        !          87738:        cmpb    ROW, MM_LROW(bp)
        !          87739:        jb      0f
        !          87740:        movb    ROW, MM_LROW(bp)
        !          87741: 0:     jmp     repos                   / reposition cursor
        !          87742: 
        !          87743: ////////
        !          87744: /
        !          87745: / asctab - table of functions indexed by ascii characters
        !          87746: /
        !          87747: ////////
        !          87748: 
        !          87749: asctab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          87750:        .word   eval,   eval,   eval,   mmbell  /* EOT  ENQ  ACK  BEL  */
        !          87751:        .word   mm_cub, mm_cht, mm_cnl, mm_ind  /* BS   HT   LF   VT  */
        !          87752:        .word   eval,   mm_cr,  mm_so,  mm_si   /* FF   CR   SO   SI  */
        !          87753:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3 */
        !          87754:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          87755:        .word   eval,   eval,   eval,   mm_esc  /* CAN  EM   SUB  ESC  */
        !          87756:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          87757:        .word   mmputc, mmputc, mmputc, mmputc  /*   ! " # \040 - \043 */
        !          87758:        .word   mmputc, mmputc, mmputc, mmputc  /* $ % & quote \044 - \047 */
        !          87759:        .word   mmputc, mmputc, mmputc, mmputc  /* ( ) * + \050 - \053 */
        !          87760:        .word   mmputc, mmputc, mmputc, mmputc  /* , - . / \054 - \057 */
        !          87761:        .word   mmputc, mmputc, mmputc, mmputc  /* 0 1 2 3 \060 - \063 */
        !          87762:        .word   mmputc, mmputc, mmputc, mmputc  /* 4 5 6 7 \064 - \067 */
        !          87763:        .word   mmputc, mmputc, mmputc, mmputc  /* 8 9 : ; \070 - \073 */
        !          87764:        .word   mmputc, mmputc, mmputc, mmputc  /* < = > ? \074 - \077 */
        !          87765:        .word   mmputc, mmputc, mmputc, mmputc  /* @ A B C \100 - \103 */
        !          87766:        .word   mmputc, mmputc, mmputc, mmputc  /* D E F G \104 - \107 */
        !          87767:        .word   mmputc, mmputc, mmputc, mmputc  /* H I J K \110 - \113 */
        !          87768:        .word   mmputc, mmputc, mmputc, mmputc  /* L M N O \114 - \117 */
        !          87769:        .word   mmputc, mmputc, mmputc, mmputc  /* P Q R S \120 - \123 */
        !          87770:        .word   mmputc, mmputc, mmputc, mmputc  /* T U V W \124 - \127 */
        !          87771:        .word   mmputc, mmputc, mmputc, mmputc  /* X Y Z [ \130 - \133 */
        !          87772:        .word   mmputc, mmputc, mmputc, mmputc  /* \ ] ^ _ \134 - \137 */
        !          87773:        .word   mmputc, mmputc, mmputc, mmputc  /* ` a b c \140 - \143 */
        !          87774:        .word   mmputc, mmputc, mmputc, mmputc  /* d e f g \144 - \147 */
        !          87775:        .word   mmputc, mmputc, mmputc, mmputc  /* h i j k \150 - \153 */
        !          87776:        .word   mmputc, mmputc, mmputc, mmputc  /* l m n o \154 - \157 */
        !          87777:        .word   mmputc, mmputc, mmputc, mmputc  /* p q r s \160 - \163 */
        !          87778:        .word   mmputc, mmputc, mmputc, mmputc  /* t u v w \164 - \167 */
        !          87779:        .word   mmputc, mmputc, mmputc, mmputc  /* x y z { \170 - \173 */
        !          87780:        .word   mmputc, mmputc, mmputc, mmputc  /* | } ~ ? \174 - \177 */
        !          87781: 
        !          87782: ////////
        !          87783: /
        !          87784: / esctab - table of functions indexed by escape characters.
        !          87785: /
        !          87786: ////////
        !          87787: 
        !          87788: esctab:        .word   mmputc, mmputc, mmputc, mmputc  /* NUL  SOH  STX  ETX  */
        !          87789:        .word   mmputc, mmputc, mmputc, mmputc  /* EOT  ENQ  ACK  BEL  */
        !          87790:        .word   mmputc, mmputc, mmputc, mmputc  /* BS   HT   LF   VT  */
        !          87791:        .word   mmputc, mmputc, mmputc, mmputc  /* FF   CR   SO   SI  */
        !          87792:        .word   mmputc, mmputc, mmputc, mmputc  /* DLE  DC1  DC2  DC3 */
        !          87793:        .word   mmputc, mmputc, mmputc, mmputc  /* DC4  NAK  SYN  ETB  */
        !          87794:        .word   mmputc, mmputc, mmputc, mmputc  /* CAN  EM   SUB  ESC  */
        !          87795:        .word   mmputc, mmputc, mmputc, mmputc  /* FS   GS   RS   US   */
        !          87796:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          87797:        .word   eval,   eval,   eval,   eval    /* $ % & quote \044 - \047 */
        !          87798:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          87799:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          87800:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          87801:        .word   eval,   eval,   eval,   mm_new  /* 4 5 6 7 \064 - \067 */
        !          87802:        .word   mm_old, eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          87803:        .word   eval,   mmspec, mmspec, eval    /* < = > ? \074 - \077 */
        !          87804:        .word   eval,   eval,   eval,   eval    /* @ A B C \100 - \103 */
        !          87805:        .word   mm_ind, mm_cnl, eval,   eval    /* D E F G \104 - \107 */
        !          87806:        .word   eval,   eval,   eval,   eval    /* H I J K \110 - \113 */
        !          87807:        .word   eval,   mm_ri,  eval,   eval    /* L M N O \114 - \117 */
        !          87808:        .word   eval,   eval,   eval,   eval    /* P Q R S \120 - \123 */
        !          87809:        .word   eval,   eval,   eval,   eval    /* T U V W \124 - \127 */
        !          87810:        .word   eval,   eval,   eval,   csi_n1  /* X Y Z [ \130 - \133 */
        !          87811:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          87812:        .word   mm_dmi, eval,   mm_emi, mminit  /* ` a b c \140 - \143 */
        !          87813:        .word   eval,   eval,   eval,   eval    /* d e f g \144 - \147 */
        !          87814:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          87815:        .word   eval,   eval,   eval,   eval    /* l m n o \154 - \157 */
        !          87816:        .word   eval,   eval,   eval,   eval    /* p q r s \160 - \163 */
        !          87817:        .word   mmspec, mmspec, eval,   eval    /* t u v w \164 - \167 */
        !          87818:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          87819:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          87820: 
        !          87821: ////////
        !          87822: /
        !          87823: / csitab - table of functions indexed by ESC [ characters.
        !          87824: /
        !          87825: ////////
        !          87826: 
        !          87827: csitab:        .word   eval,   eval,   eval,   eval    /* NUL  SOH  STX  ETX  */
        !          87828:        .word   eval,   eval,   eval,   eval    /* EOT  ENQ  ACK  BEL  */
        !          87829:        .word   eval,   eval,   eval,   eval    /* BS   HT   LF   VT  */
        !          87830:        .word   eval,   eval,   eval,   eval    /* FF   CR   SO   SI  */
        !          87831:        .word   eval,   eval,   eval,   eval    /* DLE  DC1  DC2  DC3 */
        !          87832:        .word   eval,   eval,   eval,   eval    /* DC4  NAK  SYN  ETB  */
        !          87833:        .word   eval,   eval,   eval,   eval    /* CAN  EM   SUB  ESC  */
        !          87834:        .word   eval,   eval,   eval,   eval    /* FS   GS   RS   US   */
        !          87835:        .word   eval,   eval,   eval,   eval    /*   ! " # \040 - \043 */
        !          87836:        .word   eval,   eval,   eval,   eval    /* $ % & quote \044 - \047 */
        !          87837:        .word   eval,   eval,   eval,   eval    /* ( ) * + \050 - \053 */
        !          87838:        .word   eval,   eval,   eval,   eval    /* , - . / \054 - \057 */
        !          87839:        .word   eval,   eval,   eval,   eval    /* 0 1 2 3 \060 - \063 */
        !          87840:        .word   eval,   eval,   eval,   eval    /* 4 5 6 7 \064 - \067 */
        !          87841:        .word   eval,   eval,   eval,   eval    /* 8 9 : ; \070 - \073 */
        !          87842:        .word   eval,   eval,   csi_gt, eval    /* < = > ? \074 - \077 */
        !          87843:        .word   eval,   mm_cuu, mm_cud, mm_cuf  /* @ A B C \100 - \103 */
        !          87844:        .word   mm_cub, mm_cnl, mm_cpl, mm_cha  /* D E F G \104 - \107 */
        !          87845:        .word   mm_cup, mm_cht, mm_ed,  mm_el   /* H I J K \110 - \113 */
        !          87846:        .word   mm_il,  mm_dl,  eval,   mm_ea   /* L M N O \114 - \117 */
        !          87847:        .word   eval,   eval,   eval,   mm_ind  /* P Q R S \120 - \123 */
        !          87848:        .word   mm_ri,  eval,   eval,   eval    /* T U V W \124 - \127 */
        !          87849:        .word   eval,   eval,   mm_cbt, eval    /* X Y Z [ \130 - \133 */
        !          87850:        .word   eval,   eval,   eval,   eval    /* \ ] ^ _ \134 - \137 */
        !          87851:        .word   mm_hpa, mm_hpr, eval,   eval    /* ` a b c \140 - \143 */
        !          87852:        .word   mm_vpa, mm_vpr, mm_hvp, mm_cup  /* d e f g \144 - \147 */
        !          87853:        .word   eval,   eval,   eval,   eval    /* h i j k \150 - \153 */
        !          87854:        .word   eval,   mm_sgr, eval,   eval    /* l m n o \154 - \157 */
        !          87855:        .word   eval,   eval,   mm_ssr, eval    /* p q r s \160 - \163 */
        !          87856:        .word   eval,   eval,   mm_scr, eval    /* t u v w \164 - \167 */
        !          87857:        .word   eval,   eval,   eval,   eval    /* x y z { \170 - \173 */
        !          87858:        .word   eval,   eval,   eval,   eval    /* | } ~ ? \174 - \177 */
        !          87859: 
        !          87860: ////////
        !          87861: /
        !          87862: / rowtab - array of offsets to each row
        !          87863: /
        !          87864: ////////
        !          87865: 
        !          87866: rowtab:        .word    0*NRB2,         1*NRB2,         2*NRB2,         3*NRB2
        !          87867:        .word    4*NRB2,         5*NRB2,         6*NRB2,         7*NRB2
        !          87868:        .word    8*NRB2,         9*NRB2,        10*NRB2,        11*NRB2
        !          87869:        .word   12*NRB2,        13*NRB2,        14*NRB2,        15*NRB2
        !          87870:        .word   16*NRB2,        17*NRB2,        18*NRB2,        19*NRB2
        !          87871:        .word   20*NRB2,        21*NRB2,        22*NRB2,        23*NRB2
        !          87872:        .word   24*NRB2,        25*NRB2,        26*NRB2,        27*NRB2
        !          87873:        .word   28*NRB2,        29*NRB2,        30*NRB2,        31*NRB2
        !          87874:        .word   32*NRB2,        33*NRB2,        34*NRB2,        35*NRB2
        !          87875:        .word   36*NRB2,        37*NRB2,        38*NRB2,        39*NRB2
        !          87876:        .word   40*NRB2,        41*NRB2,        42*NRB2,        43*NRB2
        !          87877:        .word   44*NRB2,        45*NRB2,        46*NRB2,        47*NRB2
        !          87878:        .word   48*NRB2,        49*NRB2,        50*NRB2,        51*NRB2
        !          87879: 
        !          87880: ////////
        !          87881: /
        !          87882: / grread( dev, iop ) - read graphics display memory
        !          87883: /
        !          87884: ////////
        !          87885: 
        !          87886: grread_:
        !          87887:        push    si
        !          87888:        push    di
        !          87889:        push    bp
        !          87890:        mov     bp, sp
        !          87891:        mov     bp, 10(bp)
        !          87892:        push    ds
        !          87893:        push    es
        !          87894:        cmp     IO_SEG(bp), $IOSYS
        !          87895:        je      0f
        !          87896:        mov     ax, uds_
        !          87897:        mov     es, ax
        !          87898: 0:     mov     di, IO_BASE(bp)
        !          87899:        mov     ax, $VSEG
        !          87900:        mov     ds, ax
        !          87901: 
        !          87902: #ifndef TECMAR
        !          87903:        mov     ax, IO_SEEK(bp)
        !          87904:        add     ax, IO_IOC(bp)
        !          87905:        cmp     ax, $BANKSZ*2
        !          87906:        ja      done
        !          87907: #endif
        !          87908: 
        !          87909:        mov     ax, IO_SEEK(bp)
        !          87910:        sub     dx, dx
        !          87911:        mov     cx, $NHB
        !          87912:        div     cx
        !          87913:        mov     si, dx
        !          87914:        mov     bx, ax
        !          87915:        shr     ax, $1
        !          87916:        mul     cx
        !          87917:        mov     dx, si
        !          87918:        add     si, ax
        !          87919:        testb   bl, $1
        !          87920:        jne     read2
        !          87921: 
        !          87922: read1: mov     cx, $NHB
        !          87923:        sub     cx, dx
        !          87924:        cmp     cx, IO_IOC(bp)
        !          87925:        jle     0f
        !          87926:        mov     cx, IO_IOC(bp)
        !          87927:        jcxz    done
        !          87928: 0:     sub     IO_IOC(bp), cx
        !          87929:        add     IO_BASE(bp), cx
        !          87930:        push    si
        !          87931:        rep
        !          87932:        movsb
        !          87933:        pop     si
        !          87934: read2: add     si, $BANKSZ
        !          87935:        mov     cx, $NHB
        !          87936:        sub     cx, dx
        !          87937:        cmp     cx, IO_IOC(bp)
        !          87938:        jle     0f
        !          87939:        mov     cx, IO_IOC(bp)
        !          87940:        jcxz    done
        !          87941: 0:     sub     IO_IOC(bp), cx
        !          87942:        add     IO_BASE(bp), cx
        !          87943:        rep
        !          87944:        movsb
        !          87945:        sub     si, $BANKSZ
        !          87946:        sub     dx, dx
        !          87947:        jmp     read1
        !          87948: 
        !          87949: done:  pop     es
        !          87950:        pop     ds
        !          87951:        pop     bp
        !          87952:        pop     di
        !          87953:        pop     si
        !          87954:        ret
        !          87955: 
        !          87956: ////////
        !          87957: /
        !          87958: / grwrite( dev, iop ) - write graphics display memory
        !          87959: /
        !          87960: ////////
        !          87961: 
        !          87962: grwrite_:
        !          87963:        push    si
        !          87964:        push    di
        !          87965:        push    bp
        !          87966:        mov     bp, sp
        !          87967:        mov     bp, 10(bp)
        !          87968:        push    ds
        !          87969:        push    es
        !          87970:        cmp     IO_SEG(bp), $IOSYS
        !          87971:        je      0f
        !          87972:        mov     ax, uds_
        !          87973:        mov     ds, ax
        !          87974: 0:     mov     si, IO_BASE(bp)
        !          87975:        mov     ax, $VSEG
        !          87976:        mov     es, ax
        !          87977: 
        !          87978: #ifndef TECMAR
        !          87979:        mov     ax, IO_SEEK(bp)
        !          87980:        add     ax, IO_IOC(bp)
        !          87981:        cmp     ax, $BANKSZ*2
        !          87982:        ja      done
        !          87983: #endif
        !          87984: 
        !          87985:        mov     ax, IO_SEEK(bp)
        !          87986:        sub     dx, dx
        !          87987:        mov     cx, $NHB
        !          87988:        div     cx
        !          87989:        mov     di, dx
        !          87990:        mov     bx, ax
        !          87991:        shr     ax, $1
        !          87992:        mul     cx
        !          87993:        mov     dx, di
        !          87994:        add     di, ax
        !          87995:        testb   bl, $1
        !          87996:        jne     page2
        !          87997: 
        !          87998: page1: mov     cx, $NHB
        !          87999:        sub     cx, dx
        !          88000:        cmp     cx, IO_IOC(bp)
        !          88001:        jle     0f
        !          88002:        mov     cx, IO_IOC(bp)
        !          88003:        jcxz    done
        !          88004: 0:     sub     IO_IOC(bp), cx
        !          88005:        add     IO_BASE(bp), cx
        !          88006:        push    di
        !          88007:        rep
        !          88008:        movsb
        !          88009:        pop     di
        !          88010: page2: add     di, $BANKSZ
        !          88011:        mov     cx, $NHB
        !          88012:        sub     cx, dx
        !          88013:        cmp     cx, IO_IOC(bp)
        !          88014:        jle     0f
        !          88015:        mov     cx, IO_IOC(bp)
        !          88016:        jcxz    done
        !          88017: 0:     sub     IO_IOC(bp), cx
        !          88018:        add     IO_BASE(bp), cx
        !          88019:        rep
        !          88020:        movsb
        !          88021:        sub     di, $BANKSZ
        !          88022:        sub     dx, dx
        !          88023:        jmp     page1
        !          88024: 
        !          88025: ////////
        !          88026: /
        !          88027: / mm_voff()    -- Disable video display
        !          88028: /
        !          88029: ////////
        !          88030:        .globl  mm_voff_
        !          88031: mm_voff_:
        !          88032:        mov     dx, $MSR
        !          88033:        movb    al, $0x12
        !          88034:        outb    dx, al
        !          88035:        ret
        !          88036: 
        !          88037: ////////
        !          88038: /
        !          88039: / mm_von()     -- Enable video display
        !          88040: /
        !          88041: ////////
        !          88042:        .globl  mm_von_
        !          88043: mm_von_:
        !          88044:        mov     dx, $MSR                / enable video display
        !          88045:        movb    al, $0x1A
        !          88046:        outb    dx, al
        !          88047:        mov     ss:mmvcnt_, $480        / 480 seconds before video disabled
        !          88048:        ret
        !          88049: 0707070064030150020407550000030000030000011777770507310713200004400000000000/newbits/kernel/USRSRC/i8086/ibm_at0707070064030112141006440000030000030000011777770507310713200005200000075156/newbits/kernel/USRSRC/i8086/ibm_at/as2.s/ $Header: /usr/src/sys/i8086/ibm_at/RCS/as2.s,v 1.2 91/06/06 18:14:46 norm Exp $
        !          88050: /
        !          88051: / (lgl-
        !          88052: /      The information contained herein is a trade secret of Mark Williams
        !          88053: /      Company, and  is confidential information.  It is provided  under a
        !          88054: /      license agreement,  and may be  copied or disclosed  only under the
        !          88055: /      terms of  that agreement.  Any  reproduction or disclosure  of this
        !          88056: /      material without the express written authorization of Mark Williams
        !          88057: /      Company or persuant to the license agreement is unlawful.
        !          88058: /
        !          88059: /      COHERENT Version 2.3.37
        !          88060: /      Copyright (c) 1982, 1983, 1984.
        !          88061: /      An unpublished work by Mark Williams Company, Chicago.
        !          88062: /      All rights reserved.
        !          88063: / -lgl)
        !          88064: ////////
        !          88065: /
        !          88066: / Machine language assist for
        !          88067: / Coherent on the IBM personal computer.
        !          88068: /
        !          88069: / $Log:        as2.s,v $
        !          88070: / Revision 1.2  91/06/06  18:14:46  norm
        !          88071: / Get memory size by reading CMOS.
        !          88072: 
        !          88073: / Revision 1.3 88/08/05  15:37:32      src
        !          88074: / AMD 286 hardware specific fixes removed - hardware now correct.
        !          88075: / Virtual Selector F000 initialized to access ROM at F0000.
        !          88076: / Normal kernel stack now used during initialization.
        !          88077: / 
        !          88078: / Revision 1.2 88/06/29  19:05:31      src
        !          88079: / AT Coherent can now come up in real-mode by patching 'realmode' variable.
        !          88080: / 
        !          88081: / Revision 1.1 88/03/24  17:33:18      src
        !          88082: / Initial revision
        !          88083: / 
        !          88084: / 88/03/10     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          88085: / Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !          88086: / These partial fixes will be removed once all CPU's are replaced.
        !          88087: /
        !          88088: / 88/03/07     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          88089: / Obsolete video() function deleted - not used, or usable in protected mode.
        !          88090: / Auto-increment mode no longer assumed, but enforced on block moves.
        !          88091: /
        !          88092: / 88/03/04     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          88093: / Memory sizing now flushes instruction pipeline before read-verify.
        !          88094: / Otherwise bus capacitance on some machines gives invalid memory indication.
        !          88095: / plrcopy, prlcopy, pclear, upcopy, kpcopy, pucopy, and pkcopy now ensure
        !          88096: / registers DS and ES refer to kernel data before calling ptov() or vrelse().
        !          88097: / MAXMEM variable added to specify maximum low memory in clicks.
        !          88098: /
        !          88099: / 87/11/22     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          88100: / Added check for extended memory in protected mode.
        !          88101: /
        !          88102: / 87/11/14     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          88103: / boot() now requests 8042 controller to initiate processor reset.
        !          88104: /
        !          88105: / 87/11/05     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          88106: / slrcopy/srlcopy/sclear renamed plrcopy/prlcopy/pclear and moved here.
        !          88107: /
        !          88108: / 87/10/27     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          88109: / System stack/data segments now setup here rather than in as1.s
        !          88110: / System stack/data moved to next 128 byte boundary for protected mode.
        !          88111: /
        !          88112: / 87/08/31     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          88113: / Timer channel 1 now reprogrammed for memory refresh.
        !          88114: /
        !          88115: / 87/07/08     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          88116: / Timer chip now programmed for 100 hz clock interrupt rather than 20 hz.
        !          88117: /
        !          88118: ////////
        !          88119: 
        !          88120: EFAULT =       14                      / Bad argument
        !          88121: EXTMEML =      0x17                    / Ext. mem size (low) offset in CMOS
        !          88122: EXTMEMH =      0x18                    /               (high)
        !          88123: PFLAGS =       0x22                    / Offset int PROC.
        !          88124: PFKERN =       0x80                    / Kernel process flag bit.
        !          88125: PIC    =       0x20                    / 8259 CSR  I/O port.
        !          88126: PICM   =       0x21                    / 8259 IMR  I/O port.
        !          88127: PIT    =       0x40                    / 8253 base I/O port.
        !          88128: KBDATA =       0x60                    / 8042 keyboard mpu data I/O port.
        !          88129: KBCTRL =       0x64                    / 8042 keyboard mpu ctrl I/O port.
        !          88130: CMOSA  =       0x70                    / Real-time Clock/CMOS addr I/O port.
        !          88131: CMOSD  =       0x71                    / Real-time Clock/CMOS data I/O port.
        !          88132: SPIC   =       0xA0                    / Slave 8259 CSR I/O port.
        !          88133: SPICM  =       0xA1                    / Slave 8259 IMR I/O port.
        !          88134: UPASIZE        =       1024                    / Size of uproc and stack
        !          88135: 
        !          88136: ////////
        !          88137: /
        !          88138: / System entry point. Under PC-DOS,
        !          88139: / which thinks that Coherent is just a large
        !          88140: / user program, the code is offset by 0x100
        !          88141: / to allow space for the base page.
        !          88142: /
        !          88143: ////////
        !          88144: 
        !          88145:        .blkb   0x0100                  / PC-DOS base page.
        !          88146:        cli                             / No interrupts, please.
        !          88147: 
        !          88148:        int     0x11                    / Obtain int 11 value before printf().
        !          88149:        mov     cs:val11, ax            / Use boot block's stack for last time.
        !          88150: 
        !          88151: /
        !          88152: / Enable the A20 address line, which is normally disabled by the ROM BIOS.
        !          88153: / This line is under the control of the 8042 keyboard interface controller.
        !          88154: /
        !          88155:        sub     cx, cx                  /
        !          88156: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !          88157:        testb   al, $2                  /
        !          88158:        loopne  0b                      /
        !          88159:        jmp     .+2             / DELAY /
        !          88160:                                        /
        !          88161:        movb    al, $0xD1               / Request next output byte to be
        !          88162:        outb    KBCTRL, al              /       sent to the 8042 output port.
        !          88163:                                        /
        !          88164:        sub     cx, cx                  /
        !          88165: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !          88166:        testb   al, $2                  /
        !          88167:        loopne  0b                      /
        !          88168:        jmp     .+2             / DELAY /
        !          88169:                                        /
        !          88170:        movb    al, $0xDF               / Enable A20 address line.
        !          88171:        outb    KBDATA, al              / See Page 1-44, IBM-AT Tech Ref.
        !          88172:                                        /
        !          88173:        sub     cx, cx                  /
        !          88174: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !          88175:        testb   al, $2                  / NOTE: A20 not enabled for up to 20 us.
        !          88176:        loopne  0b                      /
        !          88177: 
        !          88178: /
        !          88179: / Reprogram the 8253 timer so that channel 0, 
        !          88180: / which is used as the clock, interrupts at exactly
        !          88181: / 100 HZ, instead of 18.2 HZ.
        !          88182: /
        !          88183:        movb    al, $0x36               / Timer 0, LSB, MSB, mode 3
        !          88184:        outb    PIT+3, al
        !          88185:        jmp     .+2             / DELAY /
        !          88186:        jmp     .+2             / DELAY /
        !          88187:        movb    al, $0x9C               / Lsb of 59659/5 = 11932
        !          88188:        outb    PIT, al
        !          88189:        jmp     .+2             / DELAY /
        !          88190:        jmp     .+2             / DELAY /
        !          88191:        movb    al, $0x2E               / Msb of 59659/5 = 11932
        !          88192:        outb    PIT, al
        !          88193:        jmp     .+2             / DELAY /
        !          88194:        jmp     .+2             / DELAY /
        !          88195: 
        !          88196: / Reprogram channel 1 on the 8253 timer which is used for memory refresh.
        !          88197: /      movb    al, $0x54               / Timer 1, LSB, mode 2
        !          88198: /      outb    PIT+3, al
        !          88199: /      jmp     .+2             / DELAY /
        !          88200: /      jmp     .+2             / DELAY /
        !          88201: /      movb    al, $18                 / LSB of 18.
        !          88202: /      outb    PIT+1, al
        !          88203: /      jmp     .+2             / DELAY /
        !          88204: /      jmp     .+2             / DELAY /
        !          88205: 
        !          88206: / Reprogram the 1st programmable interrupt controller.
        !          88207: / It's default vector table collides with iAPX 286 protection vectors.
        !          88208: 
        !          88209:        movb    al, $0x11               / ICW1 - edge, master, ICW4
        !          88210:        outb    PIC, al
        !          88211:        jmp     .+2             / DELAY /
        !          88212:        jmp     .+2             / DELAY /
        !          88213:        movb    al, $0x20               / ICW2 - Reserve 1st 32 vectors for 286
        !          88214:        outb    PICM, al
        !          88215:        jmp     .+2             / DELAY /
        !          88216:        jmp     .+2             / DELAY /
        !          88217:        movb    al, $0x04               / ICW3 - master level 2
        !          88218:        outb    PICM, al
        !          88219:        jmp     .+2             / DELAY /
        !          88220:        jmp     .+2             / DELAY /
        !          88221:        movb    al, $0x01               / ICW4 - 8086 mode, master.
        !          88222:        outb    PICM, al
        !          88223:        jmp     .+2             / DELAY /
        !          88224:        jmp     .+2             / DELAY /
        !          88225:        movb    al, $0xFE               / Disable interrupts from master PIC.
        !          88226:        outb    PICM, al                / (except for clock interrupt).
        !          88227: 
        !          88228:        movb    al, $0xFF
        !          88229:        outb    SPICM, al               / Disable interrupts from slave PIC.
        !          88230: 
        !          88231: / Set up all trap vectors.
        !          88232: / The machine traps all have their own
        !          88233: / linkages. We have to steal the clock from
        !          88234: / the ROM, because the stacks might get switched
        !          88235: / during the INT 1C, and the EOI would get sent
        !          88236: / to the 8259 at a strange time.
        !          88237: 
        !          88238:        sub     ax, ax                  / Map DS over the 8088
        !          88239:        mov     ds, ax                  / vector area.
        !          88240: 
        !          88241:        mov     0x0000, $trap0          / Divide error vector
        !          88242:        mov     0x0002, cs
        !          88243:        mov     0x0004, $trap1          / Single step.
        !          88244:        mov     0x0006, cs
        !          88245:        mov     0x0008, $trap2          / NMI
        !          88246:        mov     0x000A, cs
        !          88247:        mov     0x000C, $trap3          / INT 3 (break)
        !          88248:        mov     0x000E, cs
        !          88249:        mov     0x0010, $trap4          / Overflow.
        !          88250:        mov     0x0012, cs
        !          88251:        mov     0x0014, $trap5          / Bound range exceeded.
        !          88252:        mov     0x0016, cs
        !          88253:        mov     0x0018, $trap6          / Invalid Opcode
        !          88254:        mov     0x001A, cs
        !          88255:        mov     0x001C, $trap7          / Processor extension not available
        !          88256:        mov     0x001E, cs
        !          88257:        mov     0x0020, $trap8          / Double exception detected.
        !          88258:        mov     0x0022, cs
        !          88259:        mov     0x0024, $trap9          / Processor extension segment overrun.
        !          88260:        mov     0x0026, cs
        !          88261:        mov     0x0028, $trap10         / Invalid task state segment.
        !          88262:        mov     0x002A, cs
        !          88263:        mov     0x002C, $trap11         / Segment not present.
        !          88264:        mov     0x002E, cs
        !          88265:        mov     0x0030, $trap12         / Stack segment overrun or not present.
        !          88266:        mov     0x0032, cs
        !          88267:        mov     0x0034, $trap13         / General protection.
        !          88268:        mov     0x0036, cs
        !          88269: 
        !          88270:        mov     0x0080, $clk            / Clock.
        !          88271:        mov     0x0082, cs
        !          88272:        mov     0x0084, $dev1           / Device 1
        !          88273:        mov     0x0086, cs
        !          88274:        mov     0x0088, $dev9           / Device 2 maps into Device 9
        !          88275:        mov     0x008A, cs
        !          88276:        mov     0x008C, $dev3           / Device 3
        !          88277:        mov     0x008E, cs
        !          88278:        mov     0x0090, $dev4           / Device 4
        !          88279:        mov     0x0092, cs
        !          88280:        mov     0x0094, $dev5           / Device 5
        !          88281:        mov     0x0096, cs
        !          88282:        mov     0x0098, $dev6           / Device 6
        !          88283:        mov     0x009A, cs
        !          88284:        mov     0x009C, $dev7           / Device 7
        !          88285:        mov     0x009E, cs
        !          88286: 
        !          88287:        mov     0x01C0, $dev8           / Device 8
        !          88288:        mov     0x01C2, cs
        !          88289:        mov     0x01C4, $dev9           / Device 9
        !          88290:        mov     0x01C6, cs
        !          88291:        mov     0x01C8, $dev10          / Device 10
        !          88292:        mov     0x01CA, cs
        !          88293:        mov     0x01CC, $dev11          / Device 11
        !          88294:        mov     0x01CE, cs
        !          88295:        mov     0x01D0, $dev12          / Device 12
        !          88296:        mov     0x01D2, cs
        !          88297:        mov     0x01D4, $dev13          / Device 13
        !          88298:        mov     0x01D6, cs
        !          88299:        mov     0x01D8, $dev14          / Device 14
        !          88300:        mov     0x01DA, cs
        !          88301:        mov     0x01DC, $dev15          / Device 15
        !          88302:        mov     0x01DE, cs
        !          88303: 
        !          88304:        mov     bx, $0x0200             / INT 80 (sys 0)
        !          88305: 0:     mov     (bx), $syc              / Set up the system call
        !          88306:        mov     2(bx), cs               / trap vector.
        !          88307:        add     bx, $4                  / Move to next vector and
        !          88308:        cmp     bx, $0x0400             / loop until all
        !          88309:        jb      0b                      / vectors are reset.
        !          88310: 
        !          88311: / Set up the system stack and data segments, by looking at the size of
        !          88312: / the text and adding this to the base address already in the CS.
        !          88313: / Relocate the stack and data to a 128 byte boundary.
        !          88314: 
        !          88315:        mov     ax, $etext_+15          / End of text segment
        !          88316:        shr     ax, $4                  / Convert to paragraphs.
        !          88317:        mov     cx, cs                  / Get code segment base.
        !          88318:        add     ax, cx                  /
        !          88319:        mov     ds, ax                  / Current data segment
        !          88320:        add     ax, $31                 / Allow virtual-physical alignment
        !          88321:        and     ax, $~31                /       [use 512 byte, need 128 byte]
        !          88322:                                        /
        !          88323:        cmp     realmode_, $0           / Virtual Addressing enabled?
        !          88324:        jne     0f                      /
        !          88325:        mov     idtsel_, ax             / Interrupt descriptor table [2 Kbytes]
        !          88326:        add     ax, $0x0080             /       2K >> 4
        !          88327:        mov     gdtsel_, ax             / Global descriptor table [64 Kbytes]
        !          88328:        add     ax, $0x1000             /       64K >> 4
        !          88329: 0:                                     /
        !          88330:        mov     es, ax                  /
        !          88331:        mov     si, $edata_-1           / Copy data to new location, backwards.
        !          88332:        mov     di, $edata_-1           /
        !          88333:        mov     cx, $edata_             /
        !          88334:        std                             /
        !          88335:        rep                             /
        !          88336:        movsb                           /
        !          88337:                                        /
        !          88338:        mov     ds, ax                  / Update data segment,
        !          88339:        mov     ss, ax                  / and stack segment.
        !          88340:        mov     sp, $u_+UPASIZE-32      / Set up initial stack.
        !          88341:        mov     scs_, cs                / Save code segment and
        !          88342:        mov     sds_, ds                / data segment bases.
        !          88343:        mov     cs:cds, ds              / For interrupts.
        !          88344: 
        !          88345: / Size up memory, starting just above the system.
        !          88346: / The memory is cleared, because somebody has to do a write
        !          88347: / to set up the parity bits.
        !          88348: 
        !          88349:        mov     di, $edata_             / Clear at edata...
        !          88350:        mov     cx, $512                / for 1 Kbyte
        !          88351:        sub     ax, ax
        !          88352:        cld
        !          88353:        rep
        !          88354:        stosw
        !          88355: 
        !          88356:        mov     bp, $edata_+1023        / Compute base.
        !          88357:        shr     bp, $4
        !          88358:        add     bp, sds_
        !          88359:        shr     bp, $6                  / Round down to a Kbyte boundary
        !          88360:        shl     bp, $6                  / so's we're in sync.
        !          88361: 
        !          88362: 0:     sub     di, di                  / Destination.
        !          88363:        mov     es, bp                  / Set extra segment and
        !          88364:        mov     es:(di), ax             / clear a word.
        !          88365:        jmp     .+2             / FLUSH /
        !          88366:        cmp     es:(di), ax             / Should be zero now.
        !          88367:        jne     0f                      / Branch if memory end
        !          88368: 
        !          88369:        mov     cx, $512                / 1K bytes, in words.
        !          88370:        cld
        !          88371:        rep
        !          88372:        stosw                           / Clear this 1K
        !          88373:        add     bp, $64                 / Move along by 1K
        !          88374:        cmp     bp, MAXMEM
        !          88375:        jb      0b                      / If not at video ram yet
        !          88376: 
        !          88377: 0:     mov     es, sds_                / Map extra.
        !          88378: 
        !          88379:        mov     ax, bp                  / Calculate top of low memory.
        !          88380:        rol     ax, $4                  /
        !          88381:        mov     dx, ax                  /
        !          88382:        and     ax, $0xFFF0             /
        !          88383:        xor     dx, ax                  /
        !          88384: 
        !          88385:        cmp     realmode_, $0           / Real Addressing Mode?
        !          88386:        je      0f                      /
        !          88387:        mov     coretop_, ax            / Yes, Record top of memory,
        !          88388:        mov     coretop_+2, dx          /
        !          88389:        jmp     start                   / and bring up system.
        !          88390: 0:
        !          88391:        mov     holebot_, ax            / Record bottom of I/O memory.
        !          88392:        mov     holebot_+2, dx          /
        !          88393: 
        !          88394:        mov     ax, gdtsel_             / Format global descriptor table map.
        !          88395:        rol     ax, $4                  /
        !          88396:        mov     dx, ax                  /
        !          88397:        and     ax, $0xFFF0             /
        !          88398:        xor     dx, ax                  /
        !          88399:        mov     gdtmap_+0, $0xFFFF      / Limit: 64K bytes.
        !          88400:        mov     gdtmap_+2, ax           /
        !          88401:        mov     gdtmap_+4, dx           /
        !          88402:                                        /
        !          88403:        sub     ax, ax                  / Erase global descriptor table.
        !          88404:        mov     cx, $0x8000             /       [32K words = 64K bytes]
        !          88405:        mov     es, gdtsel_             /
        !          88406:        sub     di, di                  /
        !          88407:        cld                             /
        !          88408:        rep                             /
        !          88409:        stosw                           /
        !          88410:                                        /
        !          88411:        mov     ax, idtsel_             / Format interrupt descriptor table map
        !          88412:        rol     ax, $4                  /
        !          88413:        mov     dx, ax                  /
        !          88414:        and     ax, $0xFFF0             /
        !          88415:        xor     dx, ax                  /
        !          88416:        mov     idtmap_+0, $2047        / Limit: 2K bytes.
        !          88417:        mov     idtmap_+2, ax           /
        !          88418:        mov     idtmap_+4, dx           /
        !          88419:                                        /
        !          88420:        sub     ax, ax                  / Erase interrupt descriptor table.
        !          88421:        mov     cx, $1024               /       [1K words = 2K bytes]
        !          88422:        mov     es, idtsel_             /
        !          88423:        sub     di, di                  /
        !          88424:        cld                             /
        !          88425:        rep                             /
        !          88426:        stosw                           /
        !          88427:                                        /
        !          88428:        mov     es, gdtsel_             /
        !          88429:        mov     di, cs                  / Define kernel code global selector.
        !          88430:        mov     ax, $etext_-1           /       Limit: etext.
        !          88431:        stosw                           /
        !          88432:        mov     dx, $0x9A00             /       Flags: Present, executable.
        !          88433:        mov     ax, cs                  /       Base:  cs << 4.
        !          88434:        rol     ax, $4                  /
        !          88435:        xor     dx, ax                  /
        !          88436:        and     ax, $0xFFF0             /
        !          88437:        stosw                           /
        !          88438:        xor     ax, dx                  /
        !          88439:        stosw                           /
        !          88440:        sub     ax, ax                  /
        !          88441:        stosw                           /
        !          88442:                                        /
        !          88443:        mov     di, ss                  / Define kernel data global selector.
        !          88444:        mov     ax, $0xFFFF             /       Limit: 64K bytes.
        !          88445:        stosw                           /
        !          88446:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          88447:        mov     ax, ss                  /       Base:  ss << 4.
        !          88448:        rol     ax, $4                  /
        !          88449:        xor     dx, ax                  /
        !          88450:        and     ax, $0xFFF0             /
        !          88451:        stosw                           /
        !          88452:        xor     ax, dx                  /
        !          88453:        stosw                           /
        !          88454:        sub     ax, ax                  /
        !          88455:        stosw                           /
        !          88456:                                        /
        !          88457:        mov     di, $8                  / Define task state segment selector[8]
        !          88458:        mov     ax, $43                 /       Limit: 44 bytes.
        !          88459:        stosw                           /
        !          88460:        mov     dx, $0x8100             /       Flags: Present, avail tss seg.
        !          88461:        mov     ax, ss                  /       Base:  (ss << 4) + &tss.
        !          88462:        rol     ax, $4                  /
        !          88463:        xor     dx, ax                  /
        !          88464:        and     ax, $0xFFF0             /
        !          88465:        xor     dx, ax                  /
        !          88466:        add     ax, $tss_               /
        !          88467:        adc     dx, $0                  /
        !          88468:        stosw                           /
        !          88469:        mov     ax, dx                  /
        !          88470:        stosw                           /
        !          88471:        sub     ax, ax                  /
        !          88472:        stosw                           /
        !          88473:                                        /
        !          88474:        mov     di, gdtsel_             / Define gdt access global selector.
        !          88475:        mov     ax, $0xFFFF             /       Limit: 64K bytes.
        !          88476:        stosw                           /
        !          88477:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          88478:        mov     ax, gdtsel_             /       Base: gdtsel << 4.
        !          88479:        rol     ax, $4                  /
        !          88480:        xor     dx, ax                  /
        !          88481:        and     ax, $0xFFF0             /
        !          88482:        stosw                           /
        !          88483:        xor     ax, dx                  /
        !          88484:        stosw                           /
        !          88485:        sub     ax, ax                  /
        !          88486:        stosw                           /
        !          88487:                                        /
        !          88488:        mov     di, idtsel_             / Define idt access global selector.
        !          88489:        mov     ax, $2047               /       Limit: 2K bytes.
        !          88490:        stosw                           /
        !          88491:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          88492:        mov     ax, idtsel_             /       Base: idtsel << 4.
        !          88493:        rol     ax, $4                  /
        !          88494:        xor     dx, ax                  /
        !          88495:        and     ax, $0xFFF0             /
        !          88496:        stosw                           /
        !          88497:        xor     ax, dx                  /
        !          88498:        stosw                           /
        !          88499:        sub     ax, ax                  /
        !          88500:        stosw                           /
        !          88501:                                        /
        !          88502:        mov     di, $0xB000             / Define video access global selector.
        !          88503:        mov     ax, $0xFFFF             /       Limit: 64K bytes.
        !          88504:        stosw                           /
        !          88505:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          88506:        mov     ax, $0xB000             /       Base:  0xB000 << 4.
        !          88507:        rol     ax, $4                  /
        !          88508:        xor     dx, ax                  /
        !          88509:        and     ax, $0xFFF0             /
        !          88510:        stosw                           /
        !          88511:        xor     ax, dx                  /
        !          88512:        stosw                           /
        !          88513:        sub     ax, ax                  /
        !          88514:        stosw                           /
        !          88515:                                        /
        !          88516:        mov     di, $0xB800             / Define video access global selector.
        !          88517:        mov     ax, $0x7FFF             /       Limit: 32 Kbytes.
        !          88518:        stosw                           /
        !          88519:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          88520:        mov     ax, $0xB800             /       Base:  0xB800 << 4.
        !          88521:        rol     ax, $4                  /
        !          88522:        xor     dx, ax                  /
        !          88523:        and     ax, $0xFFF0             /
        !          88524:        stosw                           /
        !          88525:        xor     ax, dx                  /
        !          88526:        stosw                           /
        !          88527:        sub     ax, ax                  /
        !          88528:        stosw                           /
        !          88529: 
        !          88530:        mov     di, $0xF000             / Define ROM access global selector.
        !          88531:        mov     ax, $0xFFFF             /       Limit: 64 Kbytes.
        !          88532:        stosw                           /
        !          88533:        mov     dx, $0x9000             /       Flags: Present, read only.
        !          88534:        mov     ax, $0xF000             /       Base:  0xF000 << 4.
        !          88535:        rol     ax, $4                  /
        !          88536:        xor     dx, ax                  /
        !          88537:        and     ax, $0xFFF0             /
        !          88538:        stosw                           /
        !          88539:        xor     ax, dx                  /
        !          88540:        stosw                           /
        !          88541:        sub     ax, ax                  /
        !          88542:        stosw                           /
        !          88543: 
        !          88544:        mov     es, idtsel_             / Map ES over the intr descr table.
        !          88545:        sub     ax, ax                  / Map DS over the 8088 vector area.
        !          88546:        mov     ds, ax                  /
        !          88547:        sub     si, si                  /
        !          88548:        sub     di, di                  /
        !          88549:        mov     bx, cs                  / Make CS available for comparison.
        !          88550:        mov     cx, $256                / Install 256 interrupt descriptors.
        !          88551:                                        /
        !          88552: 0:     lodsw                           / Copy interrupt IP
        !          88553:        stosw                           /
        !          88554:        lodsw                           / Copy interrupt CS
        !          88555:        stosw                           /
        !          88556:                                        /
        !          88557:        cmp     ax, bx                  / Coherent interrupt handler?
        !          88558:        mov     ax, $0x8600             /
        !          88559:        je      1f                      /
        !          88560:        sub     ax, ax                  / No, clear flags.
        !          88561:                                        /
        !          88562: 1:     stosw                           / Define IDT flags.
        !          88563:        sub     ax, ax                  / Reserved IDT word.
        !          88564:        stosw                           /
        !          88565:        loop    0b                      / Repeat for all 256 entries.
        !          88566:                                        /
        !          88567:        mov     ax, ss                  / Restore data and extra segments.
        !          88568:        mov     ds, ax                  /
        !          88569:        mov     es, ax                  /
        !          88570:                                        /
        !          88571:        clts                            / Clear task switched flag.
        !          88572:        lgdt    gdtmap_                 / Load global descriptor table map.
        !          88573:        lidt    idtmap_                 / Load interrupt descriptor table map.
        !          88574:                                        /
        !          88575:        smsw    ax                      / Enter protected mode.
        !          88576:        or      ax, $1                  /
        !          88577:        lmsw    ax                      /
        !          88578:        jmp     .+2                     / Clear pipeline.
        !          88579:                                        /
        !          88580:        mov     ax, $0x0008             / Load task state segment register.
        !          88581:        ltr     ax                      /
        !          88582:        sub     ax, ax                  / Load local descriptor table register.
        !          88583:        lldt    ax                      /
        !          88584:                                        /
        !          88585:                                        /
        !          88586:                                        / Register usage:
        !          88587:                                        / DX:AX = extended mem physical addr.
        !          88588:                                        / BX = 0.
        !          88589:                                        / SI = selector into extended memory.
        !          88590:                                        / ES = selector into extended memory.
        !          88591:                                        / DS = selector into global descr table
        !          88592:                                        /
        !          88593:        movb    al, $EXTMEMH            / high byte of pair
        !          88594:        outb    CMOSA, al               / to CMOS memory port
        !          88595:        jmp     .+2                     / DELAY
        !          88596:        inb     al, CMOSD               / get value from CMOS
        !          88597:        xchgb   ah, al
        !          88598:        jmp     .+2                     / DELAY
        !          88599:        movb    al, $EXTMEML            / low byte of pair
        !          88600:        outb    CMOSA, al               / to CMOS memory port
        !          88601:        jmp     .+2                     / DELAY
        !          88602:        inb     al, CMOSD               / get rest of pair from CMOS
        !          88603:        shr     ax, $6                  / K -> 64K conversion
        !          88604:        add     ax, $0x0010             / bias up to 1MB
        !          88605:        mov     CMOSmax_, ax            / save count of 64K hunks
        !          88606:        sub     ax, ax                  /
        !          88607:        mov     dx, $0x0010             / Initial 64 Kbyte bank of extended mem.
        !          88608:        mov     holetop_, ax            / Recorded extended memory bot in bytes.
        !          88609:        mov     holetop_+2, dx          /
        !          88610:                                        /
        !          88611:        mov     ds, gdtsel_             / Map DS onto global descr table.
        !          88612:        mov     si, $0xFFF8             / Define scratch access global selector.
        !          88613:        mov     0(si), $0xFFFF          /       Limit: 64K bytes.
        !          88614:        mov     2(si), $0x0000          /       Base:  1 Mbyte.
        !          88615:        mov     4(si), $0x9210          /       Flags: Present, writable.
        !          88616:        mov     6(si), $0x0000          /
        !          88617:                                        /
        !          88618:        sub     bx, bx                  /
        !          88619: 0:     sub     di, di                  / Destination.
        !          88620:        mov     cx, $0x8000             / 64K bytes, in words.
        !          88621:        mov     2(si), ax               / Adjust gdt to desired DX:AX mem locn.
        !          88622:        movb    4(si), dl               /
        !          88623:        mov     es, si                  / Map ES onto 64K bank of extended mem.
        !          88624:        mov     es:(di), bx             / Write word of extended memory.
        !          88625:        jmp     .+2             / FLUSH /
        !          88626:        cmp     es:(di), bx             / Verify word was correctly written.
        !          88627:        jne     0f                      / Branch if memory end.
        !          88628:                                        /
        !          88629:        cld                             /
        !          88630:        rep                             /
        !          88631:        stosw                           / Clear this 64K of extended memory.
        !          88632:                                        /
        !          88633:        inc     dx                      / Step to next 64K bank.
        !          88634:        cmp     dx, ss:CMOSmax_         / See if we're beyond what the CMOS
        !          88635:        jge     0f                      /    says we have.
        !          88636:        cmp     dx, $0x00F0             / Stop at 15 Mbyte boundary; the last
        !          88637:        jl      0b                      /    Mbyte is a dup of the 1st Mbyte.
        !          88638:                                        /
        !          88639: 0:     movb    5(si), $0               / Free the scratch selector.
        !          88640:                                        /
        !          88641:        mov     bx, ss                  / Restore data and extra segments.
        !          88642:        mov     ds, bx                  / NOTE: Do not modify DX:AX.
        !          88643:        mov     es, bx                  /
        !          88644:                                        /
        !          88645:        mov     coretop_, ax            / Recorded top of extended core memory.
        !          88646:        mov     coretop_+2, dx          /
        !          88647:        jmp     start                   / Bring up system.
        !          88648: 
        !          88649: ////////
        !          88650: /
        !          88651: / Trap an interrupt linkage.
        !          88652: / Each of the machine traps has a special little
        !          88653: / linkage, that sets up the type code and sends
        !          88654: / control off to the common trap processor. Device
        !          88655: / interrupts, other than the clock (IR0), are
        !          88656: / done here.
        !          88657: /
        !          88658: ////////
        !          88659: 
        !          88660: trap0:
        !          88661:        call    tsave
        !          88662:        mov     16(bx), $0x0000         / Divide error.
        !          88663:        jmp     trap_
        !          88664: 
        !          88665: trap1:
        !          88666:        call    tsave
        !          88667:        mov     16(bx), $0x0100         / Single step.
        !          88668:        jmp     trap_
        !          88669: 
        !          88670: trap2:
        !          88671:        call    tsave
        !          88672:        mov     16(bx), $0x0200         / Non-maskable interrupt.
        !          88673:        jmp     trap_
        !          88674: 
        !          88675: trap3:
        !          88676:        call    tsave
        !          88677:        mov     16(bx), $0x0300         / INT 3 (breakpoint).
        !          88678:        jmp     trap_
        !          88679: 
        !          88680: trap4:
        !          88681:        call    tsave
        !          88682:        mov     16(bx), $0x0400         / Overflow.
        !          88683:        jmp     trap_
        !          88684: 
        !          88685: trap5:
        !          88686:        call    tsave
        !          88687:        mov     16(bx), $0x0500         / Bound check.
        !          88688:        jmp     trap_
        !          88689: 
        !          88690: trap6:
        !          88691:        call    tsave
        !          88692:        mov     16(bx), $0x0600         / Invalid opcode.
        !          88693:        jmp     trap_
        !          88694: 
        !          88695: trap7:
        !          88696:        call    tsave
        !          88697:        mov     16(bx), $0x0700         / Processor Extension not available.
        !          88698:        jmp     trap_
        !          88699: 
        !          88700: trap8:
        !          88701:        pop     ax                      / Get error code from stack [always 0]
        !          88702:        call    tsave
        !          88703:        mov     16(bx), $0x0800         / Double Exception detected
        !          88704:        jmp     trap_
        !          88705: 
        !          88706: trap9:
        !          88707:        call    tsave
        !          88708:        mov     16(bx), $0x0900         / Processor extension segment overrun
        !          88709:        jmp     trap_
        !          88710: 
        !          88711: trap10:
        !          88712:        pop     ax                      / Get error code from stack
        !          88713:        call    tsave
        !          88714:        mov     16(bx), $0x0A00         / Invalid task state segment
        !          88715:        jmp     trap_
        !          88716: 
        !          88717: trap11:
        !          88718:        pop     ax                      / Get error code from stack
        !          88719:        call    tsave
        !          88720:        mov     16(bx), $0x0B00         / Segment not present
        !          88721:        jmp     trap_
        !          88722: 
        !          88723: trap12:
        !          88724:        pop     ax                      / Get error code from stack
        !          88725:        call    tsave
        !          88726:        mov     16(bx), $0x0C00         / Stack segment overrun or not present
        !          88727:        jmp     trap_
        !          88728: 
        !          88729: trap13:
        !          88730:        pop     ax                      / Get error code from stack
        !          88731:        call    tsave
        !          88732:        mov     16(bx), $0x0D00         / General protection
        !          88733:        jmp     trap_
        !          88734: 
        !          88735:        .globl  syc
        !          88736: 
        !          88737: syc:
        !          88738:        call    tsave
        !          88739:        mov     16(bx), $0x2000         / System calls.
        !          88740:        jmp     trap_
        !          88741: 
        !          88742: ran:
        !          88743:        call    tsave
        !          88744:        mov     16(bx), $0x2100         / Random trap.
        !          88745:        jmp     trap_
        !          88746: 
        !          88747: dev1:
        !          88748:        call    tsave
        !          88749:        mov     16(bx), $0x4001         / Device 1: keyboard
        !          88750:        ijmp    vecs_+[2*1]
        !          88751: 
        !          88752: /dev2: call    tsave                   / Device 2: mapped into device 9
        !          88753: /      mov     16(bx), $0x4002
        !          88754: /      ijmp    vecs_+[2*2]
        !          88755: 
        !          88756: dev3:
        !          88757:        call    tsave
        !          88758:        mov     16(bx), $0x4003         / Device 3: al1
        !          88759:        ijmp    vecs_+[2*3]
        !          88760: 
        !          88761: dev4:
        !          88762:        call    tsave
        !          88763:        mov     16(bx), $0x4004         / Device 4: al0
        !          88764:        ijmp    vecs_+[2*4]
        !          88765: 
        !          88766: dev5:
        !          88767:        call    tsave
        !          88768:        mov     16(bx), $0x4005         / Device 5: hard disk
        !          88769:        ijmp    vecs_+[2*5]
        !          88770: 
        !          88771: dev6:
        !          88772:        call    tsave
        !          88773:        mov     16(bx), $0x4006         / Device 6: floppy
        !          88774:        ijmp    vecs_+[2*6]
        !          88775: 
        !          88776: dev7:
        !          88777:        call    tsave
        !          88778:        mov     16(bx), $0x4007         / Device 7: lp
        !          88779:        ijmp    vecs_+[2*7]
        !          88780: 
        !          88781: dev8:
        !          88782:        call    tsave
        !          88783:        mov     16(bx), $0x4008         / Device 8:
        !          88784:        ijmp    vecs_+[2*8]
        !          88785: 
        !          88786: dev9:
        !          88787:        call    tsave
        !          88788:        mov     16(bx), $0x4009         / Device 9:
        !          88789:        ijmp    vecs_+[2*9]
        !          88790: 
        !          88791: dev10:
        !          88792:        call    tsave
        !          88793:        mov     16(bx), $0x400A         / Device 10:
        !          88794:        ijmp    vecs_+[2*10]
        !          88795: 
        !          88796: dev11:
        !          88797:        call    tsave
        !          88798:        mov     16(bx), $0x400B         / Device 11:
        !          88799:        ijmp    vecs_+[2*11]
        !          88800: 
        !          88801: dev12:
        !          88802:        call    tsave
        !          88803:        mov     16(bx), $0x400C         / Device 12:
        !          88804:        ijmp    vecs_+[2*12]
        !          88805: 
        !          88806: dev13:
        !          88807:        call    tsave
        !          88808:        mov     16(bx), $0x400D         / Device 13:
        !          88809:        ijmp    vecs_+[2*13]
        !          88810: 
        !          88811: dev14:
        !          88812:        call    tsave
        !          88813:        mov     16(bx), $0x400E         / Device 14:
        !          88814:        ijmp    vecs_+[2*14]
        !          88815: 
        !          88816: dev15:
        !          88817:        call    tsave
        !          88818:        mov     16(bx), $0x400F         / Device 15:
        !          88819:        ijmp    vecs_+[2*15]
        !          88820: 
        !          88821: ////////
        !          88822: /
        !          88823: / Clock interrupt.
        !          88824: / The clock interrupt is stolen from the ROM;
        !          88825: / if you don't do this the EOI sequence for the 8259
        !          88826: / may get mangled on context switches.
        !          88827: /
        !          88828: ////////
        !          88829: 
        !          88830: clk:
        !          88831:        call    tsave                   / Perform trap save.
        !          88832:        mov     16(bx), $0x4000
        !          88833: 
        !          88834:        sub     ax, ax                  / Assume system mode, push user flag
        !          88835:        push    ax
        !          88836:        push    18(bx)                  / IP at tick time
        !          88837: 
        !          88838:        cmpb    depth_, $0              / Correct ?
        !          88839:        jne     0f                      / If ne, yes.
        !          88840:        mov     bx, cprocp_             / User depth, check if the
        !          88841:        test    PFLAGS(bx), $PFKERN     / current process is a kernel process.
        !          88842:        jne     0f                      / If ne, yes.
        !          88843:        mov     bx, sp                  / Load stack index
        !          88844:        inc     2(bx)                   / and set user mode.
        !          88845: 
        !          88846: 0:     call    clock_                  / Call common clock and
        !          88847:        add     sp, $4                  / pop arguments.
        !          88848: 
        !          88849:        ret                             / Back to "tsave".
        !          88850: 
        !          88851: ////////
        !          88852: /
        !          88853: / This routine is called by "tsave" to dismiss an interrupt.
        !          88854: / The interrupt code is in "ax".
        !          88855: /
        !          88856: ////////
        !          88857: 
        !          88858:        .globl  eoi
        !          88859: 
        !          88860: eoi:
        !          88861:        cmpb    al, $8                  / Is this on the slave PIC?
        !          88862:        jb      0f                      / Jump if not.
        !          88863:        movb    al, $0x20               / Send a non specific EOI
        !          88864:        outb    SPIC, al                / to the slave PIC.
        !          88865: 0:     movb    al, $0x20               / Send a non specific EOI
        !          88866:        outb    PIC, al                 / to the master PIC.
        !          88867:        ret                             / Done.
        !          88868: 
        !          88869: ////////
        !          88870: /
        !          88871: / Block I/O to ports.
        !          88872: / Mainly used to read and write the silo memories in the discs.
        !          88873: / Delibrately only transfers 1 byte per loop to avoid
        !          88874: / timing problems on AT I/O chips.
        !          88875: /
        !          88876: / void outcopy(port, off, seg, n);
        !          88877: / int  port;                   /* Port address */
        !          88878: / char *off;                   /* Offset in segment */
        !          88879: / unsigned seg;                        /* Segment register base */
        !          88880: / int  n;                      /* Byte count */
        !          88881: / 
        !          88882: / void incopy(port, off, seg, n);
        !          88883: / int  port;                   /* Device */
        !          88884: / char *off;                   /* Offset */
        !          88885: / unsigned seg;                        /* Segment register base */
        !          88886: / int  n;                      /* Byte count */
        !          88887: /
        !          88888: ////////
        !          88889: 
        !          88890:        .globl  incopy_
        !          88891:        .globl  outcopy_
        !          88892: 
        !          88893: incopy_:
        !          88894:        push    di
        !          88895:        push    es
        !          88896:        push    bp
        !          88897:        mov     bp, sp
        !          88898:        mov     dx, 8(bp)               /device port
        !          88899:        les     di, 10(bp)              /seg,off pair
        !          88900:        mov     cx, 14(bp)              /n bytes
        !          88901:        jcxz    1f
        !          88902: 
        !          88903:        cld                             /auto-increment
        !          88904: 0:     inb     al, dx
        !          88905:        stosb
        !          88906:        loop    0b
        !          88907: 
        !          88908: 1:     pop     bp
        !          88909:        pop     es                      /restore regs
        !          88910:        pop     di
        !          88911:        ret
        !          88912: 
        !          88913: outcopy_:
        !          88914:        push    si
        !          88915:        push    ds
        !          88916:        push    bp
        !          88917:        mov     bp, sp
        !          88918:        mov     dx, 8(bp)               /device port
        !          88919:        lds     si, 10(bp)              /offset
        !          88920:        mov     cx, 14(bp)              /count
        !          88921:        jcxz    1f
        !          88922: 
        !          88923:        cld                             /auto-increment
        !          88924: 0:     lodsb
        !          88925:        outb    dx, al
        !          88926:        loop    0b
        !          88927: 
        !          88928: 1:     pop     bp
        !          88929:        pop     ds
        !          88930:        pop     si
        !          88931:        ret
        !          88932: 
        !          88933: ////////
        !          88934: /
        !          88935: / Copy "n" bytes of memory from base "p1" to base "p2".
        !          88936: / The copy must be done from left to right.
        !          88937: /
        !          88938: / plrcopy(p1, p2, n)
        !          88939: / paddr_t p1, p2;
        !          88940: / size_t n;
        !          88941: /
        !          88942: ////////
        !          88943: 
        !          88944:        .globl  plrcopy_
        !          88945: 
        !          88946: plrcopy_:
        !          88947:        push    si                      / Save sequence
        !          88948:        push    di
        !          88949:        push    bp
        !          88950:        mov     bp, sp
        !          88951: 
        !          88952:        push    ds                      / Save ds
        !          88953:        push    es                      / Save es
        !          88954: 
        !          88955:        push    18(bp)                  / Map SI:DI at destination ptov(p2,n).
        !          88956:        push    16(bp)
        !          88957:        push    14(bp)
        !          88958:        push    12(bp)
        !          88959:        call    ptov_
        !          88960:        add     sp, $8
        !          88961:        mov     si, dx
        !          88962:        mov     di, ax
        !          88963: 
        !          88964:        push    18(bp)                  / Map DX:AX at source   ptov(p1,n);
        !          88965:        push    16(bp)
        !          88966:        push    10(bp)
        !          88967:        push    8(bp)
        !          88968:        call    ptov_
        !          88969:        add     sp, $8
        !          88970: 
        !          88971:        mov     es, si                  / Map ES:DI at destination.
        !          88972:        mov     ds, dx                  / Map DS:SI at source.
        !          88973:        mov     si, ax
        !          88974: 
        !          88975:        mov     cx, 16(bp)              / Transfer count in bytes.
        !          88976:        cld                             / Auto Increment.
        !          88977:        clc                             /
        !          88978:        rcr     cx, $1                  / Word count
        !          88979:        rep                             /
        !          88980:        movsw                           / Move words
        !          88981:        rcl     cx, $1                  /
        !          88982:        rep                             /
        !          88983:        movsb                           / Move odd byte
        !          88984: 
        !          88985:        mov     si, es                  / Remember mapped selectors.
        !          88986:        mov     di, ds                  /
        !          88987:        pop     es                      / Restore es
        !          88988:        pop     ds                      / Restore ds
        !          88989: 
        !          88990:        push    si                      / Release mapped selectors.
        !          88991:        push    ax                      / NOTE: Offset is ignored.
        !          88992:        call    vrelse_                 /
        !          88993:        add     sp, $4                  /
        !          88994:                                        /
        !          88995:        push    di                      /
        !          88996:        push    ax                      /
        !          88997:        call    vrelse_                 /
        !          88998:        add     sp, $4                  /
        !          88999: 
        !          89000:        pop     bp                      / Standard return
        !          89001:        pop     di
        !          89002:        pop     si
        !          89003:        ret                             / Return
        !          89004: 
        !          89005: ////////
        !          89006: /
        !          89007: / Copy "n" bytes of memory from base "p1" to base "p2".
        !          89008: / The copy must be done from right to left.
        !          89009: /
        !          89010: / prlcopy(p1, p2, n)
        !          89011: / paddr_t p1, p2;
        !          89012: / size_t n;
        !          89013: /
        !          89014: ////////
        !          89015: 
        !          89016:        .globl  prlcopy_
        !          89017: 
        !          89018: prlcopy_:
        !          89019:        push    si                      / Save sequence
        !          89020:        push    di
        !          89021:        push    bp
        !          89022:        mov     bp, sp
        !          89023: 
        !          89024:        push    ds                      / Save ds
        !          89025:        push    es                      / Save es
        !          89026: 
        !          89027:        push    18(bp)                  / Map SI:DI at destination ptov(p2,n).
        !          89028:        push    16(bp)
        !          89029:        push    14(bp)
        !          89030:        push    12(bp)
        !          89031:        call    ptov_
        !          89032:        add     sp, $8
        !          89033:        mov     si, dx
        !          89034:        mov     di, ax
        !          89035: 
        !          89036:        push    18(bp)                  / Map DX:AX at source   ptov(p1,n);
        !          89037:        push    16(bp)
        !          89038:        push    10(bp)
        !          89039:        push    8(bp)
        !          89040:        call    ptov_
        !          89041:        add     sp, $8
        !          89042: 
        !          89043:        mov     es, si                  / Map ES:DI at destination.
        !          89044:        mov     ds, dx                  / Map DS:SI at source.
        !          89045:        mov     si, ax
        !          89046: 
        !          89047:        mov     cx, 16(bp)              / Transfer count in bytes
        !          89048:        add     si, cx                  / Point DS:SI at the end
        !          89049:        dec     si                      / of the source.
        !          89050:        add     di, cx                  / Point ES:DI at the end
        !          89051:        dec     di                      / of the destination.
        !          89052: 
        !          89053:        std                             / Auto decrement
        !          89054:        clc                             /
        !          89055:        rcr     cx, $1                  / Word Count
        !          89056:        rep                             /
        !          89057:        movsw                           / Move words
        !          89058:        rcl     cx, $1                  /
        !          89059:        rep                             /
        !          89060:        movsb                           / Move odd byte
        !          89061:        cld                             / Auto increment
        !          89062: 
        !          89063:        mov     si, es                  / Remember mapped selectors.
        !          89064:        mov     di, ds                  /
        !          89065:        pop     es                      / Restore es
        !          89066:        pop     ds                      / Restore ds
        !          89067: 
        !          89068:        push    si                      / Release mapped selectors.
        !          89069:        push    ax                      / NOTE: Offset is ignored.
        !          89070:        call    vrelse_                 /
        !          89071:        add     sp, $4                  /
        !          89072:                                        /
        !          89073:        push    di                      /
        !          89074:        push    ax                      /
        !          89075:        call    vrelse_                 /
        !          89076:        add     sp, $4                  /
        !          89077:                                        /
        !          89078:        mov     ax, 16(bp)              / Return transfer count.
        !          89079:        pop     bp                      / Standard return
        !          89080:        pop     di
        !          89081:        pop     si
        !          89082:        ret
        !          89083: 
        !          89084: ////////
        !          89085: /
        !          89086: / Clear "n" bytes of memory starting at physical address "p".
        !          89087: /
        !          89088: / pclear( p, n )
        !          89089: / paddr_t p;
        !          89090: / size_t n;
        !          89091: /
        !          89092: /
        !          89093: /      Notes:  At most 64K bytes of memory can be cleared.
        !          89094: /
        !          89095: ////////
        !          89096: 
        !          89097:        .globl  pclear_
        !          89098: 
        !          89099: pclear_:
        !          89100:        push    si                      / Standard save
        !          89101:        push    di
        !          89102:        push    bp
        !          89103:        mov     bp, sp
        !          89104: 
        !          89105:        push    es                      / Save es
        !          89106: 
        !          89107:        push    14(bp)                  / Map ES:DI at ptov(p2,n).
        !          89108:        push    12(bp)
        !          89109:        push    10(bp)
        !          89110:        push    8(bp)
        !          89111:        call    ptov_
        !          89112:        add     sp, $8
        !          89113:        mov     es, dx
        !          89114:        mov     di, ax
        !          89115: 
        !          89116:        shr     14(bp), $1              / Convert count from bytes to words.
        !          89117:        rcr     12(bp), $1
        !          89118:        mov     cx, 12(bp)              / Count in words.
        !          89119: 
        !          89120:        sub     ax, ax                  / Get a 0.
        !          89121:        cld                             / Zero the block.
        !          89122:        rep
        !          89123:        stosw
        !          89124: 
        !          89125:        mov     ax, es                  / Remember mapped selector.
        !          89126:        pop     es                      / Restore es.
        !          89127: 
        !          89128:        push    ax                      / Release mapped selector.
        !          89129:        push    ax                      / NOTE: Offset is ignored.
        !          89130:        call    vrelse_                 /
        !          89131:        add     sp, $4                  /
        !          89132: 
        !          89133:        pop     bp                      / Standard return.
        !          89134:        pop     di
        !          89135:        pop     si
        !          89136:        ret
        !          89137: 
        !          89138: ////////
        !          89139: /
        !          89140: / Block copy chunks of memory to a physical
        !          89141: / location from a location in either the system
        !          89142: / or user data space.
        !          89143: /
        !          89144: / upcopy(u, p, n)
        !          89145: / char *u;
        !          89146: / paddr_t p;
        !          89147: / int n;
        !          89148: /
        !          89149: / kpcopy(k, p, n);
        !          89150: / char *k;
        !          89151: / paddr_t p;
        !          89152: / int n;
        !          89153: /
        !          89154: ////////
        !          89155: 
        !          89156:        .globl  upcopy_
        !          89157: 
        !          89158: upcopy_:
        !          89159:        mov     bx, sp                  / Get set for stack index.
        !          89160:        mov     ax, 2(bx)               / User address
        !          89161:        dec     ax                      / Don't wrap too soon
        !          89162:        add     ax, 8(bx)               / Count
        !          89163:        jc      kuerr                   / Out of bounds
        !          89164:        cmp     ax, udl_                / In range?
        !          89165:        ja      kuerr                   / No
        !          89166:        push    uds_                    / Mark transfer ds as being user ds.
        !          89167:        jmp     1f                      / Finish in common code.
        !          89168: 
        !          89169:        .globl  kpcopy_
        !          89170: 
        !          89171: kpcopy_:
        !          89172:        push    ds                      / Mark transfer ds as being kernel ds.
        !          89173: 
        !          89174: 1:     push    si                      / Standard save
        !          89175:        push    di
        !          89176:        push    bp
        !          89177:        mov     bp, sp
        !          89178: 
        !          89179:        push    ds                      / Save ds, es
        !          89180:        push    es
        !          89181: 
        !          89182:        sub     ax, ax                  / ES:DI = ptov(p,n).
        !          89183:        push    ax                      /
        !          89184:        push    16(bp)                  /
        !          89185:        push    14(bp)                  /
        !          89186:        push    12(bp)                  /
        !          89187:        call    ptov_                   /
        !          89188:        add     sp, $8                  /
        !          89189:        mov     es, dx                  /
        !          89190:        mov     di, ax                  /
        !          89191:                                        /
        !          89192:        mov     ds, 6(bp)               / DS:SI = source address.
        !          89193:        mov     si, 10(bp)              /
        !          89194:        mov     cx, 16(bp)              / Byte count
        !          89195:                                        /
        !          89196:        cld                             / Auto Increment
        !          89197:        clc                             /
        !          89198:        rcr     cx, $1                  / Word count
        !          89199:        rep                             /
        !          89200:        movsw                           / Move words
        !          89201:        rcl     cx, $1                  / Move odd byte
        !          89202:        rep                             /
        !          89203:        movsb                           /
        !          89204:                                        /
        !          89205:        mov     ax, es                  / Remember mapped selector.
        !          89206:        pop     es                      / Restore es, ds.
        !          89207:        pop     ds                      /
        !          89208:                                        /
        !          89209:        push    ax                      / Release mapped selector.
        !          89210:        push    ax                      / NOTE: Offset is ignored.
        !          89211:        call    vrelse_                 /
        !          89212:        add     sp, $4                  /
        !          89213:                                        /
        !          89214:        mov     ax, 16(bp)              / Return transfer count.
        !          89215:                                        /
        !          89216:        pop     bp                      / Standard return.
        !          89217:        pop     di
        !          89218:        pop     si
        !          89219:        add     sp, $2                  / Discard marked transfer ds.
        !          89220:        ret
        !          89221: 
        !          89222: ////////
        !          89223: /
        !          89224: / Block copy memory from physical address "p"
        !          89225: / to either user or system data space.
        !          89226: /
        !          89227: / pucopy(p, u, n)
        !          89228: / paddr_t p;
        !          89229: / char *u;
        !          89230: / int n;
        !          89231: /
        !          89232: / pkcopy(p, k, n);
        !          89233: / paddr_t p;
        !          89234: / char *k;
        !          89235: / int n;
        !          89236: /
        !          89237: ////////
        !          89238: 
        !          89239:        .globl  pucopy_
        !          89240: 
        !          89241: pucopy_:
        !          89242:        mov     bx, sp                  / Stack index
        !          89243:        mov     ax, 6(bx)               / User address
        !          89244:        dec     ax                      / Don't wrap too soon
        !          89245:        add     ax, 8(bx)               / Count
        !          89246:        jc      kuerr                   / Out of bounds
        !          89247:        cmp     ax, udl_                / In range?
        !          89248:        ja      kuerr                   / No
        !          89249:        push    uds_                    / Mark transfer es as being user ds.
        !          89250:        jmp     1f                      / Common code
        !          89251: 
        !          89252:        .globl  pkcopy_
        !          89253: 
        !          89254: pkcopy_:
        !          89255:        push    ds                      / Mark transfer es as being kernel ds.
        !          89256: 
        !          89257: 1:     push    si                      / Standard save
        !          89258:        push    di
        !          89259:        push    bp
        !          89260:        mov     bp, sp
        !          89261: 
        !          89262:        push    ds                      / Save ds, es.
        !          89263:        push    es
        !          89264: 
        !          89265:        sub     ax, ax                  / DS:SI = ptov(p,n).
        !          89266:        push    ax
        !          89267:        push    16(bp)
        !          89268:        push    12(bp)
        !          89269:        push    10(bp)
        !          89270:        call    ptov_
        !          89271:        add     sp, $8
        !          89272:        mov     ds, dx
        !          89273:        mov     si, ax
        !          89274: 
        !          89275:        mov     es, 6(bp)               / ES:DI = destination.
        !          89276:        mov     di, 14(bp)              /
        !          89277:        mov     cx, 16(bp)              / Count
        !          89278: 
        !          89279:        cld                             / Incremental move
        !          89280:        clc                             /
        !          89281:        rcr     cx, $1                  / Word count
        !          89282:        rep                             /
        !          89283:        movsw                           / Move words.
        !          89284:        rcl     cx, $1                  / Move odd byte.
        !          89285:        rep                             /
        !          89286:        movsb                           /
        !          89287:                                        /
        !          89288:        mov     ax, ds                  / Rememember mapped selector.
        !          89289:        pop     es                      / Restore es, ds.
        !          89290:        pop     ds                      /
        !          89291:                                        /
        !          89292:        push    ax                      / Release mapped selector.
        !          89293:        push    ax                      / NOTE: Offset is ignored.
        !          89294:        call    vrelse_                 /
        !          89295:        add     sp, $4                  /
        !          89296:                                        /
        !          89297:        mov     ax, 16(bp)              / Return transfer count.
        !          89298:                                        /
        !          89299:        pop     bp                      / Restore registers.
        !          89300:        pop     di                      /
        !          89301:        pop     si                      /
        !          89302:        add     sp, $2                  / Discard marked transfer es.
        !          89303:        ret                             / Fin
        !          89304: 
        !          89305: ////////
        !          89306: /
        !          89307: / All of the above copy routines jump to
        !          89308: / "kuerr", with the stack untouched, if they detect
        !          89309: / a bounds error on a user address.
        !          89310: /
        !          89311: ////////
        !          89312: 
        !          89313: kuerr:
        !          89314:        mov     bx,$u_                  / Pointer to user area
        !          89315:        movb    (bx),$EFAULT            / Bad parameter error
        !          89316:        sub     ax,ax                   / Didn't copy anything
        !          89317:        ret                             / Return
        !          89318: 
        !          89319: ////////
        !          89320: /
        !          89321: / Read the equipment description. Use
        !          89322: / the "int 11" interface, so that the IBM
        !          89323: / ROM will do all the details.
        !          89324: /
        !          89325: ////////
        !          89326: 
        !          89327:        .globl  int11_
        !          89328: 
        !          89329: int11_:        mov     ax, cs:val11            / Ask the ROM
        !          89330:        ret                             / to put stuff in AX
        !          89331: 
        !          89332: ////////
        !          89333: /
        !          89334: / Bootstrap.
        !          89335: / Called by the keyboard driver on control-alt-del.
        !          89336: / Requests the 8042 controller to initiate a processor reset,
        !          89337: / which is the only way to terminate protected mode operation.
        !          89338: /
        !          89339: /      Reference: IBM-AT Technical Reference Manual,
        !          89340: /                      Real-time Clock/CMOS RAM [Page 1-45]
        !          89341: /                      Keyboard controller [Page 1-40]
        !          89342: /                      Test 3, Page 5-68.
        !          89343: /
        !          89344: ////////
        !          89345: 
        !          89346:        .globl  boot_
        !          89347: boot_:
        !          89348:        cli                             / Disable interrupts.
        !          89349:                                        /
        !          89350:        sub     cx, cx                  /
        !          89351: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !          89352:        testb   al, $2                  /
        !          89353:        loopne  0b                      /
        !          89354:        jmp     .+2             / DELAY /
        !          89355:                                        /
        !          89356:        movb    al, $0xFE               / Issue a shutdown command
        !          89357:        outb    KBCTRL, al              / to the 8042 control port.
        !          89358:                                        /
        !          89359: 0:     hlt                             / Halt until processor reset occurs.
        !          89360:        jmp     0b
        !          89361: 
        !          89362: ////////
        !          89363: /
        !          89364: / Data.
        !          89365: /
        !          89366: ////////
        !          89367: 
        !          89368:        .globl  MAXMEM
        !          89369:        .globl  vecs_
        !          89370:        .globl  realmode_
        !          89371:        .globl  gdtsel_, gdtmap_
        !          89372:        .globl  idtsel_, idtmap_
        !          89373:        .globl  CMOSmax_
        !          89374: 
        !          89375:        .shri
        !          89376: val11: .word   0                       / Value obtained from int11 [in code].
        !          89377: 
        !          89378:        .prvd
        !          89379: MAXMEM:        .word   0xA000                  / In paragraphs, must be mult. of 64
        !          89380: CMOSmax_:.word 0x0000                  / Max extended memory according ...
        !          89381:                                        / ... to CMOS bytes 0x17 and 0x18 ...
        !          89382:                                        / ... in 64K chunks.
        !          89383: realmode_:.word        0                       / Virtual Addressing Mode Enabled
        !          89384: gdtmap_:.blkw  3                       / Global descriptor table definition
        !          89385: idtmap_:.blkw  3                       / Interrupt descriptor table definition
        !          89386: gdtsel_:.word  0                       / Global descriptor table selector
        !          89387: idtsel_:.word  0                       / Interrupt descriptor table selector
        !          89388: vecs_: .word   vret_                   / Interrupt vector table
        !          89389:        .word   vret_
        !          89390:        .word   vret_
        !          89391:        .word   vret_
        !          89392:        .word   vret_
        !          89393:        .word   vret_
        !          89394:        .word   vret_
        !          89395:        .word   vret_
        !          89396:        .word   vret_
        !          89397:        .word   vret_
        !          89398:        .word   vret_
        !          89399:        .word   vret_
        !          89400:        .word   vret_
        !          89401:        .word   vret_
        !          89402:        .word   vret_
        !          89403:        .word   vret_
        !          89404: 
        !          89405: ////////
        !          89406: /
        !          89407: / Task State Segment - Coherent runs as a single protected mode task.
        !          89408: /
        !          89409: ////////
        !          89410:        .globl  tss_
        !          89411: 
        !          89412:        .prvd
        !          89413: tss_:                          / Task State Segment.
        !          89414: tss_lnk:.word  0               /  0: Back link selector to TSS.
        !          89415: tss_sp0:.word  0               /  2: SP for CPL 0.
        !          89416: tss_ss0:.word  0               /  4: SS for CPL 0.
        !          89417: tss_sp1:.word  0               /  6: SP for CPL 1.
        !          89418: tss_ss1:.word  0               /  8: SS for CPL 1.
        !          89419: tss_sp2:.word  0               / 10: SP for CPL 2.
        !          89420: tss_ss2:.word  0               / 12: SS for CPL 2.
        !          89421: tss_ip:        .word   0               / 14: IP (Entry point).
        !          89422: tss_psw:.word  0               / 16: Flag word.
        !          89423: tss_ax:        .word   0               / 18: Register AX.
        !          89424: tss_cx:        .word   0               / 20: Register CX.
        !          89425: tss_dx:        .word   0               / 22: Register DX.
        !          89426: tss_bx:        .word   0               / 24: Register BX.
        !          89427: tss_bp:        .word   0               / 26: Register BP.
        !          89428: tss_sp:        .word   0               / 28: Register SP.
        !          89429: tss_si:        .word   0               / 30: Register SI.
        !          89430: tss_di:        .word   0               / 32: Register DI.
        !          89431: tss_es:        .word   0               / 34: Register ES.
        !          89432: tss_cs:        .word   0               / 36: Register CS.
        !          89433: tss_ss:        .word   0               / 38: Register SS.
        !          89434: tss_ds:        .word   0               / 40: Register DS.
        !          89435: tss_ldt:.word  0               / 42: Task LDT Selector.
        !          89436: 0707070064030104411004440000030000030000011777770507310714100005300000010442/newbits/kernel/USRSRC/i8086/ibm_at/dmac.c/* $Header: /usr/src/sys/i8086/ibm_at/RCS/dmac.c,v 1.1 88/03/24 09:33:31 src Exp $ */
        !          89437: /* (lgl-
        !          89438:  *     The information contained herein is a trade secret of Mark Williams
        !          89439:  *     Company, and  is confidential information.  It is provided  under a
        !          89440:  *     license agreement,  and may be  copied or disclosed  only under the
        !          89441:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          89442:  *     material without the express written authorization of Mark Williams
        !          89443:  *     Company or persuant to the license agreement is unlawful.
        !          89444:  *
        !          89445:  *     COHERENT Version 2.3.37
        !          89446:  *     Copyright (c) 1982, 1983, 1984.
        !          89447:  *     An unpublished work by Mark Williams Company, Chicago.
        !          89448:  *     All rights reserved.
        !          89449:  -lgl) */
        !          89450: /*
        !          89451:  * The routines in this file
        !          89452:  * deal with the 8237 programmable
        !          89453:  * DMA controller on the system board.
        !          89454:  *
        !          89455:  * $Log:       /usr/src/sys/i8086/ibm_at/RCS/dmac.c,v $
        !          89456:  * Revision 1.1        88/03/24  09:33:31      src
        !          89457:  * Initial revision
        !          89458:  * 
        !          89459:  * 86/12/18    Allan Cornish           /usr/src/sys/i8086/ibm_at/dmac.c
        !          89460:  * Full support for DMA channels 5..7 added.
        !          89461:  */
        !          89462: #include       <sys/types.h>
        !          89463: #include       <sys/dmac.h>
        !          89464: 
        !          89465: /*
        !          89466:  * This table maps channel
        !          89467:  * numbers into DMA page address
        !          89468:  * register ports. The wiring of the
        !          89469:  * RA lines on the 74LS670 is a bit
        !          89470:  * strange.
        !          89471:  */
        !          89472: static int     dmaport[8] = {
        !          89473:        DMAPAGE+7,                      /* 0 (Free) */
        !          89474:        DMAPAGE+3,                      /* 1 (Free) */
        !          89475:        DMAPAGE+1,                      /* 2 (Floppy) */
        !          89476:        DMAPAGE+2,                      /* 3 (Free) */
        !          89477:        DMAPAGE+15,                     /* 4 (Cascade) */
        !          89478:        DMAPAGE+11,                     /* 5 */
        !          89479:        DMAPAGE+9,                      /* 6 */
        !          89480:        DMAPAGE+10                      /* 7 */
        !          89481: };
        !          89482: 
        !          89483: /*
        !          89484:  * Program the channel of the
        !          89485:  * 8237 DMA controller specified by
        !          89486:  * "chan". The "paddr" is a 20 bit
        !          89487:  * physical address. The "count" is
        !          89488:  * the byte count. The "wflag" is
        !          89489:  * true if this is a write, from the
        !          89490:  * point of view of the device.
        !          89491:  * True return if the mapping can be
        !          89492:  * set up, given the 64K limits.
        !          89493:  * The "count" is predecremented, so
        !          89494:  * that backplane "+T/C" is issued at
        !          89495:  * the expected point in time.
        !          89496:  */
        !          89497: dmaon(chan, paddr, count, wflag)
        !          89498: register int   chan;
        !          89499: paddr_t                paddr;
        !          89500: unsigned       count;
        !          89501: {
        !          89502:        register int    port;
        !          89503:        register int    s;
        !          89504: 
        !          89505:        /*
        !          89506:         * Change from 0 based transfer count to -1 based.
        !          89507:         */
        !          89508:        count--;
        !          89509: 
        !          89510:        /*
        !          89511:         * Select byte/word transfer.
        !          89512:         * Channels 0-4 use byte transfer.
        !          89513:         * Channels 5-7 use word transfers, with low 17 addr bits right shifted.
        !          89514:         */
        !          89515:        if ( chan >= 5 ) {
        !          89516:                count >>= 1;
        !          89517:                paddr >>= 1;
        !          89518:                paddr  += (paddr & 0xFF0000L);
        !          89519:        }
        !          89520: 
        !          89521:        /*
        !          89522:         * Check for DMA straddle.
        !          89523:         */
        !          89524:        if ( dmaseg(paddr) != dmaseg(paddr+count) )
        !          89525:                return (0);
        !          89526: 
        !          89527:        s = sphi();
        !          89528: 
        !          89529:        /*
        !          89530:         * Select DMA controller.
        !          89531:         */
        !          89532:        if ( chan < 4 ) {
        !          89533:                port = DMA;
        !          89534: 
        !          89535:                /*
        !          89536:                 * Program for dma read/write operation.
        !          89537:                 */
        !          89538:                if ( wflag != 0 )
        !          89539:                        outb( port + (SETMODE * 1), (chan & 3) | RDMEM );
        !          89540:                else
        !          89541:                        outb( port + (SETMODE * 1), (chan & 3) | WRMEM );
        !          89542:                outb( port + (CLEARFL * 1), 0 );
        !          89543:        }
        !          89544:        else {
        !          89545:                port = SDMA;
        !          89546: 
        !          89547:                /*
        !          89548:                 * Program for dma read/write operation.
        !          89549:                 */
        !          89550:                if ( wflag != 0 )
        !          89551:                        outb( SDMA + (SETMODE * 2), (chan & 3) | RDMEM );
        !          89552:                else
        !          89553:                        outb( SDMA + (SETMODE * 2), (chan & 3) | WRMEM );
        !          89554:                outb( SDMA + (CLEARFL * 2), 0 );
        !          89555:        }
        !          89556: 
        !          89557:        /*
        !          89558:         * Select memory bank.
        !          89559:         */
        !          89560:        outb( dmaport[chan], (int)(paddr >> 16) );
        !          89561: 
        !          89562:        if ( chan < 4 )
        !          89563:                port += ((chan & 3) << 1);
        !          89564:        else
        !          89565:                port += ((chan & 3) << 2);
        !          89566: 
        !          89567:        /*
        !          89568:         * Program memory offset in bank.
        !          89569:         */
        !          89570:        outb( port, ((int) paddr) >> 0 );
        !          89571:        outb( port, ((int) paddr) >> 8 );
        !          89572: 
        !          89573:        port++;
        !          89574:        if ( chan >= 4 )
        !          89575:                port++;
        !          89576: 
        !          89577:        /*
        !          89578:         * Program transfer count.
        !          89579:         */
        !          89580:        outb( port, count >> 0 );
        !          89581:        outb( port, count >> 8 );
        !          89582: 
        !          89583:        spl(s);
        !          89584:        return (1);
        !          89585: }
        !          89586: 
        !          89587: /*
        !          89588:  * dmago( chan ) - initiate dma transfer
        !          89589:  */
        !          89590: dmago( chan )
        !          89591: register int chan;
        !          89592: {
        !          89593:        /*
        !          89594:         * Enable dma transfers.
        !          89595:         */
        !          89596:        if ( chan < 4 )
        !          89597:                outb( DMA  + (SETMASK * 1), (chan & 3) | MASKOFF );
        !          89598:        else
        !          89599:                outb( SDMA + (SETMASK * 2), (chan & 3) | MASKOFF );
        !          89600: }
        !          89601: 
        !          89602: /*
        !          89603:  * dmaoff( chan ) - turn dma channel off, return residual count
        !          89604:  */
        !          89605: dmaoff( chan )
        !          89606: register int chan;
        !          89607: {
        !          89608:        register int port;
        !          89609:        register int count;
        !          89610:        int s;
        !          89611: 
        !          89612:        /*
        !          89613:         * Disable DMA transfers.
        !          89614:         * Obtain the -1 based residual count.
        !          89615:         */
        !          89616:        s = sphi();
        !          89617:        if ( chan < 4 ) {
        !          89618:                outb(  DMA + (SETMASK * 1), (chan & 3) | MASKON );
        !          89619:                port = DMA + ((chan & 3) << 1) + 1;
        !          89620:        }
        !          89621:        else {
        !          89622:                outb(  SDMA + (SETMASK * 2), (chan & 3) | MASKON );
        !          89623:                port = SDMA + ((chan & 3) << 2) + 2;
        !          89624:        }
        !          89625:        count  = inb(port);
        !          89626:        count += inb(port) << 8;
        !          89627:        spl( s );
        !          89628: 
        !          89629:        /*
        !          89630:         * Convert residual from -1 based to 0 based.
        !          89631:         */
        !          89632:        count++;
        !          89633: 
        !          89634:        /*
        !          89635:         * Convert residual from word based to byte based.
        !          89636:         */
        !          89637:        if ( chan >= 5 )
        !          89638:                count <<= 1;
        !          89639: 
        !          89640:        /*
        !          89641:         * Return residual count in bytes.
        !          89642:         */
        !          89643:        return count;
        !          89644: }
        !          89645: 0707070064030150001004440000030000030000011777770507310714200005300000011206/newbits/kernel/USRSRC/i8086/ibm_at/dump.c/* $Header: /usr/src/sys/i8086/ibm_at/RCS/dump.c,v 1.1 88/03/24 17:33:35 src Exp $
        !          89646:  *
        !          89647:  * Function to dump Kernel data inforation.
        !          89648:  *
        !          89649:  * $Log:       /usr/src/sys/i8086/ibm_at/RCS/dump.c,v $
        !          89650:  * Revision 1.1        88/03/24  17:33:35      src
        !          89651:  * Initial revision
        !          89652:  * 
        !          89653:  */
        !          89654: #include <ascii.h>
        !          89655: #include <coherent.h>
        !          89656: #include <sys/i8086.h>
        !          89657: #include <sys/proc.h>
        !          89658: #include <sys/uproc.h>
        !          89659: #include <sys/seg.h>
        !          89660: 
        !          89661: int nodump = 1;
        !          89662: 
        !          89663: /*
        !          89664:  * Note: ip1 is a dummy parameter facilitating access to calling stack frame.
        !          89665:  */
        !          89666: dumpall( ip1 )
        !          89667: int ip1;
        !          89668: {
        !          89669:        register PROC * pp;
        !          89670:        register SEG  * sp;
        !          89671:        faddr_t gp;
        !          89672:        faddr_t fp;
        !          89673:        int s;
        !          89674:        extern saddr_t gdtsel;
        !          89675:        extern saddr_t uasa, ucs, uds, scs, sds;
        !          89676:        extern int nesterr;
        !          89677: 
        !          89678:        if ( nodump )
        !          89679:                return;
        !          89680: 
        !          89681:        s = sphi();
        !          89682: 
        !          89683:        printf("\nuasa=%x ucs=%x uds=%x scs=%x sds=%x nesterr=%u\n",
        !          89684:                uasa, ucs, uds, scs, sds, nesterr );
        !          89685: 
        !          89686: 
        !          89687:        printf("\nGlobal Descriptor Table:\n");
        !          89688:        FP_SEL(gp) = gdtsel;
        !          89689:        FP_OFF(gp) = 5; /* offset of flags byte */
        !          89690:        FP_SEL(fp) = 0;
        !          89691:        FP_OFF(fp) = 0;
        !          89692:        do {
        !          89693:                if ( ffbyte(gp) )
        !          89694:                        vprint(fp);
        !          89695:                FP_OFF(gp) += 8;
        !          89696:                FP_SEL(fp) += 8;
        !          89697:        } while ( FP_SEL(fp) != 0 );
        !          89698: 
        !          89699:        showevq();
        !          89700:        showtim();
        !          89701:        putchar( A_FF );
        !          89702:        
        !          89703:        printf("\nProcesses:\n");
        !          89704:        for ( pp = procq.p_nforw; pp != &procq; pp = pp->p_nforw )
        !          89705:                showproc( pp );
        !          89706:        putchar( A_FF );
        !          89707: 
        !          89708:        printf( "\nMemory Segments:\n\n" );
        !          89709:        for ( sp = segmq.s_forw; sp != &segmq; sp = sp->s_forw )
        !          89710:                showseg( sp, "" );
        !          89711:        putchar( A_FF );
        !          89712: 
        !          89713:        if ( segdq.s_forw != &segdq ) {
        !          89714:                printf( "\nDisk Segments:\n\n");
        !          89715:                for ( sp = segdq.s_forw; sp != &segdq; sp = sp->s_forw )
        !          89716:                        showseg( sp, "" );
        !          89717:                putchar( A_FF );
        !          89718:        }
        !          89719: 
        !          89720:        printf("\nLocal Stack: sp=%x\n", (&ip1)-1 );
        !          89721:        FP_SEL(fp) = sds;
        !          89722:        FP_OFF(fp) = (char*)(&u) + 1022;
        !          89723:        do {
        !          89724:                printf("        %x: %x\n", FP_OFF(fp), ffword(fp) );
        !          89725:                FP_OFF(fp)  -= 2;
        !          89726:        } while ( FP_OFF(fp) >= (&ip1)-1 );
        !          89727:        putchar( A_FF );
        !          89728: 
        !          89729:        printf("\nUser Stack: ss:sp = %x:%x\n", regl[OSS], regl[OSP] );
        !          89730:        FP_SEL(gp) = gdtsel;
        !          89731:        FP_OFF(gp) = regl[OSS] & ~7;
        !          89732:        if ( ((regl[OSS]&7) == 0) && regl[OSS] && regl[OSP] && ffbyte(gp+5) ) {
        !          89733:                FP_SEL(fp) = regl[OSS];
        !          89734:                FP_OFF(fp) = regl[OSP] + 120;
        !          89735:                if ( FP_OFF(fp) > udl )
        !          89736:                        FP_OFF(fp) = udl & ~1;
        !          89737:                do {
        !          89738:                        printf("        %x: %x\n", FP_OFF(fp), ffword(fp) );
        !          89739:                        FP_OFF(fp)  -= 2;
        !          89740:                } while ( FP_OFF(fp) >= regl[OSP] );
        !          89741:        }
        !          89742:        putchar( A_FF );
        !          89743: 
        !          89744:        putchar( A_LF );
        !          89745:        spl( s );
        !          89746: }
        !          89747: 
        !          89748: static
        !          89749: showevq()
        !          89750: {
        !          89751:        register PROC * pp;
        !          89752:        register int i;
        !          89753: 
        !          89754:        printf("\nEvent Queues:\n");
        !          89755: 
        !          89756:        for ( i = 0; i < nel(linkq); i++ ) {
        !          89757: 
        !          89758:                if ( linkq[i].p_lforw == linkq[i].p_lback )
        !          89759:                        continue;
        !          89760: 
        !          89761:                pp = linkq[i].p_lforw;
        !          89762:                printf("%x:", i );
        !          89763: 
        !          89764:                do {
        !          89765:                        printf("\t%x: lforw=%x lback=%x pid=%d event=%x\n",
        !          89766:                                pp,
        !          89767:                                pp->p_lforw,
        !          89768:                                pp->p_lback,
        !          89769:                                pp->p_pid,
        !          89770:                                pp->p_event
        !          89771:                        );
        !          89772:                } while ((pp = pp->p_lforw) != (PROC *) &linkq[i] );
        !          89773:        }
        !          89774: }
        !          89775: 
        !          89776: static
        !          89777: showtim()
        !          89778: {
        !          89779:        register TIM * tp;
        !          89780:        register int i;
        !          89781: 
        !          89782:        printf("\nTiming Queues: lbolt=%lx\n", lbolt );
        !          89783: 
        !          89784:        for ( i = 0; i < nel(timq); i++ ) {
        !          89785: 
        !          89786:                if ( ! (tp = timq[i]) )
        !          89787:                        continue;
        !          89788: 
        !          89789:                printf("%x:", i );
        !          89790: 
        !          89791:                do {
        !          89792:                    printf("\t%x: next=%x last=%x func=%x farg=%x lbolt=%lx\n",
        !          89793:                        tp,
        !          89794:                        tp->t_next,
        !          89795:                        tp->t_last,
        !          89796:                        tp->t_func,
        !          89797:                        tp->t_farg,
        !          89798:                        tp->t_lbolt
        !          89799:                    );
        !          89800:                } while ( tp = tp->t_next );
        !          89801:        }
        !          89802: }
        !          89803: 
        !          89804: static
        !          89805: showproc( pp )
        !          89806: register PROC * pp;
        !          89807: {
        !          89808:        register int i;
        !          89809: 
        !          89810:        printf("\n%x:\tnforw=%x nback=%x pid=%d ppid=%d state=%x flags=%x\n",
        !          89811:                pp,
        !          89812:                pp->p_nforw,            /* Forward pointer */
        !          89813:                pp->p_nback,            /* Backward pointer */
        !          89814:                pp->p_pid,              /* Process id */
        !          89815:                pp->p_ppid,             /* Process id of parent */
        !          89816:                pp->p_state,
        !          89817:                pp->p_flags
        !          89818:        );
        !          89819: 
        !          89820:        if ( pp->p_polltim.t_last )
        !          89821:        printf("\tpolltim@%x: next=%x last=%x func=%x farg=%x lbolt=%lx\n",
        !          89822:                &pp->p_polltim,
        !          89823:                pp->p_polltim.t_next,
        !          89824:                pp->p_polltim.t_last,
        !          89825:                pp->p_polltim.t_func,
        !          89826:                pp->p_polltim.t_farg,
        !          89827:                pp->p_polltim.t_lbolt
        !          89828:        );
        !          89829: 
        !          89830:        if ( pp->p_alrmtim.t_last )
        !          89831:        printf("\talrmtim@%x: next=%x last=%x func=%x farg=%x lbolt=%lx\n",
        !          89832:                &pp->p_alrmtim,
        !          89833:                pp->p_alrmtim.t_next,
        !          89834:                pp->p_alrmtim.t_last,
        !          89835:                pp->p_alrmtim.t_func,
        !          89836:                pp->p_alrmtim.t_farg,
        !          89837:                pp->p_alrmtim.t_lbolt
        !          89838:        );
        !          89839: 
        !          89840:        for ( i = 0; i <= NUSEG; i++ ) {
        !          89841:        static char * nam[] = {  "UA", "SS", "SI", "PI", "SD",  "PD", "UX" };
        !          89842:                if ( pp->p_segp[i] ) {
        !          89843:                        printf("\n    %s: ", nam[i] );
        !          89844:                        showseg( pp->p_segp[i], "        " );
        !          89845:                }
        !          89846:        }
        !          89847: }
        !          89848: 
        !          89849: static
        !          89850: showseg( sp, prefix )
        !          89851: register SEG * sp;
        !          89852: char * prefix;
        !          89853: {
        !          89854:        printf("%x: forw=%x back=%x ip=%x flags=%x urefc=%d lrefc=%d\n",
        !          89855:                sp,
        !          89856:                sp->s_forw,             /* Forward pointer */
        !          89857:                sp->s_back,             /* Backward pointer */
        !          89858:                sp->s_ip,               /* Inode pointer for shared text */
        !          89859:                sp->s_flags,            /* Flags */
        !          89860:                sp->s_urefc,            /* Reference count of segment */
        !          89861:                sp->s_lrefc             /* Lock reference count */
        !          89862:        );
        !          89863: 
        !          89864:        printf( "%s    faddr=%X size=%X paddr=%X\n",
        !          89865:                prefix,
        !          89866:                sp->s_faddr,            /* Memory access selector */
        !          89867:                sp->s_size,             /* Size in bytes */
        !          89868:                sp->s_paddr             /* Physical base address */
        !          89869:        );
        !          89870: 
        !          89871:        printf("%s    ", prefix);
        !          89872:        vprint( sp->s_faddr );
        !          89873: }
        !          89874: 0707070064030147771004440000030000030000011777770507310714400005200000004442/newbits/kernel/USRSRC/i8086/ibm_at/md2.c/* $Header: /usr/src/sys/i8086/ibm_at/RCS/md2.c,v 1.1 88/03/24 17:33:38 src Exp $ */
        !          89875: /* (lgl-
        !          89876:  *     The information contained herein is a trade secret of Mark Williams
        !          89877:  *     Company, and  is confidential information.  It is provided  under a
        !          89878:  *     license agreement,  and may be  copied or disclosed  only under the
        !          89879:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          89880:  *     material without the express written authorization of Mark Williams
        !          89881:  *     Company or persuant to the license agreement is unlawful.
        !          89882:  *
        !          89883:  *     COHERENT Version 2.3.37
        !          89884:  *     Copyright (c) 1982, 1983, 1984.
        !          89885:  *     An unpublished work by Mark Williams Company, Chicago.
        !          89886:  *     All rights reserved.
        !          89887:  -lgl) */
        !          89888: /*
        !          89889:  * 8086/8088 Coherent.
        !          89890:  * IBM PC.
        !          89891:  *
        !          89892:  * $Log:       /usr/src/sys/i8086/ibm_at/RCS/md2.c,v $
        !          89893:  * Revision 1.1        88/03/24  17:33:38      src
        !          89894:  * Initial revision
        !          89895:  * 
        !          89896:  * 87/10/26    Allan Cornish           /usr/src/sys/i8086/ibm_at/md2.c
        !          89897:  * Clrivec() now properly resets the interrupt vector for intr 2 in slot 9.
        !          89898:  */
        !          89899: #include <sys/coherent.h>
        !          89900: #include <sys/i8086.h>
        !          89901: #include <sys/clist.h>
        !          89902: #include <errno.h>
        !          89903: #include <sys/inode.h>
        !          89904: #include <sys/proc.h>
        !          89905: #include <sys/seg.h>
        !          89906: #include <signal.h>
        !          89907: #include <sys/uproc.h>
        !          89908: 
        !          89909: int nirqslave;
        !          89910: /*
        !          89911:  * Set an interrupt vector.
        !          89912:  * Make an entry in the "vecs" table, for
        !          89913:  * use by the assist. Make sure that the channel
        !          89914:  * on the 8259 is armed.
        !          89915:  * Note that interrupt vectors 2 and 9 are mapped into channel 9.
        !          89916:  */
        !          89917: setivec(level, fun)
        !          89918: register int   level;
        !          89919: int            (*fun)();
        !          89920: {
        !          89921:        register int    picm;
        !          89922:        extern   int    (*vecs[])();
        !          89923:        extern   int    vret();
        !          89924: 
        !          89925:        if ((level &= 0x0F) == 2)
        !          89926:                level = 9;
        !          89927:        if (level==0 || vecs[level]!=&vret) {
        !          89928:                u.u_error = EDBUSY;
        !          89929:                return;
        !          89930:        }
        !          89931:        vecs[level] = fun;
        !          89932:        if ( level >= 8 ) {
        !          89933:                ++nirqslave;
        !          89934:                picm = inb(SPICM);
        !          89935:                picm &= ~(0x01 << (level-8));
        !          89936:                outb(SPICM, picm);
        !          89937:                level = 2;
        !          89938:        }
        !          89939:        picm = inb(PICM);
        !          89940:        picm &= ~(0x01 << level);
        !          89941:        outb(PICM, picm);
        !          89942: }
        !          89943: 
        !          89944: /*
        !          89945:  * Clear an interrupt vector.
        !          89946:  */
        !          89947: clrivec(level)
        !          89948: register int   level;
        !          89949: {
        !          89950:        register int    picm;
        !          89951:        extern   int    (*vecs[])();
        !          89952:        extern   int    vret();
        !          89953: 
        !          89954:        if ((level &= 0x0F) == 2)
        !          89955:                level = 9;
        !          89956:        if (level == 0)
        !          89957:                panic("clrivec: level=%d", level);
        !          89958:        vecs[level] = &vret;
        !          89959:        if (level >= 8) {
        !          89960:                --nirqslave;
        !          89961:                picm = inb(SPICM);
        !          89962:                picm |= (0x01 << (level-8));
        !          89963:                outb(SPICM, picm);
        !          89964:                level = 2;
        !          89965:        }
        !          89966:        if ((level != 2) || (nirqslave == 0)) {
        !          89967:                picm = inb(PICM);
        !          89968:                picm |= (0x01 << level);
        !          89969:                outb(PICM, picm);
        !          89970:        }
        !          89971: }
        !          89972: 0707070064030147761004440000030000030000011777770507310714400005200000016532/newbits/kernel/USRSRC/i8086/ibm_at/mmu.c/* $Header: /usr/src/sys/i8086/ibm_at/RCS/mmu.c,v 1.1 88/03/24 17:33:41 src Exp $
        !          89973:  *
        !          89974:  *     The  information  contained herein  is a trade secret  of INETCO
        !          89975:  *     Systems, and is confidential information.   It is provided under
        !          89976:  *     a license agreement,  and may be copied or disclosed  only under
        !          89977:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          89978:  *     this  material  without  the express  written  authorization  of
        !          89979:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          89980:  *
        !          89981:  *     Copyright (c) 1987
        !          89982:  *     An unpublished work by INETCO Systems, Ltd.
        !          89983:  *     All rights reserved.
        !          89984:  */
        !          89985: 
        !          89986: /*
        !          89987:  * Coherent.
        !          89988:  * Memory Management Unit.
        !          89989:  *
        !          89990:  * $Log:       /usr/src/sys/i8086/ibm_at/RCS/mmu.c,v $
        !          89991:  * Revision 1.1        88/03/24  17:33:41      src
        !          89992:  * Initial revision
        !          89993:  * 
        !          89994:  * 88/03/04    Allan Cornish   /usr/src/sys/i8086/ibm_at/mmu.c
        !          89995:  * Real-mode code ifdef'ed out [REAL_MODE].
        !          89996:  *
        !          89997:  * 88/02/16    Allan Cornish   /usr/src/sys/i8086/ibm_at/mmu.c
        !          89998:  * vtop() now incorporates offset from virtual address into physical address.
        !          89999:  *
        !          90000:  * 87/11/13    Allan Cornish   /usr/src/sys/i8086/ibm_at/mmu.c
        !          90001:  * Initial version.
        !          90002:  */
        !          90003: #include <sys/coherent.h>
        !          90004: #include <sys/seg.h>
        !          90005: #include <sys/mmu.h>
        !          90006: 
        !          90007: /**
        !          90008:  *
        !          90009:  * static faddr_t
        !          90010:  * gdtalloc()          -- search for empty global descriptor table entry
        !          90011:  */
        !          90012: static faddr_t
        !          90013: gdtalloc()
        !          90014: {
        !          90015:        register saddr_t sel;
        !          90016:        static saddr_t osel;
        !          90017:        faddr_t fp;
        !          90018:        int s;
        !          90019: 
        !          90020:        /*
        !          90021:         * Disable interrupts.
        !          90022:         */
        !          90023:        s = sphi();
        !          90024: 
        !          90025:        /*
        !          90026:         * Search for idle virtual selector.
        !          90027:         */
        !          90028:        for ( fp = 0, sel = osel + 8; sel != osel; sel += 8 ) {
        !          90029: 
        !          90030:                /*
        !          90031:                 * Selector 0 is NOT usable.
        !          90032:                 */
        !          90033:                if ( sel == 0 )
        !          90034:                        continue;
        !          90035: 
        !          90036:                /*
        !          90037:                 * Selector is available.
        !          90038:                 */
        !          90039:                if ( ffbyte( sel+5, gdtsel ) != 0 )
        !          90040:                        continue;
        !          90041: 
        !          90042:                /*
        !          90043:                 * Mark selector as being Descriptor[10].
        !          90044:                 */
        !          90045:                sfbyte( sel+5, gdtsel, 0x10 );
        !          90046: 
        !          90047:                /*
        !          90048:                 * Record selector for next search.
        !          90049:                 */
        !          90050:                osel = sel;
        !          90051: 
        !          90052:                FP_SEL(fp) = sel;
        !          90053:                break;
        !          90054:        }
        !          90055: 
        !          90056:        /*
        !          90057:         * Enable interrupts.
        !          90058:         */
        !          90059:        spl( s );
        !          90060: 
        !          90061:        return( fp );
        !          90062: }
        !          90063: 
        !          90064: /**
        !          90065:  *
        !          90066:  * void
        !          90067:  * vprint( fp )                        -- print virtual address information.
        !          90068:  * faddr_t fp;
        !          90069:  *
        !          90070:  *     Input:  fp = segment:offset pair for virtual address in question.
        !          90071:  *
        !          90072:  *     Action: Print information about virtual address.
        !          90073:  */
        !          90074: 
        !          90075: void
        !          90076: vprint( fp )
        !          90077: faddr_t fp;
        !          90078: {
        !          90079:        faddr_t gp;
        !          90080:        paddr_t paddr;
        !          90081: 
        !          90082: #if REAL_MODE > 0
        !          90083:        /*
        !          90084:         * Virtual Address Mode Disabled.
        !          90085:         */
        !          90086:        if ( gdtsel == 0 )
        !          90087:                return;
        !          90088: #endif
        !          90089: 
        !          90090:        /*
        !          90091:         * Create far pointer to appropriate gdt entry.
        !          90092:         */
        !          90093:        FP_SEL(gp) = gdtsel;
        !          90094:        FP_OFF(gp) = FP_SEL(fp) & ~7;
        !          90095: 
        !          90096:        FP_OFF(paddr) = ffword(gp+2);
        !          90097:        FP_SEL(paddr) = ffbyte(gp+4);
        !          90098: 
        !          90099:        /*
        !          90100:         * Print information about gdt entry.
        !          90101:         */
        !          90102:        printf("sel=%x paddr=%X lim=%x flags=%x\n",
        !          90103:                FP_OFF(gp), paddr, ffword(gp), ffbyte(gp+5) );
        !          90104: }
        !          90105: 
        !          90106: /**
        !          90107:  *
        !          90108:  * void
        !          90109:  * vremap( sp )                        -- (re)map segment virtual address
        !          90110:  * SEG * sp;
        !          90111:  *
        !          90112:  *     Input:  sp = pointer to segment structure to be (re)mapped.
        !          90113:  *
        !          90114:  *     Action: Update segment information.
        !          90115:  */
        !          90116: void
        !          90117: vremap( segp )
        !          90118: SEG * segp;
        !          90119: {
        !          90120:        register SEG * sp = segp;
        !          90121:        register int m;
        !          90122:        faddr_t gp;
        !          90123:        int s;
        !          90124: 
        !          90125: #if REAL_MODE > 0
        !          90126:        /*
        !          90127:         * Virtual Address Mode disabled.
        !          90128:         */
        !          90129:        if ( gdtsel == 0 ) {
        !          90130:                /*
        !          90131:                 * Calculate virtual address as shifted physical address.
        !          90132:                 */
        !          90133:                FP_SEL(sp->s_faddr) = sp->s_paddr >> 4;
        !          90134:                FP_OFF(sp->s_faddr) = sp->s_paddr & 15;
        !          90135:                return;
        !          90136:        }
        !          90137: #endif
        !          90138: 
        !          90139:        /*
        !          90140:         * Create far pointer to appropriate gdt entry.
        !          90141:         */
        !          90142:        FP_SEL(gp) = gdtsel;
        !          90143:        FP_OFF(gp) = FP_SEL(sp->s_faddr);
        !          90144: 
        !          90145:        /*
        !          90146:         * Allocate virtual selector if not already specified.
        !          90147:         */
        !          90148:        if ( FP_SEL(sp->s_faddr) == 0 )  {
        !          90149:                if ( (sp->s_faddr = gdtalloc()) == 0 )
        !          90150:                        panic( "vremap: out of gdt's\n" );
        !          90151:                FP_OFF(gp) = FP_SEL(sp->s_faddr);
        !          90152:        }
        !          90153: 
        !          90154:        /*
        !          90155:         * Ensure selector is valid gdt at privilege level 0.
        !          90156:         */
        !          90157:        if ( FP_SEL(sp->s_faddr) & 7 ) {
        !          90158:                panic("vremap( faddr=%X, ip=%x ) - not gdt at level 0\n",
        !          90159:                        sp->s_faddr, (&segp)[-1] );
        !          90160:        }
        !          90161: 
        !          90162:        /*
        !          90163:         * Verify selector is not free.
        !          90164:         */
        !          90165:        if ( ffbyte( gp+5 ) == 0 ) {
        !          90166:                panic("vremap( faddr=%X, ip=%x ) - selector is free\n",
        !          90167:                        sp->s_faddr, (&segp)[-1] );
        !          90168:        }
        !          90169: 
        !          90170:        /*
        !          90171:         * Disable interrupts.
        !          90172:         */
        !          90173:        s = sphi();
        !          90174: 
        !          90175:        /*
        !          90176:         * Set limit.
        !          90177:         */
        !          90178:        sfword( gp+0, (unsigned) (sp->s_size - 1) );
        !          90179: 
        !          90180:        /*
        !          90181:         * Set low word of base, high byte of base.
        !          90182:         */
        !          90183:        sfword( gp+2, FP_OFF(sp->s_paddr) );
        !          90184:        sfbyte( gp+4, FP_SEL(sp->s_paddr) );
        !          90185: 
        !          90186:        /*
        !          90187:         * Set access byte:
        !          90188:         *      Code = Present[80],Descriptor[10],Executable[08],Readable[02].
        !          90189:         *      Data = Present[80],Descriptor[10],               Writable[02].
        !          90190:         */
        !          90191:        m = 0x12;
        !          90192:        if ( sp->s_flags & SFCORE )
        !          90193:                m |= 0x80;
        !          90194:        if ( sp->s_flags & SFTEXT )
        !          90195:                m |= 0x08;
        !          90196:        sfbyte( gp+5, m );
        !          90197: 
        !          90198:        /*
        !          90199:         * Clear reserved word.
        !          90200:         */
        !          90201:        sfword( gp+6, 0 );
        !          90202: 
        !          90203:        /*
        !          90204:         * Enable interrupts.
        !          90205:         */
        !          90206:        spl(s);
        !          90207: }
        !          90208: 
        !          90209: /**
        !          90210:  *
        !          90211:  * faddr_t
        !          90212:  * ptov( paddr, n )            -- physical to virtual [address]
        !          90213:  * paddr_t paddr;
        !          90214:  * fsize_t n;
        !          90215:  *
        !          90216:  *     Input:  paddr = physical address.
        !          90217:  *             n = size in bytes.
        !          90218:  *
        !          90219:  *     Return: Corresponding segment:offset virtual address, or 0.
        !          90220:  *
        !          90221:  *     Notes:  Limited to 20 bit physical addresses.
        !          90222:  *             This routine is not functional in protected mode.
        !          90223:  */
        !          90224: 
        !          90225: faddr_t
        !          90226: ptov( paddr, n )
        !          90227: paddr_t paddr;
        !          90228: fsize_t n;
        !          90229: {
        !          90230:        faddr_t fp;
        !          90231:        faddr_t gp;
        !          90232:        int s;
        !          90233: 
        !          90234: #if REAL_MODE > 0
        !          90235:        /*
        !          90236:         * Virtual Address Mode Disabled.
        !          90237:         */
        !          90238:        if ( gdtsel == 0 )
        !          90239:                return( ((paddr >> 4) << 16) + (paddr % 16) );
        !          90240: #endif
        !          90241: 
        !          90242:        /*
        !          90243:         * Allocate virtual selector.
        !          90244:         */
        !          90245:        if ( (fp = gdtalloc()) == 0 )
        !          90246:                panic( "ptov:ip=%x: out of gdt's\n", ((char*) &paddr)[-1] );
        !          90247: 
        !          90248:        /*
        !          90249:         * Create far pointer to appropriate gdt entry.
        !          90250:         */
        !          90251:        FP_SEL(gp) = gdtsel;
        !          90252:        FP_OFF(gp) = FP_SEL(fp);
        !          90253: 
        !          90254:        /*
        !          90255:         * Disable interrupts.
        !          90256:         */
        !          90257:        s = sphi();
        !          90258: 
        !          90259:        /*
        !          90260:         * Set limit.
        !          90261:         */
        !          90262:        sfword( gp+0, (unsigned) (n - 1) );
        !          90263: 
        !          90264:        /*
        !          90265:         * Set low word of base, high byte of base.
        !          90266:         */
        !          90267:        sfword( gp+2, FP_OFF(paddr) );
        !          90268:        sfbyte( gp+4, FP_SEL(paddr) );
        !          90269: 
        !          90270:        /*
        !          90271:         * Set access byte: Present[80], Descriptor[10], Writable[02].
        !          90272:         */
        !          90273:        sfbyte( gp+5, 0x92 );
        !          90274: 
        !          90275:        /*
        !          90276:         * Clear reserved word.
        !          90277:         */
        !          90278:        sfword( gp+6, 0 );
        !          90279: 
        !          90280:        /*
        !          90281:         * Enable interrupts.
        !          90282:         */
        !          90283:        spl( s );
        !          90284: 
        !          90285:        /*
        !          90286:         * Return virtual address.
        !          90287:         */
        !          90288:        return( fp );
        !          90289: }
        !          90290: 
        !          90291: /**
        !          90292:  *
        !          90293:  * paddr_t
        !          90294:  * vtop( fp )                  -- virtual to physical [address]
        !          90295:  * faddr_t fp;
        !          90296:  *
        !          90297:  *     Input:  fp = segment:offset virtual address.
        !          90298:  *
        !          90299:  *     Return:  * = corresponding physical address.
        !          90300:  *             -1 = invalid virtual address.
        !          90301:  */
        !          90302: paddr_t
        !          90303: vtop( fp )
        !          90304: faddr_t fp;
        !          90305: {
        !          90306:        faddr_t gp;
        !          90307:        paddr_t paddr;
        !          90308: 
        !          90309: #if REAL_MODE > 0
        !          90310:        /*
        !          90311:         * Virtual Address Mode Disabled.
        !          90312:         */
        !          90313:        if ( gdtsel == 0 )
        !          90314:                return( (FP_SEL(fp) << 4L) + FP_OFF(fp) );
        !          90315: #endif
        !          90316: 
        !          90317:        /*
        !          90318:         * Convert virtual address to point to appropriate gdt entry.
        !          90319:         */
        !          90320:        FP_SEL(gp) = gdtsel;
        !          90321:        FP_OFF(gp) = FP_SEL(fp);
        !          90322: 
        !          90323:        /*
        !          90324:         * Validity check - Selector must be Present[80] and Descriptor[10].
        !          90325:         */
        !          90326:        if ( (ffbyte(gp+5) & 0x90) != 0x90 ) {
        !          90327:                panic( "vtop:ip=%x: sel %x invalid\n",
        !          90328:                        ((char **) &fp)[-1],
        !          90329:                        FP_SEL(fp) );
        !          90330:        }
        !          90331: 
        !          90332:        /*
        !          90333:         * Extract physical address from gdt entry.
        !          90334:         */
        !          90335:        FP_OFF(paddr) = ffword(gp+2);
        !          90336:        FP_SEL(paddr) = ffbyte(gp+4);
        !          90337: 
        !          90338:        /*
        !          90339:         * Adjust physical address by virtual address offset.
        !          90340:         */
        !          90341:        paddr += FP_OFF(fp);
        !          90342: 
        !          90343:        /*
        !          90344:         * Return physical address.
        !          90345:         */
        !          90346:        return( paddr );
        !          90347: }
        !          90348: 
        !          90349: /**
        !          90350:  *
        !          90351:  * void
        !          90352:  * vrelse( fp )                -- release virtual address
        !          90353:  * faddr_t fp;
        !          90354:  *
        !          90355:  */
        !          90356: 
        !          90357: void
        !          90358: vrelse( fp )
        !          90359: faddr_t fp;
        !          90360: {
        !          90361:        faddr_t gp;
        !          90362: 
        !          90363: #if REAL_MODE > 0
        !          90364:        /*
        !          90365:         * Virtual Address Mode Disabled.
        !          90366:         */
        !          90367:        if ( gdtsel == 0 )
        !          90368:                return;
        !          90369: #endif
        !          90370: 
        !          90371:        /*
        !          90372:         * Validity check.
        !          90373:         */
        !          90374:        if ( (FP_SEL(fp) == 0) || (FP_SEL(fp) & 7) )
        !          90375:                panic( "vrelse: sel %x invalid\n", FP_SEL(fp) );
        !          90376: 
        !          90377:        /*
        !          90378:         * Construct virtual address to point to appropriate gdt entry.
        !          90379:         */
        !          90380:        FP_SEL(gp) = gdtsel;
        !          90381:        FP_OFF(gp) = FP_SEL(fp);
        !          90382: 
        !          90383:        /*
        !          90384:         * Virtual selector already released, or not a segment descriptor.
        !          90385:         */
        !          90386:        if ( (ffbyte(gp+5) & 0x10) != 0x10 ) {
        !          90387:                panic( "vrelse:ip=%x: sel %x already released\n",
        !          90388:                        ((char **) &fp)[-1],
        !          90389:                        FP_SEL(fp) );
        !          90390:        }
        !          90391: 
        !          90392:        /*
        !          90393:         * Release virtual selector.
        !          90394:         */
        !          90395:        sfbyte( gp+5, 0 );
        !          90396: }
        !          90397: 0707070064030104510407550000030000030000011777770507310714600005000000000000/newbits/kernel/USRSRC/i8086/ibm_at/RCS0707070064030104421004440000030000030000011777770507310714600006100000011310/newbits/kernel/USRSRC/i8086/ibm_at/RCS/dmac.c,vhead     1.2;
        !          90398: branch   ;
        !          90399: access   ;
        !          90400: symbols  ;
        !          90401: locks    bin:1.2; strict;
        !          90402: comment  @ * @;
        !          90403: 
        !          90404: 
        !          90405: 1.2
        !          90406: date     91.06.20.14.41.41;  author bin;  state Exp;
        !          90407: branches ;
        !          90408: next     1.1;
        !          90409: 
        !          90410: 1.1
        !          90411: date     91.06.10.10.35.42;  author bin;  state Exp;
        !          90412: branches ;
        !          90413: next     ;
        !          90414: 
        !          90415: 
        !          90416: desc
        !          90417: @initial version prov by hal
        !          90418: @
        !          90419: 
        !          90420: 
        !          90421: 1.2
        !          90422: log
        !          90423: @update provided by hal
        !          90424: @
        !          90425: text
        !          90426: @/* $Header: /usr/src/sys/i8086/ibm_at/RCS/dmac.c,v 1.1 88/03/24 09:33:31 src Exp $ */
        !          90427: /* (lgl-
        !          90428:  *     The information contained herein is a trade secret of Mark Williams
        !          90429:  *     Company, and  is confidential information.  It is provided  under a
        !          90430:  *     license agreement,  and may be  copied or disclosed  only under the
        !          90431:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          90432:  *     material without the express written authorization of Mark Williams
        !          90433:  *     Company or persuant to the license agreement is unlawful.
        !          90434:  *
        !          90435:  *     COHERENT Version 2.3.37
        !          90436:  *     Copyright (c) 1982, 1983, 1984.
        !          90437:  *     An unpublished work by Mark Williams Company, Chicago.
        !          90438:  *     All rights reserved.
        !          90439:  -lgl) */
        !          90440: /*
        !          90441:  * The routines in this file
        !          90442:  * deal with the 8237 programmable
        !          90443:  * DMA controller on the system board.
        !          90444:  *
        !          90445:  * $Log:       /usr/src/sys/i8086/ibm_at/RCS/dmac.c,v $
        !          90446:  * Revision 1.1        88/03/24  09:33:31      src
        !          90447:  * Initial revision
        !          90448:  * 
        !          90449:  * 86/12/18    Allan Cornish           /usr/src/sys/i8086/ibm_at/dmac.c
        !          90450:  * Full support for DMA channels 5..7 added.
        !          90451:  */
        !          90452: #include       <sys/types.h>
        !          90453: #include       <sys/dmac.h>
        !          90454: 
        !          90455: /*
        !          90456:  * This table maps channel
        !          90457:  * numbers into DMA page address
        !          90458:  * register ports. The wiring of the
        !          90459:  * RA lines on the 74LS670 is a bit
        !          90460:  * strange.
        !          90461:  */
        !          90462: static int     dmaport[8] = {
        !          90463:        DMAPAGE+7,                      /* 0 (Free) */
        !          90464:        DMAPAGE+3,                      /* 1 (Free) */
        !          90465:        DMAPAGE+1,                      /* 2 (Floppy) */
        !          90466:        DMAPAGE+2,                      /* 3 (Free) */
        !          90467:        DMAPAGE+15,                     /* 4 (Cascade) */
        !          90468:        DMAPAGE+11,                     /* 5 */
        !          90469:        DMAPAGE+9,                      /* 6 */
        !          90470:        DMAPAGE+10                      /* 7 */
        !          90471: };
        !          90472: 
        !          90473: /*
        !          90474:  * Program the channel of the
        !          90475:  * 8237 DMA controller specified by
        !          90476:  * "chan". The "paddr" is a 20 bit
        !          90477:  * physical address. The "count" is
        !          90478:  * the byte count. The "wflag" is
        !          90479:  * true if this is a write, from the
        !          90480:  * point of view of the device.
        !          90481:  * True return if the mapping can be
        !          90482:  * set up, given the 64K limits.
        !          90483:  * The "count" is predecremented, so
        !          90484:  * that backplane "+T/C" is issued at
        !          90485:  * the expected point in time.
        !          90486:  */
        !          90487: dmaon(chan, paddr, count, wflag)
        !          90488: register int   chan;
        !          90489: paddr_t                paddr;
        !          90490: unsigned       count;
        !          90491: {
        !          90492:        register int    port;
        !          90493:        register int    s;
        !          90494: 
        !          90495:        /*
        !          90496:         * Change from 0 based transfer count to -1 based.
        !          90497:         */
        !          90498:        count--;
        !          90499: 
        !          90500:        /*
        !          90501:         * Select byte/word transfer.
        !          90502:         * Channels 0-4 use byte transfer.
        !          90503:         * Channels 5-7 use word transfers, with low 17 addr bits right shifted.
        !          90504:         */
        !          90505:        if ( chan >= 5 ) {
        !          90506:                count >>= 1;
        !          90507:                paddr >>= 1;
        !          90508:                paddr  += (paddr & 0xFF0000L);
        !          90509:        }
        !          90510: 
        !          90511:        /*
        !          90512:         * Check for DMA straddle.
        !          90513:         */
        !          90514:        if ( dmaseg(paddr) != dmaseg(paddr+count) )
        !          90515:                return (0);
        !          90516: 
        !          90517:        s = sphi();
        !          90518: 
        !          90519:        /*
        !          90520:         * Select DMA controller.
        !          90521:         */
        !          90522:        if ( chan < 4 ) {
        !          90523:                port = DMA;
        !          90524: 
        !          90525:                /*
        !          90526:                 * Program for dma read/write operation.
        !          90527:                 */
        !          90528:                if ( wflag != 0 )
        !          90529:                        outb( port + (SETMODE * 1), (chan & 3) | RDMEM );
        !          90530:                else
        !          90531:                        outb( port + (SETMODE * 1), (chan & 3) | WRMEM );
        !          90532:                outb( port + (CLEARFL * 1), 0 );
        !          90533:        }
        !          90534:        else {
        !          90535:                port = SDMA;
        !          90536: 
        !          90537:                /*
        !          90538:                 * Program for dma read/write operation.
        !          90539:                 */
        !          90540:                if ( wflag != 0 )
        !          90541:                        outb( SDMA + (SETMODE * 2), (chan & 3) | RDMEM );
        !          90542:                else
        !          90543:                        outb( SDMA + (SETMODE * 2), (chan & 3) | WRMEM );
        !          90544:                outb( SDMA + (CLEARFL * 2), 0 );
        !          90545:        }
        !          90546: 
        !          90547:        /*
        !          90548:         * Select memory bank.
        !          90549:         */
        !          90550:        outb( dmaport[chan], (int)(paddr >> 16) );
        !          90551: 
        !          90552:        if ( chan < 4 )
        !          90553:                port += ((chan & 3) << 1);
        !          90554:        else
        !          90555:                port += ((chan & 3) << 2);
        !          90556: 
        !          90557:        /*
        !          90558:         * Program memory offset in bank.
        !          90559:         */
        !          90560:        outb( port, ((int) paddr) >> 0 );
        !          90561:        outb( port, ((int) paddr) >> 8 );
        !          90562: 
        !          90563:        port++;
        !          90564:        if ( chan >= 4 )
        !          90565:                port++;
        !          90566: 
        !          90567:        /*
        !          90568:         * Program transfer count.
        !          90569:         */
        !          90570:        outb( port, count >> 0 );
        !          90571:        outb( port, count >> 8 );
        !          90572: 
        !          90573:        spl(s);
        !          90574:        return (1);
        !          90575: }
        !          90576: 
        !          90577: /*
        !          90578:  * dmago( chan ) - initiate dma transfer
        !          90579:  */
        !          90580: dmago( chan )
        !          90581: register int chan;
        !          90582: {
        !          90583:        /*
        !          90584:         * Enable dma transfers.
        !          90585:         */
        !          90586:        if ( chan < 4 )
        !          90587:                outb( DMA  + (SETMASK * 1), (chan & 3) | MASKOFF );
        !          90588:        else
        !          90589:                outb( SDMA + (SETMASK * 2), (chan & 3) | MASKOFF );
        !          90590: }
        !          90591: 
        !          90592: /*
        !          90593:  * dmaoff( chan ) - turn dma channel off, return residual count
        !          90594:  */
        !          90595: dmaoff( chan )
        !          90596: register int chan;
        !          90597: {
        !          90598:        register int port;
        !          90599:        register int count;
        !          90600:        int s;
        !          90601: 
        !          90602:        /*
        !          90603:         * Disable DMA transfers.
        !          90604:         * Obtain the -1 based residual count.
        !          90605:         */
        !          90606:        s = sphi();
        !          90607:        if ( chan < 4 ) {
        !          90608:                outb(  DMA + (SETMASK * 1), (chan & 3) | MASKON );
        !          90609:                port = DMA + ((chan & 3) << 1) + 1;
        !          90610:        }
        !          90611:        else {
        !          90612:                outb(  SDMA + (SETMASK * 2), (chan & 3) | MASKON );
        !          90613:                port = SDMA + ((chan & 3) << 2) + 2;
        !          90614:        }
        !          90615:        count  = inb(port);
        !          90616:        count += inb(port) << 8;
        !          90617:        spl( s );
        !          90618: 
        !          90619:        /*
        !          90620:         * Convert residual from -1 based to 0 based.
        !          90621:         */
        !          90622:        count++;
        !          90623: 
        !          90624:        /*
        !          90625:         * Convert residual from word based to byte based.
        !          90626:         */
        !          90627:        if ( chan >= 5 )
        !          90628:                count <<= 1;
        !          90629: 
        !          90630:        /*
        !          90631:         * Return residual count in bytes.
        !          90632:         */
        !          90633:        return count;
        !          90634: }
        !          90635: @
        !          90636: 
        !          90637: 
        !          90638: 1.1
        !          90639: log
        !          90640: @Initial revision
        !          90641: @
        !          90642: text
        !          90643: @d27 2
        !          90644: a28 2
        !          90645: #include       <types.h>
        !          90646: #include       <dmac.h>
        !          90647: @
        !          90648: 0707070064030104531004440000030000030000011777770507310714700006100000011775/newbits/kernel/USRSRC/i8086/ibm_at/RCS/dump.c,vhead     1.2;
        !          90649: branch   ;
        !          90650: access   ;
        !          90651: symbols  ;
        !          90652: locks    bin:1.2; strict;
        !          90653: comment  @ * @;
        !          90654: 
        !          90655: 
        !          90656: 1.2
        !          90657: date     91.06.20.14.41.52;  author bin;  state Exp;
        !          90658: branches ;
        !          90659: next     1.1;
        !          90660: 
        !          90661: 1.1
        !          90662: date     91.06.10.10.35.45;  author bin;  state Exp;
        !          90663: branches ;
        !          90664: next     ;
        !          90665: 
        !          90666: 
        !          90667: desc
        !          90668: @initial version prov by hal
        !          90669: @
        !          90670: 
        !          90671: 
        !          90672: 1.2
        !          90673: log
        !          90674: @update provided by hal
        !          90675: @
        !          90676: text
        !          90677: @/* $Header: /usr/src/sys/i8086/ibm_at/RCS/dump.c,v 1.1 88/03/24 17:33:35 src Exp $
        !          90678:  *
        !          90679:  * Function to dump Kernel data inforation.
        !          90680:  *
        !          90681:  * $Log:       /usr/src/sys/i8086/ibm_at/RCS/dump.c,v $
        !          90682:  * Revision 1.1        88/03/24  17:33:35      src
        !          90683:  * Initial revision
        !          90684:  * 
        !          90685:  */
        !          90686: #include <ascii.h>
        !          90687: #include <coherent.h>
        !          90688: #include <sys/i8086.h>
        !          90689: #include <sys/proc.h>
        !          90690: #include <sys/uproc.h>
        !          90691: #include <sys/seg.h>
        !          90692: 
        !          90693: int nodump = 1;
        !          90694: 
        !          90695: /*
        !          90696:  * Note: ip1 is a dummy parameter facilitating access to calling stack frame.
        !          90697:  */
        !          90698: dumpall( ip1 )
        !          90699: int ip1;
        !          90700: {
        !          90701:        register PROC * pp;
        !          90702:        register SEG  * sp;
        !          90703:        faddr_t gp;
        !          90704:        faddr_t fp;
        !          90705:        int s;
        !          90706:        extern saddr_t gdtsel;
        !          90707:        extern saddr_t uasa, ucs, uds, scs, sds;
        !          90708:        extern int nesterr;
        !          90709: 
        !          90710:        if ( nodump )
        !          90711:                return;
        !          90712: 
        !          90713:        s = sphi();
        !          90714: 
        !          90715:        printf("\nuasa=%x ucs=%x uds=%x scs=%x sds=%x nesterr=%u\n",
        !          90716:                uasa, ucs, uds, scs, sds, nesterr );
        !          90717: 
        !          90718: 
        !          90719:        printf("\nGlobal Descriptor Table:\n");
        !          90720:        FP_SEL(gp) = gdtsel;
        !          90721:        FP_OFF(gp) = 5; /* offset of flags byte */
        !          90722:        FP_SEL(fp) = 0;
        !          90723:        FP_OFF(fp) = 0;
        !          90724:        do {
        !          90725:                if ( ffbyte(gp) )
        !          90726:                        vprint(fp);
        !          90727:                FP_OFF(gp) += 8;
        !          90728:                FP_SEL(fp) += 8;
        !          90729:        } while ( FP_SEL(fp) != 0 );
        !          90730: 
        !          90731:        showevq();
        !          90732:        showtim();
        !          90733:        putchar( A_FF );
        !          90734:        
        !          90735:        printf("\nProcesses:\n");
        !          90736:        for ( pp = procq.p_nforw; pp != &procq; pp = pp->p_nforw )
        !          90737:                showproc( pp );
        !          90738:        putchar( A_FF );
        !          90739: 
        !          90740:        printf( "\nMemory Segments:\n\n" );
        !          90741:        for ( sp = segmq.s_forw; sp != &segmq; sp = sp->s_forw )
        !          90742:                showseg( sp, "" );
        !          90743:        putchar( A_FF );
        !          90744: 
        !          90745:        if ( segdq.s_forw != &segdq ) {
        !          90746:                printf( "\nDisk Segments:\n\n");
        !          90747:                for ( sp = segdq.s_forw; sp != &segdq; sp = sp->s_forw )
        !          90748:                        showseg( sp, "" );
        !          90749:                putchar( A_FF );
        !          90750:        }
        !          90751: 
        !          90752:        printf("\nLocal Stack: sp=%x\n", (&ip1)-1 );
        !          90753:        FP_SEL(fp) = sds;
        !          90754:        FP_OFF(fp) = (char*)(&u) + 1022;
        !          90755:        do {
        !          90756:                printf("        %x: %x\n", FP_OFF(fp), ffword(fp) );
        !          90757:                FP_OFF(fp)  -= 2;
        !          90758:        } while ( FP_OFF(fp) >= (&ip1)-1 );
        !          90759:        putchar( A_FF );
        !          90760: 
        !          90761:        printf("\nUser Stack: ss:sp = %x:%x\n", regl[OSS], regl[OSP] );
        !          90762:        FP_SEL(gp) = gdtsel;
        !          90763:        FP_OFF(gp) = regl[OSS] & ~7;
        !          90764:        if ( ((regl[OSS]&7) == 0) && regl[OSS] && regl[OSP] && ffbyte(gp+5) ) {
        !          90765:                FP_SEL(fp) = regl[OSS];
        !          90766:                FP_OFF(fp) = regl[OSP] + 120;
        !          90767:                if ( FP_OFF(fp) > udl )
        !          90768:                        FP_OFF(fp) = udl & ~1;
        !          90769:                do {
        !          90770:                        printf("        %x: %x\n", FP_OFF(fp), ffword(fp) );
        !          90771:                        FP_OFF(fp)  -= 2;
        !          90772:                } while ( FP_OFF(fp) >= regl[OSP] );
        !          90773:        }
        !          90774:        putchar( A_FF );
        !          90775: 
        !          90776:        putchar( A_LF );
        !          90777:        spl( s );
        !          90778: }
        !          90779: 
        !          90780: static
        !          90781: showevq()
        !          90782: {
        !          90783:        register PROC * pp;
        !          90784:        register int i;
        !          90785: 
        !          90786:        printf("\nEvent Queues:\n");
        !          90787: 
        !          90788:        for ( i = 0; i < nel(linkq); i++ ) {
        !          90789: 
        !          90790:                if ( linkq[i].p_lforw == linkq[i].p_lback )
        !          90791:                        continue;
        !          90792: 
        !          90793:                pp = linkq[i].p_lforw;
        !          90794:                printf("%x:", i );
        !          90795: 
        !          90796:                do {
        !          90797:                        printf("\t%x: lforw=%x lback=%x pid=%d event=%x\n",
        !          90798:                                pp,
        !          90799:                                pp->p_lforw,
        !          90800:                                pp->p_lback,
        !          90801:                                pp->p_pid,
        !          90802:                                pp->p_event
        !          90803:                        );
        !          90804:                } while ((pp = pp->p_lforw) != (PROC *) &linkq[i] );
        !          90805:        }
        !          90806: }
        !          90807: 
        !          90808: static
        !          90809: showtim()
        !          90810: {
        !          90811:        register TIM * tp;
        !          90812:        register int i;
        !          90813: 
        !          90814:        printf("\nTiming Queues: lbolt=%lx\n", lbolt );
        !          90815: 
        !          90816:        for ( i = 0; i < nel(timq); i++ ) {
        !          90817: 
        !          90818:                if ( ! (tp = timq[i]) )
        !          90819:                        continue;
        !          90820: 
        !          90821:                printf("%x:", i );
        !          90822: 
        !          90823:                do {
        !          90824:                    printf("\t%x: next=%x last=%x func=%x farg=%x lbolt=%lx\n",
        !          90825:                        tp,
        !          90826:                        tp->t_next,
        !          90827:                        tp->t_last,
        !          90828:                        tp->t_func,
        !          90829:                        tp->t_farg,
        !          90830:                        tp->t_lbolt
        !          90831:                    );
        !          90832:                } while ( tp = tp->t_next );
        !          90833:        }
        !          90834: }
        !          90835: 
        !          90836: static
        !          90837: showproc( pp )
        !          90838: register PROC * pp;
        !          90839: {
        !          90840:        register int i;
        !          90841: 
        !          90842:        printf("\n%x:\tnforw=%x nback=%x pid=%d ppid=%d state=%x flags=%x\n",
        !          90843:                pp,
        !          90844:                pp->p_nforw,            /* Forward pointer */
        !          90845:                pp->p_nback,            /* Backward pointer */
        !          90846:                pp->p_pid,              /* Process id */
        !          90847:                pp->p_ppid,             /* Process id of parent */
        !          90848:                pp->p_state,
        !          90849:                pp->p_flags
        !          90850:        );
        !          90851: 
        !          90852:        if ( pp->p_polltim.t_last )
        !          90853:        printf("\tpolltim@@%x: next=%x last=%x func=%x farg=%x lbolt=%lx\n",
        !          90854:                &pp->p_polltim,
        !          90855:                pp->p_polltim.t_next,
        !          90856:                pp->p_polltim.t_last,
        !          90857:                pp->p_polltim.t_func,
        !          90858:                pp->p_polltim.t_farg,
        !          90859:                pp->p_polltim.t_lbolt
        !          90860:        );
        !          90861: 
        !          90862:        if ( pp->p_alrmtim.t_last )
        !          90863:        printf("\talrmtim@@%x: next=%x last=%x func=%x farg=%x lbolt=%lx\n",
        !          90864:                &pp->p_alrmtim,
        !          90865:                pp->p_alrmtim.t_next,
        !          90866:                pp->p_alrmtim.t_last,
        !          90867:                pp->p_alrmtim.t_func,
        !          90868:                pp->p_alrmtim.t_farg,
        !          90869:                pp->p_alrmtim.t_lbolt
        !          90870:        );
        !          90871: 
        !          90872:        for ( i = 0; i <= NUSEG; i++ ) {
        !          90873:        static char * nam[] = {  "UA", "SS", "SI", "PI", "SD",  "PD", "UX" };
        !          90874:                if ( pp->p_segp[i] ) {
        !          90875:                        printf("\n    %s: ", nam[i] );
        !          90876:                        showseg( pp->p_segp[i], "        " );
        !          90877:                }
        !          90878:        }
        !          90879: }
        !          90880: 
        !          90881: static
        !          90882: showseg( sp, prefix )
        !          90883: register SEG * sp;
        !          90884: char * prefix;
        !          90885: {
        !          90886:        printf("%x: forw=%x back=%x ip=%x flags=%x urefc=%d lrefc=%d\n",
        !          90887:                sp,
        !          90888:                sp->s_forw,             /* Forward pointer */
        !          90889:                sp->s_back,             /* Backward pointer */
        !          90890:                sp->s_ip,               /* Inode pointer for shared text */
        !          90891:                sp->s_flags,            /* Flags */
        !          90892:                sp->s_urefc,            /* Reference count of segment */
        !          90893:                sp->s_lrefc             /* Lock reference count */
        !          90894:        );
        !          90895: 
        !          90896:        printf( "%s    faddr=%X size=%X paddr=%X\n",
        !          90897:                prefix,
        !          90898:                sp->s_faddr,            /* Memory access selector */
        !          90899:                sp->s_size,             /* Size in bytes */
        !          90900:                sp->s_paddr             /* Physical base address */
        !          90901:        );
        !          90902: 
        !          90903:        printf("%s    ", prefix);
        !          90904:        vprint( sp->s_faddr );
        !          90905: }
        !          90906: @
        !          90907: 
        !          90908: 
        !          90909: 1.1
        !          90910: log
        !          90911: @Initial revision
        !          90912: @
        !          90913: text
        !          90914: @@
        !          90915: 0707070064030147551004440000030000030000011777770507310715100006000000005500/newbits/kernel/USRSRC/i8086/ibm_at/RCS/md2.c,vhead     1.2;
        !          90916: branch   ;
        !          90917: access   ;
        !          90918: symbols  ;
        !          90919: locks    bin:1.2; strict;
        !          90920: comment  @ * @;
        !          90921: 
        !          90922: 
        !          90923: 1.2
        !          90924: date     91.06.20.14.41.58;  author bin;  state Exp;
        !          90925: branches ;
        !          90926: next     1.1;
        !          90927: 
        !          90928: 1.1
        !          90929: date     91.06.10.10.35.48;  author bin;  state Exp;
        !          90930: branches ;
        !          90931: next     ;
        !          90932: 
        !          90933: 
        !          90934: desc
        !          90935: @initial version prov by hal
        !          90936: @
        !          90937: 
        !          90938: 
        !          90939: 1.2
        !          90940: log
        !          90941: @update provided by hal
        !          90942: @
        !          90943: text
        !          90944: @/* $Header: /usr/src/sys/i8086/ibm_at/RCS/md2.c,v 1.1 88/03/24 17:33:38 src Exp $ */
        !          90945: /* (lgl-
        !          90946:  *     The information contained herein is a trade secret of Mark Williams
        !          90947:  *     Company, and  is confidential information.  It is provided  under a
        !          90948:  *     license agreement,  and may be  copied or disclosed  only under the
        !          90949:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          90950:  *     material without the express written authorization of Mark Williams
        !          90951:  *     Company or persuant to the license agreement is unlawful.
        !          90952:  *
        !          90953:  *     COHERENT Version 2.3.37
        !          90954:  *     Copyright (c) 1982, 1983, 1984.
        !          90955:  *     An unpublished work by Mark Williams Company, Chicago.
        !          90956:  *     All rights reserved.
        !          90957:  -lgl) */
        !          90958: /*
        !          90959:  * 8086/8088 Coherent.
        !          90960:  * IBM PC.
        !          90961:  *
        !          90962:  * $Log:       /usr/src/sys/i8086/ibm_at/RCS/md2.c,v $
        !          90963:  * Revision 1.1        88/03/24  17:33:38      src
        !          90964:  * Initial revision
        !          90965:  * 
        !          90966:  * 87/10/26    Allan Cornish           /usr/src/sys/i8086/ibm_at/md2.c
        !          90967:  * Clrivec() now properly resets the interrupt vector for intr 2 in slot 9.
        !          90968:  */
        !          90969: #include <sys/coherent.h>
        !          90970: #include <sys/i8086.h>
        !          90971: #include <sys/clist.h>
        !          90972: #include <errno.h>
        !          90973: #include <sys/inode.h>
        !          90974: #include <sys/proc.h>
        !          90975: #include <sys/seg.h>
        !          90976: #include <signal.h>
        !          90977: #include <sys/uproc.h>
        !          90978: 
        !          90979: int nirqslave;
        !          90980: /*
        !          90981:  * Set an interrupt vector.
        !          90982:  * Make an entry in the "vecs" table, for
        !          90983:  * use by the assist. Make sure that the channel
        !          90984:  * on the 8259 is armed.
        !          90985:  * Note that interrupt vectors 2 and 9 are mapped into channel 9.
        !          90986:  */
        !          90987: setivec(level, fun)
        !          90988: register int   level;
        !          90989: int            (*fun)();
        !          90990: {
        !          90991:        register int    picm;
        !          90992:        extern   int    (*vecs[])();
        !          90993:        extern   int    vret();
        !          90994: 
        !          90995:        if ((level &= 0x0F) == 2)
        !          90996:                level = 9;
        !          90997:        if (level==0 || vecs[level]!=&vret) {
        !          90998:                u.u_error = EDBUSY;
        !          90999:                return;
        !          91000:        }
        !          91001:        vecs[level] = fun;
        !          91002:        if ( level >= 8 ) {
        !          91003:                ++nirqslave;
        !          91004:                picm = inb(SPICM);
        !          91005:                picm &= ~(0x01 << (level-8));
        !          91006:                outb(SPICM, picm);
        !          91007:                level = 2;
        !          91008:        }
        !          91009:        picm = inb(PICM);
        !          91010:        picm &= ~(0x01 << level);
        !          91011:        outb(PICM, picm);
        !          91012: }
        !          91013: 
        !          91014: /*
        !          91015:  * Clear an interrupt vector.
        !          91016:  */
        !          91017: clrivec(level)
        !          91018: register int   level;
        !          91019: {
        !          91020:        register int    picm;
        !          91021:        extern   int    (*vecs[])();
        !          91022:        extern   int    vret();
        !          91023: 
        !          91024:        if ((level &= 0x0F) == 2)
        !          91025:                level = 9;
        !          91026:        if (level == 0)
        !          91027:                panic("clrivec: level=%d", level);
        !          91028:        vecs[level] = &vret;
        !          91029:        if (level >= 8) {
        !          91030:                --nirqslave;
        !          91031:                picm = inb(SPICM);
        !          91032:                picm |= (0x01 << (level-8));
        !          91033:                outb(SPICM, picm);
        !          91034:                level = 2;
        !          91035:        }
        !          91036:        if ((level != 2) || (nirqslave == 0)) {
        !          91037:                picm = inb(PICM);
        !          91038:                picm |= (0x01 << level);
        !          91039:                outb(PICM, picm);
        !          91040:        }
        !          91041: }
        !          91042: @
        !          91043: 
        !          91044: 
        !          91045: 1.1
        !          91046: log
        !          91047: @Initial revision
        !          91048: @
        !          91049: text
        !          91050: @d26 3
        !          91051: a28 3
        !          91052: #include <coherent.h>
        !          91053: #include <i8086.h>
        !          91054: #include <clist.h>
        !          91055: d30 3
        !          91056: a32 3
        !          91057: #include <inode.h>
        !          91058: #include <proc.h>
        !          91059: #include <seg.h>
        !          91060: d34 1
        !          91061: a34 1
        !          91062: #include <uproc.h>
        !          91063: @
        !          91064: 0707070064030104461004440000030000030000011777770507310715100006000000017361/newbits/kernel/USRSRC/i8086/ibm_at/RCS/mmu.c,vhead     1.2;
        !          91065: branch   ;
        !          91066: access   ;
        !          91067: symbols  ;
        !          91068: locks    bin:1.2; strict;
        !          91069: comment  @ * @;
        !          91070: 
        !          91071: 
        !          91072: 1.2
        !          91073: date     91.06.20.14.42.02;  author bin;  state Exp;
        !          91074: branches ;
        !          91075: next     1.1;
        !          91076: 
        !          91077: 1.1
        !          91078: date     91.06.10.10.35.54;  author bin;  state Exp;
        !          91079: branches ;
        !          91080: next     ;
        !          91081: 
        !          91082: 
        !          91083: desc
        !          91084: @initial version prov by hal
        !          91085: @
        !          91086: 
        !          91087: 
        !          91088: 1.2
        !          91089: log
        !          91090: @update provided by hal
        !          91091: @
        !          91092: text
        !          91093: @/* $Header: /usr/src/sys/i8086/ibm_at/RCS/mmu.c,v 1.1 88/03/24 17:33:41 src Exp $
        !          91094:  *
        !          91095:  *     The  information  contained herein  is a trade secret  of INETCO
        !          91096:  *     Systems, and is confidential information.   It is provided under
        !          91097:  *     a license agreement,  and may be copied or disclosed  only under
        !          91098:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          91099:  *     this  material  without  the express  written  authorization  of
        !          91100:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          91101:  *
        !          91102:  *     Copyright (c) 1987
        !          91103:  *     An unpublished work by INETCO Systems, Ltd.
        !          91104:  *     All rights reserved.
        !          91105:  */
        !          91106: 
        !          91107: /*
        !          91108:  * Coherent.
        !          91109:  * Memory Management Unit.
        !          91110:  *
        !          91111:  * $Log:       /usr/src/sys/i8086/ibm_at/RCS/mmu.c,v $
        !          91112:  * Revision 1.1        88/03/24  17:33:41      src
        !          91113:  * Initial revision
        !          91114:  * 
        !          91115:  * 88/03/04    Allan Cornish   /usr/src/sys/i8086/ibm_at/mmu.c
        !          91116:  * Real-mode code ifdef'ed out [REAL_MODE].
        !          91117:  *
        !          91118:  * 88/02/16    Allan Cornish   /usr/src/sys/i8086/ibm_at/mmu.c
        !          91119:  * vtop() now incorporates offset from virtual address into physical address.
        !          91120:  *
        !          91121:  * 87/11/13    Allan Cornish   /usr/src/sys/i8086/ibm_at/mmu.c
        !          91122:  * Initial version.
        !          91123:  */
        !          91124: #include <sys/coherent.h>
        !          91125: #include <sys/seg.h>
        !          91126: #include <sys/mmu.h>
        !          91127: 
        !          91128: /**
        !          91129:  *
        !          91130:  * static faddr_t
        !          91131:  * gdtalloc()          -- search for empty global descriptor table entry
        !          91132:  */
        !          91133: static faddr_t
        !          91134: gdtalloc()
        !          91135: {
        !          91136:        register saddr_t sel;
        !          91137:        static saddr_t osel;
        !          91138:        faddr_t fp;
        !          91139:        int s;
        !          91140: 
        !          91141:        /*
        !          91142:         * Disable interrupts.
        !          91143:         */
        !          91144:        s = sphi();
        !          91145: 
        !          91146:        /*
        !          91147:         * Search for idle virtual selector.
        !          91148:         */
        !          91149:        for ( fp = 0, sel = osel + 8; sel != osel; sel += 8 ) {
        !          91150: 
        !          91151:                /*
        !          91152:                 * Selector 0 is NOT usable.
        !          91153:                 */
        !          91154:                if ( sel == 0 )
        !          91155:                        continue;
        !          91156: 
        !          91157:                /*
        !          91158:                 * Selector is available.
        !          91159:                 */
        !          91160:                if ( ffbyte( sel+5, gdtsel ) != 0 )
        !          91161:                        continue;
        !          91162: 
        !          91163:                /*
        !          91164:                 * Mark selector as being Descriptor[10].
        !          91165:                 */
        !          91166:                sfbyte( sel+5, gdtsel, 0x10 );
        !          91167: 
        !          91168:                /*
        !          91169:                 * Record selector for next search.
        !          91170:                 */
        !          91171:                osel = sel;
        !          91172: 
        !          91173:                FP_SEL(fp) = sel;
        !          91174:                break;
        !          91175:        }
        !          91176: 
        !          91177:        /*
        !          91178:         * Enable interrupts.
        !          91179:         */
        !          91180:        spl( s );
        !          91181: 
        !          91182:        return( fp );
        !          91183: }
        !          91184: 
        !          91185: /**
        !          91186:  *
        !          91187:  * void
        !          91188:  * vprint( fp )                        -- print virtual address information.
        !          91189:  * faddr_t fp;
        !          91190:  *
        !          91191:  *     Input:  fp = segment:offset pair for virtual address in question.
        !          91192:  *
        !          91193:  *     Action: Print information about virtual address.
        !          91194:  */
        !          91195: 
        !          91196: void
        !          91197: vprint( fp )
        !          91198: faddr_t fp;
        !          91199: {
        !          91200:        faddr_t gp;
        !          91201:        paddr_t paddr;
        !          91202: 
        !          91203: #if REAL_MODE > 0
        !          91204:        /*
        !          91205:         * Virtual Address Mode Disabled.
        !          91206:         */
        !          91207:        if ( gdtsel == 0 )
        !          91208:                return;
        !          91209: #endif
        !          91210: 
        !          91211:        /*
        !          91212:         * Create far pointer to appropriate gdt entry.
        !          91213:         */
        !          91214:        FP_SEL(gp) = gdtsel;
        !          91215:        FP_OFF(gp) = FP_SEL(fp) & ~7;
        !          91216: 
        !          91217:        FP_OFF(paddr) = ffword(gp+2);
        !          91218:        FP_SEL(paddr) = ffbyte(gp+4);
        !          91219: 
        !          91220:        /*
        !          91221:         * Print information about gdt entry.
        !          91222:         */
        !          91223:        printf("sel=%x paddr=%X lim=%x flags=%x\n",
        !          91224:                FP_OFF(gp), paddr, ffword(gp), ffbyte(gp+5) );
        !          91225: }
        !          91226: 
        !          91227: /**
        !          91228:  *
        !          91229:  * void
        !          91230:  * vremap( sp )                        -- (re)map segment virtual address
        !          91231:  * SEG * sp;
        !          91232:  *
        !          91233:  *     Input:  sp = pointer to segment structure to be (re)mapped.
        !          91234:  *
        !          91235:  *     Action: Update segment information.
        !          91236:  */
        !          91237: void
        !          91238: vremap( segp )
        !          91239: SEG * segp;
        !          91240: {
        !          91241:        register SEG * sp = segp;
        !          91242:        register int m;
        !          91243:        faddr_t gp;
        !          91244:        int s;
        !          91245: 
        !          91246: #if REAL_MODE > 0
        !          91247:        /*
        !          91248:         * Virtual Address Mode disabled.
        !          91249:         */
        !          91250:        if ( gdtsel == 0 ) {
        !          91251:                /*
        !          91252:                 * Calculate virtual address as shifted physical address.
        !          91253:                 */
        !          91254:                FP_SEL(sp->s_faddr) = sp->s_paddr >> 4;
        !          91255:                FP_OFF(sp->s_faddr) = sp->s_paddr & 15;
        !          91256:                return;
        !          91257:        }
        !          91258: #endif
        !          91259: 
        !          91260:        /*
        !          91261:         * Create far pointer to appropriate gdt entry.
        !          91262:         */
        !          91263:        FP_SEL(gp) = gdtsel;
        !          91264:        FP_OFF(gp) = FP_SEL(sp->s_faddr);
        !          91265: 
        !          91266:        /*
        !          91267:         * Allocate virtual selector if not already specified.
        !          91268:         */
        !          91269:        if ( FP_SEL(sp->s_faddr) == 0 )  {
        !          91270:                if ( (sp->s_faddr = gdtalloc()) == 0 )
        !          91271:                        panic( "vremap: out of gdt's\n" );
        !          91272:                FP_OFF(gp) = FP_SEL(sp->s_faddr);
        !          91273:        }
        !          91274: 
        !          91275:        /*
        !          91276:         * Ensure selector is valid gdt at privilege level 0.
        !          91277:         */
        !          91278:        if ( FP_SEL(sp->s_faddr) & 7 ) {
        !          91279:                panic("vremap( faddr=%X, ip=%x ) - not gdt at level 0\n",
        !          91280:                        sp->s_faddr, (&segp)[-1] );
        !          91281:        }
        !          91282: 
        !          91283:        /*
        !          91284:         * Verify selector is not free.
        !          91285:         */
        !          91286:        if ( ffbyte( gp+5 ) == 0 ) {
        !          91287:                panic("vremap( faddr=%X, ip=%x ) - selector is free\n",
        !          91288:                        sp->s_faddr, (&segp)[-1] );
        !          91289:        }
        !          91290: 
        !          91291:        /*
        !          91292:         * Disable interrupts.
        !          91293:         */
        !          91294:        s = sphi();
        !          91295: 
        !          91296:        /*
        !          91297:         * Set limit.
        !          91298:         */
        !          91299:        sfword( gp+0, (unsigned) (sp->s_size - 1) );
        !          91300: 
        !          91301:        /*
        !          91302:         * Set low word of base, high byte of base.
        !          91303:         */
        !          91304:        sfword( gp+2, FP_OFF(sp->s_paddr) );
        !          91305:        sfbyte( gp+4, FP_SEL(sp->s_paddr) );
        !          91306: 
        !          91307:        /*
        !          91308:         * Set access byte:
        !          91309:         *      Code = Present[80],Descriptor[10],Executable[08],Readable[02].
        !          91310:         *      Data = Present[80],Descriptor[10],               Writable[02].
        !          91311:         */
        !          91312:        m = 0x12;
        !          91313:        if ( sp->s_flags & SFCORE )
        !          91314:                m |= 0x80;
        !          91315:        if ( sp->s_flags & SFTEXT )
        !          91316:                m |= 0x08;
        !          91317:        sfbyte( gp+5, m );
        !          91318: 
        !          91319:        /*
        !          91320:         * Clear reserved word.
        !          91321:         */
        !          91322:        sfword( gp+6, 0 );
        !          91323: 
        !          91324:        /*
        !          91325:         * Enable interrupts.
        !          91326:         */
        !          91327:        spl(s);
        !          91328: }
        !          91329: 
        !          91330: /**
        !          91331:  *
        !          91332:  * faddr_t
        !          91333:  * ptov( paddr, n )            -- physical to virtual [address]
        !          91334:  * paddr_t paddr;
        !          91335:  * fsize_t n;
        !          91336:  *
        !          91337:  *     Input:  paddr = physical address.
        !          91338:  *             n = size in bytes.
        !          91339:  *
        !          91340:  *     Return: Corresponding segment:offset virtual address, or 0.
        !          91341:  *
        !          91342:  *     Notes:  Limited to 20 bit physical addresses.
        !          91343:  *             This routine is not functional in protected mode.
        !          91344:  */
        !          91345: 
        !          91346: faddr_t
        !          91347: ptov( paddr, n )
        !          91348: paddr_t paddr;
        !          91349: fsize_t n;
        !          91350: {
        !          91351:        faddr_t fp;
        !          91352:        faddr_t gp;
        !          91353:        int s;
        !          91354: 
        !          91355: #if REAL_MODE > 0
        !          91356:        /*
        !          91357:         * Virtual Address Mode Disabled.
        !          91358:         */
        !          91359:        if ( gdtsel == 0 )
        !          91360:                return( ((paddr >> 4) << 16) + (paddr % 16) );
        !          91361: #endif
        !          91362: 
        !          91363:        /*
        !          91364:         * Allocate virtual selector.
        !          91365:         */
        !          91366:        if ( (fp = gdtalloc()) == 0 )
        !          91367:                panic( "ptov:ip=%x: out of gdt's\n", ((char*) &paddr)[-1] );
        !          91368: 
        !          91369:        /*
        !          91370:         * Create far pointer to appropriate gdt entry.
        !          91371:         */
        !          91372:        FP_SEL(gp) = gdtsel;
        !          91373:        FP_OFF(gp) = FP_SEL(fp);
        !          91374: 
        !          91375:        /*
        !          91376:         * Disable interrupts.
        !          91377:         */
        !          91378:        s = sphi();
        !          91379: 
        !          91380:        /*
        !          91381:         * Set limit.
        !          91382:         */
        !          91383:        sfword( gp+0, (unsigned) (n - 1) );
        !          91384: 
        !          91385:        /*
        !          91386:         * Set low word of base, high byte of base.
        !          91387:         */
        !          91388:        sfword( gp+2, FP_OFF(paddr) );
        !          91389:        sfbyte( gp+4, FP_SEL(paddr) );
        !          91390: 
        !          91391:        /*
        !          91392:         * Set access byte: Present[80], Descriptor[10], Writable[02].
        !          91393:         */
        !          91394:        sfbyte( gp+5, 0x92 );
        !          91395: 
        !          91396:        /*
        !          91397:         * Clear reserved word.
        !          91398:         */
        !          91399:        sfword( gp+6, 0 );
        !          91400: 
        !          91401:        /*
        !          91402:         * Enable interrupts.
        !          91403:         */
        !          91404:        spl( s );
        !          91405: 
        !          91406:        /*
        !          91407:         * Return virtual address.
        !          91408:         */
        !          91409:        return( fp );
        !          91410: }
        !          91411: 
        !          91412: /**
        !          91413:  *
        !          91414:  * paddr_t
        !          91415:  * vtop( fp )                  -- virtual to physical [address]
        !          91416:  * faddr_t fp;
        !          91417:  *
        !          91418:  *     Input:  fp = segment:offset virtual address.
        !          91419:  *
        !          91420:  *     Return:  * = corresponding physical address.
        !          91421:  *             -1 = invalid virtual address.
        !          91422:  */
        !          91423: paddr_t
        !          91424: vtop( fp )
        !          91425: faddr_t fp;
        !          91426: {
        !          91427:        faddr_t gp;
        !          91428:        paddr_t paddr;
        !          91429: 
        !          91430: #if REAL_MODE > 0
        !          91431:        /*
        !          91432:         * Virtual Address Mode Disabled.
        !          91433:         */
        !          91434:        if ( gdtsel == 0 )
        !          91435:                return( (FP_SEL(fp) << 4L) + FP_OFF(fp) );
        !          91436: #endif
        !          91437: 
        !          91438:        /*
        !          91439:         * Convert virtual address to point to appropriate gdt entry.
        !          91440:         */
        !          91441:        FP_SEL(gp) = gdtsel;
        !          91442:        FP_OFF(gp) = FP_SEL(fp);
        !          91443: 
        !          91444:        /*
        !          91445:         * Validity check - Selector must be Present[80] and Descriptor[10].
        !          91446:         */
        !          91447:        if ( (ffbyte(gp+5) & 0x90) != 0x90 ) {
        !          91448:                panic( "vtop:ip=%x: sel %x invalid\n",
        !          91449:                        ((char **) &fp)[-1],
        !          91450:                        FP_SEL(fp) );
        !          91451:        }
        !          91452: 
        !          91453:        /*
        !          91454:         * Extract physical address from gdt entry.
        !          91455:         */
        !          91456:        FP_OFF(paddr) = ffword(gp+2);
        !          91457:        FP_SEL(paddr) = ffbyte(gp+4);
        !          91458: 
        !          91459:        /*
        !          91460:         * Adjust physical address by virtual address offset.
        !          91461:         */
        !          91462:        paddr += FP_OFF(fp);
        !          91463: 
        !          91464:        /*
        !          91465:         * Return physical address.
        !          91466:         */
        !          91467:        return( paddr );
        !          91468: }
        !          91469: 
        !          91470: /**
        !          91471:  *
        !          91472:  * void
        !          91473:  * vrelse( fp )                -- release virtual address
        !          91474:  * faddr_t fp;
        !          91475:  *
        !          91476:  */
        !          91477: 
        !          91478: void
        !          91479: vrelse( fp )
        !          91480: faddr_t fp;
        !          91481: {
        !          91482:        faddr_t gp;
        !          91483: 
        !          91484: #if REAL_MODE > 0
        !          91485:        /*
        !          91486:         * Virtual Address Mode Disabled.
        !          91487:         */
        !          91488:        if ( gdtsel == 0 )
        !          91489:                return;
        !          91490: #endif
        !          91491: 
        !          91492:        /*
        !          91493:         * Validity check.
        !          91494:         */
        !          91495:        if ( (FP_SEL(fp) == 0) || (FP_SEL(fp) & 7) )
        !          91496:                panic( "vrelse: sel %x invalid\n", FP_SEL(fp) );
        !          91497: 
        !          91498:        /*
        !          91499:         * Construct virtual address to point to appropriate gdt entry.
        !          91500:         */
        !          91501:        FP_SEL(gp) = gdtsel;
        !          91502:        FP_OFF(gp) = FP_SEL(fp);
        !          91503: 
        !          91504:        /*
        !          91505:         * Virtual selector already released, or not a segment descriptor.
        !          91506:         */
        !          91507:        if ( (ffbyte(gp+5) & 0x10) != 0x10 ) {
        !          91508:                panic( "vrelse:ip=%x: sel %x already released\n",
        !          91509:                        ((char **) &fp)[-1],
        !          91510:                        FP_SEL(fp) );
        !          91511:        }
        !          91512: 
        !          91513:        /*
        !          91514:         * Release virtual selector.
        !          91515:         */
        !          91516:        sfbyte( gp+5, 0 );
        !          91517: }
        !          91518: @
        !          91519: 
        !          91520: 
        !          91521: 1.1
        !          91522: log
        !          91523: @Initial revision
        !          91524: @
        !          91525: text
        !          91526: @d32 1
        !          91527: a32 1
        !          91528: #include <coherent.h>
        !          91529: @
        !          91530: 0707070064030104441004440000030000030000011777770507310715400006000000076047/newbits/kernel/USRSRC/i8086/ibm_at/RCS/as2.s,vhead     1.2;
        !          91531: branch   ;
        !          91532: access   ;
        !          91533: symbols  ;
        !          91534: locks    ;
        !          91535: comment  @@;
        !          91536: 
        !          91537: 
        !          91538: 1.2
        !          91539: date     91.06.06.18.14.46;  author norm;  state Exp;
        !          91540: branches ;
        !          91541: next     1.1;
        !          91542: 
        !          91543: 1.1
        !          91544: date     91.06.06.18.13.16;  author hal;  state Exp;
        !          91545: branches ;
        !          91546: next     ;
        !          91547: 
        !          91548: 
        !          91549: desc
        !          91550: @Machine-dependent stuff.
        !          91551: @
        !          91552: 
        !          91553: 
        !          91554: 1.2
        !          91555: log
        !          91556: @Get memory size by reading CMOS.
        !          91557: @
        !          91558: text
        !          91559: @/ $Header: /usr/src/sys/i8086/ibm_at/RCS/as2.s,v 1.3 88/08/05 15:37:32 src Exp $
        !          91560: /
        !          91561: / (lgl-
        !          91562: /      The information contained herein is a trade secret of Mark Williams
        !          91563: /      Company, and  is confidential information.  It is provided  under a
        !          91564: /      license agreement,  and may be  copied or disclosed  only under the
        !          91565: /      terms of  that agreement.  Any  reproduction or disclosure  of this
        !          91566: /      material without the express written authorization of Mark Williams
        !          91567: /      Company or persuant to the license agreement is unlawful.
        !          91568: /
        !          91569: /      COHERENT Version 2.3.37
        !          91570: /      Copyright (c) 1982, 1983, 1984.
        !          91571: /      An unpublished work by Mark Williams Company, Chicago.
        !          91572: /      All rights reserved.
        !          91573: / -lgl)
        !          91574: ////////
        !          91575: /
        !          91576: / Machine language assist for
        !          91577: / Coherent on the IBM personal computer.
        !          91578: /
        !          91579: / $Log:        /usr/src/sys/i8086/ibm_at/RCS/as2.s,v $
        !          91580: / Revision 1.3 88/08/05  15:37:32      src
        !          91581: / AMD 286 hardware specific fixes removed - hardware now correct.
        !          91582: / Virtual Selector F000 initialized to access ROM at F0000.
        !          91583: / Normal kernel stack now used during initialization.
        !          91584: / 
        !          91585: / Revision 1.2 88/06/29  19:05:31      src
        !          91586: / AT Coherent can now come up in real-mode by patching 'realmode' variable.
        !          91587: / 
        !          91588: / Revision 1.1 88/03/24  17:33:18      src
        !          91589: / Initial revision
        !          91590: / 
        !          91591: / 88/03/10     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          91592: / Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !          91593: / These partial fixes will be removed once all CPU's are replaced.
        !          91594: /
        !          91595: / 88/03/07     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          91596: / Obsolete video() function deleted - not used, or usable in protected mode.
        !          91597: / Auto-increment mode no longer assumed, but enforced on block moves.
        !          91598: /
        !          91599: / 88/03/04     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          91600: / Memory sizing now flushes instruction pipeline before read-verify.
        !          91601: / Otherwise bus capacitance on some machines gives invalid memory indication.
        !          91602: / plrcopy, prlcopy, pclear, upcopy, kpcopy, pucopy, and pkcopy now ensure
        !          91603: / registers DS and ES refer to kernel data before calling ptov() or vrelse().
        !          91604: / MAXMEM variable added to specify maximum low memory in clicks.
        !          91605: /
        !          91606: / 87/11/22     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          91607: / Added check for extended memory in protected mode.
        !          91608: /
        !          91609: / 87/11/14     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          91610: / boot() now requests 8042 controller to initiate processor reset.
        !          91611: /
        !          91612: / 87/11/05     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          91613: / slrcopy/srlcopy/sclear renamed plrcopy/prlcopy/pclear and moved here.
        !          91614: /
        !          91615: / 87/10/27     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          91616: / System stack/data segments now setup here rather than in as1.s
        !          91617: / System stack/data moved to next 128 byte boundary for protected mode.
        !          91618: /
        !          91619: / 87/08/31     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          91620: / Timer channel 1 now reprogrammed for memory refresh.
        !          91621: /
        !          91622: / 87/07/08     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !          91623: / Timer chip now programmed for 100 hz clock interrupt rather than 20 hz.
        !          91624: /
        !          91625: ////////
        !          91626: 
        !          91627: EFAULT =       14                      / Bad argument
        !          91628: EXTMEML =      0x17                    / Ext. mem size (low) offset in CMOS
        !          91629: EXTMEMH =      0x18                    /               (high)
        !          91630: PFLAGS =       0x22                    / Offset int PROC.
        !          91631: PFKERN =       0x80                    / Kernel process flag bit.
        !          91632: PIC    =       0x20                    / 8259 CSR  I/O port.
        !          91633: PICM   =       0x21                    / 8259 IMR  I/O port.
        !          91634: PIT    =       0x40                    / 8253 base I/O port.
        !          91635: KBDATA =       0x60                    / 8042 keyboard mpu data I/O port.
        !          91636: KBCTRL =       0x64                    / 8042 keyboard mpu ctrl I/O port.
        !          91637: CMOSA  =       0x70                    / Real-time Clock/CMOS addr I/O port.
        !          91638: CMOSD  =       0x71                    / Real-time Clock/CMOS data I/O port.
        !          91639: SPIC   =       0xA0                    / Slave 8259 CSR I/O port.
        !          91640: SPICM  =       0xA1                    / Slave 8259 IMR I/O port.
        !          91641: UPASIZE        =       1024                    / Size of uproc and stack
        !          91642: 
        !          91643: ////////
        !          91644: /
        !          91645: / System entry point. Under PC-DOS,
        !          91646: / which thinks that Coherent is just a large
        !          91647: / user program, the code is offset by 0x100
        !          91648: / to allow space for the base page.
        !          91649: /
        !          91650: ////////
        !          91651: 
        !          91652:        .blkb   0x0100                  / PC-DOS base page.
        !          91653:        cli                             / No interrupts, please.
        !          91654: 
        !          91655:        int     0x11                    / Obtain int 11 value before printf().
        !          91656:        mov     cs:val11, ax            / Use boot block's stack for last time.
        !          91657: 
        !          91658: /
        !          91659: / Enable the A20 address line, which is normally disabled by the ROM BIOS.
        !          91660: / This line is under the control of the 8042 keyboard interface controller.
        !          91661: /
        !          91662:        sub     cx, cx                  /
        !          91663: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !          91664:        testb   al, $2                  /
        !          91665:        loopne  0b                      /
        !          91666:        jmp     .+2             / DELAY /
        !          91667:                                        /
        !          91668:        movb    al, $0xD1               / Request next output byte to be
        !          91669:        outb    KBCTRL, al              /       sent to the 8042 output port.
        !          91670:                                        /
        !          91671:        sub     cx, cx                  /
        !          91672: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !          91673:        testb   al, $2                  /
        !          91674:        loopne  0b                      /
        !          91675:        jmp     .+2             / DELAY /
        !          91676:                                        /
        !          91677:        movb    al, $0xDF               / Enable A20 address line.
        !          91678:        outb    KBDATA, al              / See Page 1-44, IBM-AT Tech Ref.
        !          91679:                                        /
        !          91680:        sub     cx, cx                  /
        !          91681: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !          91682:        testb   al, $2                  / NOTE: A20 not enabled for up to 20 us.
        !          91683:        loopne  0b                      /
        !          91684: 
        !          91685: /
        !          91686: / Reprogram the 8253 timer so that channel 0, 
        !          91687: / which is used as the clock, interrupts at exactly
        !          91688: / 100 HZ, instead of 18.2 HZ.
        !          91689: /
        !          91690:        movb    al, $0x36               / Timer 0, LSB, MSB, mode 3
        !          91691:        outb    PIT+3, al
        !          91692:        jmp     .+2             / DELAY /
        !          91693:        jmp     .+2             / DELAY /
        !          91694:        movb    al, $0x9C               / Lsb of 59659/5 = 11932
        !          91695:        outb    PIT, al
        !          91696:        jmp     .+2             / DELAY /
        !          91697:        jmp     .+2             / DELAY /
        !          91698:        movb    al, $0x2E               / Msb of 59659/5 = 11932
        !          91699:        outb    PIT, al
        !          91700:        jmp     .+2             / DELAY /
        !          91701:        jmp     .+2             / DELAY /
        !          91702: 
        !          91703: / Reprogram channel 1 on the 8253 timer which is used for memory refresh.
        !          91704: /      movb    al, $0x54               / Timer 1, LSB, mode 2
        !          91705: /      outb    PIT+3, al
        !          91706: /      jmp     .+2             / DELAY /
        !          91707: /      jmp     .+2             / DELAY /
        !          91708: /      movb    al, $18                 / LSB of 18.
        !          91709: /      outb    PIT+1, al
        !          91710: /      jmp     .+2             / DELAY /
        !          91711: /      jmp     .+2             / DELAY /
        !          91712: 
        !          91713: / Reprogram the 1st programmable interrupt controller.
        !          91714: / It's default vector table collides with iAPX 286 protection vectors.
        !          91715: 
        !          91716:        movb    al, $0x11               / ICW1 - edge, master, ICW4
        !          91717:        outb    PIC, al
        !          91718:        jmp     .+2             / DELAY /
        !          91719:        jmp     .+2             / DELAY /
        !          91720:        movb    al, $0x20               / ICW2 - Reserve 1st 32 vectors for 286
        !          91721:        outb    PICM, al
        !          91722:        jmp     .+2             / DELAY /
        !          91723:        jmp     .+2             / DELAY /
        !          91724:        movb    al, $0x04               / ICW3 - master level 2
        !          91725:        outb    PICM, al
        !          91726:        jmp     .+2             / DELAY /
        !          91727:        jmp     .+2             / DELAY /
        !          91728:        movb    al, $0x01               / ICW4 - 8086 mode, master.
        !          91729:        outb    PICM, al
        !          91730:        jmp     .+2             / DELAY /
        !          91731:        jmp     .+2             / DELAY /
        !          91732:        movb    al, $0xFE               / Disable interrupts from master PIC.
        !          91733:        outb    PICM, al                / (except for clock interrupt).
        !          91734: 
        !          91735:        movb    al, $0xFF
        !          91736:        outb    SPICM, al               / Disable interrupts from slave PIC.
        !          91737: 
        !          91738: / Set up all trap vectors.
        !          91739: / The machine traps all have their own
        !          91740: / linkages. We have to steal the clock from
        !          91741: / the ROM, because the stacks might get switched
        !          91742: / during the INT 1C, and the EOI would get sent
        !          91743: / to the 8259 at a strange time.
        !          91744: 
        !          91745:        sub     ax, ax                  / Map DS over the 8088
        !          91746:        mov     ds, ax                  / vector area.
        !          91747: 
        !          91748:        mov     0x0000, $trap0          / Divide error vector
        !          91749:        mov     0x0002, cs
        !          91750:        mov     0x0004, $trap1          / Single step.
        !          91751:        mov     0x0006, cs
        !          91752:        mov     0x0008, $trap2          / NMI
        !          91753:        mov     0x000A, cs
        !          91754:        mov     0x000C, $trap3          / INT 3 (break)
        !          91755:        mov     0x000E, cs
        !          91756:        mov     0x0010, $trap4          / Overflow.
        !          91757:        mov     0x0012, cs
        !          91758:        mov     0x0014, $trap5          / Bound range exceeded.
        !          91759:        mov     0x0016, cs
        !          91760:        mov     0x0018, $trap6          / Invalid Opcode
        !          91761:        mov     0x001A, cs
        !          91762:        mov     0x001C, $trap7          / Processor extension not available
        !          91763:        mov     0x001E, cs
        !          91764:        mov     0x0020, $trap8          / Double exception detected.
        !          91765:        mov     0x0022, cs
        !          91766:        mov     0x0024, $trap9          / Processor extension segment overrun.
        !          91767:        mov     0x0026, cs
        !          91768:        mov     0x0028, $trap10         / Invalid task state segment.
        !          91769:        mov     0x002A, cs
        !          91770:        mov     0x002C, $trap11         / Segment not present.
        !          91771:        mov     0x002E, cs
        !          91772:        mov     0x0030, $trap12         / Stack segment overrun or not present.
        !          91773:        mov     0x0032, cs
        !          91774:        mov     0x0034, $trap13         / General protection.
        !          91775:        mov     0x0036, cs
        !          91776: 
        !          91777:        mov     0x0080, $clk            / Clock.
        !          91778:        mov     0x0082, cs
        !          91779:        mov     0x0084, $dev1           / Device 1
        !          91780:        mov     0x0086, cs
        !          91781:        mov     0x0088, $dev9           / Device 2 maps into Device 9
        !          91782:        mov     0x008A, cs
        !          91783:        mov     0x008C, $dev3           / Device 3
        !          91784:        mov     0x008E, cs
        !          91785:        mov     0x0090, $dev4           / Device 4
        !          91786:        mov     0x0092, cs
        !          91787:        mov     0x0094, $dev5           / Device 5
        !          91788:        mov     0x0096, cs
        !          91789:        mov     0x0098, $dev6           / Device 6
        !          91790:        mov     0x009A, cs
        !          91791:        mov     0x009C, $dev7           / Device 7
        !          91792:        mov     0x009E, cs
        !          91793: 
        !          91794:        mov     0x01C0, $dev8           / Device 8
        !          91795:        mov     0x01C2, cs
        !          91796:        mov     0x01C4, $dev9           / Device 9
        !          91797:        mov     0x01C6, cs
        !          91798:        mov     0x01C8, $dev10          / Device 10
        !          91799:        mov     0x01CA, cs
        !          91800:        mov     0x01CC, $dev11          / Device 11
        !          91801:        mov     0x01CE, cs
        !          91802:        mov     0x01D0, $dev12          / Device 12
        !          91803:        mov     0x01D2, cs
        !          91804:        mov     0x01D4, $dev13          / Device 13
        !          91805:        mov     0x01D6, cs
        !          91806:        mov     0x01D8, $dev14          / Device 14
        !          91807:        mov     0x01DA, cs
        !          91808:        mov     0x01DC, $dev15          / Device 15
        !          91809:        mov     0x01DE, cs
        !          91810: 
        !          91811:        mov     bx, $0x0200             / INT 80 (sys 0)
        !          91812: 0:     mov     (bx), $syc              / Set up the system call
        !          91813:        mov     2(bx), cs               / trap vector.
        !          91814:        add     bx, $4                  / Move to next vector and
        !          91815:        cmp     bx, $0x0400             / loop until all
        !          91816:        jb      0b                      / vectors are reset.
        !          91817: 
        !          91818: / Set up the system stack and data segments, by looking at the size of
        !          91819: / the text and adding this to the base address already in the CS.
        !          91820: / Relocate the stack and data to a 128 byte boundary.
        !          91821: 
        !          91822:        mov     ax, $etext_+15          / End of text segment
        !          91823:        shr     ax, $4                  / Convert to paragraphs.
        !          91824:        mov     cx, cs                  / Get code segment base.
        !          91825:        add     ax, cx                  /
        !          91826:        mov     ds, ax                  / Current data segment
        !          91827:        add     ax, $31                 / Allow virtual-physical alignment
        !          91828:        and     ax, $~31                /       [use 512 byte, need 128 byte]
        !          91829:                                        /
        !          91830:        cmp     realmode_, $0           / Virtual Addressing enabled?
        !          91831:        jne     0f                      /
        !          91832:        mov     idtsel_, ax             / Interrupt descriptor table [2 Kbytes]
        !          91833:        add     ax, $0x0080             /       2K >> 4
        !          91834:        mov     gdtsel_, ax             / Global descriptor table [64 Kbytes]
        !          91835:        add     ax, $0x1000             /       64K >> 4
        !          91836: 0:                                     /
        !          91837:        mov     es, ax                  /
        !          91838:        mov     si, $edata_-1           / Copy data to new location, backwards.
        !          91839:        mov     di, $edata_-1           /
        !          91840:        mov     cx, $edata_             /
        !          91841:        std                             /
        !          91842:        rep                             /
        !          91843:        movsb                           /
        !          91844:                                        /
        !          91845:        mov     ds, ax                  / Update data segment,
        !          91846:        mov     ss, ax                  / and stack segment.
        !          91847:        mov     sp, $u_+UPASIZE-32      / Set up initial stack.
        !          91848:        mov     scs_, cs                / Save code segment and
        !          91849:        mov     sds_, ds                / data segment bases.
        !          91850:        mov     cs:cds, ds              / For interrupts.
        !          91851: 
        !          91852: / Size up memory, starting just above the system.
        !          91853: / The memory is cleared, because somebody has to do a write
        !          91854: / to set up the parity bits.
        !          91855: 
        !          91856:        mov     di, $edata_             / Clear at edata...
        !          91857:        mov     cx, $512                / for 1 Kbyte
        !          91858:        sub     ax, ax
        !          91859:        cld
        !          91860:        rep
        !          91861:        stosw
        !          91862: 
        !          91863:        mov     bp, $edata_+1023        / Compute base.
        !          91864:        shr     bp, $4
        !          91865:        add     bp, sds_
        !          91866:        shr     bp, $6                  / Round down to a Kbyte boundary
        !          91867:        shl     bp, $6                  / so's we're in sync.
        !          91868: 
        !          91869: 0:     sub     di, di                  / Destination.
        !          91870:        mov     es, bp                  / Set extra segment and
        !          91871:        mov     es:(di), ax             / clear a word.
        !          91872:        jmp     .+2             / FLUSH /
        !          91873:        cmp     es:(di), ax             / Should be zero now.
        !          91874:        jne     0f                      / Branch if memory end
        !          91875: 
        !          91876:        mov     cx, $512                / 1K bytes, in words.
        !          91877:        cld
        !          91878:        rep
        !          91879:        stosw                           / Clear this 1K
        !          91880:        add     bp, $64                 / Move along by 1K
        !          91881:        cmp     bp, MAXMEM
        !          91882:        jb      0b                      / If not at video ram yet
        !          91883: 
        !          91884: 0:     mov     es, sds_                / Map extra.
        !          91885: 
        !          91886:        mov     ax, bp                  / Calculate top of low memory.
        !          91887:        rol     ax, $4                  /
        !          91888:        mov     dx, ax                  /
        !          91889:        and     ax, $0xFFF0             /
        !          91890:        xor     dx, ax                  /
        !          91891: 
        !          91892:        cmp     realmode_, $0           / Real Addressing Mode?
        !          91893:        je      0f                      /
        !          91894:        mov     coretop_, ax            / Yes, Record top of memory,
        !          91895:        mov     coretop_+2, dx          /
        !          91896:        jmp     start                   / and bring up system.
        !          91897: 0:
        !          91898:        mov     holebot_, ax            / Record bottom of I/O memory.
        !          91899:        mov     holebot_+2, dx          /
        !          91900: 
        !          91901:        mov     ax, gdtsel_             / Format global descriptor table map.
        !          91902:        rol     ax, $4                  /
        !          91903:        mov     dx, ax                  /
        !          91904:        and     ax, $0xFFF0             /
        !          91905:        xor     dx, ax                  /
        !          91906:        mov     gdtmap_+0, $0xFFFF      / Limit: 64K bytes.
        !          91907:        mov     gdtmap_+2, ax           /
        !          91908:        mov     gdtmap_+4, dx           /
        !          91909:                                        /
        !          91910:        sub     ax, ax                  / Erase global descriptor table.
        !          91911:        mov     cx, $0x8000             /       [32K words = 64K bytes]
        !          91912:        mov     es, gdtsel_             /
        !          91913:        sub     di, di                  /
        !          91914:        cld                             /
        !          91915:        rep                             /
        !          91916:        stosw                           /
        !          91917:                                        /
        !          91918:        mov     ax, idtsel_             / Format interrupt descriptor table map
        !          91919:        rol     ax, $4                  /
        !          91920:        mov     dx, ax                  /
        !          91921:        and     ax, $0xFFF0             /
        !          91922:        xor     dx, ax                  /
        !          91923:        mov     idtmap_+0, $2047        / Limit: 2K bytes.
        !          91924:        mov     idtmap_+2, ax           /
        !          91925:        mov     idtmap_+4, dx           /
        !          91926:                                        /
        !          91927:        sub     ax, ax                  / Erase interrupt descriptor table.
        !          91928:        mov     cx, $1024               /       [1K words = 2K bytes]
        !          91929:        mov     es, idtsel_             /
        !          91930:        sub     di, di                  /
        !          91931:        cld                             /
        !          91932:        rep                             /
        !          91933:        stosw                           /
        !          91934:                                        /
        !          91935:        mov     es, gdtsel_             /
        !          91936:        mov     di, cs                  / Define kernel code global selector.
        !          91937:        mov     ax, $etext_-1           /       Limit: etext.
        !          91938:        stosw                           /
        !          91939:        mov     dx, $0x9A00             /       Flags: Present, executable.
        !          91940:        mov     ax, cs                  /       Base:  cs << 4.
        !          91941:        rol     ax, $4                  /
        !          91942:        xor     dx, ax                  /
        !          91943:        and     ax, $0xFFF0             /
        !          91944:        stosw                           /
        !          91945:        xor     ax, dx                  /
        !          91946:        stosw                           /
        !          91947:        sub     ax, ax                  /
        !          91948:        stosw                           /
        !          91949:                                        /
        !          91950:        mov     di, ss                  / Define kernel data global selector.
        !          91951:        mov     ax, $0xFFFF             /       Limit: 64K bytes.
        !          91952:        stosw                           /
        !          91953:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          91954:        mov     ax, ss                  /       Base:  ss << 4.
        !          91955:        rol     ax, $4                  /
        !          91956:        xor     dx, ax                  /
        !          91957:        and     ax, $0xFFF0             /
        !          91958:        stosw                           /
        !          91959:        xor     ax, dx                  /
        !          91960:        stosw                           /
        !          91961:        sub     ax, ax                  /
        !          91962:        stosw                           /
        !          91963:                                        /
        !          91964:        mov     di, $8                  / Define task state segment selector[8]
        !          91965:        mov     ax, $43                 /       Limit: 44 bytes.
        !          91966:        stosw                           /
        !          91967:        mov     dx, $0x8100             /       Flags: Present, avail tss seg.
        !          91968:        mov     ax, ss                  /       Base:  (ss << 4) + &tss.
        !          91969:        rol     ax, $4                  /
        !          91970:        xor     dx, ax                  /
        !          91971:        and     ax, $0xFFF0             /
        !          91972:        xor     dx, ax                  /
        !          91973:        add     ax, $tss_               /
        !          91974:        adc     dx, $0                  /
        !          91975:        stosw                           /
        !          91976:        mov     ax, dx                  /
        !          91977:        stosw                           /
        !          91978:        sub     ax, ax                  /
        !          91979:        stosw                           /
        !          91980:                                        /
        !          91981:        mov     di, gdtsel_             / Define gdt access global selector.
        !          91982:        mov     ax, $0xFFFF             /       Limit: 64K bytes.
        !          91983:        stosw                           /
        !          91984:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          91985:        mov     ax, gdtsel_             /       Base: gdtsel << 4.
        !          91986:        rol     ax, $4                  /
        !          91987:        xor     dx, ax                  /
        !          91988:        and     ax, $0xFFF0             /
        !          91989:        stosw                           /
        !          91990:        xor     ax, dx                  /
        !          91991:        stosw                           /
        !          91992:        sub     ax, ax                  /
        !          91993:        stosw                           /
        !          91994:                                        /
        !          91995:        mov     di, idtsel_             / Define idt access global selector.
        !          91996:        mov     ax, $2047               /       Limit: 2K bytes.
        !          91997:        stosw                           /
        !          91998:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          91999:        mov     ax, idtsel_             /       Base: idtsel << 4.
        !          92000:        rol     ax, $4                  /
        !          92001:        xor     dx, ax                  /
        !          92002:        and     ax, $0xFFF0             /
        !          92003:        stosw                           /
        !          92004:        xor     ax, dx                  /
        !          92005:        stosw                           /
        !          92006:        sub     ax, ax                  /
        !          92007:        stosw                           /
        !          92008:                                        /
        !          92009:        mov     di, $0xB000             / Define video access global selector.
        !          92010:        mov     ax, $0xFFFF             /       Limit: 64K bytes.
        !          92011:        stosw                           /
        !          92012:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          92013:        mov     ax, $0xB000             /       Base:  0xB000 << 4.
        !          92014:        rol     ax, $4                  /
        !          92015:        xor     dx, ax                  /
        !          92016:        and     ax, $0xFFF0             /
        !          92017:        stosw                           /
        !          92018:        xor     ax, dx                  /
        !          92019:        stosw                           /
        !          92020:        sub     ax, ax                  /
        !          92021:        stosw                           /
        !          92022:                                        /
        !          92023:        mov     di, $0xB800             / Define video access global selector.
        !          92024:        mov     ax, $0x7FFF             /       Limit: 32 Kbytes.
        !          92025:        stosw                           /
        !          92026:        mov     dx, $0x9200             /       Flags: Present, writable.
        !          92027:        mov     ax, $0xB800             /       Base:  0xB800 << 4.
        !          92028:        rol     ax, $4                  /
        !          92029:        xor     dx, ax                  /
        !          92030:        and     ax, $0xFFF0             /
        !          92031:        stosw                           /
        !          92032:        xor     ax, dx                  /
        !          92033:        stosw                           /
        !          92034:        sub     ax, ax                  /
        !          92035:        stosw                           /
        !          92036: 
        !          92037:        mov     di, $0xF000             / Define ROM access global selector.
        !          92038:        mov     ax, $0xFFFF             /       Limit: 64 Kbytes.
        !          92039:        stosw                           /
        !          92040:        mov     dx, $0x9000             /       Flags: Present, read only.
        !          92041:        mov     ax, $0xF000             /       Base:  0xF000 << 4.
        !          92042:        rol     ax, $4                  /
        !          92043:        xor     dx, ax                  /
        !          92044:        and     ax, $0xFFF0             /
        !          92045:        stosw                           /
        !          92046:        xor     ax, dx                  /
        !          92047:        stosw                           /
        !          92048:        sub     ax, ax                  /
        !          92049:        stosw                           /
        !          92050: 
        !          92051:        mov     es, idtsel_             / Map ES over the intr descr table.
        !          92052:        sub     ax, ax                  / Map DS over the 8088 vector area.
        !          92053:        mov     ds, ax                  /
        !          92054:        sub     si, si                  /
        !          92055:        sub     di, di                  /
        !          92056:        mov     bx, cs                  / Make CS available for comparison.
        !          92057:        mov     cx, $256                / Install 256 interrupt descriptors.
        !          92058:                                        /
        !          92059: 0:     lodsw                           / Copy interrupt IP
        !          92060:        stosw                           /
        !          92061:        lodsw                           / Copy interrupt CS
        !          92062:        stosw                           /
        !          92063:                                        /
        !          92064:        cmp     ax, bx                  / Coherent interrupt handler?
        !          92065:        mov     ax, $0x8600             /
        !          92066:        je      1f                      /
        !          92067:        sub     ax, ax                  / No, clear flags.
        !          92068:                                        /
        !          92069: 1:     stosw                           / Define IDT flags.
        !          92070:        sub     ax, ax                  / Reserved IDT word.
        !          92071:        stosw                           /
        !          92072:        loop    0b                      / Repeat for all 256 entries.
        !          92073:                                        /
        !          92074:        mov     ax, ss                  / Restore data and extra segments.
        !          92075:        mov     ds, ax                  /
        !          92076:        mov     es, ax                  /
        !          92077:                                        /
        !          92078:        clts                            / Clear task switched flag.
        !          92079:        lgdt    gdtmap_                 / Load global descriptor table map.
        !          92080:        lidt    idtmap_                 / Load interrupt descriptor table map.
        !          92081:                                        /
        !          92082:        smsw    ax                      / Enter protected mode.
        !          92083:        or      ax, $1                  /
        !          92084:        lmsw    ax                      /
        !          92085:        jmp     .+2                     / Clear pipeline.
        !          92086:                                        /
        !          92087:        mov     ax, $0x0008             / Load task state segment register.
        !          92088:        ltr     ax                      /
        !          92089:        sub     ax, ax                  / Load local descriptor table register.
        !          92090:        lldt    ax                      /
        !          92091:                                        /
        !          92092:                                        /
        !          92093:                                        / Register usage:
        !          92094:                                        / DX:AX = extended mem physical addr.
        !          92095:                                        / BX = 0.
        !          92096:                                        / SI = selector into extended memory.
        !          92097:                                        / ES = selector into extended memory.
        !          92098:                                        / DS = selector into global descr table
        !          92099:                                        /
        !          92100:        movb    al, $EXTMEMH            / high byte of pair
        !          92101:        outb    CMOSA, al               / to CMOS memory port
        !          92102:        jmp     .+2                     / DELAY
        !          92103:        inb     al, CMOSD               / get value from CMOS
        !          92104:        xchgb   ah, al
        !          92105:        jmp     .+2                     / DELAY
        !          92106:        movb    al, $EXTMEML            / low byte of pair
        !          92107:        outb    CMOSA, al               / to CMOS memory port
        !          92108:        jmp     .+2                     / DELAY
        !          92109:        inb     al, CMOSD               / get rest of pair from CMOS
        !          92110:        shr     ax, $6                  / K -> 64K conversion
        !          92111:        add     ax, $0x0010             / bias up to 1MB
        !          92112:        mov     CMOSmax_, ax            / save count of 64K hunks
        !          92113:        sub     ax, ax                  /
        !          92114:        mov     dx, $0x0010             / Initial 64 Kbyte bank of extended mem.
        !          92115:        mov     holetop_, ax            / Recorded extended memory bot in bytes.
        !          92116:        mov     holetop_+2, dx          /
        !          92117:                                        /
        !          92118:        mov     ds, gdtsel_             / Map DS onto global descr table.
        !          92119:        mov     si, $0xFFF8             / Define scratch access global selector.
        !          92120:        mov     0(si), $0xFFFF          /       Limit: 64K bytes.
        !          92121:        mov     2(si), $0x0000          /       Base:  1 Mbyte.
        !          92122:        mov     4(si), $0x9210          /       Flags: Present, writable.
        !          92123:        mov     6(si), $0x0000          /
        !          92124:                                        /
        !          92125:        sub     bx, bx                  /
        !          92126: 0:     sub     di, di                  / Destination.
        !          92127:        mov     cx, $0x8000             / 64K bytes, in words.
        !          92128:        mov     2(si), ax               / Adjust gdt to desired DX:AX mem locn.
        !          92129:        movb    4(si), dl               /
        !          92130:        mov     es, si                  / Map ES onto 64K bank of extended mem.
        !          92131:        mov     es:(di), bx             / Write word of extended memory.
        !          92132:        jmp     .+2             / FLUSH /
        !          92133:        cmp     es:(di), bx             / Verify word was correctly written.
        !          92134:        jne     0f                      / Branch if memory end.
        !          92135:                                        /
        !          92136:        cld                             /
        !          92137:        rep                             /
        !          92138:        stosw                           / Clear this 64K of extended memory.
        !          92139:                                        /
        !          92140:        inc     dx                      / Step to next 64K bank.
        !          92141:        cmp     dx, ss:CMOSmax_         / See if we're beyond what the CMOS
        !          92142:        jge     0f                      /    says we have.
        !          92143:        cmp     dx, $0x00F0             / Stop at 15 Mbyte boundary; the last
        !          92144:        jl      0b                      /    Mbyte is a dup of the 1st Mbyte.
        !          92145:                                        /
        !          92146: 0:     movb    5(si), $0               / Free the scratch selector.
        !          92147:                                        /
        !          92148:        mov     bx, ss                  / Restore data and extra segments.
        !          92149:        mov     ds, bx                  / NOTE: Do not modify DX:AX.
        !          92150:        mov     es, bx                  /
        !          92151:                                        /
        !          92152:        mov     coretop_, ax            / Recorded top of extended core memory.
        !          92153:        mov     coretop_+2, dx          /
        !          92154:        jmp     start                   / Bring up system.
        !          92155: 
        !          92156: ////////
        !          92157: /
        !          92158: / Trap an interrupt linkage.
        !          92159: / Each of the machine traps has a special little
        !          92160: / linkage, that sets up the type code and sends
        !          92161: / control off to the common trap processor. Device
        !          92162: / interrupts, other than the clock (IR0), are
        !          92163: / done here.
        !          92164: /
        !          92165: ////////
        !          92166: 
        !          92167: trap0:
        !          92168:        call    tsave
        !          92169:        mov     16(bx), $0x0000         / Divide error.
        !          92170:        jmp     trap_
        !          92171: 
        !          92172: trap1:
        !          92173:        call    tsave
        !          92174:        mov     16(bx), $0x0100         / Single step.
        !          92175:        jmp     trap_
        !          92176: 
        !          92177: trap2:
        !          92178:        call    tsave
        !          92179:        mov     16(bx), $0x0200         / Non-maskable interrupt.
        !          92180:        jmp     trap_
        !          92181: 
        !          92182: trap3:
        !          92183:        call    tsave
        !          92184:        mov     16(bx), $0x0300         / INT 3 (breakpoint).
        !          92185:        jmp     trap_
        !          92186: 
        !          92187: trap4:
        !          92188:        call    tsave
        !          92189:        mov     16(bx), $0x0400         / Overflow.
        !          92190:        jmp     trap_
        !          92191: 
        !          92192: trap5:
        !          92193:        call    tsave
        !          92194:        mov     16(bx), $0x0500         / Bound check.
        !          92195:        jmp     trap_
        !          92196: 
        !          92197: trap6:
        !          92198:        call    tsave
        !          92199:        mov     16(bx), $0x0600         / Invalid opcode.
        !          92200:        jmp     trap_
        !          92201: 
        !          92202: trap7:
        !          92203:        call    tsave
        !          92204:        mov     16(bx), $0x0700         / Processor Extension not available.
        !          92205:        jmp     trap_
        !          92206: 
        !          92207: trap8:
        !          92208:        pop     ax                      / Get error code from stack [always 0]
        !          92209:        call    tsave
        !          92210:        mov     16(bx), $0x0800         / Double Exception detected
        !          92211:        jmp     trap_
        !          92212: 
        !          92213: trap9:
        !          92214:        call    tsave
        !          92215:        mov     16(bx), $0x0900         / Processor extension segment overrun
        !          92216:        jmp     trap_
        !          92217: 
        !          92218: trap10:
        !          92219:        pop     ax                      / Get error code from stack
        !          92220:        call    tsave
        !          92221:        mov     16(bx), $0x0A00         / Invalid task state segment
        !          92222:        jmp     trap_
        !          92223: 
        !          92224: trap11:
        !          92225:        pop     ax                      / Get error code from stack
        !          92226:        call    tsave
        !          92227:        mov     16(bx), $0x0B00         / Segment not present
        !          92228:        jmp     trap_
        !          92229: 
        !          92230: trap12:
        !          92231:        pop     ax                      / Get error code from stack
        !          92232:        call    tsave
        !          92233:        mov     16(bx), $0x0C00         / Stack segment overrun or not present
        !          92234:        jmp     trap_
        !          92235: 
        !          92236: trap13:
        !          92237:        pop     ax                      / Get error code from stack
        !          92238:        call    tsave
        !          92239:        mov     16(bx), $0x0D00         / General protection
        !          92240:        jmp     trap_
        !          92241: 
        !          92242:        .globl  syc
        !          92243: 
        !          92244: syc:
        !          92245:        call    tsave
        !          92246:        mov     16(bx), $0x2000         / System calls.
        !          92247:        jmp     trap_
        !          92248: 
        !          92249: ran:
        !          92250:        call    tsave
        !          92251:        mov     16(bx), $0x2100         / Random trap.
        !          92252:        jmp     trap_
        !          92253: 
        !          92254: dev1:
        !          92255:        call    tsave
        !          92256:        mov     16(bx), $0x4001         / Device 1: keyboard
        !          92257:        ijmp    vecs_+[2*1]
        !          92258: 
        !          92259: /dev2: call    tsave                   / Device 2: mapped into device 9
        !          92260: /      mov     16(bx), $0x4002
        !          92261: /      ijmp    vecs_+[2*2]
        !          92262: 
        !          92263: dev3:
        !          92264:        call    tsave
        !          92265:        mov     16(bx), $0x4003         / Device 3: al1
        !          92266:        ijmp    vecs_+[2*3]
        !          92267: 
        !          92268: dev4:
        !          92269:        call    tsave
        !          92270:        mov     16(bx), $0x4004         / Device 4: al0
        !          92271:        ijmp    vecs_+[2*4]
        !          92272: 
        !          92273: dev5:
        !          92274:        call    tsave
        !          92275:        mov     16(bx), $0x4005         / Device 5: hard disk
        !          92276:        ijmp    vecs_+[2*5]
        !          92277: 
        !          92278: dev6:
        !          92279:        call    tsave
        !          92280:        mov     16(bx), $0x4006         / Device 6: floppy
        !          92281:        ijmp    vecs_+[2*6]
        !          92282: 
        !          92283: dev7:
        !          92284:        call    tsave
        !          92285:        mov     16(bx), $0x4007         / Device 7: lp
        !          92286:        ijmp    vecs_+[2*7]
        !          92287: 
        !          92288: dev8:
        !          92289:        call    tsave
        !          92290:        mov     16(bx), $0x4008         / Device 8:
        !          92291:        ijmp    vecs_+[2*8]
        !          92292: 
        !          92293: dev9:
        !          92294:        call    tsave
        !          92295:        mov     16(bx), $0x4009         / Device 9:
        !          92296:        ijmp    vecs_+[2*9]
        !          92297: 
        !          92298: dev10:
        !          92299:        call    tsave
        !          92300:        mov     16(bx), $0x400A         / Device 10:
        !          92301:        ijmp    vecs_+[2*10]
        !          92302: 
        !          92303: dev11:
        !          92304:        call    tsave
        !          92305:        mov     16(bx), $0x400B         / Device 11:
        !          92306:        ijmp    vecs_+[2*11]
        !          92307: 
        !          92308: dev12:
        !          92309:        call    tsave
        !          92310:        mov     16(bx), $0x400C         / Device 12:
        !          92311:        ijmp    vecs_+[2*12]
        !          92312: 
        !          92313: dev13:
        !          92314:        call    tsave
        !          92315:        mov     16(bx), $0x400D         / Device 13:
        !          92316:        ijmp    vecs_+[2*13]
        !          92317: 
        !          92318: dev14:
        !          92319:        call    tsave
        !          92320:        mov     16(bx), $0x400E         / Device 14:
        !          92321:        ijmp    vecs_+[2*14]
        !          92322: 
        !          92323: dev15:
        !          92324:        call    tsave
        !          92325:        mov     16(bx), $0x400F         / Device 15:
        !          92326:        ijmp    vecs_+[2*15]
        !          92327: 
        !          92328: ////////
        !          92329: /
        !          92330: / Clock interrupt.
        !          92331: / The clock interrupt is stolen from the ROM;
        !          92332: / if you don't do this the EOI sequence for the 8259
        !          92333: / may get mangled on context switches.
        !          92334: /
        !          92335: ////////
        !          92336: 
        !          92337: clk:
        !          92338:        call    tsave                   / Perform trap save.
        !          92339:        mov     16(bx), $0x4000
        !          92340: 
        !          92341:        sub     ax, ax                  / Assume system mode, push user flag
        !          92342:        push    ax
        !          92343:        push    18(bx)                  / IP at tick time
        !          92344: 
        !          92345:        cmpb    depth_, $0              / Correct ?
        !          92346:        jne     0f                      / If ne, yes.
        !          92347:        mov     bx, cprocp_             / User depth, check if the
        !          92348:        test    PFLAGS(bx), $PFKERN     / current process is a kernel process.
        !          92349:        jne     0f                      / If ne, yes.
        !          92350:        mov     bx, sp                  / Load stack index
        !          92351:        inc     2(bx)                   / and set user mode.
        !          92352: 
        !          92353: 0:     call    clock_                  / Call common clock and
        !          92354:        add     sp, $4                  / pop arguments.
        !          92355: 
        !          92356:        ret                             / Back to "tsave".
        !          92357: 
        !          92358: ////////
        !          92359: /
        !          92360: / This routine is called by "tsave" to dismiss an interrupt.
        !          92361: / The interrupt code is in "ax".
        !          92362: /
        !          92363: ////////
        !          92364: 
        !          92365:        .globl  eoi
        !          92366: 
        !          92367: eoi:
        !          92368:        cmpb    al, $8                  / Is this on the slave PIC?
        !          92369:        jb      0f                      / Jump if not.
        !          92370:        movb    al, $0x20               / Send a non specific EOI
        !          92371:        outb    SPIC, al                / to the slave PIC.
        !          92372: 0:     movb    al, $0x20               / Send a non specific EOI
        !          92373:        outb    PIC, al                 / to the master PIC.
        !          92374:        ret                             / Done.
        !          92375: 
        !          92376: ////////
        !          92377: /
        !          92378: / Block I/O to ports.
        !          92379: / Mainly used to read and write the silo memories in the discs.
        !          92380: / Delibrately only transfers 1 byte per loop to avoid
        !          92381: / timing problems on AT I/O chips.
        !          92382: /
        !          92383: / void outcopy(port, off, seg, n);
        !          92384: / int  port;                   /* Port address */
        !          92385: / char *off;                   /* Offset in segment */
        !          92386: / unsigned seg;                        /* Segment register base */
        !          92387: / int  n;                      /* Byte count */
        !          92388: / 
        !          92389: / void incopy(port, off, seg, n);
        !          92390: / int  port;                   /* Device */
        !          92391: / char *off;                   /* Offset */
        !          92392: / unsigned seg;                        /* Segment register base */
        !          92393: / int  n;                      /* Byte count */
        !          92394: /
        !          92395: ////////
        !          92396: 
        !          92397:        .globl  incopy_
        !          92398:        .globl  outcopy_
        !          92399: 
        !          92400: incopy_:
        !          92401:        push    di
        !          92402:        push    es
        !          92403:        push    bp
        !          92404:        mov     bp, sp
        !          92405:        mov     dx, 8(bp)               /device port
        !          92406:        les     di, 10(bp)              /seg,off pair
        !          92407:        mov     cx, 14(bp)              /n bytes
        !          92408:        jcxz    1f
        !          92409: 
        !          92410:        cld                             /auto-increment
        !          92411: 0:     inb     al, dx
        !          92412:        stosb
        !          92413:        loop    0b
        !          92414: 
        !          92415: 1:     pop     bp
        !          92416:        pop     es                      /restore regs
        !          92417:        pop     di
        !          92418:        ret
        !          92419: 
        !          92420: outcopy_:
        !          92421:        push    si
        !          92422:        push    ds
        !          92423:        push    bp
        !          92424:        mov     bp, sp
        !          92425:        mov     dx, 8(bp)               /device port
        !          92426:        lds     si, 10(bp)              /offset
        !          92427:        mov     cx, 14(bp)              /count
        !          92428:        jcxz    1f
        !          92429: 
        !          92430:        cld                             /auto-increment
        !          92431: 0:     lodsb
        !          92432:        outb    dx, al
        !          92433:        loop    0b
        !          92434: 
        !          92435: 1:     pop     bp
        !          92436:        pop     ds
        !          92437:        pop     si
        !          92438:        ret
        !          92439: 
        !          92440: ////////
        !          92441: /
        !          92442: / Copy "n" bytes of memory from base "p1" to base "p2".
        !          92443: / The copy must be done from left to right.
        !          92444: /
        !          92445: / plrcopy(p1, p2, n)
        !          92446: / paddr_t p1, p2;
        !          92447: / size_t n;
        !          92448: /
        !          92449: ////////
        !          92450: 
        !          92451:        .globl  plrcopy_
        !          92452: 
        !          92453: plrcopy_:
        !          92454:        push    si                      / Save sequence
        !          92455:        push    di
        !          92456:        push    bp
        !          92457:        mov     bp, sp
        !          92458: 
        !          92459:        push    ds                      / Save ds
        !          92460:        push    es                      / Save es
        !          92461: 
        !          92462:        push    18(bp)                  / Map SI:DI at destination ptov(p2,n).
        !          92463:        push    16(bp)
        !          92464:        push    14(bp)
        !          92465:        push    12(bp)
        !          92466:        call    ptov_
        !          92467:        add     sp, $8
        !          92468:        mov     si, dx
        !          92469:        mov     di, ax
        !          92470: 
        !          92471:        push    18(bp)                  / Map DX:AX at source   ptov(p1,n);
        !          92472:        push    16(bp)
        !          92473:        push    10(bp)
        !          92474:        push    8(bp)
        !          92475:        call    ptov_
        !          92476:        add     sp, $8
        !          92477: 
        !          92478:        mov     es, si                  / Map ES:DI at destination.
        !          92479:        mov     ds, dx                  / Map DS:SI at source.
        !          92480:        mov     si, ax
        !          92481: 
        !          92482:        mov     cx, 16(bp)              / Transfer count in bytes.
        !          92483:        cld                             / Auto Increment.
        !          92484:        clc                             /
        !          92485:        rcr     cx, $1                  / Word count
        !          92486:        rep                             /
        !          92487:        movsw                           / Move words
        !          92488:        rcl     cx, $1                  /
        !          92489:        rep                             /
        !          92490:        movsb                           / Move odd byte
        !          92491: 
        !          92492:        mov     si, es                  / Remember mapped selectors.
        !          92493:        mov     di, ds                  /
        !          92494:        pop     es                      / Restore es
        !          92495:        pop     ds                      / Restore ds
        !          92496: 
        !          92497:        push    si                      / Release mapped selectors.
        !          92498:        push    ax                      / NOTE: Offset is ignored.
        !          92499:        call    vrelse_                 /
        !          92500:        add     sp, $4                  /
        !          92501:                                        /
        !          92502:        push    di                      /
        !          92503:        push    ax                      /
        !          92504:        call    vrelse_                 /
        !          92505:        add     sp, $4                  /
        !          92506: 
        !          92507:        pop     bp                      / Standard return
        !          92508:        pop     di
        !          92509:        pop     si
        !          92510:        ret                             / Return
        !          92511: 
        !          92512: ////////
        !          92513: /
        !          92514: / Copy "n" bytes of memory from base "p1" to base "p2".
        !          92515: / The copy must be done from right to left.
        !          92516: /
        !          92517: / prlcopy(p1, p2, n)
        !          92518: / paddr_t p1, p2;
        !          92519: / size_t n;
        !          92520: /
        !          92521: ////////
        !          92522: 
        !          92523:        .globl  prlcopy_
        !          92524: 
        !          92525: prlcopy_:
        !          92526:        push    si                      / Save sequence
        !          92527:        push    di
        !          92528:        push    bp
        !          92529:        mov     bp, sp
        !          92530: 
        !          92531:        push    ds                      / Save ds
        !          92532:        push    es                      / Save es
        !          92533: 
        !          92534:        push    18(bp)                  / Map SI:DI at destination ptov(p2,n).
        !          92535:        push    16(bp)
        !          92536:        push    14(bp)
        !          92537:        push    12(bp)
        !          92538:        call    ptov_
        !          92539:        add     sp, $8
        !          92540:        mov     si, dx
        !          92541:        mov     di, ax
        !          92542: 
        !          92543:        push    18(bp)                  / Map DX:AX at source   ptov(p1,n);
        !          92544:        push    16(bp)
        !          92545:        push    10(bp)
        !          92546:        push    8(bp)
        !          92547:        call    ptov_
        !          92548:        add     sp, $8
        !          92549: 
        !          92550:        mov     es, si                  / Map ES:DI at destination.
        !          92551:        mov     ds, dx                  / Map DS:SI at source.
        !          92552:        mov     si, ax
        !          92553: 
        !          92554:        mov     cx, 16(bp)              / Transfer count in bytes
        !          92555:        add     si, cx                  / Point DS:SI at the end
        !          92556:        dec     si                      / of the source.
        !          92557:        add     di, cx                  / Point ES:DI at the end
        !          92558:        dec     di                      / of the destination.
        !          92559: 
        !          92560:        std                             / Auto decrement
        !          92561:        clc                             /
        !          92562:        rcr     cx, $1                  / Word Count
        !          92563:        rep                             /
        !          92564:        movsw                           / Move words
        !          92565:        rcl     cx, $1                  /
        !          92566:        rep                             /
        !          92567:        movsb                           / Move odd byte
        !          92568:        cld                             / Auto increment
        !          92569: 
        !          92570:        mov     si, es                  / Remember mapped selectors.
        !          92571:        mov     di, ds                  /
        !          92572:        pop     es                      / Restore es
        !          92573:        pop     ds                      / Restore ds
        !          92574: 
        !          92575:        push    si                      / Release mapped selectors.
        !          92576:        push    ax                      / NOTE: Offset is ignored.
        !          92577:        call    vrelse_                 /
        !          92578:        add     sp, $4                  /
        !          92579:                                        /
        !          92580:        push    di                      /
        !          92581:        push    ax                      /
        !          92582:        call    vrelse_                 /
        !          92583:        add     sp, $4                  /
        !          92584:                                        /
        !          92585:        mov     ax, 16(bp)              / Return transfer count.
        !          92586:        pop     bp                      / Standard return
        !          92587:        pop     di
        !          92588:        pop     si
        !          92589:        ret
        !          92590: 
        !          92591: ////////
        !          92592: /
        !          92593: / Clear "n" bytes of memory starting at physical address "p".
        !          92594: /
        !          92595: / pclear( p, n )
        !          92596: / paddr_t p;
        !          92597: / size_t n;
        !          92598: /
        !          92599: /
        !          92600: /      Notes:  At most 64K bytes of memory can be cleared.
        !          92601: /
        !          92602: ////////
        !          92603: 
        !          92604:        .globl  pclear_
        !          92605: 
        !          92606: pclear_:
        !          92607:        push    si                      / Standard save
        !          92608:        push    di
        !          92609:        push    bp
        !          92610:        mov     bp, sp
        !          92611: 
        !          92612:        push    es                      / Save es
        !          92613: 
        !          92614:        push    14(bp)                  / Map ES:DI at ptov(p2,n).
        !          92615:        push    12(bp)
        !          92616:        push    10(bp)
        !          92617:        push    8(bp)
        !          92618:        call    ptov_
        !          92619:        add     sp, $8
        !          92620:        mov     es, dx
        !          92621:        mov     di, ax
        !          92622: 
        !          92623:        shr     14(bp), $1              / Convert count from bytes to words.
        !          92624:        rcr     12(bp), $1
        !          92625:        mov     cx, 12(bp)              / Count in words.
        !          92626: 
        !          92627:        sub     ax, ax                  / Get a 0.
        !          92628:        cld                             / Zero the block.
        !          92629:        rep
        !          92630:        stosw
        !          92631: 
        !          92632:        mov     ax, es                  / Remember mapped selector.
        !          92633:        pop     es                      / Restore es.
        !          92634: 
        !          92635:        push    ax                      / Release mapped selector.
        !          92636:        push    ax                      / NOTE: Offset is ignored.
        !          92637:        call    vrelse_                 /
        !          92638:        add     sp, $4                  /
        !          92639: 
        !          92640:        pop     bp                      / Standard return.
        !          92641:        pop     di
        !          92642:        pop     si
        !          92643:        ret
        !          92644: 
        !          92645: ////////
        !          92646: /
        !          92647: / Block copy chunks of memory to a physical
        !          92648: / location from a location in either the system
        !          92649: / or user data space.
        !          92650: /
        !          92651: / upcopy(u, p, n)
        !          92652: / char *u;
        !          92653: / paddr_t p;
        !          92654: / int n;
        !          92655: /
        !          92656: / kpcopy(k, p, n);
        !          92657: / char *k;
        !          92658: / paddr_t p;
        !          92659: / int n;
        !          92660: /
        !          92661: ////////
        !          92662: 
        !          92663:        .globl  upcopy_
        !          92664: 
        !          92665: upcopy_:
        !          92666:        mov     bx, sp                  / Get set for stack index.
        !          92667:        mov     ax, 2(bx)               / User address
        !          92668:        dec     ax                      / Don't wrap too soon
        !          92669:        add     ax, 8(bx)               / Count
        !          92670:        jc      kuerr                   / Out of bounds
        !          92671:        cmp     ax, udl_                / In range?
        !          92672:        ja      kuerr                   / No
        !          92673:        push    uds_                    / Mark transfer ds as being user ds.
        !          92674:        jmp     1f                      / Finish in common code.
        !          92675: 
        !          92676:        .globl  kpcopy_
        !          92677: 
        !          92678: kpcopy_:
        !          92679:        push    ds                      / Mark transfer ds as being kernel ds.
        !          92680: 
        !          92681: 1:     push    si                      / Standard save
        !          92682:        push    di
        !          92683:        push    bp
        !          92684:        mov     bp, sp
        !          92685: 
        !          92686:        push    ds                      / Save ds, es
        !          92687:        push    es
        !          92688: 
        !          92689:        sub     ax, ax                  / ES:DI = ptov(p,n).
        !          92690:        push    ax                      /
        !          92691:        push    16(bp)                  /
        !          92692:        push    14(bp)                  /
        !          92693:        push    12(bp)                  /
        !          92694:        call    ptov_                   /
        !          92695:        add     sp, $8                  /
        !          92696:        mov     es, dx                  /
        !          92697:        mov     di, ax                  /
        !          92698:                                        /
        !          92699:        mov     ds, 6(bp)               / DS:SI = source address.
        !          92700:        mov     si, 10(bp)              /
        !          92701:        mov     cx, 16(bp)              / Byte count
        !          92702:                                        /
        !          92703:        cld                             / Auto Increment
        !          92704:        clc                             /
        !          92705:        rcr     cx, $1                  / Word count
        !          92706:        rep                             /
        !          92707:        movsw                           / Move words
        !          92708:        rcl     cx, $1                  / Move odd byte
        !          92709:        rep                             /
        !          92710:        movsb                           /
        !          92711:                                        /
        !          92712:        mov     ax, es                  / Remember mapped selector.
        !          92713:        pop     es                      / Restore es, ds.
        !          92714:        pop     ds                      /
        !          92715:                                        /
        !          92716:        push    ax                      / Release mapped selector.
        !          92717:        push    ax                      / NOTE: Offset is ignored.
        !          92718:        call    vrelse_                 /
        !          92719:        add     sp, $4                  /
        !          92720:                                        /
        !          92721:        mov     ax, 16(bp)              / Return transfer count.
        !          92722:                                        /
        !          92723:        pop     bp                      / Standard return.
        !          92724:        pop     di
        !          92725:        pop     si
        !          92726:        add     sp, $2                  / Discard marked transfer ds.
        !          92727:        ret
        !          92728: 
        !          92729: ////////
        !          92730: /
        !          92731: / Block copy memory from physical address "p"
        !          92732: / to either user or system data space.
        !          92733: /
        !          92734: / pucopy(p, u, n)
        !          92735: / paddr_t p;
        !          92736: / char *u;
        !          92737: / int n;
        !          92738: /
        !          92739: / pkcopy(p, k, n);
        !          92740: / paddr_t p;
        !          92741: / char *k;
        !          92742: / int n;
        !          92743: /
        !          92744: ////////
        !          92745: 
        !          92746:        .globl  pucopy_
        !          92747: 
        !          92748: pucopy_:
        !          92749:        mov     bx, sp                  / Stack index
        !          92750:        mov     ax, 6(bx)               / User address
        !          92751:        dec     ax                      / Don't wrap too soon
        !          92752:        add     ax, 8(bx)               / Count
        !          92753:        jc      kuerr                   / Out of bounds
        !          92754:        cmp     ax, udl_                / In range?
        !          92755:        ja      kuerr                   / No
        !          92756:        push    uds_                    / Mark transfer es as being user ds.
        !          92757:        jmp     1f                      / Common code
        !          92758: 
        !          92759:        .globl  pkcopy_
        !          92760: 
        !          92761: pkcopy_:
        !          92762:        push    ds                      / Mark transfer es as being kernel ds.
        !          92763: 
        !          92764: 1:     push    si                      / Standard save
        !          92765:        push    di
        !          92766:        push    bp
        !          92767:        mov     bp, sp
        !          92768: 
        !          92769:        push    ds                      / Save ds, es.
        !          92770:        push    es
        !          92771: 
        !          92772:        sub     ax, ax                  / DS:SI = ptov(p,n).
        !          92773:        push    ax
        !          92774:        push    16(bp)
        !          92775:        push    12(bp)
        !          92776:        push    10(bp)
        !          92777:        call    ptov_
        !          92778:        add     sp, $8
        !          92779:        mov     ds, dx
        !          92780:        mov     si, ax
        !          92781: 
        !          92782:        mov     es, 6(bp)               / ES:DI = destination.
        !          92783:        mov     di, 14(bp)              /
        !          92784:        mov     cx, 16(bp)              / Count
        !          92785: 
        !          92786:        cld                             / Incremental move
        !          92787:        clc                             /
        !          92788:        rcr     cx, $1                  / Word count
        !          92789:        rep                             /
        !          92790:        movsw                           / Move words.
        !          92791:        rcl     cx, $1                  / Move odd byte.
        !          92792:        rep                             /
        !          92793:        movsb                           /
        !          92794:                                        /
        !          92795:        mov     ax, ds                  / Rememember mapped selector.
        !          92796:        pop     es                      / Restore es, ds.
        !          92797:        pop     ds                      /
        !          92798:                                        /
        !          92799:        push    ax                      / Release mapped selector.
        !          92800:        push    ax                      / NOTE: Offset is ignored.
        !          92801:        call    vrelse_                 /
        !          92802:        add     sp, $4                  /
        !          92803:                                        /
        !          92804:        mov     ax, 16(bp)              / Return transfer count.
        !          92805:                                        /
        !          92806:        pop     bp                      / Restore registers.
        !          92807:        pop     di                      /
        !          92808:        pop     si                      /
        !          92809:        add     sp, $2                  / Discard marked transfer es.
        !          92810:        ret                             / Fin
        !          92811: 
        !          92812: ////////
        !          92813: /
        !          92814: / All of the above copy routines jump to
        !          92815: / "kuerr", with the stack untouched, if they detect
        !          92816: / a bounds error on a user address.
        !          92817: /
        !          92818: ////////
        !          92819: 
        !          92820: kuerr:
        !          92821:        mov     bx,$u_                  / Pointer to user area
        !          92822:        movb    (bx),$EFAULT            / Bad parameter error
        !          92823:        sub     ax,ax                   / Didn't copy anything
        !          92824:        ret                             / Return
        !          92825: 
        !          92826: ////////
        !          92827: /
        !          92828: / Read the equipment description. Use
        !          92829: / the "int 11" interface, so that the IBM
        !          92830: / ROM will do all the details.
        !          92831: /
        !          92832: ////////
        !          92833: 
        !          92834:        .globl  int11_
        !          92835: 
        !          92836: int11_:        mov     ax, cs:val11            / Ask the ROM
        !          92837:        ret                             / to put stuff in AX
        !          92838: 
        !          92839: ////////
        !          92840: /
        !          92841: / Bootstrap.
        !          92842: / Called by the keyboard driver on control-alt-del.
        !          92843: / Requests the 8042 controller to initiate a processor reset,
        !          92844: / which is the only way to terminate protected mode operation.
        !          92845: /
        !          92846: /      Reference: IBM-AT Technical Reference Manual,
        !          92847: /                      Real-time Clock/CMOS RAM [Page 1-45]
        !          92848: /                      Keyboard controller [Page 1-40]
        !          92849: /                      Test 3, Page 5-68.
        !          92850: /
        !          92851: ////////
        !          92852: 
        !          92853:        .globl  boot_
        !          92854: boot_:
        !          92855:        cli                             / Disable interrupts.
        !          92856:                                        /
        !          92857:        sub     cx, cx                  /
        !          92858: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !          92859:        testb   al, $2                  /
        !          92860:        loopne  0b                      /
        !          92861:        jmp     .+2             / DELAY /
        !          92862:                                        /
        !          92863:        movb    al, $0xFE               / Issue a shutdown command
        !          92864:        outb    KBCTRL, al              / to the 8042 control port.
        !          92865:                                        /
        !          92866: 0:     hlt                             / Halt until processor reset occurs.
        !          92867:        jmp     0b
        !          92868: 
        !          92869: ////////
        !          92870: /
        !          92871: / Data.
        !          92872: /
        !          92873: ////////
        !          92874: 
        !          92875:        .globl  MAXMEM
        !          92876:        .globl  vecs_
        !          92877:        .globl  realmode_
        !          92878:        .globl  gdtsel_, gdtmap_
        !          92879:        .globl  idtsel_, idtmap_
        !          92880:        .globl  CMOSmax_
        !          92881: 
        !          92882:        .shri
        !          92883: val11: .word   0                       / Value obtained from int11 [in code].
        !          92884: 
        !          92885:        .prvd
        !          92886: MAXMEM:        .word   0xA000                  / In paragraphs, must be mult. of 64
        !          92887: CMOSmax_:.word 0x0000                  / Max extended memory according ...
        !          92888:                                        / ... to CMOS bytes 0x17 and 0x18 ...
        !          92889:                                        / ... in 64K chunks.
        !          92890: realmode_:.word        0                       / Virtual Addressing Mode Enabled
        !          92891: gdtmap_:.blkw  3                       / Global descriptor table definition
        !          92892: idtmap_:.blkw  3                       / Interrupt descriptor table definition
        !          92893: gdtsel_:.word  0                       / Global descriptor table selector
        !          92894: idtsel_:.word  0                       / Interrupt descriptor table selector
        !          92895: vecs_: .word   vret_                   / Interrupt vector table
        !          92896:        .word   vret_
        !          92897:        .word   vret_
        !          92898:        .word   vret_
        !          92899:        .word   vret_
        !          92900:        .word   vret_
        !          92901:        .word   vret_
        !          92902:        .word   vret_
        !          92903:        .word   vret_
        !          92904:        .word   vret_
        !          92905:        .word   vret_
        !          92906:        .word   vret_
        !          92907:        .word   vret_
        !          92908:        .word   vret_
        !          92909:        .word   vret_
        !          92910:        .word   vret_
        !          92911: 
        !          92912: ////////
        !          92913: /
        !          92914: / Task State Segment - Coherent runs as a single protected mode task.
        !          92915: /
        !          92916: ////////
        !          92917:        .globl  tss_
        !          92918: 
        !          92919:        .prvd
        !          92920: tss_:                          / Task State Segment.
        !          92921: tss_lnk:.word  0               /  0: Back link selector to TSS.
        !          92922: tss_sp0:.word  0               /  2: SP for CPL 0.
        !          92923: tss_ss0:.word  0               /  4: SS for CPL 0.
        !          92924: tss_sp1:.word  0               /  6: SP for CPL 1.
        !          92925: tss_ss1:.word  0               /  8: SS for CPL 1.
        !          92926: tss_sp2:.word  0               / 10: SP for CPL 2.
        !          92927: tss_ss2:.word  0               / 12: SS for CPL 2.
        !          92928: tss_ip:        .word   0               / 14: IP (Entry point).
        !          92929: tss_psw:.word  0               / 16: Flag word.
        !          92930: tss_ax:        .word   0               / 18: Register AX.
        !          92931: tss_cx:        .word   0               / 20: Register CX.
        !          92932: tss_dx:        .word   0               / 22: Register DX.
        !          92933: tss_bx:        .word   0               / 24: Register BX.
        !          92934: tss_bp:        .word   0               / 26: Register BP.
        !          92935: tss_sp:        .word   0               / 28: Register SP.
        !          92936: tss_si:        .word   0               / 30: Register SI.
        !          92937: tss_di:        .word   0               / 32: Register DI.
        !          92938: tss_es:        .word   0               / 34: Register ES.
        !          92939: tss_cs:        .word   0               / 36: Register CS.
        !          92940: tss_ss:        .word   0               / 38: Register SS.
        !          92941: tss_ds:        .word   0               / 40: Register DS.
        !          92942: tss_ldt:.word  0               / 42: Task LDT Selector.
        !          92943: @
        !          92944: 
        !          92945: 
        !          92946: 1.1
        !          92947: log
        !          92948: @Shipped with COH 3.0.0
        !          92949: @
        !          92950: text
        !          92951: @d70 2
        !          92952: d542 13
        !          92953: d583 2
        !          92954: d889 1
        !          92955: a889 1
        !          92956: / fsize_t n;
        !          92957: d961 1
        !          92958: a961 1
        !          92959: / fsize_t n;
        !          92960: d1039 1
        !          92961: a1039 1
        !          92962: / fsize_t n;
        !          92963: d1322 1
        !          92964: d1329 3
        !          92965: @
        !          92966: 0707070064030064240407550000000000000000011777770507310716400005400000000000/newbits/kernel/USRSRC/i8086/ibm_at/objects0707070064030147740407550000030000030000011777770507310716400004100000000000/newbits/kernel/USRSRC/i8086/src0707070064030111371006440000030000030000011777770507310716400004700000061647/newbits/kernel/USRSRC/i8086/src/as1.s/ $Header: /x/usr/src/sys/i8086/src/RCS/as1.s,v 1.2 91/06/20 14:07:20 hal Exp $
        !          92967: 
        !          92968: / (lgl-
        !          92969: /      The information contained herein is a trade secret of Mark Williams
        !          92970: /      Company, and  is confidential information.  It is provided  under a
        !          92971: /      license agreement,  and may be  copied or disclosed  only under the
        !          92972: /      terms of  that agreement.  Any  reproduction or disclosure  of this
        !          92973: /      material without the express written authorization of Mark Williams
        !          92974: /      Company or persuant to the license agreement is unlawful.
        !          92975: /
        !          92976: /      COHERENT Version 2.3.37
        !          92977: /      Copyright (c) 1982, 1983, 1984.
        !          92978: /      An unpublished work by Mark Williams Company, Chicago.
        !          92979: /      All rights reserved.
        !          92980: / -lgl)
        !          92981: ////////
        !          92982: /
        !          92983: / Machine language assist for
        !          92984: / 8086/8088 Coherent. This contains the parts
        !          92985: / that are common to all machines.
        !          92986: /
        !          92987: / Note that several of the following constants can be invalidated
        !          92988: / by changing the contents of ../h/*proc.h among others,
        !          92989: / or by changing the number of automatic variables in the functions
        !          92990: / called on the paths leading to consave or conrest.  Tread with caution.
        !          92991: /
        !          92992: / $Log:        as1.s,v $
        !          92993: / Revision 1.2  91/06/20  14:07:20  hal
        !          92994: / I'm not sure what changed here.
        !          92995: 
        !          92996: / Revision 1.3 88/08/05  08:32:09      src
        !          92997: / Kludges for AMD 286 bug have been removed.
        !          92998: / 
        !          92999: / Revision 1.2 88/06/24  16:02:08      src
        !          93000: / Bug: inb/outb did not work properly in split stack/data operation.
        !          93001: / Fix: inb/outb now explicitly reference the stack segment.
        !          93002: / 
        !          93003: / Revision 1.1 88/03/24  17:39:08      src
        !          93004: / Initial revision
        !          93005: / 
        !          93006: / 88/03/10     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          93007: / Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !          93008: / These partial fixes will be removed once all CPU's are replaced.
        !          93009: /
        !          93010: / 88/03/04     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          93011: / tmpcs*/tmpds* temporary variables renamed to sav_*.
        !          93012: / usave/conrest/etc now handle odd byte alignment on stack.
        !          93013: / envrest/conrest now do interrupt return as last instruction.
        !          93014: /
        !          93015: / 87/12/21     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          93016: / fclear(f,n) function added.
        !          93017: /
        !          93018: / 87/12/04     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          93019: / kfcopy(k,f,n) and fkcopy(f,k,n) routines added.
        !          93020: /
        !          93021: / 87/12/03     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          93022: / popf replaced by 'push cs; mov ax,$0f; push ax; iret; 0:' due to popf int bug.
        !          93023: /
        !          93024: / 87/11/05     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          93025: / slrcopy/srlcopy/sclear renamed plrcopy/prlcopy/pclear and moved to ibm*/as2.s
        !          93026: /
        !          93027: / 87/10/27     Allan Cornish   /usr/src/sys/i8086/src/as1.s
        !          93028: / System stack/data segments now setup in ibm/ibm_at as2.s
        !          93029: /
        !          93030: / 87/02/06     Allan Cornish
        !          93031: / Functions ffword and sfword added to fetch and set far memory.
        !          93032: /
        !          93033: ////////
        !          93034: 
        !          93035: UPASIZE        =       1024                    / Size of uproc and stack
        !          93036: USIZE  =       0x114                   / sizeof(UPROC)
        !          93037: USZ1   =       140                     / Word count for usave, uproc size
        !          93038: UMCSP  =       0x06                    / offset of sp in u_syscon
        !          93039: EFAULT =       14                      / Bad argument
        !          93040: PFLAGS =       0x22                    / Offset into PROC.
        !          93041: PFKERN =       0x80                    / Kernel process flag bit.
        !          93042: SIDEV  =       0x40                    / Device interrupt trap code.
        !          93043: 
        !          93044: ////////
        !          93045: /
        !          93046: / After performing machine specific
        !          93047: / trap vector setup, the startup code jumps
        !          93048: / here. The DS maps the vectors.
        !          93049: /
        !          93050: ////////
        !          93051: 
        !          93052:        .globl  start
        !          93053: 
        !          93054: start:
        !          93055: / Call the machine setup code.
        !          93056: / Call Coherent main.
        !          93057: / On return, send control off to the user
        !          93058: / at its entry point.
        !          93059: 
        !          93060:        mov     sp, $u_+UPASIZE-32      / Stack pointer for init
        !          93061:        call    i8086_                  / Do it.
        !          93062:        sti                             / Interrupts on, and
        !          93063:        call    main_                   / call Coherent mainline.
        !          93064:        cli                             / Interrupts off.
        !          93065:        incb    depth_                  / Set stack depth to user.
        !          93066:        sub     ax, ax                  / User mode IP.
        !          93067:        mov     bx, uds_                / User mode DS, ES, SS
        !          93068:        mov     cx, ucs_                / User mode CS.
        !          93069:        mov     dx, $0x0200             / User mode FL.
        !          93070: 
        !          93071:        mov     ds, bx                  / Map data segment
        !          93072:        mov     es, bx                  / Map extra segment
        !          93073:        mov     ss, bx                  / Map stack segment
        !          93074: 
        !          93075:        mov     sp, $sb-aicodep_        / User's stack
        !          93076:        push    dx                      / Flags
        !          93077:        push    cx                      / CS
        !          93078:        push    ax                      / IP
        !          93079:        iret                            / Go to user state.
        !          93080: 
        !          93081: ////////
        !          93082: /
        !          93083: / Trap and interrupt save.
        !          93084: / These routines will be very familiar to any
        !          93085: / RSX-11M hackers out there; it is just the ever
        !          93086: / common co-routine call. The caller is called back,
        !          93087: / with "bx" pointing to the saved "ax" on the stack,
        !          93088: / with interrupts enabled. The called routine must
        !          93089: / set 16(bx), which was initially the call back address,
        !          93090: / to something non zero in the high byte if it does
        !          93091: / not want an EOI sent to the 8259.
        !          93092: /
        !          93093: / ttsave, tksave, tisave, and tusave could be folded into a single routine
        !          93094: / with many tests and branches, but the frequency of passage through
        !          93095: / this code warrants a minimally branched execution, and special casing
        !          93096: / the interrupted context allows minimal memory references.
        !          93097: /
        !          93098: ////////
        !          93099: 
        !          93100:        .globl  tsave
        !          93101: 
        !          93102: tsave:                         / What level of interrupt ?
        !          93103:        push    ds                      / Save current data base
        !          93104:        mov     ds, cs:cds              / remap to system data space.
        !          93105:        pop     sav_ds                  /
        !          93106:        decb    depth_                  / Adjust stack depth.
        !          93107:        je      tkusave                 / If e, stack switch may be needed.
        !          93108: ttsave:                                / Interrupted within interrupt
        !          93109:        cmp     sp,$u_+USIZE+50         / Check for stack
        !          93110:        jbe     tabort                  / overflow
        !          93111:        push    ss                      / Fake save ss
        !          93112:        push    sp                      / Fake save sp
        !          93113:        push    sav_ds                  / Save ds
        !          93114:        push    bx                      / Save bx
        !          93115: 
        !          93116:        sti                             / More interrupts ok
        !          93117: 
        !          93118:        push    ax                      / Save ax
        !          93119:        push    dx                      / and remainder
        !          93120:        push    cx                      / of machine
        !          93121:        push    es                      / state
        !          93122:        mov     ax,ds                   / Map es
        !          93123:        mov     es,ax                   / to system ds
        !          93124:        mov     bx,sp                   / Load index
        !          93125:        icall   16(bx)                  / and call the caller
        !          93126:        mov     bx,sp                   / Load index
        !          93127:        mov     ax,16(bx)               / fetch trap type
        !          93128:        cmpb    ah, $SIDEV              / see if eoi
        !          93129:        jne     ttkdone                 / can be skipped
        !          93130: 
        !          93131:        cli                             / don't let eoi swamp us
        !          93132:        call    eoi                     / Dismiss interrupt
        !          93133: ttkdone:                       / Common ttsave/tksave finish
        !          93134:        pop     es                      / Restore
        !          93135:        pop     cx                      / the
        !          93136:        pop     dx                      / machine state
        !          93137:        pop     ax                      / state
        !          93138: 
        !          93139:        cli                             / No more interrupts
        !          93140: 
        !          93141:        incb    depth_                  / Reset stack level
        !          93142:        pop     bx                      / Restore the
        !          93143:        pop     ds                      / last parts
        !          93144:        add     sp,$6                   / forget ss, sp, and ra.
        !          93145:        iret                            / Done.
        !          93146: 
        !          93147: tabort:                                / Uarea stack overflowed
        !          93148:        add     sp,$300                 / Make room for death.
        !          93149:        mov     ax,$oops                / Load
        !          93150:        push    ax                      / message
        !          93151:        call    panic_                  / and die.
        !          93152: 
        !          93153: tkusave:                       / Kernel or user process interrupted
        !          93154:        mov     sav_bx,bx               / Save bx in temp
        !          93155:        mov     bx,cprocp_              / Load proc pointer
        !          93156:        test    PFLAGS(bx),$PFKERN      / Kernel process ?
        !          93157:        je      tusave                  / Sorry, go do it all.
        !          93158: tksave:                                / Kernel process interrupted
        !          93159:        push    ss                      / Fake save ss
        !          93160:        push    sp                      / Fake save sp
        !          93161:        push    sav_ds                  / Save ds
        !          93162:        push    sav_bx                  / Save bx
        !          93163: 
        !          93164:        sti                             / More interrupts ok.
        !          93165: 
        !          93166:        cmp     bx,iprocp_              / Is this the idle process ?
        !          93167:        je      tisave                  / Yes, very easy
        !          93168:        push    ax                      / Save the
        !          93169:        push    dx                      / rest of
        !          93170:        push    cx                      / the machine
        !          93171:        push    es                      / state
        !          93172:        mov     ax,ds                   / And map
        !          93173:        mov     es,ax                   / extra to system data
        !          93174:        mov     bx,sp                   / Load index
        !          93175:        icall   16(bx)                  / and call the caller back.
        !          93176:        mov     bx,sp                   / Load index
        !          93177:        mov     ax,16(bx)               / and pull trap type.
        !          93178:        cmpb    ah, $SIDEV              / Machine trap?
        !          93179:        jne     ttkdone                 / Yes, skip dismiss
        !          93180:        call    eoi                     / Dismiss interrupt
        !          93181:        jmp     ttkdone                 / Finish above
        !          93182: 
        !          93183: tisave:                                / Idle process interrupted, nothing to save
        !          93184:        sub     sp,$8                   / Push junk
        !          93185:        mov     bx,sp                   / Load index
        !          93186:        icall   16(bx)                  / and call the caller back.
        !          93187:        mov     bx,sp                   / Load index
        !          93188:        mov     ax,16(bx)               / and pull trap type.
        !          93189:        cmpb    ah, $SIDEV              / Machine trap ?
        !          93190:        jne     0f                      / Yes, skip dismiss.
        !          93191:        call    eoi                     / Dismiss interrupt
        !          93192: 0:
        !          93193:        call    stand_                  / Clock, part 2
        !          93194:        cli                             / No more interrupts
        !          93195: 
        !          93196:        add     sp,$18                  / Pop everything
        !          93197:        incb    depth_                  / Reset level
        !          93198:        iret                            / Done
        !          93199: 
        !          93200: tusave:                                / User process interrupted
        !          93201:        mov     bx, $u_+UPASIZE         / Get base of user area and
        !          93202:        pop     -8(bx)                  / pop the data that
        !          93203:        pop     -6(bx)                  / was pushed onto the user
        !          93204:        pop     -4(bx)                  / stack onto the new
        !          93205:        pop     -2(bx)                  / system stack.
        !          93206:        mov     sav_ss, ss              / Save the old stack segment
        !          93207:        mov     sav_sp, sp              / and stack pointer, then
        !          93208:        mov     ss, sds_                / switch onto the
        !          93209:        lea     sp, -8(bx)              / new stack in the user area.
        !          93210:        push    sav_ss                  / Push old ss
        !          93211:        push    sav_sp                  / Push old sp
        !          93212:        push    sav_ds                  / Push old ds and
        !          93213:        push    sav_bx                  / push old bx.
        !          93214: 
        !          93215:        sti                             / Allow more interrupts.
        !          93216: 
        !          93217:        push    ax                      / Save the
        !          93218:        push    dx                      / remainder of
        !          93219:        push    cx                      / the machine
        !          93220:        push    es                      / state.
        !          93221:        mov     ax, ds                  / Map extra
        !          93222:        mov     es, ax                  / segment to system data.
        !          93223:        mov     bx, sp                  / Load up an index into the stack
        !          93224:        icall   16(bx)                  / and call the caller back.
        !          93225:        mov     bx, sp                  / Load up stack index.
        !          93226:        mov     ax, 16(bx)              / Pull trap type.
        !          93227:        cmpb    ah, $SIDEV              / Is this a machine trap ?
        !          93228:        jne     0f                      / Yes, skip dismiss.
        !          93229:        call    eoi                     / Do the dismiss.
        !          93230: 0:     mov     bx, cprocp_             / Have we become kernel?
        !          93231:        test    PFLAGS(bx), $PFKERN     / If so, do kernel return.
        !          93232:        jne     ttkdone                 /
        !          93233: 
        !          93234:        call    stand_                  / Clock, part 2
        !          93235:        pop     es                      / Restore the
        !          93236:        pop     cx                      / easy part of the
        !          93237:        pop     dx                      / machine
        !          93238:        pop     ax                      / state.
        !          93239: 
        !          93240:        cli                             / Interrupts off.
        !          93241: 
        !          93242:        incb    depth_                  / Adjust stack depth and
        !          93243:        pop     sav_bx                  / Pop off the old bx and
        !          93244:        pop     sav_ds                  / ds into statics, then
        !          93245:        pop     bx                      / map DS:BX over top of what
        !          93246:        pop     ds                      / was the previous stack.
        !          93247:        add     sp, $2                  / Pop ra.
        !          93248:        pop     -6(bx)                  / Copy the IP,
        !          93249:        pop     -4(bx)                  / the CS and the old
        !          93250:        pop     -2(bx)                  / FW onto the user's stack, then
        !          93251:        lea     sp, -6(bx)              / switch back
        !          93252:        mov     bx, ds                  / to the
        !          93253:        mov     ss, bx                  / user's stack.
        !          93254:        mov     ds, cs:cds              /
        !          93255:        mov     bx, sav_bx              / Reload the bx and the
        !          93256:        mov     ds, sav_ds              / ds, then
        !          93257:        iret                            / exit interrupt.
        !          93258: 
        !          93259: ////////
        !          93260: /
        !          93261: / This dummy routine is put in vector
        !          93262: / table slots that are unused. All it does is
        !          93263: / return to the caller.
        !          93264: /
        !          93265: ////////
        !          93266: 
        !          93267:        .globl  vret_
        !          93268: 
        !          93269: vret_: ret
        !          93270: 
        !          93271: ////////
        !          93272: /
        !          93273: / Fetch a word from the user's data space.
        !          93274: /
        !          93275: / getuwd(u)
        !          93276: / char *u;
        !          93277: /
        !          93278: ////////
        !          93279: 
        !          93280:        .globl  getuwd_
        !          93281:        .globl  getupd_
        !          93282: 
        !          93283: getuwd_:
        !          93284: getupd_:
        !          93285:        mov     bx,sp                   / Base pointer
        !          93286:        mov     bx,2(bx)                / Argument
        !          93287:        cmp     bx,udl_                 / In range?
        !          93288:        ja      kuerr                   / No
        !          93289: 
        !          93290:        push    es                      / Save extra map and
        !          93291:        mov     es, uds_                / remap over the user's data.
        !          93292:        mov     ax,es:(bx)              / Get word
        !          93293:        pop     es                      / Restore es.
        !          93294:        ret                             / Return
        !          93295: 
        !          93296: ////////
        !          93297: /
        !          93298: / Fetch a word from the user's code space.
        !          93299: /
        !          93300: / getuwi(u)
        !          93301: / char *u;
        !          93302: /
        !          93303: ////////
        !          93304: 
        !          93305:        .globl  getuwi_
        !          93306: 
        !          93307: getuwi_:
        !          93308:        mov     bx,sp                   / Base pointer
        !          93309:        mov     bx,2(bx)                / Argument
        !          93310:        cmp     bx,ucl_                 / In range?
        !          93311:        ja      kuerr                   / No
        !          93312: 
        !          93313:        push    es                      / Save extra.
        !          93314:        mov     es,ucs_                 / Users data segment
        !          93315:        mov     ax,es:(bx)              / Get word
        !          93316:        pop     es                      / Restore extra.
        !          93317:        ret                             / Return
        !          93318: 
        !          93319: ////////
        !          93320: /
        !          93321: / Fetch a byte from the user's data space.
        !          93322: /
        !          93323: / getubd(u)
        !          93324: / char *u;
        !          93325: /
        !          93326: ////////
        !          93327: 
        !          93328:        .globl  getubd_
        !          93329: 
        !          93330: getubd_:
        !          93331:        mov     bx,sp                   / Base pointer
        !          93332:        mov     bx,2(bx)                / Argument
        !          93333:        cmp     bx,udl_                 / In range?
        !          93334:        ja      kuerr                   / No
        !          93335: 
        !          93336:        push    es                      / Save es.
        !          93337:        mov     es,uds_                 / Users data segment
        !          93338:        movb    al,es:(bx)              / Get word
        !          93339:        pop     es                      / Restore es.
        !          93340:        subb    ah,ah                   / Clear upper half
        !          93341:        ret                             / Return
        !          93342: 
        !          93343: ////////
        !          93344: /
        !          93345: / Store a word into the user's data space.
        !          93346: /
        !          93347: / putuwd(u, w)
        !          93348: / char *u;
        !          93349: / int w;
        !          93350: /
        !          93351: ////////
        !          93352: 
        !          93353:        .globl  putuwd_
        !          93354: 
        !          93355: putuwd_:
        !          93356:        mov     bx,sp                   / Base pointer
        !          93357:        mov     ax,4(bx)                / New value
        !          93358:        mov     bx,2(bx)                / Argument
        !          93359:        cmp     bx,udl_                 / In range?
        !          93360:        ja      kuerr                   / No
        !          93361: 
        !          93362:        push    es                      / Save es.
        !          93363:        mov     es,uds_                 / Users data segment
        !          93364:        mov     es:(bx),ax              / Set value
        !          93365:        pop     es                      / Restore es.
        !          93366:        sub     ax,ax                   / Succesful
        !          93367:        ret                             / Return
        !          93368: 
        !          93369: ////////
        !          93370: /
        !          93371: / Store a word into the user's code space.
        !          93372: /
        !          93373: / putuwi(u, w)
        !          93374: / char *u;
        !          93375: / int w;
        !          93376: /
        !          93377: ////////
        !          93378: 
        !          93379:        .globl  putuwi_
        !          93380: 
        !          93381: putuwi_:
        !          93382:        mov     bx,sp                   / Base pointer
        !          93383:        mov     ax,4(bx)                / New value
        !          93384:        mov     bx,2(bx)                / Argument
        !          93385:        cmp     bx,ucl_                 / In range?
        !          93386:        ja      kuerr                   / No
        !          93387: 
        !          93388:        push    ucs_                    / Get physical address.
        !          93389:        sub     ax, ax                  / DX:AX = phy = vtop( ucs:0 );
        !          93390:        push    ax                      /
        !          93391:        call    vtop_                   /
        !          93392:        add     sp, $4                  /
        !          93393:                                        /
        !          93394:        sub     bx, bx                  / Get writable virtual address.
        !          93395:        push    bx                      / DX:AX = fp = ptov( phy, ucl );
        !          93396:        push    ucl_                    /
        !          93397:        push    dx                      /
        !          93398:        push    ax                      /
        !          93399:        call    ptov_                   /
        !          93400:        add     sp, $8                  /
        !          93401:                                        /
        !          93402:        mov     bx, sp                  /
        !          93403:        mov     ax, 4(bx)               / New value
        !          93404:        mov     bx, 2(bx)               / Argument
        !          93405:        push    es                      / Save ES
        !          93406:        mov     es, dx                  / Users (writable) code segment
        !          93407:        mov     es:(bx), ax             / Set value
        !          93408:        pop     es                      / Restore es
        !          93409:                                        /
        !          93410:        push    dx                      / Release writable virtual address.
        !          93411:        sub     ax, ax                  / vrelse( fp );
        !          93412:        push    ax                      /
        !          93413:        call    vrelse_                 /
        !          93414:        add     sp, $4                  /
        !          93415:                                        /
        !          93416:        sub     ax,ax                   / Succesful
        !          93417:        ret                             / Return
        !          93418: 
        !          93419: ////////
        !          93420: /
        !          93421: / Store a byte into the user's data space.
        !          93422: /
        !          93423: / putubd(u, w)
        !          93424: / char *u;
        !          93425: / int w;
        !          93426: /
        !          93427: ////////
        !          93428: 
        !          93429:        .globl  putubd_
        !          93430: 
        !          93431: putubd_:
        !          93432:        mov     bx,sp                   / Base pointer
        !          93433:        mov     ax,4(bx)                / New value
        !          93434:        mov     bx,2(bx)                / Argument
        !          93435:        cmp     bx,udl_                 / In range?
        !          93436:        ja      kuerr                   / No
        !          93437: 
        !          93438:        push    es                      / Save es.
        !          93439:        mov     es,uds_                 / Users data segment
        !          93440:        movb    es:(bx),al              / Set value
        !          93441:        pop     es                      / Restore es.
        !          93442:        sub     ax,ax                   / Succesful
        !          93443:        ret                             / Return
        !          93444: 
        !          93445: ////////
        !          93446: /
        !          93447: / Block transfer "n" bytes from location
        !          93448: / "k" in the system map to location "u" in the
        !          93449: / user's data space. Return the number of bytes
        !          93450: / transferred.
        !          93451: /
        !          93452: / kucopy(k, u, n)
        !          93453: / char *k;
        !          93454: / char *u;
        !          93455: / int n;
        !          93456: /
        !          93457: ////////
        !          93458: 
        !          93459:        .globl  kucopy_
        !          93460: 
        !          93461: kucopy_:
        !          93462:        mov     bx,sp                   / Base pointer
        !          93463:        mov     ax,4(bx)                / User address
        !          93464:        dec     ax                      / Don't wrap too soon
        !          93465:        add     ax,6(bx)                / Add count
        !          93466:        jc      kuerr                   / Out of bounds
        !          93467:        cmp     ax,udl_                 / In range?
        !          93468:        ja      kuerr                   / No
        !          93469: 
        !          93470:        push    si                      / Save si
        !          93471:        push    di                      / Save di
        !          93472:        push    es                      / Save es.
        !          93473: 
        !          93474:        mov     si,2(bx)                / Kernel address
        !          93475:        mov     di,4(bx)                / User address
        !          93476:        mov     cx,6(bx)                / Count
        !          93477:        mov     ax,cx                   / Move here to return
        !          93478:        mov     es,uds_                 / Map extra segment to user
        !          93479: 
        !          93480:        cld                             / Auto increment
        !          93481:        clc                             /
        !          93482:        rcr     cx, $1                  / Calculate Word count
        !          93483:        rep                             /
        !          93484:        movsw                           / Move words.
        !          93485:        rcl     cx, $1
        !          93486:        rep
        !          93487:        movsb                           / Move odd byte.
        !          93488: 
        !          93489:        pop     es                      / Restore es.
        !          93490:        pop     di                      / Restore di
        !          93491:        pop     si                      / Restore si
        !          93492:        ret                             / Return
        !          93493: 
        !          93494: ////////
        !          93495: /
        !          93496: / Block copy "n" bytes from location "u" in
        !          93497: / the user data space to location "k" in the system
        !          93498: / data space. Return the actual number of bytes
        !          93499: / moved.
        !          93500: /
        !          93501: / ukcopy(u, k, n)
        !          93502: / char *u;
        !          93503: / char *k;
        !          93504: / int n;
        !          93505: /
        !          93506: ////////
        !          93507: 
        !          93508:        .globl  ukcopy_
        !          93509: 
        !          93510: ukcopy_:
        !          93511:        mov     bx,sp                   / Base pointer
        !          93512:        mov     ax,2(bx)                / User address
        !          93513:        dec     ax                      / Don't wrap too soon
        !          93514:        add     ax,6(bx)                / Count
        !          93515:        jc      kuerr                   / Out of bounds
        !          93516:        cmp     ax,udl_                 / In range?
        !          93517:        ja      kuerr                   / No
        !          93518: 
        !          93519:        push    si                      / Save si
        !          93520:        push    di                      / Save di
        !          93521:        push    ds                      / Save ds
        !          93522: 
        !          93523:        mov     si,2(bx)                / User address
        !          93524:        mov     di,4(bx)                / Kernel address
        !          93525:        mov     cx,6(bx)                / Count
        !          93526:        mov     ax,cx                   / Move here to return
        !          93527:        mov     bx, uds_                / Map data segment
        !          93528:        mov     ds, bx                  / avoiding bug in 8088.
        !          93529: 
        !          93530:        cld                             / Auto increment
        !          93531:        clc                             /
        !          93532:        rcr     cx, $1                  / Word count, odd byte in carry.
        !          93533:        rep                             /
        !          93534:        movsw                           / Move words.
        !          93535:        rcl     cx, $1
        !          93536:        rep                             / Move odd byte.
        !          93537:        movsb
        !          93538: 
        !          93539:        pop     ds                      / Restore ds
        !          93540:        pop     di                      / Restore di
        !          93541:        pop     si                      / Restore si
        !          93542:        ret                             / Return
        !          93543: 
        !          93544: ////////
        !          93545: /
        !          93546: / All of the above copy routines jump to
        !          93547: / "kuerr", with the stack untouched, if they detect
        !          93548: / a bounds error on a user address.
        !          93549: /
        !          93550: ////////
        !          93551: 
        !          93552: kuerr:
        !          93553:        mov     bx,$u_                  / Pointer to user area
        !          93554:        movb    (bx),$EFAULT            / Bad parameter error
        !          93555:        sub     ax,ax                   / Didn't copy anything
        !          93556:        ret                             / Return
        !          93557: 
        !          93558: ////////
        !          93559: /
        !          93560: / sfbyte( fp, b )      -- set far byte
        !          93561: / int far * fp;
        !          93562: / int b;
        !          93563: /
        !          93564: ////////
        !          93565: 
        !          93566:        .globl  sfbyte_
        !          93567: 
        !          93568: sfbyte_:push   es              / sfbyte( fp, b )
        !          93569:        push    di              / register int far * fp;        /* ES:DI */
        !          93570:        push    bp              / register int b;               /* AX */
        !          93571:        mov     bp, sp          / {
        !          93572:        les     di, 8(bp)       /
        !          93573:        mov     ax, 12(bp)      /
        !          93574:                                /
        !          93575:        movb    es:(di), al     /       *fp = b;
        !          93576:                                /
        !          93577:        pop     bp              / }
        !          93578:        pop     di
        !          93579:        pop     es
        !          93580:        ret
        !          93581: 
        !          93582: ////////
        !          93583: /
        !          93584: / sfword( fp, w )      -- set far word
        !          93585: / int far * fp;
        !          93586: / int w;
        !          93587: /
        !          93588: ////////
        !          93589: 
        !          93590:        .globl  sfword_
        !          93591: 
        !          93592: sfword_:push   es              / sfword( fp, w )
        !          93593:        push    di              / register int far * fp;        /* ES:DI */
        !          93594:        push    bp              / register int w;               /* AX */
        !          93595:        mov     bp, sp          / {
        !          93596:        les     di, 8(bp)       /
        !          93597:        mov     ax, 12(bp)      /
        !          93598:                                /
        !          93599:        mov     es:(di), ax     /       *fp = w;
        !          93600:                                /
        !          93601:        pop     bp              / }
        !          93602:        pop     di
        !          93603:        pop     es
        !          93604:        ret
        !          93605: 
        !          93606: ////////
        !          93607: /
        !          93608: / ffbyte( fp )         -- fetch far byte
        !          93609: / int far * fp;
        !          93610: /
        !          93611: ////////
        !          93612: 
        !          93613:        .globl  ffbyte_
        !          93614: 
        !          93615: ffbyte_:push   es              / ffbyte( fp )
        !          93616:        push    di              / register int far * fp;        /* ES:DI */
        !          93617:        push    bp              / {
        !          93618:        mov     bp, sp          /
        !          93619:        les     di, 8(bp)       /
        !          93620:                                /
        !          93621:        sub     ax, ax          /
        !          93622:        movb    al, es:(di)     /       return *fp;
        !          93623:                                /
        !          93624:        pop     bp              / }
        !          93625:        pop     di
        !          93626:        pop     es
        !          93627:        ret
        !          93628: 
        !          93629: ////////
        !          93630: /
        !          93631: / ffword( fp )         -- fetch far word
        !          93632: / int far * fp;
        !          93633: /
        !          93634: ////////
        !          93635: 
        !          93636:        .globl  ffword_
        !          93637: 
        !          93638: ffword_:push   es              / ffword( fp )
        !          93639:        push    di              / register int far * fp;        /* ES:DI */
        !          93640:        push    bp              / {
        !          93641:        mov     bp, sp          /
        !          93642:        les     di, 8(bp)       /
        !          93643:                                /
        !          93644:        mov     ax, es:(di)     /       return *fp;
        !          93645:                                /
        !          93646:        pop     bp              / }
        !          93647:        pop     di
        !          93648:        pop     es
        !          93649:        ret
        !          93650: 
        !          93651: ////////
        !          93652: /
        !          93653: / Block transfer "n" bytes from location
        !          93654: / "k" in the system map to location "f"
        !          93655: / in the virtual address space.
        !          93656: / Return the number of bytes / transferred.
        !          93657: /
        !          93658: / kfcopy(k, f, n)
        !          93659: / char *k;
        !          93660: / faddr_t f;
        !          93661: / int n;
        !          93662: /
        !          93663: ////////
        !          93664: 
        !          93665:        .globl  kfcopy_
        !          93666: 
        !          93667: kfcopy_:
        !          93668:        push    si                      / Save si
        !          93669:        push    di                      / Save di
        !          93670:        push    bp                      / Save bp
        !          93671:        mov     bp, sp                  / Base pointer
        !          93672:        push    es                      / Save es.
        !          93673: 
        !          93674:        mov     si, 8(bp)               / Kernel address
        !          93675:        les     di, 10(bp)              / Far address
        !          93676:        mov     cx, 14(bp)              / Count
        !          93677:        mov     ax, cx                  / Move here to return
        !          93678: 
        !          93679:        cld                             / Auto increment
        !          93680:        clc                             /
        !          93681:        rcr     cx, $1                  / Calculate Word count.
        !          93682:        rep                             /
        !          93683:        movsw                           / Move words.
        !          93684:        rcl     cx, $1                  /
        !          93685:        rep                             /
        !          93686:        movsb                           / Move odd byte.
        !          93687:                                        /
        !          93688:        pop     es                      / Restore es.
        !          93689:        pop     bp                      / Restore bp.
        !          93690:        pop     di                      / Restore di
        !          93691:        pop     si                      / Restore si
        !          93692:        ret                             / Return
        !          93693: 
        !          93694: ////////
        !          93695: /
        !          93696: / Block transfer "n" bytes from location
        !          93697: / "f" in the virtual addres sspace to
        !          93698: / location "f" in the system map.
        !          93699: / Return the number of bytes / transferred.
        !          93700: /
        !          93701: / fkcopy(f, k, n)
        !          93702: / faddr_t f;
        !          93703: / char *k;
        !          93704: / int n;
        !          93705: /
        !          93706: ////////
        !          93707: 
        !          93708:        .globl  fkcopy_
        !          93709: 
        !          93710: fkcopy_:
        !          93711:        push    si                      / Save si
        !          93712:        push    di                      / Save di
        !          93713:        push    bp                      / Save bp
        !          93714:        mov     bp, sp                  / Base pointer
        !          93715:        push    ds                      / Save ds.
        !          93716: 
        !          93717:        lds     si, 8(bp)               / Far address
        !          93718:        mov     di, 12(bp)              / Kernel address
        !          93719:        mov     cx, 14(bp)              / Count
        !          93720:        mov     ax, cx                  / Move here to return
        !          93721: 
        !          93722:        cld                             / Auto increment
        !          93723:        clc                             /
        !          93724:        rcr     cx, $1                  / Calculate Word count.
        !          93725:        rep                             /
        !          93726:        movsw                           / Move words.
        !          93727:        rcl     cx, $1                  /
        !          93728:        rep                             /
        !          93729:        movsb                           / Move odd byte.
        !          93730:                                        /
        !          93731:        pop     ds                      / Restore ds.
        !          93732:        pop     bp                      / Restore bp.
        !          93733:        pop     di                      / Restore di
        !          93734:        pop     si                      / Restore si
        !          93735:        ret                             / Return
        !          93736: 
        !          93737: ////////
        !          93738: /
        !          93739: / fclear( fp, n )      - Erase far memory.
        !          93740: / faddr_t fp;
        !          93741: / unsigned n;
        !          93742: /
        !          93743: ////////
        !          93744: 
        !          93745:        .globl  fclear_
        !          93746: 
        !          93747: fclear_:
        !          93748:        push    es                      / Save es
        !          93749:        push    di                      / Save di
        !          93750:        push    bp                      / Save bp
        !          93751:        mov     bp, sp                  / Base pointer
        !          93752: 
        !          93753:        les     di, 8(bp)               / Far address
        !          93754:        mov     cx, 12(bp)              / Count
        !          93755:        sub     ax, ax                  /
        !          93756: 
        !          93757:        cld                             / Auto increment
        !          93758:        clc                             /
        !          93759:        rcr     cx, $1                  / Calculate Word count.
        !          93760:        rep                             /
        !          93761:        stosw                           / Clear words.
        !          93762:        rcl     cx, $1                  /
        !          93763:        rep                             /
        !          93764:        stosb                           / Clear odd byte.
        !          93765:                                        /
        !          93766:        pop     bp                      / Restore bp.
        !          93767:        pop     di                      / Restore di.
        !          93768:        pop     es                      / Restore es.
        !          93769:        ret                             / Return
        !          93770: 
        !          93771: ////////
        !          93772: /
        !          93773: / Profile scaling.
        !          93774: /
        !          93775: ////////
        !          93776: 
        !          93777:        .globl  pscale_
        !          93778: 
        !          93779: pscale_:
        !          93780:        mov     bx,sp                   / Base pointer
        !          93781:        mov     ax,2(bx)                / Multiply
        !          93782:        mul     4(bx)                   /
        !          93783:        mov     ax,dx                   / Get high half
        !          93784:        ret                             / And return
        !          93785: 
        !          93786: ////////
        !          93787: /
        !          93788: / Save the environment of a process
        !          93789: / envsave(p)
        !          93790: / MENV *p;
        !          93791: /
        !          93792: / Save the context of a process
        !          93793: / consave(p)
        !          93794: / MCON *p;
        !          93795: /
        !          93796: ////////
        !          93797: 
        !          93798:        .globl  consave_
        !          93799:        .globl  envsave_
        !          93800: 
        !          93801: envsave_:
        !          93802: consave_:
        !          93803:        mov     cx, di                  / Hide di.
        !          93804:        mov     bx, sp                  / Point bx at the stack and
        !          93805:        mov     di, 2(bx)               / di at the MCON block.
        !          93806:        cld                             / Ensure increment.
        !          93807:        mov     ax, cx                  / Save di
        !          93808:        stosw
        !          93809:        mov     ax, si                  / Save si
        !          93810:        stosw
        !          93811:        mov     ax, bp                  / Save bp
        !          93812:        stosw
        !          93813:        mov     ax, sp                  / Save sp
        !          93814:        stosw
        !          93815:        mov     ax, (bx)                / Save ra as pc
        !          93816:        stosw
        !          93817:        pushf                           / Save fw
        !          93818:        pop     ax
        !          93819:        stosw
        !          93820:        movb    al, depth_              / Save stack depth
        !          93821:        cbw
        !          93822:        stosw
        !          93823:        mov     di, cx                  / Put di back,
        !          93824:        sub     ax, ax                  / indicate a state save and
        !          93825:        ret                             / return to caller.
        !          93826: 
        !          93827: ////////
        !          93828: /
        !          93829: / Restore the environment of a process.
        !          93830: / envrest(p)
        !          93831: / MENV *p;
        !          93832: /
        !          93833: ////////
        !          93834: 
        !          93835:        .globl  envrest_
        !          93836: 
        !          93837: envrest_:
        !          93838:        cli
        !          93839:        cld
        !          93840:        mov     bx,sp                   / Base pointer
        !          93841:        mov     si,2(bx)                / Pointer to context
        !          93842:        lodsw                           / Restore di
        !          93843:        mov     di,ax                   /
        !          93844:        lodsw                           / Restore si
        !          93845:        mov     cx,ax                   / Save for later
        !          93846:        lodsw                           / Restore bp
        !          93847:        mov     bp,ax                   /
        !          93848:        lodsw                           / Restore sp
        !          93849:        mov     sp,ax                   /
        !          93850:        mov     bx,ax                   / Our frame
        !          93851:        push    cs                      / Push current CS
        !          93852:        lodsw                           / Restore pc
        !          93853:        push    ax                      /
        !          93854:        lodsw                           / Restore flags
        !          93855:        mov     (bx),ax                 / Stack now in form PSW,CS,IP.
        !          93856:        lodsw                           / Restore stack depth
        !          93857:        cli                             / No more interrupts
        !          93858:        movb    depth_, al
        !          93859:        mov     si,cx                   / Restore si
        !          93860:        mov     ax,$1                   / We are restoring
        !          93861:        iret                            / Return through PSW,CS,IP.
        !          93862: 
        !          93863: ////////
        !          93864: /
        !          93865: / Restore the context of a process.
        !          93866: / Called with interrupts disabled from dispatch.
        !          93867: / conrest(u, o)
        !          93868: / saddr_t u;
        !          93869: /
        !          93870: ////////
        !          93871: 
        !          93872:        .globl  conrest_
        !          93873: 
        !          93874: conrest_:
        !          93875:        decb    depth_                  / Falsify user/system state
        !          93876:        sti                             / Interrupts ok here
        !          93877:                        / Save current uarea
        !          93878:        call    usave_                  / Save the uarea in its segment.
        !          93879:                        / Copy in new uarea
        !          93880:        mov     bx,sp                   / Base pointer
        !          93881:        mov     ax, 2(bx)               / Fetch uarea saddr_t
        !          93882:        mov     bx, 4(bx)               / Fetch syscon offset
        !          93883:        mov     uasa_, ax               / Save uarea saddr_t
        !          93884:        mov     cx,$USZ1                / uproc size
        !          93885: /      mov     es,sds_                 / system data segment
        !          93886:        mov     di,$u_                  / system data uarea offset
        !          93887:        mov     ds,ax                   / uarea segment
        !          93888:        sub     si,si                   / uarea offset
        !          93889:        mov     sp,UMCSP(bx)            / new stack
        !          93890:        cld                             / increment
        !          93891:        rep                             / repeat
        !          93892:        movsw                           / copy uproc
        !          93893:        mov     di,sp                   / stack offset in system data
        !          93894:        and     di,$~1                  / ensure word alignment
        !          93895:        mov     cx,$u_+UPASIZE          / compute byte
        !          93896:        sub     cx,di                   / count
        !          93897:        mov     si,$UPASIZE             / compute offset
        !          93898:        sub     si,cx                   / in segment
        !          93899:        shr     cx,$1                   / make word count
        !          93900:        rep                             / repeat
        !          93901:        movsw                           / copy stack
        !          93902:                        / Clean up
        !          93903:        mov     ax, es                  / Restore data
        !          93904:        mov     ds, ax                  / segment
        !          93905:                        / Now restore context
        !          93906:        add     bx, $u_                 / convert to address
        !          93907:        mov     si, bx                  / Get source index for restore
        !          93908:        lodsw                           / Restore di
        !          93909:        mov     di,ax                   /
        !          93910:        lodsw                           / Restore si
        !          93911:        mov     cx,ax                   / Save for later
        !          93912:        lodsw                           / Restore bp
        !          93913:        mov     bp,ax                   /
        !          93914:        lodsw                           / Restore sp
        !          93915:        mov     sp,ax                   /
        !          93916:        mov     bx,ax                   / Our frame
        !          93917:        push    cs                      / Push current CS
        !          93918:        lodsw                           / Restore pc
        !          93919:        push    ax                      /
        !          93920:        lodsw                           / Restore flags
        !          93921:        mov     (bx),ax                 / Stack now in form PSW,CS,IP.
        !          93922:        lodsw                           / Restore stack depth
        !          93923:        cli                             / No more interrupts
        !          93924:        movb    depth_, al
        !          93925:        mov     si,cx                   / Restore si
        !          93926:        mov     ax,$1                   / We are restoring
        !          93927:        iret                            / Return through PSW,CS,IP.
        !          93928: 
        !          93929: ////////
        !          93930: / usave()
        !          93931: / Save uarea in segment.
        !          93932: / Knowing that ds points to the system data segment
        !          93933: / and that es should map there also.
        !          93934: / And guaranteed not to step on ax or bx for conrest
        !          93935: /
        !          93936:        .globl  usave_
        !          93937: 0:     ret
        !          93938: usave_:
        !          93939:        cmp     uasa_, $0               /
        !          93940:        je      0b
        !          93941:        push    es                      / Save es
        !          93942:        push    si                      / Save si
        !          93943:        push    di                      / Save di
        !          93944:        mov     cx,$USZ1                / count
        !          93945:        sub     di,di                   / uarea segment offset
        !          93946:        mov     es,uasa_                / uarea segment
        !          93947:        mov     si,$u_                  / system data offset
        !          93948: /      mov     ds,sds_                 / system data segment
        !          93949:        cld                             / increment
        !          93950:        rep                             / repeat
        !          93951:        movsw                           / copy uproc
        !          93952:        mov     si,sp                   / stack offset in system data
        !          93953:        and     si,$~1                  / ensure word alignment
        !          93954:        mov     cx,$u_+UPASIZE          / compute byte
        !          93955:        sub     cx,si                   / count
        !          93956:        mov     di,$UPASIZE             / compute offset
        !          93957:        sub     di,cx                   / in segment
        !          93958:        shr     cx,$1                   / make word count
        !          93959:        rep                             / repeat
        !          93960:        movsw                           / copy stack
        !          93961:        pop     di                      / Restore di
        !          93962:        pop     si                      / Restore si
        !          93963:        pop     es                      / Restore extra
        !          93964:        ret
        !          93965: 
        !          93966: / Save useful registers.
        !          93967: /
        !          93968:        .globl  msysgen_
        !          93969: /
        !          93970: / msysgen(p)
        !          93971: / MGEN *p;
        !          93972: /
        !          93973: msysgen_:
        !          93974:        ret                             / Nothing useful to save
        !          93975: 
        !          93976: / Disable interrupts.  Previous value is returned.
        !          93977: /
        !          93978:        .globl  sphi_
        !          93979: 
        !          93980: sphi_:
        !          93981:        pushf                           / Save flags
        !          93982:        pop     ax                      / Return current value
        !          93983:        cli                             / Disable interrupts
        !          93984:        ret                             / And return
        !          93985: 
        !          93986: / Enable interrupts.  Previous value is returned.
        !          93987: /
        !          93988:        .globl  splo_
        !          93989: 
        !          93990: splo_:
        !          93991:        pushf
        !          93992:        pop     ax
        !          93993:        sti
        !          93994:        ret
        !          93995: 
        !          93996: / Change interrupt flag.  Previous value is returned.
        !          93997: /
        !          93998:        .globl  spl_
        !          93999: 
        !          94000: spl_:
        !          94001:        pop     ax                      / ip
        !          94002:        pop     bx                      / psw
        !          94003:        push    bx
        !          94004:        push    bx                      / push psw, cs, ip for iret
        !          94005:        push    cs
        !          94006:        push    ax
        !          94007:        pushf                           / old psw
        !          94008:        pop     ax
        !          94009:        iret
        !          94010: 
        !          94011: ////////
        !          94012: /
        !          94013: / Idle routine.
        !          94014: / Enable interupts, and wait for something to
        !          94015: / happen. Does not do anything to the 8259, bacause
        !          94016: / this will be set up correctly.
        !          94017: /
        !          94018: ////////
        !          94019: 
        !          94020:        .globl  _idle_
        !          94021: 
        !          94022: _idle_:        sti                             / Interupts on.
        !          94023:        hlt                             / Wait for an interrupt
        !          94024:        ret                             / and return.
        !          94025: 
        !          94026: ////////
        !          94027: /
        !          94028: / The world is indeed grim.
        !          94029: / Halt. Keep the interrupts on so that the
        !          94030: / keyboard can get int.
        !          94031: /
        !          94032: ////////
        !          94033: 
        !          94034:        .globl  halt_
        !          94035: 
        !          94036: halt_: sti                             / Be safe,
        !          94037: 0:
        !          94038:        hlt                             / and halt.
        !          94039:        jmp     0b                      / Paranoid, yes sir.
        !          94040: 
        !          94041: ////////
        !          94042: /
        !          94043: / Basic port level I/O.
        !          94044: /
        !          94045: / int  inb(port);
        !          94046: / int  outb(port, data);
        !          94047: /
        !          94048: ////////
        !          94049: 
        !          94050:        .globl  inb_
        !          94051:        .globl  outb_
        !          94052: 
        !          94053: inb_:  mov     bx, sp
        !          94054:        mov     dx, ss:2(bx)
        !          94055:        sub     ax, ax
        !          94056:        inb     al, dx
        !          94057:        ret
        !          94058: 
        !          94059: outb_: mov     bx, sp
        !          94060:        mov     dx, ss:2(bx)
        !          94061:        mov     ax, ss:4(bx)
        !          94062:        outb    dx, al
        !          94063:        ret
        !          94064: 
        !          94065: ////////
        !          94066: /
        !          94067: / Routines to move data to and from
        !          94068: / the system auxiliary segment.
        !          94069: /
        !          94070: ////////
        !          94071: 
        !          94072:        .globl  ageti_
        !          94073: 
        !          94074: ageti_:
        !          94075:        mov     bx,sp                   / Base pointer
        !          94076:        mov     bx,2(bx)                / Pointer
        !          94077:        push    es                      / Save extra mapping and
        !          94078:        mov     es, sas_                / remap.
        !          94079:        mov     ax,es:(bx)              / Get value
        !          94080:        pop     es                      / Restore es and
        !          94081:        ret                             / Return
        !          94082: 
        !          94083:        .globl  aputp_
        !          94084:        .globl  aputi_
        !          94085: 
        !          94086: aputp_:
        !          94087: aputi_:
        !          94088:        mov     bx,sp                   / Base pointer
        !          94089:        mov     ax,4(bx)                / Value
        !          94090:        mov     bx,2(bx)                / Pointer
        !          94091:        push    es                      / Save extra base and
        !          94092:        mov     es, sas_                / remap.
        !          94093:        mov     es:(bx),ax              / Set value
        !          94094:        pop     es                      / Restore extra base
        !          94095:        ret                             / Return
        !          94096: 
        !          94097:        .globl  aputc_
        !          94098: 
        !          94099: aputc_:
        !          94100:        mov     bx,sp                   / Base pointer
        !          94101:        mov     ax,4(bx)                / Value
        !          94102:        mov     bx,2(bx)                / Pointer
        !          94103:        push    es                      / Save es and
        !          94104:        mov     es, sas_                / remap.
        !          94105:        movb    es:(bx),al              / Set value
        !          94106:        pop     es                      / Restore es and
        !          94107:        ret                             / Return
        !          94108: 
        !          94109: ////////
        !          94110: /
        !          94111: / Data. 
        !          94112: / A small number of variables must be
        !          94113: / in the code segment. All of these variables have
        !          94114: / something to do with the interrupt linkage; when you
        !          94115: / get an interrupt the only thing that is valid is
        !          94116: / the code segment.
        !          94117: /
        !          94118: ////////
        !          94119: 
        !          94120:        .globl  cds
        !          94121: 
        !          94122:        .shri
        !          94123: cds:   .blkw   1                       / Copy of "sds_".
        !          94124: 
        !          94125:        .globl  u_
        !          94126:        .globl  depth_, sas_,   scs_,   sds_,   ucs_
        !          94127:        .globl  ucl_,   uds_,   udl_
        !          94128: 
        !          94129:        .bssd
        !          94130:        .even
        !          94131: u_:    .blkb   UPASIZE
        !          94132: 
        !          94133:        .prvd
        !          94134: oops:  .ascii  "stack overflow"
        !          94135:        .byte   0
        !          94136: 
        !          94137: depth_:        .byte   0                       / System state.
        !          94138: 
        !          94139:        .even
        !          94140: sas_:  .blkw   1                       / System auxiliary segment.
        !          94141: scs_:  .blkw   1                       / System code segment.
        !          94142: sds_:  .blkw   1                       / System data segment.
        !          94143: ucs_:  .blkw   1                       / User code segment.
        !          94144: ucl_:  .blkw   1                       / User code limit.
        !          94145: uds_:  .blkw   1                       / User data segment.
        !          94146: udl_:  .blkw   1                       / User data limit.
        !          94147: sav_ds:        .blkw   1                       / Four scratch words
        !          94148: sav_bx:        .blkw   1
        !          94149: sav_ss:        .blkw   1
        !          94150: sav_sp:        .blkw   1
        !          94151: 
        !          94152: ////////
        !          94153: /
        !          94154: / This is the image of the init process.
        !          94155: / It gets copied into a user segment when the system
        !          94156: / is first brought up. It must be in the data segment, because
        !          94157: / that is how it is used, and it must be dephased in a funny
        !          94158: / way because it is executed at location 0.
        !          94159: /
        !          94160: ////////
        !          94161: 
        !          94162:        .globl  aicodep_                / Position of code.
        !          94163:        .globl  aicodes_                / Size of code.
        !          94164:        .globl  aidatap_                / Position of data.
        !          94165:        .globl  aidatas_                / Size of data.
        !          94166: 
        !          94167:        .shrd
        !          94168: aicodep_:
        !          94169:        sub     ax,ax                   / No environment
        !          94170:        push    ax
        !          94171:        mov     ax,$argl-aidatap_       / Argument list
        !          94172:        push    ax
        !          94173:        mov     ax,$fn-aidatap_         / File name
        !          94174:        push    ax
        !          94175:        sub     sp,$2                   / Dummy word for exec
        !          94176:        sys     11                      / Sys exec
        !          94177:        jmp     .                       / This should not return
        !          94178: aicodes_ = .-aicodep_
        !          94179: 
        !          94180: aidatap_:
        !          94181:        .word   0                       /
        !          94182:        .word   0                       / Errno
        !          94183:        .word   0                       /
        !          94184:        .word   0                       /
        !          94185:        .word   0                       /
        !          94186:        .word   0                       /
        !          94187:        .word   0                       /
        !          94188:        .word   0                       /
        !          94189: argl:  .word   fn-aidatap_             / argv[0] = "/etc/init";
        !          94190:        .word   a1-aidatap_             / argv[1] = "";
        !          94191:        .word   0                       / argv[2] = NULL;
        !          94192: 
        !          94193: fn:    .ascii  "/etc/init\000"
        !          94194: a1:    .byte   0
        !          94195: 
        !          94196:        .even
        !          94197:        .blkb   64
        !          94198: sb:
        !          94199: aidatas_ = .-aidatap_
        !          94200: 0707070064030104471006440000030000030000011777770507310717400005100000007712/newbits/kernel/USRSRC/i8086/src/clist.s/ $Header: /usr/src/sys/i8086/src/RCS/clist.s,v 1.1 88/03/24 17:39:16 src Exp $
        !          94201: 
        !          94202: / (lgl-
        !          94203: /      The information contained herein is a trade secret of Mark Williams
        !          94204: /      Company, and  is confidential information.  It is provided  under a
        !          94205: /      license agreement,  and may be  copied or disclosed  only under the
        !          94206: /      terms of  that agreement.  Any  reproduction or disclosure  of this
        !          94207: /      material without the express written authorization of Mark Williams
        !          94208: /      Company or persuant to the license agreement is unlawful.
        !          94209: /
        !          94210: /      COHERENT Version 2.3.37
        !          94211: /      Copyright (c) 1982, 1983, 1984.
        !          94212: /      An unpublished work by Mark Williams Company, Chicago.
        !          94213: /      All rights reserved.
        !          94214: / -lgl)
        !          94215: ////////
        !          94216: /
        !          94217: / i8086 coherent clist hack.
        !          94218: / cltinit, getq and putq have been tuned.
        !          94219: / the remaining functions are as produced by cc -S coh/clist.c
        !          94220: / with NCPCL substituted
        !          94221: /
        !          94222: / $Log:        /usr/src/sys/i8086/src/RCS/clist.s,v $
        !          94223: / Revision 1.1 88/03/24  17:39:16      src
        !          94224: / Initial revision
        !          94225: / 
        !          94226: 
        !          94227: #include <sys/const.h>
        !          94228: 
        !          94229:        .shri
        !          94230: L10001:        .word   NCPCL+2
        !          94231:        .globl  cltinit_
        !          94232: cltinit_:
        !          94233:        push    si
        !          94234:        push    di
        !          94235:        push    bp
        !          94236:        mov     bp, sp
        !          94237:        sub     sp, $0x0C
        !          94238: 
        !          94239:        pushf                   / s =
        !          94240:        cli                     / sphi()
        !          94241:        sub     di, di
        !          94242:        mov     ax, NCLIST_
        !          94243:        imul    cs:L10001
        !          94244:        mov     -0x0C(bp), ax
        !          94245:        add     ax, clistp_
        !          94246:        mov     -0x04(bp), ax
        !          94247: 
        !          94248: L3:    sub     -0x04(bp), $NCPCL+2
        !          94249:        mov     ax, -0x04(bp)
        !          94250:        cmp     ax, clistp_
        !          94251:        jb      L2
        !          94252: 
        !          94253: L10002:        mov     si, -0x04(bp)
        !          94254:        mov     (si), di
        !          94255:        mov     di, si
        !          94256:        jmp     L3
        !          94257: 
        !          94258: L2:    mov     cltfree_, di
        !          94259:        call    spl_
        !          94260:        add     sp, $0x02
        !          94261: 
        !          94262:        mov     sp, bp
        !          94263:        pop     bp
        !          94264:        pop     di
        !          94265:        pop     si
        !          94266:        ret
        !          94267: 
        !          94268:        .globl  getq_
        !          94269: 
        !          94270: getq_:
        !          94271:        mov     dx, si
        !          94272:        push    bp
        !          94273:        mov     bp, sp
        !          94274: 
        !          94275:        mov     bp, 4(bp)       / bp = cqp
        !          94276:        sub     ax, ax          / ax = 0
        !          94277:        cmp     (bp), ax        / if (cqp->cq_cc == 0)
        !          94278:        jne     0f
        !          94279:        dec     ax              / return (-1)
        !          94280:        jmp     2f
        !          94281: 
        !          94282: 0:     pushf                   / s =
        !          94283:        cli                     / sphi()
        !          94284:        mov     si, 6(bp)       / si = op = cqp->cq_op
        !          94285:        mov     bx, 8(bp)       / bx = ox = cqp->cq_ox
        !          94286:        movb    al, 2(bx,si)    / ax = op->cl_ch[ox]
        !          94287:        dec     (bp)            / if (--cqp->cq_cc == 0)
        !          94288:        je      0f
        !          94289:        inc     bx              / ++ox
        !          94290:        cmp     bx, $NCPCL      / if (ox == NCPL)
        !          94291:        jne     1f
        !          94292: 
        !          94293: 0:     sub     bx, bx          / ox = 0;
        !          94294:        mov     cx, (si)        / cx = np = op->cl_fp
        !          94295:        mov     6(bp), cx       / cqp->cq_op = np
        !          94296:        cmp     cx, bx          / if (np == 0)
        !          94297:        jne     0f
        !          94298:        mov     2(bp), bx       / cqp->cq_ip = 0
        !          94299:        mov     4(bp), bx       / cqp->cq_ix = 0
        !          94300: 
        !          94301: 0:     mov     cx, cltfree_    / cx = tmp = cltfree
        !          94302:        mov     (si), cx        / op->cl_fp = tmp
        !          94303:        mov     cltfree_, si    / cltfree = op
        !          94304:        cmp     cltwant_, bx    / if (cltwant != 0)
        !          94305:        je      1f
        !          94306:        mov     cltwant_, bx    / cltwant = 0
        !          94307:        mov     cx, $cltwant_   / wakeup(&cltwant)
        !          94308:        push    bx      / save
        !          94309:        push    dx      / save
        !          94310:        push    ax      / save
        !          94311:        push    cx
        !          94312:        call    wakeup_
        !          94313:        pop     cx      / clear stack
        !          94314:        pop     ax      / restore
        !          94315:        pop     dx      / restore
        !          94316:        pop     bx      / restore
        !          94317: 
        !          94318: 1:     mov     8(bp), bx       / cqp->cq_ox = ox
        !          94319:        mov     cx, ax
        !          94320:        call    spl_            / spl(s)
        !          94321:        add     sp, $2
        !          94322:        mov     ax, cx
        !          94323: 
        !          94324: 2:     pop     bp
        !          94325:        mov     si, dx
        !          94326:        ret
        !          94327: 
        !          94328:        .globl  putq_
        !          94329: 
        !          94330: putq_:
        !          94331:        mov     dx, si
        !          94332:        push    bp
        !          94333:        mov     bp, sp
        !          94334: 
        !          94335:        mov     cx, 6(bp)       / cx = c
        !          94336:        mov     bp, 4(bp)       / bp = cqp
        !          94337:        sub     ax, ax          / ax = 0
        !          94338:        pushf                   / s =
        !          94339:        cli                     / sphi()
        !          94340:        mov     si, 2(bp)       / si = ip = cqp->cq_ip
        !          94341:        mov     bx, 4(bp)       / bx = ix = cqp->cq_ix
        !          94342:        cmp     bx, ax          / if (ix == 0)
        !          94343:        jne     2f
        !          94344:        mov     si, cltfree_    / ip = cltfree
        !          94345:        cmp     si, ax          / if (ip == 0)
        !          94346:        jne     0f
        !          94347:        call    spl_            / spl(s)
        !          94348:        add     sp, $2
        !          94349:        mov     ax, $-1         / return (-1)
        !          94350:        jmp     3f
        !          94351: 
        !          94352: 0:     mov     bx, (si)        / tmp = ip->cl_fp
        !          94353:        mov     cltfree_, bx    / cltfree = tmp
        !          94354:        mov     (si), ax        / ip->cl_fp = 0
        !          94355:        mov     bx, 2(bp)       / np = cqp->cq_ip
        !          94356:        cmp     bx, ax          / if (np == 0)
        !          94357:        jne     0f
        !          94358:        mov     6(bp), si       / cqp->cq_op = ip
        !          94359:        jmp     1f
        !          94360: 
        !          94361: 0:     mov     (bx), si        / np->cl_fp = ip
        !          94362: 
        !          94363: 1:     mov     2(bp), si       / cqp->cq_ip = ip
        !          94364:        mov     bx, ax          / bx = ix = cqp->cq_ix = 0
        !          94365: 
        !          94366: 2:     movb    2(bx,si), cl    / ip->cl_ch[ix] = c
        !          94367:        inc     bx              / ix++
        !          94368:        cmp     bx, $NCPCL      / if (ix == NCPCL)
        !          94369:        jne     0f
        !          94370:        mov     bx, ax          / ix = 0
        !          94371: 
        !          94372: 0:     mov     4(bp), bx       / cqp->cq_ix = ix
        !          94373:        inc     (bp)            / cqp->cq_cc++
        !          94374:        call    spl_            / spl(s)
        !          94375:        add     sp, $2
        !          94376:        mov     ax, cx          / return (c)
        !          94377: 
        !          94378: 3:     pop     bp
        !          94379:        mov     si, dx
        !          94380:        ret
        !          94381: 
        !          94382:        .globl  clrq_
        !          94383: 
        !          94384: clrq_:
        !          94385:        push    si
        !          94386:        push    di
        !          94387:        push    bp
        !          94388:        mov     bp, sp
        !          94389: 
        !          94390:        mov     si, 0x08(bp)
        !          94391:        call    sphi_
        !          94392:        mov     di, ax
        !          94393: 
        !          94394: L18:   push    si
        !          94395:        call    getq_
        !          94396:        add     sp, $0x02
        !          94397:        or      ax, ax
        !          94398:        jge     L18
        !          94399:        push    di
        !          94400:        call    spl_
        !          94401:        add     sp, $0x02
        !          94402: 
        !          94403:        pop     bp
        !          94404:        pop     di
        !          94405:        pop     si
        !          94406:        ret
        !          94407: 
        !          94408:        .globl  waitq_
        !          94409: 
        !          94410: waitq_:
        !          94411:        push    si
        !          94412:        push    di
        !          94413:        push    bp
        !          94414:        mov     bp, sp
        !          94415: 
        !          94416: L21:   cmp     cltfree_, $0x00
        !          94417:        jne     L19
        !          94418:        mov     cltwant_, $0x01
        !          94419:        sub     ax, ax
        !          94420:        push    ax
        !          94421:        push    ax
        !          94422:        mov     ax, $0x0100
        !          94423:        push    ax
        !          94424:        mov     ax, $cltwant_
        !          94425:        push    ax
        !          94426:        call    sleep_
        !          94427:        add     sp, $0x08
        !          94428:        jmp     L21
        !          94429: 
        !          94430: L19:   pop     bp
        !          94431:        pop     di
        !          94432:        pop     si
        !          94433:        ret
        !          94434: 0707070064030147721006440000030000030000011777770507310717500005300000003433/newbits/kernel/USRSRC/i8086/src/clocked.c/*
        !          94435:  * clocked.c - support routines for alternate clock rate
        !          94436:  *
        !          94437:  *  altclk_in(hz, fn) - install routine with specified rate
        !          94438:  *                      "hz" should be a multiple of system rate of 100 Hz
        !          94439:  *                     return 0 if completed ok, -1 otherwise
        !          94440:  *
        !          94441:  *  altclk_out()      - uninstall alternate clock routine and restore system rate
        !          94442:  *                     return old value of "altclk"
        !          94443:  *
        !          94444:  *  altclk_rate(hz)   - set clock interrupt rate
        !          94445:  *                     new rate must be an even multiple of system rate "HZ"
        !          94446:  *                     return 0 if completed ok, -1 otherwise
        !          94447:  *
        !          94448:  *  History:
        !          94449:  *    90/08/08 hws     initial version, works with hs.c modified for com[1-4]
        !          94450:  *    90/08/14 hws     make it more like a Unix system call
        !          94451:  */
        !          94452: 
        !          94453: #include       <sys/coherent.h>                /* altclk */
        !          94454: #include       <sys/const.h>           /* HZ */
        !          94455: 
        !          94456: #define        PIT     0x40            /* 8253 port */
        !          94457: #define        TMR0_M3 0x36            /* timer 0, mode 3 */
        !          94458: 
        !          94459: #if 0
        !          94460:                                /* nominal IBM rate is 1.1900 MHz */
        !          94461: #define        SYS_HZ  1190000L        /* rate of input clock to timer 0 */
        !          94462: #else
        !          94463:                                /* current kernel rate is 1.1932 MHz */
        !          94464: #define        SYS_HZ  1193200L        /* rate of input clock to timer 0 */
        !          94465: #endif
        !          94466: 
        !          94467: typedef int (*PFI)();          /* pointer to function returning int */
        !          94468: 
        !          94469: altclk_rate(hz)
        !          94470: unsigned int hz;
        !          94471: {
        !          94472:        int s;                  /* to save CPU irpt flag */
        !          94473:        unsigned int interval;  /* period for hz, in units of 1.19 MHz ticks */
        !          94474:        int ret;
        !          94475: 
        !          94476:        if (hz >= HZ && hz % HZ == 0) {         /* can't go slower than HZ! */
        !          94477:                interval = SYS_HZ/hz;
        !          94478:                s = sphi();                     /* disable irpts */
        !          94479:                outb(PIT+3, TMR0_M3);
        !          94480:                outb(PIT, interval & 0xff);
        !          94481:                outb(PIT, interval >> 8);       /* unsigned shift */
        !          94482:                spl(s);                         /* restore previous irpt state */
        !          94483:                ret = 0;
        !          94484:        } else {
        !          94485:                ret = -1;
        !          94486:        }
        !          94487:        return ret;
        !          94488: }
        !          94489: 
        !          94490: int altclk_in(hz, fn)
        !          94491: int hz;
        !          94492: PFI fn;
        !          94493: {
        !          94494:        int ret;
        !          94495: 
        !          94496:        if ((ret = altclk_rate(hz)) == 0)
        !          94497:                altclk = fn;
        !          94498:        return ret;
        !          94499: }
        !          94500: 
        !          94501: PFI altclk_out()
        !          94502: {
        !          94503:        PFI ret;
        !          94504: 
        !          94505:        ret = altclk;
        !          94506:        if (ret) {
        !          94507:                altclk_rate(HZ);
        !          94508:                altclk = 0;
        !          94509:        }
        !          94510:        return ret;
        !          94511: }
        !          94512: 0707070064030147701004440000030000030000011777770507310717600005200000000376/newbits/kernel/USRSRC/i8086/src/cs_sel.s////////
        !          94513: /
        !          94514: / Get cs selector - return 0 if in kernel, CS if not in kernel.
        !          94515: /
        !          94516: / This version is for resident drivers.
        !          94517: / There is a different version (cs_self.s) for loadable drivers.
        !          94518: /
        !          94519: / int  cs_sel();
        !          94520: /
        !          94521: ////////
        !          94522: 
        !          94523:        .globl  cs_sel_
        !          94524: cs_sel_:
        !          94525:        sub     ax, ax
        !          94526:        ret
        !          94527: 0707070064030147711006440000030000030000011777770507310717600005100000011606/newbits/kernel/USRSRC/i8086/src/defer.s/ $Header: /usr/src/sys/i8086/src/RCS/defer.s,v 1.2 88/04/04 17:05:05 src Exp $
        !          94528: /
        !          94529: /      The  information  contained herein  is a trade secret  of INETCO
        !          94530: /      Systems, and is confidential information.   It is provided under
        !          94531: /      a license agreement,  and may be copied or disclosed  only under
        !          94532: /      the terms of that agreement.   Any reproduction or disclosure of
        !          94533: /      this  material  without  the express  written  authorization  of
        !          94534: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          94535: /
        !          94536: /      Copyright (c) 1986
        !          94537: /      An unpublished work by INETCO Systems, Ltd.
        !          94538: /      All rights reserved.
        !          94539: /
        !          94540: 
        !          94541: ////////
        !          94542: /
        !          94543: / Defer a function [from interrupt level] for later execution
        !          94544: /
        !          94545: /      defer( f, a )   - defer a function [usually from interrupt level]
        !          94546: /      defend()        - execute deferred functions
        !          94547: /
        !          94548: / $Log:        /usr/src/sys/i8086/src/RCS/defer.s,v $
        !          94549: / Revision 1.2 88/04/04  17:05:05      src
        !          94550: / ldefer/ldefend functions now allow deferred functions from loadable drivers.
        !          94551: / 
        !          94552: / Revision 1.1 88/03/24  17:39:20      src
        !          94553: / Initial revision
        !          94554: / 
        !          94555: / 86/11/19     Allan Cornish           /usr/src/sys/i8086/src/defer.s
        !          94556: / defer(func,arg) and defend() functions ported to Coherent from RTX.
        !          94557: /
        !          94558: ////////
        !          94559: 
        !          94560:        .globl  defend_
        !          94561:        .globl  defer_
        !          94562:        .globl  ldefer
        !          94563: 
        !          94564:        .bssd
        !          94565: defunc:        .blkw   128             / static void (*defunc[128])();
        !          94566: defarg:        .blkw   128             / static char * defarg[128];
        !          94567: defqix:        .blkw   1               / static int defqix;
        !          94568: defqox:        .blkw   1               / static int defqox;
        !          94569: ldcseg:        .blkw   128             / static saddr_t ldcseg[128];
        !          94570: ldfunc:        .blkw   128             / static void (*ldfunc[128])();
        !          94571:        .shri
        !          94572: 
        !          94573: ////////
        !          94574: /
        !          94575: / void
        !          94576: / defer( f, a )                -- defer a function [usually from interrupt level]
        !          94577: / int (*f)();
        !          94578: / char *a;
        !          94579: /
        !          94580: /      Input:  f = pointer to function to be deferred.
        !          94581: /              a = argument to pass to function when it is invoked.
        !          94582: /
        !          94583: /      Action: Schedule function 'f' to be invoked with argument 'a'
        !          94584: /              during the transition from interrupt service level back
        !          94585: /              to user mode.
        !          94586: /
        !          94587: /      Return: None.
        !          94588: /
        !          94589: /      Notes:  13 instructions executed.  Interrupt latency = 7 instructions.
        !          94590: /              Only 127 functions can be deferred at any one time.
        !          94591: /              Exceeding this limit will cause loss of ALL deferred functions.
        !          94592: /
        !          94593: ////////
        !          94594: 
        !          94595: defer_:                                /
        !          94596:        pop     ax              / Convert IP into PSW,CS,IP to allow iret.
        !          94597:        pushf                   /
        !          94598:        push    cs              /
        !          94599:        push    ax              /
        !          94600:        mov     bx, sp          / defer( f, a )
        !          94601:        mov     ax, ss:6(bx)    / register int (*f)();          /* AX */
        !          94602:        mov     dx, ss:8(bx)    / register char *a;             /* DX */
        !          94603:                                / {
        !          94604:                                /       register int x;         /* BX */
        !          94605:                                /
        !          94606:        cli                     /       sphi();
        !          94607:        mov     bx, defqix      /       x = defqix;
        !          94608:        mov     defunc(bx), ax  /       defunc[x] = f;
        !          94609:        mov     defarg(bx), dx  /       defarg[x] = a;
        !          94610:        addb    defqix, $2      /       defqix++;
        !          94611: //     sti                     /       splo();
        !          94612:        iret                    / }
        !          94613: 
        !          94614: ////////
        !          94615: /
        !          94616: / void
        !          94617: / defend( )            -- evaluate deferred functions
        !          94618: /
        !          94619: /      Action: Evaluate all deferred functions.
        !          94620: /
        !          94621: /      Notes:  Should be called periodically by busy-wait device drivers.
        !          94622: /              4 + (n * 7) instructions executed, where n = # deferred func.
        !          94623: ////////
        !          94624: 
        !          94625: defend_:                       / defend()
        !          94626:                                / {
        !          94627:                                /
        !          94628:        mov     bx, defqox      /       register int x = defqox;    /* BX */
        !          94629:                                /
        !          94630:        cmp     bx, defqix      /       if ( x != defqix ) {
        !          94631:        je      1f              /
        !          94632:                                /               do {
        !          94633: 0:     addb    defqox, $2      /                       defqox++;
        !          94634:                                /
        !          94635:        push    defarg(bx)      /                       (*defunc[x])
        !          94636:        icall   defunc(bx)      /                               (defarg[x]);
        !          94637:        add     sp, $2          /
        !          94638:                                /
        !          94639:        mov     bx, defqox      /                       x = defqox;
        !          94640:        cmp     bx, defqix      /
        !          94641:        jne     0b              /               } while ( x != defqix );
        !          94642:                                /       }
        !          94643: 1:     ret                     / }
        !          94644: 
        !          94645: ////////
        !          94646: /
        !          94647: / void
        !          94648: / ldefer( f, a )       -- defer a far function [usually from interrupt level]
        !          94649: / int (far*f)();
        !          94650: / char *a;
        !          94651: /
        !          94652: /      Input:  f = pointer to loadable driver function to be deferred.
        !          94653: /              a = argument to pass to function when it is invoked.
        !          94654: /
        !          94655: /      Action: Schedule loadable driver function 'f' to be invoked with
        !          94656: /              argument 'a' during the transition from interrupt service
        !          94657: /              level back to user mode.
        !          94658: /
        !          94659: /      Return: None.
        !          94660: /
        !          94661: /      Notes:  16 instructions executed.  Interrupt latency = 8 instructions.
        !          94662: /              Only 127 functions can be deferred at any one time.
        !          94663: /              Exceeding this limit will cause loss of ALL deferred functions.
        !          94664: /
        !          94665: ////////
        !          94666: 
        !          94667: ldefer:                                /
        !          94668:        pop     ax              / Convert IP into PSW,CS,IP to allow iret.
        !          94669:        pushf                   /
        !          94670:        push    cs              /
        !          94671:        push    ax              /
        !          94672:        mov     bx, sp          / defer( f, a )
        !          94673:        mov     ax, ss:6(bx)    / register int (*f)();          /* CX:AX */
        !          94674:        mov     cx, ss:8(bx)    /
        !          94675:        mov     dx, ss:10(bx)   / register char *a;             /* DX */
        !          94676:                                / {
        !          94677:                                /       register int x;         /* BX */
        !          94678:                                /
        !          94679:        cli                     /       sphi();
        !          94680:        mov     bx, defqix      /       x = defqix;
        !          94681:        mov     ldfunc(bx), ax  /       ldfunc[x] = FP_OFF(f);
        !          94682:        mov     ldcseg(bx), cx  /       ldcseg[x] = FP_SEL(f);
        !          94683:        mov     defunc(bx),$ldefend/    defunc[x] = ldefend;
        !          94684:        mov     defarg(bx), dx  /       defarg[x] = a;
        !          94685:        addb    defqix, $2      /       defqix++;
        !          94686: //     sti                     /       splo();
        !          94687:        iret                    / }
        !          94688: 
        !          94689: ////////
        !          94690: /
        !          94691: / static void
        !          94692: / ldefend( )           -- evaluate deferred far function
        !          94693: /
        !          94694: /      Action: Evaluate deferred far function.
        !          94695: /
        !          94696: /      Notes:  Only called by defend().  Register BX contains driver's defqox.
        !          94697: /
        !          94698: ////////
        !          94699: 
        !          94700: ldefend:                       / PARAMETERS MUST REMAIN AT 4(BP).
        !          94701:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          94702:        mov     bp, sp          /
        !          94703:                                /
        !          94704:        mov     ax, ldfunc(bx)  / AX = Driver function to be invoked.
        !          94705:                                /
        !          94706:        push    ldcseg(bx)      / Define driver entry point.
        !          94707:        push    four            /
        !          94708:                                /
        !          94709:        xcall   -4(bp)          / Invoke driver entry point, which will
        !          94710:                                /       in turn invoke the deferred function.
        !          94711:                                /
        !          94712:        mov     sp, bp          / Return to caller.
        !          94713:        pop     bp              /
        !          94714:        ret                     /
        !          94715: 
        !          94716:        .prvd
        !          94717: four:  .word   4
        !          94718:        .shri
        !          94719: 0707070064030147671006440000030000030000011777770507310720000005300000007734/newbits/kernel/USRSRC/i8086/src/dmalock.c/* $Header: /usr/src/sys/i8086/src/RCS/dmalock.c,v 1.1 89/06/30 16:21:26 src Exp $
        !          94720:  *
        !          94721:  *     The  information  contained herein  is a trade secret  of INETCO
        !          94722:  *     Systems, Ltd, and is  confidential information.   It is provided
        !          94723:  *     under a license agreement,  and may be copied or disclosed  only
        !          94724:  *     under  the  terms  of  that  agreement.    Any  reproduction  or
        !          94725:  *     disclosure  of  this   material   without  the  express  written
        !          94726:  *     authorization of INETCO Systems, Ltd. or persuant to the license
        !          94727:  *     agreement is unlawful.
        !          94728:  *
        !          94729:  *     Copyright (c) 1989
        !          94730:  *     An unpublished work by INETCO Systems, Ltd.
        !          94731:  *     All rights reserved.
        !          94732:  *
        !          94733:  * $Description: $
        !          94734:  *     Routines to lock/unlock the DMA controller chip.
        !          94735:  *
        !          94736:  * $Author: src $
        !          94737:  *
        !          94738:  * $Creation: June 21, 1989 $
        !          94739:  *
        !          94740:  * $Log:       /usr/src/sys/i8086/src/RCS/dmalock.c,v $
        !          94741:  * Revision 1.1        89/06/30  16:21:26      src
        !          94742:  * Initial revision
        !          94743:  * 
        !          94744:  */
        !          94745: 
        !          94746: #include <sys/timeout.h>
        !          94747: 
        !          94748: typedef void (* vfp_t)();              /* Void function pointer type.       */
        !          94749: 
        !          94750: /*
        !          94751:  * If the following variable is non-zero, DMA controller locking is enabled,
        !          94752:  * allowing at access to only one DMA channel at a time.
        !          94753:  */
        !          94754: int DMALCK = 1;
        !          94755: 
        !          94756: static TIM * dmatail = (TIM *)0;       /* DMA deferred function queue tail. */
        !          94757: static TIM * dmahead = (TIM *)0;       /* DMA deferred function queue head. */
        !          94758: 
        !          94759: /*
        !          94760:  * int
        !          94761:  * dmalock( dfp, fun, arg )
        !          94762:  * TIM * dfp;
        !          94763:  * vfp_t fun;
        !          94764:  * int  arg;
        !          94765:  *
        !          94766:  *     Inputs: dfp  = Deferred function structure pointer.
        !          94767:  *             fun  = Function to call if request is deferred.
        !          94768:  *             arg  = Argument to pass to function.
        !          94769:  *
        !          94770:  *     Action: Either locks DMA controller immediately or defers function
        !          94771:  *             call until lock can be granted.
        !          94772:  *
        !          94773:  *     Return: 0 = Lock granted or -1 = Lock deferred.
        !          94774:  *
        !          94775:  *     Notes:  DMA controller locking was introduced to cure a bug on the
        !          94776:  *             NCR DMA controller, where overlapped DMA caused problems.
        !          94777:  *             No action is taken if DMA locking is disabled.
        !          94778:  */
        !          94779: 
        !          94780: int
        !          94781: dmalock( dfp, fun, arg )
        !          94782: register TIM  * dfp;
        !          94783: vfp_t          fun;
        !          94784: int            arg;
        !          94785: {
        !          94786:        register int s;         /* Interrupt mask state. */
        !          94787: 
        !          94788:        /*
        !          94789:         * If DMA locking is disabled, allow functions to proceed.
        !          94790:         */
        !          94791:        if ( DMALCK == 0 )
        !          94792:                return( 0 );
        !          94793: 
        !          94794:        /*
        !          94795:         * Record function and argument to be invoked upon dmaunlock.
        !          94796:         */
        !          94797:        dfp->t_func = fun;
        !          94798:        dfp->t_farg = arg;
        !          94799:        dfp->t_next = (TIM *)0;
        !          94800: 
        !          94801:        s = sphi();
        !          94802: 
        !          94803:        /*
        !          94804:         * If the queue is empty, put our structure at the head.
        !          94805:         */
        !          94806:        if ( dmahead == (TIM *)0 ) {
        !          94807:                dmahead = dfp;
        !          94808:                dmatail = dfp;
        !          94809:                spl( s );
        !          94810:                return( 0 );
        !          94811:        }
        !          94812: 
        !          94813:        /*
        !          94814:         * PARANOIA:    If our structure is already at the head of the queue,
        !          94815:         *              print a message and return.
        !          94816:         */
        !          94817:        if ( dmahead == dfp ) {
        !          94818:                spl( s );
        !          94819:                printf( "dmalock: driver attempting to doubly lock DMA controller.\n" );
        !          94820:                return( 0 );
        !          94821:        }
        !          94822: 
        !          94823:        /*
        !          94824:         * Append to tail of DMA deferred function queue.
        !          94825:         */
        !          94826:        dmatail->t_next = dfp;
        !          94827:        dmatail         = dfp;
        !          94828:        spl( s );
        !          94829:        return( -1 );
        !          94830: }
        !          94831: 
        !          94832: /*
        !          94833:  * void
        !          94834:  * dmaunlock( dfp )
        !          94835:  * TIM * dfp;
        !          94836:  *
        !          94837:  *     Inputs: dfp = Deferred function structure pointer.
        !          94838:  *
        !          94839:  *     Action: Unlocks the DMA controller and calls the next deferred
        !          94840:  *             function, if any.
        !          94841:  *
        !          94842:  *     Notes:  No action is taken if the deferred function structure pointer
        !          94843:  *             is not the same as the one used to lock the DMA controller.
        !          94844:  */
        !          94845: 
        !          94846: void
        !          94847: dmaunlock( dfp )
        !          94848: register TIM * dfp;
        !          94849: {
        !          94850:        register TIM *  qp;     /* Temporary function queue pointer.    */
        !          94851:        register int    s;      /* Interrupt mask state.                */
        !          94852: 
        !          94853:        s = sphi();
        !          94854: 
        !          94855:        /*
        !          94856:         * If the DMA controller is not locked, return.
        !          94857:         */
        !          94858:        if ( dmahead == (TIM *)0 ) {
        !          94859:                spl( s );
        !          94860:                return;
        !          94861:        }
        !          94862: 
        !          94863:        /*
        !          94864:         * If our lock is not the one holding the DMA controller:
        !          94865:         */
        !          94866:        if ( dmahead != dfp ) {
        !          94867: 
        !          94868:                /*
        !          94869:                 * Look for us in queue.
        !          94870:                 */
        !          94871:                for ( qp = dmahead; qp != dmatail; qp = qp->t_next )
        !          94872: 
        !          94873:                        /*
        !          94874:                         * If found, remove us.
        !          94875:                         */
        !          94876:                        if ( qp->t_next == dfp ) {
        !          94877:                                qp->t_next = dfp->t_next;
        !          94878: 
        !          94879:                                if ( dmatail == dfp )
        !          94880:                                        dmatail = qp;
        !          94881: 
        !          94882:                                break;
        !          94883:                        }
        !          94884: 
        !          94885:                spl( s );
        !          94886:                return;
        !          94887:        }
        !          94888: 
        !          94889:        /*
        !          94890:         * If there are no functions waiting for us, empty queue and return.
        !          94891:         */
        !          94892:        if ( dmahead == dmatail ) {
        !          94893:                dmahead = (TIM *)0;
        !          94894:                spl( s );
        !          94895:                return;
        !          94896:        }
        !          94897: 
        !          94898:        /*
        !          94899:         * Remove us and execute next deferred function.
        !          94900:         */
        !          94901:        dmahead = dmahead->t_next;
        !          94902:        spl( s );
        !          94903:        (*dmahead->t_func)( dmahead->t_farg, dmahead );
        !          94904: }
        !          94905: 
        !          94906: 0707070064030147661006440000030000030000011777770507310720200005000000043427/newbits/kernel/USRSRC/i8086/src/exec.c/* $Header: /usr/src/sys/i8086/src/RCS/exec.c,v 1.1 88/03/24 17:39:26 src Exp $ */
        !          94907: /* (lgl-
        !          94908:  *     The information contained herein is a trade secret of Mark Williams
        !          94909:  *     Company, and  is confidential information.  It is provided  under a
        !          94910:  *     license agreement,  and may be  copied or disclosed  only under the
        !          94911:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          94912:  *     material without the express written authorization of Mark Williams
        !          94913:  *     Company or persuant to the license agreement is unlawful.
        !          94914:  *
        !          94915:  *     COHERENT Version 2.3.37
        !          94916:  *     Copyright (c) 1982, 1983, 1984.
        !          94917:  *     An unpublished work by Mark Williams Company, Chicago.
        !          94918:  *     All rights reserved.
        !          94919:  -lgl) */
        !          94920: /*
        !          94921:  * This file contains a special version
        !          94922:  * of "sys exec" for the i8086. This version has
        !          94923:  * no driver load code in it (save space) and has
        !          94924:  * special load code so that the text of a shared
        !          94925:  * and separated image can be shared.
        !          94926:  * Loadable kernel processes are partially supported:
        !          94927:  * the process text and data must be ld'ed with the system
        !          94928:  * and the l.out executed must have no loadable or allocateable
        !          94929:  * segments.
        !          94930:  *
        !          94931:  * $Log:       /usr/src/sys/i8086/src/RCS/exec.c,v $
        !          94932:  * Revision 1.1        88/03/24  17:39:26      src
        !          94933:  * Initial revision
        !          94934:  * 
        !          94935:  * 88/01/21    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          94936:  * Segments are now de-associated from processes before freeing the segment.
        !          94937:  *
        !          94938:  * 87/12/03    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          94939:  * ld_start() now reverts to kernel mode [depth=0] from user mode [depth=1].
        !          94940:  *
        !          94941:  * 87/11/25    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          94942:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          94943:  *
        !          94944:  * 87/11/14    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          94945:  * Init code+data now split into icodep/icodes and idatap/idatas.
        !          94946:  *
        !          94947:  * 87/11/05    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          94948:  * New seg struct now used to allow extended addressing.
        !          94949:  *
        !          94950:  * 87/10/09    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          94951:  * pload() now handles new format [separate code] loadable device drivers.
        !          94952:  *
        !          94953:  * 87/10/08    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          94954:  * Exsread() initializes the (IO).io_flag field to 0.
        !          94955:  */
        !          94956: #include <sys/coherent.h>
        !          94957: #include <acct.h>
        !          94958: #include <sys/buf.h>
        !          94959: #include <canon.h>
        !          94960: #include <sys/con.h>
        !          94961: #include <errno.h>
        !          94962: #include <sys/filsys.h>
        !          94963: #include <sys/ino.h>
        !          94964: #include <sys/inode.h>
        !          94965: #include <l.out.h>
        !          94966: #include <sys/proc.h>
        !          94967: #include <sys/sched.h>
        !          94968: #include <sys/seg.h>
        !          94969: #include <signal.h>
        !          94970: #include <sys/uproc.h>
        !          94971: #include <sys/i8086.h>
        !          94972: 
        !          94973: /*
        !          94974:  * Sizes.
        !          94975:  */
        !          94976: #define        sh      ((fsize_t)sizeof(struct ldheader))
        !          94977: #define si     lssize[L_SHRI]
        !          94978: #define pi     lssize[L_PRVI]
        !          94979: #define bi     lssize[L_BSSI]
        !          94980: #define sd     lssize[L_SHRD]
        !          94981: #define pd     lssize[L_PRVD]
        !          94982: #define bd     lssize[L_BSSD]
        !          94983: 
        !          94984: /*
        !          94985:  * Segments.
        !          94986:  */
        !          94987: #define upsp   pp->p_segp[SIUSERP]
        !          94988: #define sssp   pp->p_segp[SISTACK]
        !          94989: #define        sisp    pp->p_segp[SISTEXT]
        !          94990: #define pisp   pp->p_segp[SIPTEXT]
        !          94991: #define pdsp   pp->p_segp[SIPDATA]
        !          94992: 
        !          94993: /*
        !          94994:  * Loadable driver initiation point.
        !          94995:  */
        !          94996: static
        !          94997: ld_start()
        !          94998: {
        !          94999:        register SEG * sp;
        !          95000:        register int ret;
        !          95001: 
        !          95002:        /*
        !          95003:         * Kernel processes start by default at user level.
        !          95004:         * Revert to kernel level.
        !          95005:         */
        !          95006:        if ( depth == 1 )
        !          95007:                depth--;
        !          95008: 
        !          95009:        /*
        !          95010:         * Initialize memory references.
        !          95011:         */
        !          95012:        u.u_btime = timer.t_time;
        !          95013:        sproto();
        !          95014:        segload();
        !          95015: 
        !          95016: 
        !          95017:        /*
        !          95018:         * Invoke the driver if it has a shared or private code segment.
        !          95019:         */
        !          95020:        ret = 100;
        !          95021:        if ( (sp = SELF->p_segp[SISTEXT]) || (sp = SELF->p_segp[SIPTEXT]) ) {
        !          95022:                ret = ld_xcall( sp->s_faddr );
        !          95023:        }
        !          95024: 
        !          95025:        uexit( ret );
        !          95026: }
        !          95027: 
        !          95028: /*
        !          95029:  * Set up the first process, a small programme which will exec
        !          95030:  * the init programme.
        !          95031:  */
        !          95032: eveinit(sp)
        !          95033: SEG *sp;
        !          95034: {
        !          95035:        register PROC *pp;
        !          95036:        SELF = pp = eprocp;
        !          95037: 
        !          95038:        /*
        !          95039:         * Record user area.
        !          95040:         */
        !          95041:        pp->p_segp[SIUSERP] = sp;
        !          95042: 
        !          95043:        /*
        !          95044:         * Allocate, record, initialize code segment, make it executable.
        !          95045:         */
        !          95046:        if ((sp=salloc((fsize_t)icodes, 0)) == NULL)
        !          95047:                panic("eveinit(code)");
        !          95048:        pp->p_segp[SIPTEXT] = sp;
        !          95049:        kfcopy( icodep, sp->s_faddr, icodes );
        !          95050:        sp->s_flags |= SFTEXT;
        !          95051:        vremap(sp);
        !          95052: 
        !          95053:        /*
        !          95054:         * Allocate, record, and initialize data segment.
        !          95055:         */
        !          95056:        if ((sp=salloc((fsize_t)idatas, 0)) == NULL)
        !          95057:                panic("eveinit(data)");
        !          95058:        pp->p_segp[SIPDATA] = sp;
        !          95059:        kfcopy( idatap, sp->s_faddr, idatas );
        !          95060: 
        !          95061:        /*
        !          95062:         * Allocate and record stack segment.
        !          95063:         */
        !          95064:        if ((sp=salloc((fsize_t)UPASIZE, SFDOWN)) == NULL)
        !          95065:                panic("eveinit()");
        !          95066:        pp->p_segp[SISTACK] = sp;
        !          95067: 
        !          95068:        /*
        !          95069:         * Start process.
        !          95070:         */
        !          95071:        u.u_argp = 0;
        !          95072:        if (sproto() == 0)
        !          95073:                panic("eveinit()");
        !          95074:        segload();
        !          95075: }
        !          95076: 
        !          95077: /*
        !          95078:  * Load a driver which has already been linked into the system image.
        !          95079:  */
        !          95080: pload( np )
        !          95081: char * np;
        !          95082: {
        !          95083:        register INODE * ip;
        !          95084:        register PROC  * cpp;
        !          95085:        struct seg     * sp;
        !          95086:        fsize_t         lssize[NUSEG];          /* Segment sizes */
        !          95087:        int             lflag;                  /* l_flags from l.out */
        !          95088:        vaddr_t         pc;                     /* l_entry from l.out */
        !          95089:        int             r;                      /* Flag for "exload" */
        !          95090:        int             s;
        !          95091:        extern char     end[];
        !          95092: 
        !          95093: 
        !          95094:        if (super() == 0) {
        !          95095:                return( -1 );
        !          95096:        }
        !          95097: 
        !          95098:        /*
        !          95099:         * Coalesce memory BEFORE loading driver, since it can't be moved.
        !          95100:         */
        !          95101:        krunch(10000);
        !          95102: 
        !          95103:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL) {
        !          95104:                return( -1 );
        !          95105:        }
        !          95106: 
        !          95107:        /*
        !          95108:         * New format loadable drivers must have separate code/data.
        !          95109:         * It must have executable code, but no initialized data.
        !          95110:         * Uninitialized data must match the kernel data size.
        !          95111:         */
        !          95112:        if ( ((lflag & (LF_KER|LF_SHR|LF_SEP)) != (LF_SEP|LF_KER))
        !          95113:          || (si==0) || (sd!=0) || (pd!=0) || (bd != (int)end) ) {
        !          95114:                u.u_error = EBADFMT;
        !          95115:                idetach(ip);
        !          95116:                return( -1 );
        !          95117:        }
        !          95118: 
        !          95119:        /*
        !          95120:         * Allocate and initialize driver code segment.
        !          95121:         * NOTE: Must be system segment to prevent relocation.
        !          95122:         */
        !          95123:        sp = ssalloc(&r, ip, SFTEXT|SFHIGH|SFNSWP|SFSYST, si+pi+bi, sh, si+pi);
        !          95124: 
        !          95125:        /*
        !          95126:         * Release driver object file.
        !          95127:         */
        !          95128:        idetach(ip);
        !          95129: 
        !          95130:        if ( r < 0 ) {
        !          95131:                u.u_error = ENOMEM;
        !          95132:                return( -1 );
        !          95133:        }
        !          95134: 
        !          95135:        /*
        !          95136:         * Spawn kernel process to service driver.
        !          95137:         */
        !          95138:        if ((cpp = process(ld_start)) == NULL ) {
        !          95139:                u.u_error = ENOMEM;
        !          95140:                sfree(sp);
        !          95141:                return( -1 );
        !          95142:        }
        !          95143: 
        !          95144:        /*
        !          95145:         * Record the basename of the loaded driver.
        !          95146:         */
        !          95147:        kscopy( u.u_direct.d_name, cpp->p_segp[SIUSERP],
        !          95148:                offset(uproc,u_comm[0]), sizeof(u.u_comm) );
        !          95149: 
        !          95150:        /*
        !          95151:         * Record the driver code segment in the process's private code.
        !          95152:         */
        !          95153:        cpp->p_segp[SIPTEXT] = sp;
        !          95154:        cpp->p_cval = CVCHILD;
        !          95155:        cpp->p_sval = SVCHILD;
        !          95156:        cpp->p_rval = RVCHILD;
        !          95157:        cpp->p_ppid = 1;
        !          95158: 
        !          95159:        /*
        !          95160:         * Make the process executable.
        !          95161:         */
        !          95162:        s = sphi();
        !          95163:        setrun( cpp );
        !          95164:        spl( s );
        !          95165: 
        !          95166:        /*
        !          95167:         * Return driver process id.
        !          95168:         */
        !          95169:        return( cpp->p_pid );
        !          95170: }
        !          95171: 
        !          95172: /*
        !          95173:  * Given a major number, undo the previous function.
        !          95174:  */
        !          95175: puload(m)
        !          95176: int m;
        !          95177: {
        !          95178:        register CON *cp;
        !          95179:        register DRV *dp;
        !          95180: 
        !          95181:        dp = &drvl[m];
        !          95182:        lock(dp->d_gate);
        !          95183:        if (m>=drvn || (cp=dp->d_conp)==NULL) {
        !          95184:                u.u_error = ENXIO;
        !          95185:                goto ret;
        !          95186:        }
        !          95187:        (*cp->c_uload)();
        !          95188:        if ( ! u.u_error)
        !          95189:                dp->d_conp = NULL;
        !          95190: ret:
        !          95191:        unlock(dp->d_gate);
        !          95192:        return (0);
        !          95193: }
        !          95194: 
        !          95195: /*
        !          95196:  * Pass control to an image in a file.
        !          95197:  * Make sure the format is acceptable. Release
        !          95198:  * the old segments. Read in the new ones. Some special
        !          95199:  * care is taken so that shared and (more important) shared
        !          95200:  * and separated images can be run on the 8086.
        !          95201:  */
        !          95202: pexece(np, argp, envp)
        !          95203: char   *np;
        !          95204: char   *argp[];
        !          95205: char   *envp[];
        !          95206: {
        !          95207:        register INODE  *ip;                    /* Load file INODE */
        !          95208:        register PROC   *pp;                    /* A cheap copy of SELF */
        !          95209:        register SEG    *ssp;                   /* New stack segment */
        !          95210:        register SEG    *segp;
        !          95211:        register fsize_t        ss;                     /* Segment size temp. */
        !          95212:        register int    i;                      /* For looping over segments */
        !          95213:        int             r;                      /* Flag for "exload" */
        !          95214:        int             lflag;                  /* l_flags from l.out */
        !          95215:        vaddr_t         pc;                     /* l_entry from l.out */
        !          95216:        vaddr_t         sp;                     /* Initial stack pointer */
        !          95217:        fsize_t         lssize[NUSEG];          /* Segment sizes */
        !          95218:        fsize_t         codsize;                /* Total if CS segment  */
        !          95219:        fsize_t         datsize;                /* Total of DS segment  */
        !          95220:        extern fsize_t  exround();              /* Paragraph rounder */
        !          95221: 
        !          95222:        pp = SELF;
        !          95223:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL) {
        !          95224:                return;
        !          95225:        }
        !          95226: 
        !          95227:        if ( (lflag & LF_SEP) == 0 ) {
        !          95228:                u.u_error = EBADFMT;
        !          95229:                idetach(ip);
        !          95230:                return;
        !          95231:        }
        !          95232: 
        !          95233:        /*
        !          95234:         * Kernel processes are now supported through the sload() system call.
        !          95235:         * 87/10/09     Allan Cornish.
        !          95236:         */
        !          95237:        if ((lflag&LF_KER) != 0) {
        !          95238:                u.u_error = EBADFMT;
        !          95239:                idetach(ip);
        !          95240:                return;
        !          95241:        }
        !          95242: 
        !          95243:        /*
        !          95244:         * If a shared and separated image
        !          95245:         * has stuff in segments that makes it impossible
        !          95246:         * to share, give an error immediately so that we don't
        !          95247:         * lose the parent.
        !          95248:         */
        !          95249:        lflag &= LF_SHR|LF_SEP;
        !          95250: 
        !          95251:        if (lflag==(LF_SHR|LF_SEP) && (pi!=0 || bi!=0)) {
        !          95252:                u.u_error = EBADFMT;
        !          95253:                idetach(ip);
        !          95254:                return;
        !          95255:        }
        !          95256: 
        !          95257:        if ((ssp=exstack(&sp, argp, envp)) == NULL) {
        !          95258:                idetach(ip);
        !          95259:                return;
        !          95260:        }
        !          95261: 
        !          95262:        switch (lflag) {
        !          95263:        case LF_SEP:
        !          95264:                codsize = si+pi+bi;
        !          95265:                datsize = ssp->s_size+sd+pd+bd;
        !          95266:                break;
        !          95267:        case LF_SHR|LF_SEP:
        !          95268:                codsize = si;
        !          95269:                datsize = ssp->s_size+exround(sd)+pd+bd;
        !          95270:                break;
        !          95271:        }
        !          95272:        codsize = (codsize+(BSIZE-1)) & ~(BSIZE-1);
        !          95273:        datsize = (datsize+(BSIZE-1)) & ~(BSIZE-1);
        !          95274:        if ( (codsize >= MAXU) || (datsize >= MAXU) ) {
        !          95275:                u.u_error = E2BIG;
        !          95276:                idetach(ip);
        !          95277:                return;
        !          95278:        }
        !          95279: 
        !          95280:        /*
        !          95281:         * At this point the file has been
        !          95282:         * validated as an object module, and the
        !          95283:         * argument list has been built. Release all of
        !          95284:         * the original segments. At this point we have
        !          95285:         * committed to the new image. A "sys exec" that
        !          95286:         * gets an I/O error is doomed.
        !          95287:         * NOTE: User-area segment is NOT released.
        !          95288:         *       Segment pointer in proc is erased BEFORE invoking sfree().
        !          95289:         */
        !          95290:        for ( i = 1; i < NUSEG; ++i ) {
        !          95291:                if ((segp = pp->p_segp[i]) != NULL) {
        !          95292:                        pp->p_segp[i] = NULL;
        !          95293:                        sfree(segp);
        !          95294:                }
        !          95295:        }
        !          95296: 
        !          95297:        /*
        !          95298:         * Read in the loadable segments.
        !          95299:         */
        !          95300:        sssp = ssp;
        !          95301:        switch (lflag) {
        !          95302:        case 0:
        !          95303:                ss = si+pi+sd+pd;
        !          95304:                pdsp = ssalloc(&r, ip, 0, ss+bi+bd, sh, ss);
        !          95305:                if (r < 0)
        !          95306:                        goto out;
        !          95307:                break;
        !          95308: 
        !          95309:        case LF_SHR:
        !          95310:                ss = exround(si+sd);
        !          95311:                pdsp = ssalloc(&r, ip, 0, ss+pi+pd+bi+bd, sh, si);
        !          95312:                if (r < 0)
        !          95313:                        goto out;
        !          95314:                if (exsread(pdsp, ip, sd, sh+si+pi, si) == NULL)
        !          95315:                        goto out;
        !          95316:                if (exsread(pdsp, ip, pi, sh+si, ss) == NULL)
        !          95317:                        goto out;
        !          95318:                if (exsread(pdsp, ip, pd, sh+si+pi+sd, ss+pi) == NULL)
        !          95319:                        goto out;
        !          95320:                break;
        !          95321: 
        !          95322:        case LF_SEP:
        !          95323:                pisp = ssalloc(&r, ip, SFTEXT, si+pi+bi, sh, si+pi);
        !          95324:                if (r < 0)
        !          95325:                        goto out;
        !          95326:                pdsp = ssalloc(&r, ip, 0, sd+pd+bd, sh+si+pi, sd+pd);
        !          95327:                if (r < 0)
        !          95328:                        goto out;
        !          95329:                break;
        !          95330: 
        !          95331:        case LF_SHR|LF_SEP:
        !          95332:                /* pi=0, bi=0 */
        !          95333:                sisp = ssalloc(&r, ip, SFSHRX|SFTEXT, si, sh, si);
        !          95334:                if (r < 0)
        !          95335:                        goto out;
        !          95336:                ss = exround(sd);
        !          95337:                pdsp = ssalloc(&r, ip, 0, ss+pd+bd, sh+si, sd);
        !          95338:                if (r<0 || exsread(pdsp, ip, pd, sh+si+sd, ss) == NULL)
        !          95339:                        goto out;
        !          95340:        }
        !          95341:        if (sproto() == 0)
        !          95342:                 goto out;
        !          95343: #if 0
        !          95344:        if ( (datsize != pdsp->s_size) ||
        !          95345:             ( (lflag==LF_SEP) && (codsize != pisp->s_size) ) ||
        !          95346:             ( (lflag==(LF_SEP|LF_SHR)) && (codsize != sisp->s_size) ) ) {
        !          95347:                printf("\nExec ERROR:  codsize: 0x%X  datsize: 0x%X\n", 
        !          95348:                                        codsize, datsize);
        !          95349:                printf(
        !          95350:                "pdsp->s_size: 0x%X  pisp->s_size: 0x%X  sisp->s_size: 0x%X\n",
        !          95351:                        pdsp->s_size, pisp->s_size, sisp->s_size);
        !          95352:        }
        !          95353: #endif
        !          95354:        /*
        !          95355:         * The new image is read in
        !          95356:         * and mapped. Perform the final grunge
        !          95357:         * (set-uid stuff, accounting, loading up
        !          95358:         * registers, etc).
        !          95359:         */
        !          95360:        u.u_flag &= ~AFORK;
        !          95361:        kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm));
        !          95362:        if (iaccess(ip, IPR) == 0) {    /* Can't read ? no dump or trace */
        !          95363:                pp->p_flags |= PFNDMP;
        !          95364:                pp->p_flags &= ~PFTRAC;
        !          95365:        }
        !          95366:        if (iaccess(ip, IPW) == 0)      /* Can't write ? no trace */
        !          95367:                pp->p_flags &= ~PFTRAC;
        !          95368:        if ((ip->i_mode&ISUID) != 0) {  /* Set user id ? no trace */
        !          95369:                pp->p_uid = u.u_uid = ip->i_uid;
        !          95370:                pp->p_flags &= ~PFTRAC;
        !          95371:        }
        !          95372:        if ((ip->i_mode&ISGID) != 0) {  /* Set group id ? no trace */
        !          95373:                u.u_gid = ip->i_gid;
        !          95374:                pp->p_flags &= ~PFTRAC;
        !          95375:        }
        !          95376:        for (i=0; i<NSIG; ++i)
        !          95377:                if (u.u_sfunc[i] != SIG_IGN)
        !          95378:                        u.u_sfunc[i] = SIG_DFL;
        !          95379:        if ((pp->p_flags&PFTRAC) != 0)  /* Being traced */
        !          95380:                sendsig(SIGTRAP, pp);
        !          95381:        idetach(ip);
        !          95382:        msetusr(pc, sp);
        !          95383:        segload();
        !          95384:        return (0);
        !          95385: 
        !          95386:        /*
        !          95387:         * We did not make it.
        !          95388:         * Release the INODE for the load
        !          95389:         * file, and return through the "sys exit"
        !          95390:         * code with a "SIGSYS", or with the signal actually received
        !          95391:         * if we are aborting due to interrupted exec.
        !          95392:         */
        !          95393: out:
        !          95394:        idetach(ip);
        !          95395:        if (u.u_error == EINTR)
        !          95396:                pexit(nondsig());
        !          95397:        pexit(SIGSYS);
        !          95398: }
        !          95399: 
        !          95400: /*
        !          95401:  * Open an l.out, make sure it is an l.out and executable and return the
        !          95402:  * appropriate information.
        !          95403:  */
        !          95404: INODE *
        !          95405: exlopen(np, ssizep, flagp, pcp)
        !          95406: char *np;
        !          95407: fsize_t *ssizep;
        !          95408: int *flagp;
        !          95409: vaddr_t *pcp;
        !          95410: {
        !          95411:        register INODE *ip;
        !          95412:        register struct ldheader *ldp;
        !          95413:        register int n;
        !          95414:        register BUF *bp;
        !          95415:        int m;
        !          95416: 
        !          95417:        /*
        !          95418:         * Make sure the file is really an executable l.out and read the
        !          95419:         * header in.
        !          95420:         */
        !          95421:        if (ftoi(np, 'r') != 0)
        !          95422:                return (NULL);
        !          95423:        ip = u.u_cdiri;
        !          95424:        if (iaccess(ip, IPE) == 0) {
        !          95425:                idetach(ip);
        !          95426:                return (NULL);
        !          95427:        }
        !          95428:        if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) {
        !          95429:                u.u_error = EACCES;
        !          95430:                idetach(ip);
        !          95431:                return (NULL);
        !          95432:        }
        !          95433:        if ((bp=vread(ip, (daddr_t)0)) == NULL) {
        !          95434:                u.u_error = EBADFMT;
        !          95435:                idetach(ip);
        !          95436:                return (NULL);
        !          95437:        }
        !          95438: 
        !          95439:        /*
        !          95440:         * Copy everything we need from the l.out header and check magic
        !          95441:         * number and machine type.
        !          95442:         */
        !          95443:        ldp = FP_OFF(bp->b_faddr);
        !          95444:        m = ldp->l_magic;
        !          95445:        canint(m);
        !          95446:        if (m != L_MAGIC) {
        !          95447:                u.u_error = ENOEXEC;
        !          95448:                brelease(bp);
        !          95449:                idetach(ip);
        !          95450:                return (NULL);
        !          95451:        }
        !          95452:        m = ldp->l_machine;
        !          95453:        canint(m);
        !          95454:        if (m != mactype) {
        !          95455:                u.u_error = EBADFMT;
        !          95456:                brelease(bp);
        !          95457:                idetach(ip);
        !          95458:                return (NULL);
        !          95459:        }
        !          95460:        kkcopy(ldp->l_ssize, ssizep, NXSEG*sizeof(fsize_t));
        !          95461:        for (n=0; n<NXSEG; n++)
        !          95462:                cansize(ssizep[n]);
        !          95463:        *flagp = ldp->l_flag;
        !          95464:        canint(*flagp);
        !          95465:        *pcp = ldp->l_entry;
        !          95466:        canvaddr(*pcp);
        !          95467:        brelease(bp);
        !          95468:        return (ip);
        !          95469: }
        !          95470: 
        !          95471: /*
        !          95472:  * Given a segment `sp', read `ss' bytes from the inode `ip' starting
        !          95473:  * at seek address `sa' into offset `so' in the segment.
        !          95474:  */
        !          95475: SEG *
        !          95476: exsread(sp, ip, ss, sa, so)
        !          95477: register SEG *sp;
        !          95478: INODE *ip;
        !          95479: fsize_t ss;
        !          95480: fsize_t sa;
        !          95481: fsize_t so;
        !          95482: {
        !          95483:        while (ss > 0) {
        !          95484:                u.u_io.io_seg = IOPHY;
        !          95485:                u.u_io.io_seek = sa;
        !          95486:                u.u_io.io_phys = sp->s_paddr + so;
        !          95487:                u.u_io.io_flag = 0;
        !          95488:                if (ss >= 4096) {
        !          95489:                        u.u_io.io_ioc = 4096;
        !          95490:                        ss -= 4096;
        !          95491:                } else {
        !          95492:                        u.u_io.io_ioc = ss;
        !          95493:                        ss = 0;
        !          95494:                }
        !          95495:                sp->s_lrefc++;
        !          95496:                iread(ip, &u.u_io);
        !          95497:                sp->s_lrefc--;
        !          95498:                if (nondsig()) {
        !          95499:                        u.u_error = EINTR;
        !          95500:                        break;
        !          95501:                }
        !          95502:                sa += 4096;
        !          95503:                so += 4096;
        !          95504:        }
        !          95505:        if (u.u_error == 0)
        !          95506:                return (sp);
        !          95507:        return (NULL);
        !          95508: }
        !          95509: 
        !          95510: /*
        !          95511:  * Given a pointer to a list of arguments and a pointer to a list of
        !          95512:  * environments, return a stack with the arguments and environments on it.
        !          95513:  */
        !          95514: SEG *
        !          95515: exstack(iusp, argp, envp)
        !          95516: char **iusp;           /* Back patch sp value */
        !          95517: char *argp[];          /* Arguments for new process */
        !          95518: char *envp[];          /* Environments for new process */
        !          95519: {
        !          95520:        SEG *sp;                /* Stack segment pointer */
        !          95521:        struct adata {          /* Storage for arg and env data */
        !          95522:                char    **up;           /* User vector pointer */
        !          95523:                int     np;             /* Number of pointers in vector */
        !          95524:                int     nc;             /* Number of characters in strings */
        !          95525:        } arg, env;
        !          95526:        struct sdata {          /* To keep segment pointers */
        !          95527:                vaddr_t base;           /* Top of segment virtual */
        !          95528:                vaddr_t ap;             /* Argc, argv, envp pointer */
        !          95529:                vaddr_t vp;             /* Argv[i], envp[i] pointer */
        !          95530:                vaddr_t cp;             /* Argv[i][j], envp[i][j] pointer */
        !          95531:        } aux, stk;
        !          95532:        aold_t aold;                    /* Auxiliary map storage */
        !          95533:        register char **usrvp;          /* Vector pointer into user seg */
        !          95534:        register char *usrcp;           /* Character pointer into user seg */
        !          95535:        register int c;                 /* Character fetched from user */
        !          95536:        register int chrsz;             /* Size of strings */
        !          95537:        register struct adata *adp;     /* Arg and env scanner */
        !          95538:        register int vecsz;             /* Size of vectors */
        !          95539:        register int stksz;             /* Size of stack argument region */
        !          95540: 
        !          95541:        /* Validate and evaluate size of args and envs */
        !          95542:        arg.up = argp;
        !          95543:        env.up = envp;
        !          95544:        chrsz = 0;
        !          95545:        vecsz = 0;
        !          95546:        for (adp = &arg; ; adp = &env) {
        !          95547:                adp->np = 0;
        !          95548:                adp->nc = 0;
        !          95549:                if (excount(adp->up, &adp->np, &adp->nc) == 0)
        !          95550:                        return (NULL);
        !          95551:                chrsz += adp->nc * sizeof(char);
        !          95552:                vecsz += adp->np * sizeof(char *);
        !          95553:                if (adp == &env)
        !          95554:                        break;
        !          95555:        }
        !          95556: 
        !          95557:        /* Calculate stack size and allocate it */
        !          95558:        chrsz = roundu(chrsz, sizeof(int));
        !          95559:        stksz = sizeof(int)             /* argc */
        !          95560:                + sizeof(char **)       /* argv */
        !          95561:                + sizeof(char **)       /* envp */
        !          95562:                + vecsz                 /* argv[i] and envp[i] */
        !          95563:                + chrsz                 /* *argv[i] and *envp[i] */
        !          95564:                + sizeof(int)           /* Mystery zero word */
        !          95565:                + sizeof(char *)        /* Splimit for z8000 */
        !          95566:                + sizeof(int);          /* errno */
        !          95567:        stksz += ISTSIZE;
        !          95568:        if (stksz > MADSIZE) {
        !          95569:                u.u_error = E2BIG;
        !          95570:                return (NULL);
        !          95571:        }
        !          95572:        if ((sp=salloc((fsize_t)stksz, SFDOWN)) == NULL)
        !          95573:                return (NULL);
        !          95574:        stksz -= ISTSIZE;
        !          95575: 
        !          95576:        /*
        !          95577:         * Initialize segment data.
        !          95578:         */
        !          95579:        asave(aold);
        !          95580: 
        !          95581:        abase(FP_SEL(sp->s_faddr));
        !          95582:        aux.base = sp->s_size;
        !          95583:        aux.ap = aux.base - stksz;
        !          95584:        aux.vp = aux.ap + sizeof(int) + 2*sizeof(char **);
        !          95585:        aux.cp = aux.vp + vecsz;
        !          95586: 
        !          95587:        stk.base = ISTVIRT;
        !          95588:        stk.ap = stk.base - stksz;
        !          95589:        stk.vp = stk.ap + sizeof(int) + 2*sizeof(char **);
        !          95590:        stk.cp = stk.vp + vecsz;
        !          95591: 
        !          95592:        /*
        !          95593:         * Write argc.
        !          95594:         */
        !          95595:        aputi((int *)aux.ap, arg.np-1);
        !          95596:        aux.ap += sizeof(int);
        !          95597: 
        !          95598:        /*
        !          95599:         * Arguments and environments.
        !          95600:         */
        !          95601:        for (adp = &arg; ; adp = &env) {
        !          95602: 
        !          95603:                /* Write argv or envp */
        !          95604:                aputp((char ***)aux.ap, (char **)stk.vp);
        !          95605:                aux.ap += sizeof(char **);
        !          95606:                if ((usrvp = adp->up) != NULL) {
        !          95607: 
        !          95608:                        /* Write argv[i] or envp[i] */
        !          95609:                        while ((usrcp = getupd(usrvp++)) != NULL) {
        !          95610:                                aputp((char **)aux.vp, (char *)stk.cp);
        !          95611:                                aux.vp += sizeof(char *);
        !          95612:                                stk.vp += sizeof(char *);
        !          95613: 
        !          95614:                                /* Write argv[i][j] or envp[i][j] */
        !          95615:                                do {
        !          95616:                                        c = getubd(usrcp++);
        !          95617:                                        aputc((char *)aux.cp, c);
        !          95618:                                        aux.cp += sizeof(char);
        !          95619:                                        stk.cp += sizeof(char);
        !          95620:                                } while (c != '\0');
        !          95621:                        }
        !          95622:                }
        !          95623: 
        !          95624:                /* Write argv[argc] or envp[envc] */
        !          95625:                aputp((char **)aux.vp, NULL);
        !          95626:                aux.vp += sizeof(char *);
        !          95627:                stk.vp += sizeof(char *);
        !          95628:                if (adp == &env)
        !          95629:                        break;
        !          95630:        }
        !          95631: 
        !          95632:        /*
        !          95633:         * Clear out the slop.
        !          95634:         */
        !          95635:        aux.base -= sizeof(int);
        !          95636:        aputi((int *) aux.base, 0);             /* errno */
        !          95637:        aux.base -= sizeof(char *);
        !          95638:        aputp((char **) aux.base, (char *)stk.base - sp->s_size + SOVSIZE);
        !          95639:        aux.base -= sizeof(int);
        !          95640:        aputi((int *) aux.base, 0);             /* mystery word */
        !          95641: 
        !          95642:        arest(aold);
        !          95643: 
        !          95644:        /*
        !          95645:         * Patch some values and return.
        !          95646:         */
        !          95647:        *iusp = stk.ap;         /* Patch initial usp */
        !          95648:        u.u_argc = arg.np-1;
        !          95649:        u.u_argp = stk.vp;      /* Points after NULL of envs */
        !          95650:        return (sp);
        !          95651: }
        !          95652: 
        !          95653: /*
        !          95654:  * Given a pointer to a list of arguments, a pointer to an argument count
        !          95655:  * and a pointer to a byte count, update incrementally the argument count
        !          95656:  * and the byte count.
        !          95657:  */
        !          95658: excount(usrvp, nap, nbp)
        !          95659: register char **usrvp;
        !          95660: int *nap;
        !          95661: int *nbp;
        !          95662: {
        !          95663:        register char *usrcp;
        !          95664:        register int c;
        !          95665:        register unsigned nb;
        !          95666:        register unsigned na;
        !          95667: 
        !          95668:        na = 1;
        !          95669:        nb = 0;
        !          95670:        if (usrvp != NULL) {
        !          95671:                for (;;) {
        !          95672:                        usrcp = getupd(usrvp++);
        !          95673:                        if (u.u_error)
        !          95674:                                return (0);
        !          95675:                        if (usrcp == NULL)
        !          95676:                                break;
        !          95677:                        na++;
        !          95678:                        for (;;) {
        !          95679:                                c = getubd(usrcp++);
        !          95680:                                if (u.u_error)
        !          95681:                                        return (0);
        !          95682:                                nb++;
        !          95683:                                if (c == '\0')
        !          95684:                                        break;
        !          95685:                        }
        !          95686:                }
        !          95687:        }
        !          95688:        *nap += na;
        !          95689:        *nbp += nb;
        !          95690:        return (1);
        !          95691: }
        !          95692: 
        !          95693: /*
        !          95694:  * Round up a size to a paragraph
        !          95695:  * (mod 16) boundry.
        !          95696:  * This is really mod 512 to make swapping work
        !          95697:  */
        !          95698: fsize_t
        !          95699: exround(s)
        !          95700: fsize_t        s;
        !          95701: {
        !          95702:        return ((s+15)&~0x0F);
        !          95703: }
        !          95704: 0707070064030147651006440000030000030000011777770507310720700005200000007677/newbits/kernel/USRSRC/i8086/src/krunch.c/* $Header: /usr/src/sys/i8086/src/RCS/krunch.c,v 1.1 88/03/24 17:39:33 src Exp $ */
        !          95705: /*
        !          95706:  *     The  information  contained herein  is a trade secret  of INETCO
        !          95707:  *     Systems, and is confidential information.   It is provided under
        !          95708:  *     a license agreement,  and may be copied or disclosed  only under
        !          95709:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          95710:  *     this  material  without  the express  written  authorization  of
        !          95711:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          95712:  *
        !          95713:  *     Copyright (c) 1987.
        !          95714:  *     An unpublished work by INETCO Systems, Ltd.
        !          95715:  *     All rights reserved.
        !          95716:  */
        !          95717: 
        !          95718: /*
        !          95719:  * Coherent.
        !          95720:  * Segment crunch.
        !          95721:  *
        !          95722:  * $Log:       /usr/src/sys/i8086/src/RCS/krunch.c,v $
        !          95723:  * Revision 1.1        88/03/24  17:39:33      src
        !          95724:  * Initial revision
        !          95725:  * 
        !          95726:  * 87/12/02    Allan Cornish   /usr/src/sys/i8086/src/krunch.c
        !          95727:  * krunch() now locks/unlocks segment gate.
        !          95728:  *
        !          95729:  * 87/11/26    Allan Cornish   /usr/src/sys/i8086/src/krunch.c
        !          95730:  * krunch() now called to merge unused memory by moving segments.
        !          95731:  */
        !          95732: #include <sys/coherent.h>
        !          95733: #include <sys/i8086.h>
        !          95734: #include <sys/proc.h>
        !          95735: #include <sys/seg.h>
        !          95736: 
        !          95737: /*
        !          95738:  * Time interval in clock ticks between krunch attempts: default 2 seconds.
        !          95739:  */
        !          95740: int KRUNCH = 200;
        !          95741: 
        !          95742: /**
        !          95743:  *
        !          95744:  * krunch( n )
        !          95745:  * int n;
        !          95746:  *
        !          95747:  *     Input:  n = maximum number of segments to be moved.
        !          95748:  *
        !          95749:  *     Action: Scan the segmentation list, looking for unused memory
        !          95750:  *             immediately below unlocked application segments,
        !          95751:  *             moving the segment down into the unused memory.
        !          95752:  */
        !          95753: krunch( n )
        !          95754: int n;
        !          95755: {
        !          95756:        register SEG *sp;
        !          95757:        paddr_t paddr;
        !          95758:        saddr_t osel;
        !          95759:        static TIM tim;
        !          95760:        int s;
        !          95761: 
        !          95762:        if ( depth != 0 ) {
        !          95763:                printf("krunch(%d,depth=%d) ", n, depth );      /** DEBUG **/
        !          95764:                return;
        !          95765:        }
        !          95766: 
        !          95767:        /*
        !          95768:         * Do not crunch segment list if swapper is active.
        !          95769:         */
        !          95770:        if ( (KRUNCH == 0) || (sexflag != 0) )
        !          95771:                return;
        !          95772: 
        !          95773:        /*
        !          95774:         * Segment count of 0 indicates a request to schedule delayed krunch(1).
        !          95775:         */
        !          95776:        if ( n <= 0 ) {
        !          95777:                if ( tim.t_last != NULL )
        !          95778:                        timeout( &tim, KRUNCH, krunch, 1 );
        !          95779:                return;
        !          95780:        }
        !          95781: 
        !          95782:        /*
        !          95783:         * Segmentation is locked - retry later.
        !          95784:         */
        !          95785:        s = sphi();
        !          95786:        if ( locked(seglink) ) {
        !          95787:                timeout( &tim, KRUNCH, krunch, n );
        !          95788:                spl(s);
        !          95789:                return;
        !          95790:        }
        !          95791:        lock(seglink);
        !          95792:        spl(s);
        !          95793: 
        !          95794: #if EBUG > 1
        !          95795:        printf("krunch(%d) ", n );
        !          95796: #endif
        !          95797: 
        !          95798:        for ( paddr = corebot, sp = &segmq;
        !          95799:              (sp = sp->s_forw) != &segmq ;
        !          95800:              paddr = sp->s_paddr + sp->s_size ) {
        !          95801: 
        !          95802:                /*
        !          95803:                 * No hole exists.
        !          95804:                 */
        !          95805:                if ( paddr == sp->s_paddr )
        !          95806:                        continue;
        !          95807: 
        !          95808: #if EBUG > 1
        !          95809:                printf("hole(p=%X,n=%X) seg(p=%X,n=%X,f=%x,u=%x,l=%x) ",
        !          95810:                        paddr,
        !          95811:                        sp->s_paddr - paddr,
        !          95812:                        sp->s_paddr,
        !          95813:                        sp->s_size,
        !          95814:                        sp->s_flags & (SFSYST|SFHIGH),
        !          95815:                        sp->s_urefc,
        !          95816:                        sp->s_lrefc );
        !          95817: #endif
        !          95818: 
        !          95819:                /*
        !          95820:                 * Don't try to shuffle high segments into low memory.
        !          95821:                 */
        !          95822:                if ( sp->s_flags & SFHIGH )
        !          95823:                        break;
        !          95824: 
        !          95825:                /*
        !          95826:                 * System segment.
        !          95827:                 */
        !          95828:                if ( sp->s_flags & SFSYST )
        !          95829:                        continue;
        !          95830: 
        !          95831:                /*
        !          95832:                 * Segment may be in process of being swapped in/out.
        !          95833:                 */
        !          95834:                if ( (sp->s_flags & SFCORE) == 0 )
        !          95835:                        continue;
        !          95836: 
        !          95837:                /*
        !          95838:                 * Segment is locked for I/O.
        !          95839:                 */
        !          95840:                if ( sp->s_lrefc != sp->s_urefc )
        !          95841:                        continue;
        !          95842: 
        !          95843: #if EBUG > 0
        !          95844:                printf("move(dst=%X,src=%X,len=%X) ",
        !          95845:                        paddr, sp->s_paddr,sp->s_size );
        !          95846: #endif
        !          95847:                /*
        !          95848:                 * Remember previous virtual address.
        !          95849:                 */
        !          95850:                osel = FP_SEL(sp->s_faddr);
        !          95851: 
        !          95852:                /*
        !          95853:                 * Shift segment into the hole.
        !          95854:                 */
        !          95855:                plrcopy( sp->s_paddr, paddr, sp->s_size );
        !          95856:                sp->s_paddr = paddr;
        !          95857:                vremap( sp );
        !          95858: 
        !          95859: #if EBUG > 0
        !          95860:                if ( FP_SEL(sp->s_faddr) != osel ) {
        !          95861:                        printf("krunch: osel=%x nsel=%x\n",
        !          95862:                                osel, FP_SEL(sp->s_faddr) );
        !          95863:                }
        !          95864: #endif
        !          95865: 
        !          95866:                /*
        !          95867:                 * Ensure user segmentation is updated.
        !          95868:                 * We may have moved the current process.
        !          95869:                 */
        !          95870:                if ( (SELF->p_pid != 0) && ((ucs == osel) || (uds == osel)) )
        !          95871:                        segload();
        !          95872:                if ( uasa == osel )
        !          95873:                        uasa = FP_SEL(sp->s_faddr);
        !          95874: 
        !          95875:                /*
        !          95876:                 * Crunch count reached.
        !          95877:                 */
        !          95878:                if ( --n <= 0 )
        !          95879:                        break;
        !          95880:        }
        !          95881: 
        !          95882:        /*
        !          95883:         * Cancel timer if all low memory holes eliminated.
        !          95884:         */
        !          95885:        if ( (KRUNCH == 0) || (sp == &segmq) || (sp->s_flags & SFHIGH) )
        !          95886:                timeout( &tim, 0, NULL, 0 );
        !          95887: 
        !          95888:        /*
        !          95889:         * Attempt to crunch another segment in KRUNCH clock ticks.
        !          95890:         */
        !          95891:        else
        !          95892:                timeout( &tim, KRUNCH, krunch, 1 );
        !          95893: 
        !          95894:        unlock(seglink);
        !          95895: 
        !          95896: #if EBUG > 0
        !          95897:        printf("\n");
        !          95898: #endif
        !          95899: }
        !          95900: 0707070064030147641006440000030000030000011777770507310721000004600000004047/newbits/kernel/USRSRC/i8086/src/ld.c/* $Header: /usr/src/sys/i8086/src/RCS/ld.c,v 1.1 88/03/24 17:39:36 src Exp $
        !          95901:  *
        !          95902:  *     The  information  contained herein  is a trade secret  of INETCO
        !          95903:  *     Systems, and is confidential information.   It is provided under
        !          95904:  *     a license agreement,  and may be copied or disclosed  only under
        !          95905:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          95906:  *     this  material  without  the express  written  authorization  of
        !          95907:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          95908:  *
        !          95909:  *     Copyright (c) 1986
        !          95910:  *     An unpublished work by INETCO Systems, Ltd.
        !          95911:  *     All rights reserved.
        !          95912:  */
        !          95913: 
        !          95914: /*
        !          95915:  * Pseudo-Device Interface to Loadable Drivers.
        !          95916:  *
        !          95917:  * $Log:       /usr/src/sys/i8086/src/RCS/ld.c,v $
        !          95918:  * Revision 1.1        88/03/24  17:39:36      src
        !          95919:  * Initial revision
        !          95920:  * 
        !          95921:  * 87/12/08    Allan Cornish   /usr/src/sys/i8086/src/ld.c
        !          95922:  * Block device interface added to loadable drivers.
        !          95923:  *
        !          95924:  * 87/10/25    Allan Cornish           /usr/src/sys/i8086/drv/ld.c
        !          95925:  * Initial version.
        !          95926:  */
        !          95927: 
        !          95928: #include       <sys/coherent.h>
        !          95929: #include       <sys/fdisk.h>
        !          95930: #include       <sys/buf.h>
        !          95931: #include       <sys/con.h>
        !          95932: #include       <sys/stat.h>
        !          95933: #include       <sys/uproc.h>
        !          95934: #include       <errno.h>
        !          95935: 
        !          95936: /*
        !          95937:  * Driver configuration.
        !          95938:  */
        !          95939: void   ld_open();
        !          95940: void   ld_close();
        !          95941: void   ld_read();
        !          95942: void   ld_write();
        !          95943: void   ld_block();
        !          95944: int    ld_ioctl();
        !          95945: void   ld_power();
        !          95946: void   ld_time();
        !          95947: int    ld_poll();
        !          95948: void   nulldev();
        !          95949: void   nonedev();
        !          95950: 
        !          95951: /*
        !          95952:  * Loadable driver: Pseudeo-device configuration.
        !          95953:  */
        !          95954: CON ldrvpsy = {
        !          95955:        DFCHR|DFBLK|DFPOL,              /* Flags */
        !          95956:        0,                              /* Major index */
        !          95957:        ld_open,                        /* Open */
        !          95958:        ld_close,                       /* Close */
        !          95959:        ld_block,                       /* Block */
        !          95960:        ld_read,                        /* Read */
        !          95961:        ld_write,                       /* Write */
        !          95962:        ld_ioctl,                       /* Ioctl */
        !          95963:        ld_power,                       /* Powerfail */
        !          95964:        ld_time,                        /* Timeout */
        !          95965:        nulldev,                        /* Load */
        !          95966:        nulldev,                        /* Unload */
        !          95967:        ld_poll                         /* Poll */
        !          95968: };
        !          95969: 
        !          95970: /*
        !          95971:  * Loadable driver: Code selectors.
        !          95972:  */
        !          95973: saddr_t ldrvsel[NDRV];
        !          95974: 
        !          95975: /*
        !          95976:  * Loadable driver: Pointers to driver configuration table.
        !          95977:  */
        !          95978: CON * ldrvcon[NDRV];
        !          95979: 
        !          95980: /*
        !          95981:  * Loadable driver: Selector referencing interrupt handler's code segment.
        !          95982:  */
        !          95983: saddr_t ldrvics[16];
        !          95984: 
        !          95985: /*
        !          95986:  * Loadable driver: Pointers to interrupt handlers within the loadable driver.
        !          95987:  */
        !          95988: void (*ldrvipc[16])();
        !          95989: 0707070064030147621006440000030000030000011777770507310721000005000000031676/newbits/kernel/USRSRC/i8086/src/ldas.s/ /usr/src/sys/i8086/src/ldas.s
        !          95990: / 
        !          95991: ////////
        !          95992: /
        !          95993: /      Loadable Driver Interface Routines.
        !          95994: /
        !          95995: /      Loadable drivers execute in separate code segments, and are unable
        !          95996: /      to directly call kernel service routines.
        !          95997: /      Loadable drivers call a kernel service stub within their code segment,
        !          95998: /      which has has the same name as the desired service routine.
        !          95999: /      The driver service stub performs a far call to one of these routines.
        !          96000: /      These routines perform a near call to the desired kernel routine,
        !          96001: /      and then perform a far return to the driver service stub routine.
        !          96002: /      The driver service stub routine then does a near return to the driver.
        !          96003: /
        !          96004: / 90/09/11  Hal Snyder
        !          96005: / Add ld_call()
        !          96006: /
        !          96007: / $Log:        /usr/src/sys/i8086/src/RCS/ldas.s,v $
        !          96008: / Revision 1.2 91/03/01  09:23:04      root
        !          96009: / Part of COHERENT 3.1.0 kernel
        !          96010: / 
        !          96011: / Revision 1.1 88/03/24  17:39:39      src
        !          96012: / Initial revision
        !          96013: / 
        !          96014: / 87/12/08     Allan Cornish   /usr/src/sys/i8086/src/ldas.s
        !          96015: / Block device interface added to loadable drivers.
        !          96016: / ldtimcall() function added to support timed functions in loadable drivers.
        !          96017: /
        !          96018: / 87/10/25     Allan Cornish   /usr/src/sys/i8086/src/ldas.s
        !          96019: / Initial version - interface to/from loadable driver processes.
        !          96020: /
        !          96021: ////////
        !          96022: 
        !          96023:        .globl  ld_xcall_
        !          96024:        .globl  ld_call_
        !          96025:        .globl  xcalled
        !          96026:        .globl  ldtimcall_
        !          96027:        .globl  ld_open_
        !          96028:        .globl  ld_close_
        !          96029:        .globl  ld_read_
        !          96030:        .globl  ld_write_
        !          96031:        .globl  ld_block_
        !          96032:        .globl  ld_ioctl_
        !          96033:        .globl  ld_power_
        !          96034:        .globl  ld_time_
        !          96035:        .globl  ld_poll_
        !          96036:        .globl  ldrvint_                / void  (*ldrvint[16])();
        !          96037: 
        !          96038: ////////
        !          96039: /
        !          96040: / Constants
        !          96041: /
        !          96042: ////////
        !          96043: 
        !          96044:        T_LDRV  = 12                    / Offset(tim,t_ldrv).
        !          96045:        B_FLAG  = 6                     / Offset(buf,b_flag).
        !          96046:        B_DEV   = 8                     / Offset(buf,b_dev ).
        !          96047:        BFERR   = 4                     / buf.b_flag bit set on I/O error.
        !          96048:        DRV_J   = 4                     / offset in driver of dispatcher
        !          96049: 
        !          96050: ////////
        !          96051: /
        !          96052: / External References
        !          96053: /
        !          96054: ////////
        !          96055: 
        !          96056:        .globl  nonedev_                / extern void    nonedev();
        !          96057:        .globl  ldrvcon_                / extern CON *   ldrvcon[NDRV];
        !          96058:        .globl  ldrvsel_                / extern saddr_t ldrvsel[NDRV];
        !          96059:        .globl  ldrvics_                / extern saddr_t ldrvics[16];
        !          96060:        .globl  ldrvipc_                / extern void  (*ldrvipc[16])();
        !          96061: 
        !          96062: ////////
        !          96063: /
        !          96064: / Shared Data
        !          96065: /
        !          96066: ////////
        !          96067:        .shrd
        !          96068: ldrvint_:                      / Loadable Driver Interrupt Entry Points.
        !          96069:        .word   ld_intr0
        !          96070:        .word   ld_intr1
        !          96071:        .word   ld_intr2
        !          96072:        .word   ld_intr3
        !          96073:        .word   ld_intr4
        !          96074:        .word   ld_intr5
        !          96075:        .word   ld_intr6
        !          96076:        .word   ld_intr7
        !          96077:        .word   ld_intr8
        !          96078:        .word   ld_intr9
        !          96079:        .word   ld_intr10
        !          96080:        .word   ld_intr11
        !          96081:        .word   ld_intr12
        !          96082:        .word   ld_intr13
        !          96083:        .word   ld_intr14
        !          96084:        .word   ld_intr15
        !          96085: 
        !          96086: ////////
        !          96087: /
        !          96088: / Private Data
        !          96089: /
        !          96090: ////////
        !          96091: 
        !          96092:        .prvd
        !          96093:        .shri
        !          96094: 
        !          96095: ////////
        !          96096: /
        !          96097: / Driver Configuration: Offsets to Function Pointers
        !          96098: /
        !          96099: ////////
        !          96100: 
        !          96101:        C_OPEN=4
        !          96102:        C_CLOSE=6
        !          96103:        C_BLOCK=8
        !          96104:        C_READ=10
        !          96105:        C_WRITE=12
        !          96106:        C_IOCTL=14
        !          96107:        C_POWER=16
        !          96108:        C_TIMER=18
        !          96109:        C_LOAD=20
        !          96110:        C_ULOAD=22
        !          96111:        C_POLL=24
        !          96112: 
        !          96113: ////////
        !          96114: /
        !          96115: / ld_xcall( fp )       - invoke far function.
        !          96116: / int (far *fp)();
        !          96117: /
        !          96118: ////////
        !          96119: 
        !          96120: ld_xcall_:
        !          96121:        cli
        !          96122:        push    bp
        !          96123:        mov     bp, sp
        !          96124:        xcall   4(bp)
        !          96125:        pop     bp
        !          96126:        ret
        !          96127: 
        !          96128: ////////
        !          96129: /
        !          96130: / call a driver function from the kernel
        !          96131: /   sel                - CS selector for the driver
        !          96132: /   fn         - offset in the driver of the function we want
        !          96133: /   arg[1-3]    - optional arguments
        !          96134: /
        !          96135: / ld_call(sel, fn, arg1, arg2, arg3)
        !          96136: / int sel;
        !          96137: / int (*fn)(void);
        !          96138: / int arg1, arg2, arg3;
        !          96139: /
        !          96140: ////////
        !          96141: 
        !          96142: / stack when ld_call() is called:
        !          96143: /      arg3
        !          96144: /      arg2
        !          96145: /      arg1
        !          96146: /      fn
        !          96147: /      sel
        !          96148: /      return IP
        !          96149: 
        !          96150: ld_call_:                      / PARAMETERS (arg[1-3]) MUST BE FOUND AT 4(BP).
        !          96151:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96152: /      lea     bp, 4(sp)       / this is what the next 2 instructions do
        !          96153:        mov     bp, sp
        !          96154:        add     bp, $4
        !          96155:                                /
        !          96156:        push    0(bp)           / Push sel to allow far call
        !          96157:        push    $DRV_J          /
        !          96158:                                /
        !          96159:        mov     ax, 2(bp)       / Push fn
        !          96160:                                /
        !          96161:        xcall   -8(bp)          / Invoke driver interface, which will
        !          96162:                                /       in turn invoke driver function.
        !          96163:                                /
        !          96164:        lea     sp, -4(bp)      /
        !          96165:        pop     bp              /
        !          96166:        ret                     /
        !          96167: 
        !          96168: ////////
        !          96169: /
        !          96170: /
        !          96171: / ldtimcall( arg, tp )  - service timed far function.
        !          96172: /
        !          96173: ////////
        !          96174: 
        !          96175: ldtimcall_:                            /
        !          96176:        push    bp                      /
        !          96177:        mov     bp, sp                  /
        !          96178:                                        /
        !          96179:        mov     bx, 6(bp)               /
        !          96180:        mov     ax, T_LDRV+2(bx)        /
        !          96181:        push    ax                      / Loadable driver code selector.
        !          96182:        push    $DRV_J                  / Loadable driver invocation offset.
        !          96183:        mov     ax, T_LDRV(bx)          / Desired far function.
        !          96184:                                        /
        !          96185:        xcall   -4(bp)                  /
        !          96186:                                        /
        !          96187:        mov     sp, bp                  /
        !          96188:        pop     bp                      /
        !          96189:        ret
        !          96190: 
        !          96191: ////////
        !          96192: /
        !          96193: / xcalled( f, args )
        !          96194: / int (*f)();
        !          96195: /
        !          96196: /      Input:  AX is pointer to kernel function to be invoked.
        !          96197: /
        !          96198: /      Action: Perform a near call to the specified kernel function,
        !          96199: /              passing 6 words as optional arguments.
        !          96200: /              Perform a far return.
        !          96201: /
        !          96202: /      Notes:  Invoked by far call from loadable device driver.
        !          96203: /
        !          96204: ////////
        !          96205: 
        !          96206: xcalled:                       / 6(bp) = grand-parent IP.
        !          96207:        push    bp              / 4(bp) = parent CS
        !          96208:        mov     bp, sp          / 2(bp) = parent IP
        !          96209:                                / AX    = destination function.
        !          96210:        push    20(bp)  / Arg 7 /
        !          96211:        push    18(bp)  / Arg 6 /
        !          96212:        push    16(bp)  / Arg 5 /
        !          96213:        push    14(bp)  / Arg 4 /
        !          96214:        push    12(bp)  / Arg 3 /
        !          96215:        push    10(bp)  / Arg 2 /
        !          96216:        push     8(bp)  / Arg 1 /
        !          96217:        icall   ax              /
        !          96218:                                /
        !          96219:        mov     sp, bp          / Return to loadable driver.
        !          96220:        pop     bp              /
        !          96221:        xret                    /
        !          96222: 
        !          96223: ////////
        !          96224: /
        !          96225: / ld_open( dev, mode )         - Open Routine.
        !          96226: / dev_t dev;
        !          96227: / int mode;
        !          96228: /
        !          96229: ////////
        !          96230: 
        !          96231: ld_open_:                      / PARAMETERS MUST REMAIN AT 4(BP).
        !          96232:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96233:        mov     bp, sp          /
        !          96234:                                /
        !          96235:        sub     bx, bx          / Calculate major device number * 2.
        !          96236:        movb    bl, 5(bp)       /
        !          96237:        shl     bx, $1          /
        !          96238:                                /
        !          96239:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          96240:        jcxz    0f              /
        !          96241:        push    cx              /
        !          96242:        push    $DRV_J          / Loadable driver invocation offset.
        !          96243:                                /
        !          96244:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          96245:        or      bx, bx          /
        !          96246:        je      0f              /
        !          96247:                                /
        !          96248:        mov     ax, C_OPEN(bx)  / Identify driver function to be invoked.
        !          96249:        or      ax, ax          /
        !          96250:        je      0f              /
        !          96251:                                /
        !          96252:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96253:                                /       in turn invoke driver function.
        !          96254:                                /
        !          96255:        mov     sp, bp          / Return to caller.
        !          96256:        pop     bp              /
        !          96257:        ret                     /
        !          96258: 
        !          96259: 0:     mov     sp, bp
        !          96260:        pop     bp
        !          96261:        jmp     nonedev_
        !          96262: 
        !          96263: ////////
        !          96264: /
        !          96265: / ld_close( dev )              - Close Routine.
        !          96266: / dev_t dev;
        !          96267: /
        !          96268: ////////
        !          96269: 
        !          96270: ld_close_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          96271:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96272:        mov     bp, sp          /
        !          96273:                                /
        !          96274:        sub     bx, bx          / Calculate major device number * 2.
        !          96275:        movb    bl, 5(bp)       /
        !          96276:        shl     bx, $1          /
        !          96277:                                /
        !          96278:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          96279:        jcxz    0f              /
        !          96280:        push    cx              /
        !          96281:        push    $DRV_J          / Loadable driver invocation offset.
        !          96282:                                /
        !          96283:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          96284:        or      bx, bx          /
        !          96285:        je      0f              /
        !          96286:                                /
        !          96287:        mov     ax, C_CLOSE(bx) / Identify driver function to be invoked.
        !          96288:        or      ax, ax          /
        !          96289:        je      0f              /
        !          96290:                                /
        !          96291:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96292:                                /       in turn invoke driver function.
        !          96293:                                /
        !          96294:        mov     sp, bp          / Return to caller.
        !          96295:        pop     bp              /
        !          96296:        ret                     /
        !          96297: 
        !          96298: 0:     mov     sp, bp
        !          96299:        pop     bp
        !          96300:        jmp     nonedev_
        !          96301: 
        !          96302: ////////
        !          96303: /
        !          96304: / ld_read( dev, iop )          - Read Routine.
        !          96305: / dev_t dev;
        !          96306: / IO * iop;
        !          96307: /
        !          96308: ////////
        !          96309: 
        !          96310: ld_read_:                      / PARAMETERS MUST REMAIN AT 4(BP).
        !          96311:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96312:        mov     bp, sp          /
        !          96313:                                /
        !          96314:        sub     bx, bx          / Calculate major device number * 2.
        !          96315:        movb    bl, 5(bp)       /
        !          96316:        shl     bx, $1          /
        !          96317:                                /
        !          96318:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          96319:        jcxz    0f              /
        !          96320:        push    cx              /
        !          96321:        push    $DRV_J          / Loadable driver invocation offset.
        !          96322:                                /
        !          96323:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          96324:        or      bx, bx          /
        !          96325:        je      0f              /
        !          96326:                                /
        !          96327:        mov     ax, C_READ(bx)  / Identify driver function to be invoked.
        !          96328:        or      ax, ax          /
        !          96329:        je      0f              /
        !          96330:                                /
        !          96331:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96332:                                /       in turn invoke driver function.
        !          96333:                                /
        !          96334:        mov     sp, bp          / Return to caller.
        !          96335:        pop     bp              /
        !          96336:        ret                     /
        !          96337: 
        !          96338: 0:     mov     sp, bp
        !          96339:        pop     bp
        !          96340:        jmp     nonedev_
        !          96341: 
        !          96342: ///////
        !          96343: /
        !          96344: / ld_write( dev, iop )         - Write Routine.
        !          96345: / dev_t dev;
        !          96346: / IO * iop;
        !          96347: /
        !          96348: ////////
        !          96349: 
        !          96350: ld_write_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          96351:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96352:        mov     bp, sp          /
        !          96353:                                /
        !          96354:        sub     bx, bx          / Calculate major device number * 2.
        !          96355:        movb    bl, 5(bp)       /
        !          96356:        shl     bx, $1          /
        !          96357:                                /
        !          96358:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          96359:        jcxz    0f              /
        !          96360:        push    cx              /
        !          96361:        push    $DRV_J          / Loadable driver invocation offset.
        !          96362:                                /
        !          96363:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          96364:        or      bx, bx          /
        !          96365:        je      0f              /
        !          96366:                                /
        !          96367:        mov     ax, C_WRITE(bx) / Identify driver function to be invoked.
        !          96368:        or      ax, ax          /
        !          96369:        je      0f              /
        !          96370:                                /
        !          96371:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96372:                                /       in turn invoke driver function.
        !          96373:                                /
        !          96374:        mov     sp, bp          / Return to caller.
        !          96375:        pop     bp              /
        !          96376:        ret                     /
        !          96377: 
        !          96378: 0:     mov     sp, bp
        !          96379:        pop     bp
        !          96380:        jmp     nonedev_
        !          96381: 
        !          96382: ///////
        !          96383: /
        !          96384: / ld_block( bp )               - Block Routine.
        !          96385: / BUF * bp;
        !          96386: /
        !          96387: ////////
        !          96388: 
        !          96389: ld_block_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          96390:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96391:        mov     bp, sp          /
        !          96392:                                /
        !          96393:        mov     bx, 4(bp)       / Calculate major device number * 2.
        !          96394:        movb    bl, B_DEV+1(bx) /
        !          96395:        subb    bh, bh          /
        !          96396:        shl     bx, $1          /
        !          96397:                                /
        !          96398:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          96399:        jcxz    0f              /
        !          96400:        push    cx              /
        !          96401:        push    $DRV_J          / Loadable driver invocation offset.
        !          96402:                                /
        !          96403:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          96404:        or      bx, bx          /
        !          96405:        je      0f              /
        !          96406:                                /
        !          96407:        mov     ax, C_BLOCK(bx) / Identify driver function to be invoked.
        !          96408:        or      ax, ax          /
        !          96409:        je      0f              /
        !          96410:                                /
        !          96411:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96412:                                /       in turn invoke driver function.
        !          96413:                                /
        !          96414:        mov     sp, bp          / Return to caller.
        !          96415:        pop     bp              /
        !          96416:        ret                     /
        !          96417: 
        !          96418: 0:     mov     bx, 4(bp)       / bp->b_flag |= BFERR.
        !          96419:        or    B_FLAG(bx),$BFERR /
        !          96420:        mov     sp, bp          /
        !          96421:        pop     bp              /
        !          96422:        jmp     bdone_          / bdone(bp);
        !          96423: 
        !          96424: ////////
        !          96425: /
        !          96426: / ld_ioctl( dev, iop )         - Ioctl Routine.
        !          96427: / dev_t dev;
        !          96428: / IO * iop;
        !          96429: /
        !          96430: ////////
        !          96431: 
        !          96432: ld_ioctl_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          96433:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96434:        mov     bp, sp          /
        !          96435:                                /
        !          96436:        sub     bx, bx          / Calculate major device number * 2.
        !          96437:        movb    bl, 5(bp)       /
        !          96438:        shl     bx, $1          /
        !          96439:                                /
        !          96440:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          96441:        jcxz    0f              /
        !          96442:        push    cx              /
        !          96443:        push    $DRV_J          / Loadable driver invocation offset.
        !          96444:                                /
        !          96445:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          96446:        or      bx, bx          /
        !          96447:        je      0f              /
        !          96448:                                /
        !          96449:        mov     ax, C_IOCTL(bx) / Identify driver function to be invoked.
        !          96450:        or      ax, ax          /
        !          96451:        je      0f              /
        !          96452:                                /
        !          96453:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96454:                                /       in turn invoke driver function.
        !          96455:                                /
        !          96456:        mov     sp, bp          / Return to caller.
        !          96457:        pop     bp              /
        !          96458:        ret                     /
        !          96459: 
        !          96460: 0:     mov     sp, bp
        !          96461:        pop     bp
        !          96462:        jmp     nonedev_
        !          96463: 
        !          96464: ////////
        !          96465: /
        !          96466: / ld_power( dev )              - Powerfail Routine.
        !          96467: / dev_t dev;
        !          96468: /
        !          96469: ////////
        !          96470: 
        !          96471: ld_power_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          96472:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96473:        mov     bp, sp          /
        !          96474:                                /
        !          96475:        sub     bx, bx          / Calculate major device number * 2.
        !          96476:        movb    bl, 5(bp)       /
        !          96477:        shl     bx, $1          /
        !          96478:                                /
        !          96479:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          96480:        jcxz    0f              /
        !          96481:        push    cx              /
        !          96482:        push    $DRV_J          / Loadable driver invocation offset.
        !          96483:                                /
        !          96484:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          96485:        or      bx, bx          /
        !          96486:        je      0f              /
        !          96487:                                /
        !          96488:        mov     ax, C_POWER(bx) / Identify driver function to be invoked.
        !          96489:        or      ax, ax          /
        !          96490:        je      0f              /
        !          96491:                                /
        !          96492:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96493:                                /       in turn invoke driver function.
        !          96494:                                /
        !          96495:        mov     sp, bp          / Return to caller.
        !          96496:        pop     bp              /
        !          96497:        ret                     /
        !          96498: 
        !          96499: 0:     mov     sp, bp
        !          96500:        pop     bp
        !          96501:        jmp     nonedev_
        !          96502: 
        !          96503: ////////
        !          96504: /
        !          96505: / ld_time( dev )               - Timer Routine.
        !          96506: / dev_t dev;
        !          96507: /
        !          96508: ////////
        !          96509: 
        !          96510: ld_time_:                      / PARAMETERS MUST REMAIN AT 4(BP).
        !          96511:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96512:        mov     bp, sp          /
        !          96513:                                /
        !          96514:        sub     bx, bx          / Calculate major device number * 2.
        !          96515:        movb    bl, 5(bp)       /
        !          96516:        shl     bx, $1          /
        !          96517:                                /
        !          96518:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          96519:        jcxz    0f              /
        !          96520:        push    cx              /
        !          96521:        push    $DRV_J          / Loadable driver invocation offset.
        !          96522:                                /
        !          96523:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          96524:        or      bx, bx          /
        !          96525:        je      0f              /
        !          96526:                                /
        !          96527:        mov     ax, C_TIMER(bx) / Identify driver function to be invoked.
        !          96528:        or      ax, ax          /
        !          96529:        je      0f              /
        !          96530:                                /
        !          96531:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96532:                                /       in turn invoke driver function.
        !          96533:                                /
        !          96534:        mov     sp, bp          / Return to caller.
        !          96535:        pop     bp              /
        !          96536:        ret                     /
        !          96537: 
        !          96538: 0:     mov     sp, bp
        !          96539:        pop     bp
        !          96540:        jmp     nonedev_
        !          96541: 
        !          96542: ////////
        !          96543: /
        !          96544: / ld_poll( dev, ev, msec )     - Poll Routine.
        !          96545: / dev_t dev;
        !          96546: / int ev;
        !          96547: / int msec;
        !          96548: /
        !          96549: ////////
        !          96550: 
        !          96551: ld_poll_:                      / PARAMETERS MUST REMAIN AT 4(BP).
        !          96552:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          96553:        mov     bp, sp          /
        !          96554:                                /
        !          96555:        sub     bx, bx          / Calculate major device number * 2.
        !          96556:        movb    bl, 5(bp)       /
        !          96557:        shl     bx, $1          /
        !          96558:                                /
        !          96559:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          96560:        jcxz    0f              /
        !          96561:        push    cx              /
        !          96562:        push    $DRV_J          / Loadable driver invocation offset.
        !          96563:                                /
        !          96564:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          96565:        or      bx, bx          /
        !          96566:        je      0f              /
        !          96567:                                /
        !          96568:        mov     ax, C_POLL(bx)  / Identify driver function to be invoked.
        !          96569:        or      ax, ax          /
        !          96570:        je      0f              /
        !          96571:                                /
        !          96572:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96573:                                /       in turn invoke driver function.
        !          96574:                                /
        !          96575:        mov     sp, bp          / Return to caller.
        !          96576:        pop     bp              /
        !          96577:        ret                     /
        !          96578: 
        !          96579: 0:     mov     sp, bp
        !          96580:        pop     bp
        !          96581:        jmp     nonedev_
        !          96582: 
        !          96583: ////////
        !          96584: /
        !          96585: / Loadable Driver Interrupt Entry Points.
        !          96586: /
        !          96587: /      Invoked by Coherent to service specific interrupt.
        !          96588: /      Identifies which loadable driver interrupt vector to be used.
        !          96589: /      Invokes interrupt handler which will do far call to loadable driver.
        !          96590: /
        !          96591: ////////
        !          96592: 
        !          96593: ld_intr0:
        !          96594:        mov     bx, $0          /
        !          96595:        jmp     ld_intr         /
        !          96596: 
        !          96597: ld_intr1:
        !          96598:        mov     bx, $2          /
        !          96599:        jmp     ld_intr         /
        !          96600: 
        !          96601: ld_intr2:
        !          96602:        mov     bx, $4          /
        !          96603:        jmp     ld_intr         /
        !          96604: 
        !          96605: ld_intr3:
        !          96606:        mov     bx, $6          /
        !          96607:        jmp     ld_intr         /
        !          96608: 
        !          96609: ld_intr4:
        !          96610:        mov     bx, $8          /
        !          96611:        jmp     ld_intr         /
        !          96612: 
        !          96613: ld_intr5:
        !          96614:        mov     bx, $10         /
        !          96615:        jmp     ld_intr         /
        !          96616: 
        !          96617: ld_intr6:
        !          96618:        mov     bx, $12         /
        !          96619:        jmp     ld_intr         /
        !          96620: 
        !          96621: ld_intr7:
        !          96622:        mov     bx, $14         /
        !          96623:        jmp     ld_intr         /
        !          96624: 
        !          96625: ld_intr8:
        !          96626:        mov     bx, $16         /
        !          96627:        jmp     ld_intr         /
        !          96628: 
        !          96629: ld_intr9:
        !          96630:        mov     bx, $18         /
        !          96631:        jmp     ld_intr         /
        !          96632: 
        !          96633: ld_intr10:
        !          96634:        mov     bx, $20         /
        !          96635:        jmp     ld_intr         /
        !          96636: 
        !          96637: ld_intr11:
        !          96638:        mov     bx, $22         /
        !          96639:        jmp     ld_intr         /
        !          96640: 
        !          96641: ld_intr12:
        !          96642:        mov     bx, $24         /
        !          96643:        jmp     ld_intr         /
        !          96644: 
        !          96645: ld_intr13:
        !          96646:        mov     bx, $26         /
        !          96647:        jmp     ld_intr         /
        !          96648: 
        !          96649: ld_intr14:
        !          96650:        mov     bx, $28         /
        !          96651:        jmp     ld_intr         /
        !          96652: 
        !          96653: ld_intr15:
        !          96654:        mov     bx, $30         /
        !          96655:        jmp     ld_intr         /
        !          96656: 
        !          96657: ////////
        !          96658: /
        !          96659: / Loadable driver interrupt handler.
        !          96660: /
        !          96661: /
        !          96662: /      Input:  bx = interrupt number * 2.
        !          96663: /
        !          96664: ////////
        !          96665: 
        !          96666: ld_intr:
        !          96667:        push    bp              /
        !          96668:        mov     bp, sp          /
        !          96669:                                /
        !          96670:        mov     cx,ldrvics_(bx) / Prepare driver interface CS:IP.
        !          96671:        jcxz    0f              /
        !          96672:        push    cx              /
        !          96673:        push    $DRV_J          / Loadable driver invocation offset.
        !          96674:                                /
        !          96675:        mov     ax,ldrvipc_(bx) / Identify interrupt handler to be invoked.
        !          96676:        or      ax, ax          /
        !          96677:        je      0f              /
        !          96678:                                /
        !          96679:        xcall   -4(bp)          / Invoke driver interface, which will
        !          96680:                                /       in turn invoke driver function.
        !          96681:                                /
        !          96682: 0:     mov     sp, bp          /
        !          96683:        pop     bp              /
        !          96684:        ret                     /
        !          96685: 0707070064030147631006440000030000030000011777770507310721300004700000012535/newbits/kernel/USRSRC/i8086/src/md1.c/* $Header: /usr/src/sys/i8086/src/RCS/md1.c,v 1.2 88/08/05 15:34:26 src Exp $ */
        !          96686: /* (lgl-
        !          96687:  *     The information contained herein is a trade secret of Mark Williams
        !          96688:  *     Company, and  is confidential information.  It is provided  under a
        !          96689:  *     license agreement,  and may be  copied or disclosed  only under the
        !          96690:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          96691:  *     material without the express written authorization of Mark Williams
        !          96692:  *     Company or persuant to the license agreement is unlawful.
        !          96693:  *
        !          96694:  *     COHERENT Version 2.3.37
        !          96695:  *     Copyright (c) 1982, 1983, 1984.
        !          96696:  *     An unpublished work by Mark Williams Company, Chicago.
        !          96697:  *     All rights reserved.
        !          96698:  -lgl) */
        !          96699: /*
        !          96700:  * 8086/8088 Coherent.
        !          96701:  * All machines.
        !          96702:  * Machine dependent stuff.
        !          96703:  *
        !          96704:  * $Log:       /usr/src/sys/i8086/src/RCS/md1.c,v $
        !          96705:  * Revision 1.2        88/08/05  15:34:26      src
        !          96706:  * mproto(), segload(), and msetsys() functions simplified.
        !          96707:  * 
        !          96708:  * Revision 1.1        88/03/24  17:39:43      src
        !          96709:  * Initial revision
        !          96710:  * 
        !          96711:  * 88/03/10    Allan Cornish           /usr/src/sys/coh/proc.c
        !          96712:  * Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !          96713:  * These partial fixes will be removed once all CPU's are replaced.
        !          96714:  *
        !          96715:  * 88/02/13    Allan Cornish           /usr/src/sys/i8086/src/md1.c
        !          96716:  * segload() now checks for regl[OIP] being system code segment.
        !          96717:  * iAPX-286 protected mode interrupt gates enable interrupts momentarily.
        !          96718:  *
        !          96719:  * 88/01/21    Allan Cornish           /usr/src/sys/i8086/src/md1.c
        !          96720:  * Segments are now de-associated from processes before freeing the segment.
        !          96721:  *
        !          96722:  * 87/11/05    Allan Cornish           /usr/src/sys/i8086/src/md1.c
        !          96723:  * New seg struct now used to allow extended addressing.
        !          96724:  *
        !          96725:  * 87/09/21    Allan Cornish   /usr/src/sys/i8086/src/md1.c
        !          96726:  * mproto() and setload() modified to support loadable driver processes.
        !          96727:  */
        !          96728: #include <sys/coherent.h>
        !          96729: #include <sys/i8086.h>
        !          96730: #include <sys/clist.h>
        !          96731: #include <errno.h>
        !          96732: #include <sys/inode.h>
        !          96733: #include <sys/proc.h>
        !          96734: #include <sys/seg.h>
        !          96735: #include <signal.h>
        !          96736: #include <sys/uproc.h>
        !          96737: 
        !          96738: /*
        !          96739:  * Calculate segmentation for a
        !          96740:  * new program. If there is a stack segment
        !          96741:  * present merge it into the data segment and
        !          96742:  * relocate the argument list.
        !          96743:  * Make sure that the changes are reflected in the u.u_segl array
        !          96744:  * which sproto sets up.
        !          96745:  */
        !          96746: mproto()
        !          96747: {
        !          96748:        register PROC   *pp;
        !          96749:        register SEG    *dsp;
        !          96750:        register SEG    *ssp;
        !          96751:        register SEG    *csp;
        !          96752:        fsize_t         ds;
        !          96753:        fsize_t         ss;
        !          96754:        unsigned int    so;
        !          96755:        unsigned int    *up;
        !          96756:        unsigned int    v;
        !          96757: 
        !          96758:        pp = SELF;
        !          96759: 
        !          96760:        dsp = pp->p_segp[SIPDATA];
        !          96761: 
        !          96762:        if ( ((pp->p_flags & PFKERN) == 0)
        !          96763:          && ((ssp=pp->p_segp[SISTACK]) != NULL) ) {
        !          96764:                ds = dsp->s_size;
        !          96765:                ss = ssp->s_size;
        !          96766:                so = ds + ss;
        !          96767:                if (seggrow(dsp, (fsize_t)so) == 0)
        !          96768:                        return (0);
        !          96769:                plrcopy( ssp->s_paddr, dsp->s_paddr + ds, ss);
        !          96770:                pp->p_segp[SISTACK] = NULL;
        !          96771:                sfree(ssp);
        !          96772:                u.u_sproto.mp_svb = ds;
        !          96773:                u.u_sproto.mp_svl = so;
        !          96774:                if (u.u_argp != NULL) {
        !          96775:                        abase(FP_SEL(dsp->s_faddr));
        !          96776:                        up = u.u_argp += so;
        !          96777:                        --up;
        !          96778:                        while (ageti(--up) != NULL)
        !          96779:                                ;
        !          96780:                        up -= 2+u.u_argc;
        !          96781:                        while ((v=ageti(up)) != NULL)
        !          96782:                                aputi(up++, v+so);
        !          96783:                        while ((v=ageti(++up)) != NULL)
        !          96784:                                aputi(up, v+so);
        !          96785:                }
        !          96786:                return (sproto());      /* Recurse to fix u.u_segl */
        !          96787:        }
        !          96788: 
        !          96789:        /*
        !          96790:         * Shared code, private code, or kernel code [csp == NULL].
        !          96791:         * NOTE: Combined code/data no longer supported.
        !          96792:         */
        !          96793:        if ( (csp = pp->p_segp[SISTEXT]) == NULL )
        !          96794:                csp = pp->p_segp[SIPTEXT];
        !          96795: 
        !          96796:        /*
        !          96797:         * Special case if no code/data segment specified.
        !          96798:         */
        !          96799:        u.u_sproto.mp_cbp = (csp != NULL) ? &FP_SEL(csp->s_faddr) : &scs;
        !          96800:        u.u_sproto.mp_dbp = (dsp != NULL) ? &FP_SEL(dsp->s_faddr) : &sds;
        !          96801:        u.u_sproto.mp_csl = (csp != NULL) ? csp->s_size - 1 : 0;
        !          96802:        u.u_sproto.mp_dsl = (dsp != NULL) ? dsp->s_size - 1 : 0;
        !          96803: 
        !          96804:        return (1);
        !          96805: }
        !          96806: 
        !          96807: /*
        !          96808:  * Load up segmentation registers.
        !          96809:  */
        !          96810: segload()
        !          96811: {
        !          96812:        register unsigned *ip;
        !          96813:        register unsigned s;
        !          96814: 
        !          96815:        ucs = *u.u_sproto.mp_cbp;
        !          96816:        uds = *u.u_sproto.mp_dbp;
        !          96817:        ucl =  u.u_sproto.mp_csl;
        !          96818:        udl =  u.u_sproto.mp_dsl;
        !          96819: 
        !          96820:        ip = regl;
        !          96821:        ip[OCS] = ucs;
        !          96822:        ip[ODS] = s = uds;
        !          96823:        ip[OES] = s;
        !          96824:        ip[OSS] = s;
        !          96825: }
        !          96826: 
        !          96827: /*
        !          96828:  * Set up a new process.
        !          96829:  */
        !          96830: msetusr(ip, sp)
        !          96831: vaddr_t sp;
        !          96832: vaddr_t ip;
        !          96833: {
        !          96834:        regl[OIP] = ip;
        !          96835:        regl[OSP] = sp + u.u_sproto.mp_svl;
        !          96836: }
        !          96837: 
        !          96838: /*
        !          96839:  * Set up initial context for a system process.
        !          96840:  * System processes run at depth 1, just like any
        !          96841:  * user process. This is necessary to make sure that
        !          96842:  * the machine state save is correctly handled, just
        !          96843:  * in case the clock hits a kernel process executing
        !          96844:  * out of the IBM ROM.
        !          96845:  */
        !          96846: msetsys(mp, fn, us)
        !          96847: register MCON *mp;
        !          96848: int (*fn)();
        !          96849: saddr_t us;
        !          96850: {
        !          96851:        mp->mc_sp = (int)(&u) + UPASIZE - 32;
        !          96852:        mp->mc_pc = fn;
        !          96853:        mp->mc_fw = 0;
        !          96854:        mp->mc_depth = 1;
        !          96855: }
        !          96856: 
        !          96857: /*
        !          96858:  * Set the given address in the user area to the given value if it is
        !          96859:  * okay to do so.
        !          96860:  */
        !          96861: msetuof(a, v)
        !          96862: register int a;
        !          96863: {
        !          96864:        if (a<UPASIZE+OBP*2 || a>UPASIZE+OFW*2)
        !          96865:                return (0);
        !          96866:        if (a == UPASIZE+OCS*2)
        !          96867:                return (0);
        !          96868:        if (a == UPASIZE+ODS*2)
        !          96869:                return (0);
        !          96870:        if (a == UPASIZE+OES*2)
        !          96871:                return (0);
        !          96872:        if (a == UPASIZE+OSS*2)
        !          96873:                return (0);
        !          96874:        if (a == UPASIZE+OID*2)         /* Protect trap id */
        !          96875:                return (0);
        !          96876:        if (a == UPASIZE+ORA*2)
        !          96877:                return (0);             /* Protect trap return link */
        !          96878:        *((int *)((int)&u+a)) = v;
        !          96879:        return (1);
        !          96880: }
        !          96881: 
        !          96882: /*
        !          96883:  * Cause a signal routine to be executed.
        !          96884:  */
        !          96885: msigint(n, f)
        !          96886: {
        !          96887:        register int *usp;
        !          96888: 
        !          96889:        usp = regl[OSP];
        !          96890:        putuwd(--usp, regl[OFW]);
        !          96891:        putuwd(--usp, regl[OIP]);
        !          96892:        putuwd(--usp, n);
        !          96893:        regl[OFW] &= ~MFTTB;
        !          96894:        regl[OIP] = f;
        !          96895:        regl[OSP] = usp;
        !          96896:        if (n != SIGTRAP)
        !          96897:                u.u_sfunc[n-1] = SIG_DFL;
        !          96898: }
        !          96899: 
        !          96900: /*
        !          96901:  * Cause the next instruction to single step.
        !          96902:  */
        !          96903: msigsin()
        !          96904: {
        !          96905:        regl[OFW] |= MFTTB;
        !          96906: }
        !          96907: 
        !          96908: /*
        !          96909:  * Fix up context.
        !          96910:  */
        !          96911: mfixcon(pp)
        !          96912: PROC *pp;
        !          96913: {
        !          96914: }
        !          96915: 
        !          96916: /*
        !          96917:  * Idle kernel process.
        !          96918:  */
        !          96919: idle()
        !          96920: {
        !          96921:        for (;;) {
        !          96922:                disflag = 1;
        !          96923:                _idle();
        !          96924:        }
        !          96925: }
        !          96926: 0707070064030147611006440000030000030000011777770507310721500005100000007165/newbits/kernel/USRSRC/i8086/src/mmain.c/* $Header: /usr/src/sys/i8086/src/RCS/mmain.c,v 1.2 88/08/05 15:43:42 src Exp $ */
        !          96927: /* (lgl-
        !          96928:  *     The information contained herein is a trade secret of Mark Williams
        !          96929:  *     Company, and  is confidential information.  It is provided  under a
        !          96930:  *     license agreement,  and may be  copied or disclosed  only under the
        !          96931:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          96932:  *     material without the express written authorization of Mark Williams
        !          96933:  *     Company or persuant to the license agreement is unlawful.
        !          96934:  *
        !          96935:  *     COHERENT Version 2.3.37
        !          96936:  *     Copyright (c) 1982, 1983, 1984.
        !          96937:  *     An unpublished work by Mark Williams Company, Chicago.
        !          96938:  *     All rights reserved.
        !          96939:  -lgl) */
        !          96940: /*
        !          96941:  * 8086/8088 Coherent.
        !          96942:  * All machines.
        !          96943:  * Machine dependent stuff.
        !          96944:  *
        !          96945:  * $Log:       /usr/src/sys/i8086/src/RCS/mmain.c,v $
        !          96946:  * Revision 1.2        88/08/05  15:43:42      src
        !          96947:  * Bug:        Spawning large number of processes would cause system to crash.
        !          96948:  * Fix:        Kernel alloc space no longer overlaps loadable driver data.
        !          96949:  * 
        !          96950:  * Revision 1.1        88/03/24  17:39:46      src
        !          96951:  * Initial revision
        !          96952:  * 
        !          96953:  * 88/02/24    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          96954:  * corebot is now aligned on a 512 byte boundary.
        !          96955:  *
        !          96956:  * 87/11/30    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          96957:  * Check for kernel data space > 64 Kbytes now done AFTER rounding up.
        !          96958:  *
        !          96959:  * 87/11/21    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          96960:  * Use of bruc/ctob macros eliminated since no longer valid in protected mode.
        !          96961:  *
        !          96962:  * 87/11/14    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          96963:  * Init code+data now split into icodep/icodes and idatap/idatas.
        !          96964:  *
        !          96965:  * 87/11/12    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          96966:  * Corebot/coretop now paddr_t rather than saddr_t to support protected mode.
        !          96967:  *
        !          96968:  * 87/10/05    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          96969:  * Loadable driver data slot allocation added.
        !          96970:  *
        !          96971:  * 87/05/08    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          96972:  * Ctob(sds) is now cast as ctob((paddr_t)sds) to avoid address truncation.
        !          96973:  *
        !          96974:  * 86/07/23    Allan Cornish
        !          96975:  * Added check for kernel data space exceeding 64 Kbytes.
        !          96976:  */
        !          96977: #include <sys/coherent.h>
        !          96978: #include <sys/i8086.h>
        !          96979: #include <sys/clist.h>
        !          96980: #include <errno.h>
        !          96981: #include <sys/inode.h>
        !          96982: #include <sys/proc.h>
        !          96983: #include <sys/seg.h>
        !          96984: #include <signal.h>
        !          96985: #include <sys/uproc.h>
        !          96986: #include <sys/buf.h>
        !          96987: 
        !          96988: saddr_t uasa;  /* Currently active uarea */
        !          96989: 
        !          96990: /*
        !          96991:  * General initialisation.
        !          96992:  */
        !          96993: i8086()
        !          96994: {
        !          96995:        register unsigned allocp;
        !          96996:        extern vaddr_t  aicodep;
        !          96997:        extern vaddr_t  aicodes;
        !          96998:        extern vaddr_t  aidatap;
        !          96999:        extern vaddr_t  aidatas;
        !          97000:        extern vaddr_t  etext;
        !          97001:        extern vaddr_t  end;
        !          97002:        auto faddr_t    fp;
        !          97003:        long datsize;
        !          97004:        unsigned bsize, csize, isize, ssize;
        !          97005: 
        !          97006:        /*
        !          97007:         * Set up memory bases.
        !          97008:         * Align the buffers modulo BSIZE (512) in the physical space,
        !          97009:         * so that any machines that have only 16 bit DMA counters will
        !          97010:         * work out.
        !          97011:         */
        !          97012:        datsize = (long)&end;
        !          97013:        datsize += ALLSIZE;
        !          97014:        datsize += NBUF * sizeof(BUF);
        !          97015:        datsize += ssize = NSLOT*(sizeof(int) + slotsz);
        !          97016:        datsize += isize = NINODE*sizeof(INODE);
        !          97017:        datsize += csize = NCLIST*sizeof(CLIST);
        !          97018:        datsize += bsize = NBUF*BSIZE;
        !          97019:        datsize = (datsize + 511) & ~511;
        !          97020:        if ( datsize >= 0x10000L )
        !          97021:                panic("Kernel data exceeds 64 Kbytes");
        !          97022: 
        !          97023:        blockp  = datsize - bsize - ((sds&0x1F)<<4);
        !          97024:        clistp  = (unsigned)blockp - csize;
        !          97025:        inodep  = (unsigned)clistp - isize;
        !          97026:        slotp   = (unsigned)inodep - ssize;
        !          97027:        allocp = &end;
        !          97028:        blockp += (sds << 4L);
        !          97029:        if ((unsigned)allocp > (unsigned)slotp)
        !          97030:                panic("No alloc space");
        !          97031:        corebot = ((sds << 4L) + datsize + 511) & ~511;
        !          97032:        asize = (unsigned)slotp - allocp;
        !          97033:        msize = (coretop-holetop+holebot-corebot) / 1024;
        !          97034:        allkp = setarena(allocp, asize);
        !          97035:        icodep = (char *)&aicodep;
        !          97036:        icodes = (int)&aicodes;
        !          97037:        idatap = (char *)&aidatap;
        !          97038:        idatas = (int)&aidatas;
        !          97039:        fp = ptov( corebot, (fsize_t) UPASIZE );
        !          97040:        uasa   = FP_SEL(fp);
        !          97041: }
        !          97042: 
        !          97043: 0707070064030147571004440000030000030000011777770507310721500005300000000547/newbits/kernel/USRSRC/i8086/src/support.c#include <sys/al.h>
        !          97044: /*
        !          97045:  * the following kernel resident parts are shared by loadable serial drivers
        !          97046:  *   (see al.h and poll_clk.h)
        !          97047:  */
        !          97048: int    com_usage[NUM_AL_PORTS];        /* COM_UNUSED/COM_IRQ/COM_POLLED */
        !          97049: TTY    *(tp_table[NUM_AL_PORTS]);      /* table of pointers for polling */
        !          97050: int    poll_rate;                      /* poll_* variables are explained */
        !          97051: int    poll_owner;                     /* in poll_clk.h */
        !          97052: 0707070064030147601006440000030000030000011777770507310721500004700000012002/newbits/kernel/USRSRC/i8086/src/tab.c/* $Header: /usr/src/sys/i8086/src/RCS/tab.c,v 1.1 88/03/24 17:39:50 src Exp $ */
        !          97053: /* (lgl-
        !          97054:  *     The information contained herein is a trade secret of Mark Williams
        !          97055:  *     Company, and  is confidential information.  It is provided  under a
        !          97056:  *     license agreement,  and may be  copied or disclosed  only under the
        !          97057:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          97058:  *     material without the express written authorization of Mark Williams
        !          97059:  *     Company or persuant to the license agreement is unlawful.
        !          97060:  *
        !          97061:  *     COHERENT Version 2.3.37
        !          97062:  *     Copyright (c) 1982, 1983, 1984.
        !          97063:  *     An unpublished work by Mark Williams Company, Chicago.
        !          97064:  *     All rights reserved.
        !          97065:  -lgl) */
        !          97066: /*
        !          97067:  * Coherent.
        !          97068:  * Tables for the Intel 8086.
        !          97069:  *
        !          97070:  * $Log:       /usr/src/sys/i8086/src/RCS/tab.c,v $
        !          97071:  * Revision 1.1        88/03/24  17:39:50      src
        !          97072:  * Initial revision
        !          97073:  * 
        !          97074:  * 87/08/14    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          97075:  * Added tick() as system call 73.
        !          97076:  *
        !          97077:  * 87/07/08    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          97078:  * Added alarm2() as system call 72.
        !          97079:  *
        !          97080:  * 86/11/21    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          97081:  * Added msgctl(), msgget(), msgrcv(), msgsnd() as system calls 68 to 71.
        !          97082:  *
        !          97083:  * 86/11/19    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          97084:  * Added fcntl() and poll() as system calls 66 and 67.
        !          97085:  *
        !          97086:  * 85/07/09    Allan Cornish
        !          97087:  * Added getpgrp() as system call 63.
        !          97088:  */
        !          97089: #include <sys/coherent.h>
        !          97090: #include <sys/i8086.h>
        !          97091: #include <sys/systab.h>
        !          97092: 
        !          97093: /*
        !          97094:  * System call functions.
        !          97095:  */
        !          97096: int    unone();
        !          97097: int    unull();
        !          97098: int    uexit();
        !          97099: int    ufork();
        !          97100: int    uread();
        !          97101: int    uwrite();
        !          97102: int    uopen();
        !          97103: int    uclose();
        !          97104: int    uwait();
        !          97105: int    ucreat();
        !          97106: int    ulink();
        !          97107: int    uunlink();
        !          97108: int    uexece();
        !          97109: int    uchdir();
        !          97110: int    umknod();
        !          97111: int    uchmod();
        !          97112: int    uchown();
        !          97113: char   *ubrk();
        !          97114: int    ustat();
        !          97115: long   ulseek();
        !          97116: int    ugetpid();
        !          97117: int    umount();
        !          97118: int    uumount();
        !          97119: int    usetuid();
        !          97120: int    ugetuid();
        !          97121: int    ustime();
        !          97122: int    uptrace();
        !          97123: int    ualarm();
        !          97124: int    ufstat();
        !          97125: int    upause();
        !          97126: int    uutime();
        !          97127: int    ustty();
        !          97128: int    ugtty();
        !          97129: int    uaccess();
        !          97130: int    unice();
        !          97131: int    uftime();
        !          97132: int    uftime();
        !          97133: int    usync();
        !          97134: int    ukill();
        !          97135: int    udup();
        !          97136: int    upipe();
        !          97137: int    utimes();
        !          97138: int    uprofil();
        !          97139: long   uunique();
        !          97140: int    usetgid();
        !          97141: int    ugetgid();
        !          97142: int    (*usignal())();
        !          97143: int    usload();
        !          97144: int    usuload();
        !          97145: int    uacct();
        !          97146: int    ulock();
        !          97147: int    uioctl();
        !          97148: int    ugetegid();
        !          97149: int    uumask();
        !          97150: int    uchroot();
        !          97151: int    usetpgrp();
        !          97152: int    ugetpgrp();
        !          97153: int    ugeteuid();
        !          97154: int    ufcntl();
        !          97155: int    upoll();
        !          97156: long   ualarm2();
        !          97157: long   utick();
        !          97158: 
        !          97159: /*
        !          97160:  * System call table.
        !          97161:  */
        !          97162: struct systab sysitab[NMICALL] ={
        !          97163:        0,  INT,        unone,                  /*  0 = ??? */
        !          97164:        2,  INT,        uexit,                  /*  1 = exit */
        !          97165:        0,  INT,        ufork,                  /*  2 = fork */
        !          97166:        6,  INT,        uread,                  /*  3 = read */
        !          97167:        6,  INT,        uwrite,                 /*  4 = write */
        !          97168:        4,  INT,        uopen,                  /*  5 = open */
        !          97169:        2,  INT,        uclose,                 /*  6 = close */
        !          97170:        2,  INT,        uwait,                  /*  7 = wait */
        !          97171:        4,  INT,        ucreat,                 /*  8 = creat */
        !          97172:        4,  INT,        ulink,                  /*  9 = link */
        !          97173:        2,  INT,        uunlink,                /* 10 = unlink */
        !          97174:        6,  INT,        uexece,                 /* 11 = exec */
        !          97175:        2,  INT,        uchdir,                 /* 12 = chdir */
        !          97176:        0,  INT,        unone,                  /* 13 = ??? */
        !          97177:        6,  INT,        umknod,                 /* 14 = mknod */
        !          97178:        4,  INT,        uchmod,                 /* 15 = chmod */
        !          97179:        6,  INT,        uchown,                 /* 16 = chown */
        !          97180:        2,  INT,        ubrk,                   /* 17 = break */
        !          97181:        4,  INT,        ustat,                  /* 18 = stat */
        !          97182:        8,  LONG,       ulseek,                 /* 19 = lseek */
        !          97183:        0,  INT,        ugetpid,                /* 20 = getpid */
        !          97184:        6,  INT,        umount,                 /* 21 = mount */
        !          97185:        2,  INT,        uumount,                /* 22 = umount */
        !          97186:        2,  INT,        usetuid,                /* 23 = setuid */
        !          97187:        0,  INT,        ugetuid,                /* 24 = getuid */
        !          97188:        2,  INT,        ustime,                 /* 25 = stime */
        !          97189:        8,  INT,        uptrace,                /* 26 = ptrace */
        !          97190:        2,  INT,        ualarm,                 /* 27 = alarm */
        !          97191:        4,  INT,        ufstat,                 /* 28 = fstat */
        !          97192:        0,  INT,        upause,                 /* 29 = pause */
        !          97193:        4,  INT,        uutime,                 /* 30 = utime */
        !          97194:        0,  INT,        unone,                  /* 31 = ??? */
        !          97195:        0,  INT,        unone,                  /* 32 = ??? */
        !          97196:        4,  INT,        uaccess,                /* 33 = access */
        !          97197:        2,  INT,        unice,                  /* 34 = nice */
        !          97198:        2,  INT,        uftime,                 /* 35 = ftime */
        !          97199:        0,  INT,        usync,                  /* 36 = sync */
        !          97200:        4,  INT,        ukill,                  /* 37 = kill */
        !          97201:        0,  INT,        unone,                  /* 38 = ??? */
        !          97202:        0,  INT,        unone,                  /* 39 = ??? */
        !          97203:        0,  INT,        unone,                  /* 40 = ??? */
        !          97204:        4,  INT,        udup,                   /* 41 = dup */
        !          97205:        2,  INT,        upipe,                  /* 42 = pipe */
        !          97206:        2,  INT,        utimes,                 /* 43 = times */
        !          97207:        8,  INT,        uprofil,                /* 44 = profil */
        !          97208:        0,  LONG,       uunique,                /* 45 = unique */
        !          97209:        2,  INT,        usetgid,                /* 46 = setgid */
        !          97210:        0,  INT,        ugetgid,                /* 47 = getgid */
        !          97211:        4,  INT,        usignal,                /* 48 = signal */
        !          97212:        0,  INT,        unone,                  /* 49 = ??? */
        !          97213:        0,  INT,        unone,                  /* 50 = ??? */
        !          97214:        2,  INT,        uacct,                  /* 51 = acct */
        !          97215:        0,  INT,        unull,                  /* 52 = ??? (phys) */
        !          97216:        0,  INT,        ulock,                  /* 53 = lock */
        !          97217:        6,  INT,        uioctl,                 /* 54 = ioctl */
        !          97218:        0,  INT,        unone,                  /* 55 = ??? (mpx) */
        !          97219:        0,  INT,        ugetegid,               /* 56 = getegid */
        !          97220:        0,  INT,        ugeteuid,               /* 57 = geteuid */
        !          97221:        0,  INT,        unone,                  /* 58 = ??? */
        !          97222:        0,  INT,        unone,                  /* 59 = ??? */
        !          97223:        2,  INT,        uumask,                 /* 60 = umask */
        !          97224:        2,  INT,        uchroot,                /* 61 = chroot */
        !          97225:        0,  INT,        usetpgrp,               /* 62 = setpgrp */
        !          97226:        0,  INT,        ugetpgrp,               /* 63 = getpgrp */
        !          97227:        2,  INT,        usload,                 /* 64 = sload */
        !          97228:        2,  INT,        usuload,                /* 65 = suload */
        !          97229:        6,  INT,        ufcntl,                 /* 66 = fcntl */
        !          97230:        8,  INT,        upoll,                  /* 67 = poll */
        !          97231:        0,  INT,        unone,                  /* 68 (was 6, msgctl) */
        !          97232:        0,  INT,        unone,                  /* 69 (was 6, msgget) */
        !          97233:        0,  INT,        unone,                  /* 70 (was 12, msgrcv) */
        !          97234:        0,  INT,        unone,                  /* 71 (was 8, msgsnd) */
        !          97235:        4,  LONG,       ualarm2,                /* 72 = alarm2 */
        !          97236:        0,  LONG,       utick                   /* 73 = tick  */
        !          97237: };
        !          97238: 0707070064030147561006440000030000030000011777770507310721700005000000012415/newbits/kernel/USRSRC/i8086/src/trap.c/* $Header: /usr/src/sys/i8086/src/RCS/trap.c,v 1.1 88/03/24 17:39:53 src Exp $ */
        !          97239: /* (lgl-
        !          97240:  *     The information contained herein is a trade secret of Mark Williams
        !          97241:  *     Company, and  is confidential information.  It is provided  under a
        !          97242:  *     license agreement,  and may be  copied or disclosed  only under the
        !          97243:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          97244:  *     material without the express written authorization of Mark Williams
        !          97245:  *     Company or persuant to the license agreement is unlawful.
        !          97246:  *
        !          97247:  *     COHERENT Version 2.3.37
        !          97248:  *     Copyright (c) 1982, 1983, 1984.
        !          97249:  *     An unpublished work by Mark Williams Company, Chicago.
        !          97250:  *     All rights reserved.
        !          97251:  -lgl) */
        !          97252: /*
        !          97253:  * Trap handler.
        !          97254:  * 8086/8088 Coherent, IBM PC.
        !          97255:  *
        !          97256:  * $Log:       /usr/src/sys/i8086/src/RCS/trap.c,v $
        !          97257:  * Revision 1.1        88/03/24  17:39:53      src
        !          97258:  * Initial revision
        !          97259:  * 
        !          97260:  * 88/03/06    Allan Cornish           /usr/src/sys/i8086/src/trap.c
        !          97261:  * Exception diagnostistics extended.
        !          97262:  *
        !          97263:  * 87/11/02    Allan Cornish           /usr/src/sys/i8086/src/trap.c
        !          97264:  * iAPX 286 exception traps added.
        !          97265:  */
        !          97266: #include <sys/coherent.h>
        !          97267: #include <sys/i8086.h>
        !          97268: #include <sys/systab.h>
        !          97269: #include <errno.h>
        !          97270: #include <sys/proc.h>
        !          97271: #include <sys/seg.h>
        !          97272: #include <signal.h>
        !          97273: #include <sys/uproc.h>
        !          97274: 
        !          97275: #ifndef        EBUG
        !          97276: #define        EBUG 1
        !          97277: #endif
        !          97278: 
        !          97279: /*
        !          97280:  * Trap handler.
        !          97281:  * The arguments are the registers,
        !          97282:  * saved on the stack by machine code. This call
        !          97283:  * is different from most C calls in that the registers
        !          97284:  * get copied back; if you change a "trap" parameter then
        !          97285:  * the machine register will be altered when the trap is
        !          97286:  * dismissed.
        !          97287:  */
        !          97288: trap(es, cx, dx, ax, bx, ds, usp, uss, id, ip, cs, fw)
        !          97289: unsigned es, cx, dx, ax, bx, ds, usp, uss, id, ip, cs, fw;
        !          97290: {
        !          97291:        register struct systab  *stp;
        !          97292:        register int    syscall;
        !          97293:        register int    callnum;
        !          97294:        register int    sigcode;
        !          97295:        long            l;
        !          97296: 
        !          97297:        if ( (id >> 8) == SINMI )
        !          97298:                panic( "Parity error: cs=%x ip=%x\n", cs, ip );
        !          97299: 
        !          97300:        if (depth != 0) {
        !          97301: #if EBUG > 0
        !          97302:                faddr_t fp;
        !          97303:                FP_SEL(fp) = ax;  printf("ax "); vprint(fp);
        !          97304:                FP_SEL(fp) = cs;  printf("cs "); vprint(fp);
        !          97305:                FP_SEL(fp) = ds;  printf("ds "); vprint(fp);
        !          97306:                FP_SEL(fp) = es;  printf("es "); vprint(fp);
        !          97307:                FP_SEL(fp) = uss; printf("ss "); vprint(fp);
        !          97308: #endif
        !          97309:                panic("system trap: id=%x ip=%x ax=%x", id, ip, ax);
        !          97310:        }
        !          97311: 
        !          97312:        if ((SELF->p_flags&PFKERN) != 0) {
        !          97313: #if EBUG > 0
        !          97314:                faddr_t fp;
        !          97315:                FP_SEL(fp) = ax;  printf("ax "); vprint(fp);
        !          97316:                FP_SEL(fp) = cs;  printf("cs "); vprint(fp);
        !          97317:                FP_SEL(fp) = ds;  printf("ds "); vprint(fp);
        !          97318:                FP_SEL(fp) = es;  printf("es "); vprint(fp);
        !          97319:                FP_SEL(fp) = uss; printf("ss "); vprint(fp);
        !          97320: #endif
        !          97321:                panic("pid%d: kernel process trap: id=%x, ip=%x ax=%d",
        !          97322:                        SELF->p_pid, id, ip, ax);
        !          97323:        }
        !          97324: 
        !          97325:        /*
        !          97326:         * System call.
        !          97327:         */
        !          97328:        if ( (id >> 8) == SISYS ) {
        !          97329:                u.u_error = 0;
        !          97330:                sigcode = 0;
        !          97331:                syscall = getuwi(ip-2);
        !          97332:                if (u.u_error != 0 || (syscall&0xFF) != 0xCD) {
        !          97333:                        sigcode = SIGSYS;
        !          97334:                        goto trapend;
        !          97335:                }
        !          97336:                callnum = (syscall>>8) & 0x7F;
        !          97337:                if (callnum >= NMICALL) {
        !          97338:                        sigcode = SIGSYS;
        !          97339:                        goto trapend;
        !          97340:                }
        !          97341:                stp = &sysitab[callnum];
        !          97342:                ukcopy(usp+2, u.u_args, stp->s_alen);
        !          97343:                if (u.u_error != 0) {
        !          97344:                        sigcode = SIGSYS;
        !          97345:                        goto trapend;
        !          97346:                }
        !          97347:                u.u_io.io_seg = IOUSR;
        !          97348:                if (envsave(&u.u_sigenv) != 0)
        !          97349:                        u.u_error = EINTR;
        !          97350:                else if ( stp->s_alen <= (3 * sizeof(int)) ) {
        !          97351:                        l = (*(long(*)())stp->s_func)(u.u_args[0],
        !          97352:                                                      u.u_args[1],
        !          97353:                                                      u.u_args[2] );
        !          97354:                        ax = ((struct l *) &l)->l_lo;
        !          97355:                        dx = ((struct l *) &l)->l_hi;
        !          97356:                }
        !          97357:                else {
        !          97358:                        l = (*(long(*)())stp->s_func)(u.u_args[0],
        !          97359:                                                      u.u_args[1],
        !          97360:                                                      u.u_args[2],
        !          97361:                                                      u.u_args[3],
        !          97362:                                                      u.u_args[4],
        !          97363:                                                      u.u_args[5]);
        !          97364:                        ax = ((struct l *) &l)->l_lo;
        !          97365:                        dx = ((struct l *) &l)->l_hi;
        !          97366:                }
        !          97367:                if (u.u_error != 0) {
        !          97368:                        ax = -1;
        !          97369:                        dx = -1;
        !          97370:                        putuwd(MUERR, u.u_error);
        !          97371:                        if (u.u_error == EFAULT)
        !          97372:                                sigcode = SIGSYS;
        !          97373:                }
        !          97374:        }
        !          97375: 
        !          97376:        /*
        !          97377:         * Trap.
        !          97378:         */
        !          97379:        else switch (id>>8) {
        !          97380: 
        !          97381:        case SIDIV:
        !          97382:                sigcode = SIGDIVE;
        !          97383:                break;
        !          97384: 
        !          97385:        case SISST:
        !          97386:                sigcode = SIGTRAP;
        !          97387:                break;
        !          97388: 
        !          97389:        case SIBPT:
        !          97390:                sigcode = SIGTRAP;
        !          97391:                break;
        !          97392: 
        !          97393:        case SIOVF:
        !          97394:                sigcode = SIGOVFL;
        !          97395:                break;
        !          97396: 
        !          97397:        case SIBND:
        !          97398:                /*
        !          97399:                 * Bound
        !          97400:                 */
        !          97401:                sigcode = SIGOVFL;
        !          97402:                break;
        !          97403: 
        !          97404:        case SIOP:
        !          97405:                /*
        !          97406:                 * Invalid opcode
        !          97407:                 */
        !          97408:                sigcode = SIGSEGV;
        !          97409:                break;
        !          97410: 
        !          97411:        case SIXNP:
        !          97412:                /*
        !          97413:                 * Processor extension not available
        !          97414:                 */
        !          97415:                sigcode = SIGSEGV;
        !          97416:                break;
        !          97417: 
        !          97418:        case SIDBL:
        !          97419:                /*
        !          97420:                 * Double exception
        !          97421:                 */
        !          97422:                panic("double exception: cs=%x ip=%x", cs, ip);
        !          97423:                sigcode = SIGSEGV;
        !          97424:                break;
        !          97425: 
        !          97426:        case SIXS:
        !          97427:                /*
        !          97428:                 * Processor extension segment overrun
        !          97429:                 */
        !          97430:                sigcode = SIGSEGV;
        !          97431:                break;
        !          97432: 
        !          97433:        case SITS:
        !          97434:                /*
        !          97435:                 * Invalid task state segment
        !          97436:                 */
        !          97437:                panic("invalid tss: cs=%x ip=%x", cs, ip);
        !          97438:                sigcode = SIGSEGV;
        !          97439:                break;
        !          97440: 
        !          97441:        case SINP:
        !          97442:                /*
        !          97443:                 * Segment not present
        !          97444:                 */
        !          97445:                sigcode = SIGSEGV;
        !          97446:                break;
        !          97447: 
        !          97448:        case SISS:
        !          97449:                /*
        !          97450:                 * Stack segment overrun/not present
        !          97451:                 */
        !          97452:                sigcode = SIGKILL;
        !          97453:                break;
        !          97454: 
        !          97455:        case SIGP:
        !          97456:                /*
        !          97457:                 * General protection.
        !          97458:                 */
        !          97459:                sigcode = SIGSEGV;
        !          97460:                break;
        !          97461: 
        !          97462:        default:
        !          97463:                panic("user trap: id=%x ip=%x\n", id, ip );
        !          97464:        }
        !          97465: 
        !          97466: trapend:
        !          97467:        if ( sigcode != 0 ) {
        !          97468:                if ( sigcode == SIGSEGV ) {
        !          97469: #if EBUG > 0
        !          97470:                        faddr_t fp;
        !          97471:                        FP_SEL(fp) = ax;  printf("\tax "); vprint(fp);
        !          97472:                        FP_SEL(fp) = cs;  printf("\tcs "); vprint(fp);
        !          97473:                        FP_SEL(fp) = ds;  printf("\tds "); vprint(fp);
        !          97474:                        FP_SEL(fp) = es;  printf("\tes "); vprint(fp);
        !          97475:                        FP_SEL(fp) = uss; printf("\tss "); vprint(fp);
        !          97476:                        printf("user trap: SEGV id=%x ax=%x pid=%d\n",
        !          97477:                                id, ax, SELF->p_pid );
        !          97478:                        printf("\tip=%x sp=%x\n", ip, usp );
        !          97479: 
        !          97480:                        /*
        !          97481:                         * Force core dump.
        !          97482:                         */
        !          97483:                        u.u_sfunc[SIGSEGV] = SIG_DFL;
        !          97484: #endif
        !          97485:                }
        !          97486:                sendsig(sigcode, SELF);
        !          97487:        }
        !          97488: }
        !          97489: 0707070064030104720407550000030000030000011777770507310722000004500000000000/newbits/kernel/USRSRC/i8086/src/RCS0707070064030057031004440000030000030000011777770507310722000005600000035446/newbits/kernel/USRSRC/i8086/src/RCS/ldas.s,vhead     1.2;
        !          97490: access   ;
        !          97491: symbols  ;
        !          97492: locks    ;
        !          97493: comment  @/ @;
        !          97494: 
        !          97495: 
        !          97496: 1.2
        !          97497: date     91.03.01.09.23.04;  author root;  state Exp;
        !          97498: branches 1.2.1.1;
        !          97499: next   1.1;
        !          97500: 
        !          97501: 1.1
        !          97502: date     91.03.01.09.21.44;  author root;  state Exp;
        !          97503: branches ;
        !          97504: next   ;
        !          97505: 
        !          97506: 1.2.1.1
        !          97507: date     91.03.14.13.32.09;  author root;  state Exp;
        !          97508: branches ;
        !          97509: next   ;
        !          97510: 
        !          97511: 
        !          97512: desc
        !          97513: @Hooks linked to kernel code segment for linkage to loaded drivers
        !          97514: @
        !          97515: 
        !          97516: 
        !          97517: 1.2
        !          97518: log
        !          97519: @Part of COHERENT 3.1.0 kernel
        !          97520: @
        !          97521: text
        !          97522: @/ /usr/src/sys/i8086/src/ldas.s
        !          97523: / 
        !          97524: ////////
        !          97525: /
        !          97526: /      Loadable Driver Interface Routines.
        !          97527: /
        !          97528: /      Loadable drivers execute in separate code segments, and are unable
        !          97529: /      to directly call kernel service routines.
        !          97530: /      Loadable drivers call a kernel service stub within their code segment,
        !          97531: /      which has has the same name as the desired service routine.
        !          97532: /      The driver service stub performs a far call to one of these routines.
        !          97533: /      These routines perform a near call to the desired kernel routine,
        !          97534: /      and then perform a far return to the driver service stub routine.
        !          97535: /      The driver service stub routine then does a near return to the driver.
        !          97536: /
        !          97537: / 90/09/11  Hal Snyder
        !          97538: / Add ld_call()
        !          97539: /
        !          97540: / $Log:        /usr/src/sys/i8086/src/RCS/ldas.s,v $
        !          97541: / Revision 1.1 88/03/24  17:39:39      src
        !          97542: / Initial revision
        !          97543: / 
        !          97544: / 87/12/08     Allan Cornish   /usr/src/sys/i8086/src/ldas.s
        !          97545: / Block device interface added to loadable drivers.
        !          97546: / ldtimcall() function added to support timed functions in loadable drivers.
        !          97547: /
        !          97548: / 87/10/25     Allan Cornish   /usr/src/sys/i8086/src/ldas.s
        !          97549: / Initial version - interface to/from loadable driver processes.
        !          97550: /
        !          97551: ////////
        !          97552: 
        !          97553:        .globl  ld_xcall_
        !          97554:        .globl  ld_call_
        !          97555:        .globl  xcalled
        !          97556:        .globl  ldtimcall_
        !          97557:        .globl  ld_open_
        !          97558:        .globl  ld_close_
        !          97559:        .globl  ld_read_
        !          97560:        .globl  ld_write_
        !          97561:        .globl  ld_block_
        !          97562:        .globl  ld_ioctl_
        !          97563:        .globl  ld_power_
        !          97564:        .globl  ld_time_
        !          97565:        .globl  ld_poll_
        !          97566:        .globl  ldrvint_                / void  (*ldrvint[16])();
        !          97567: 
        !          97568: ////////
        !          97569: /
        !          97570: / Constants
        !          97571: /
        !          97572: ////////
        !          97573: 
        !          97574:        T_LDRV  = 12                    / Offset(tim,t_ldrv).
        !          97575:        B_FLAG  = 6                     / Offset(buf,b_flag).
        !          97576:        B_DEV   = 8                     / Offset(buf,b_dev ).
        !          97577:        BFERR   = 4                     / buf.b_flag bit set on I/O error.
        !          97578:        DRV_J   = 4                     / offset in driver of dispatcher
        !          97579: 
        !          97580: ////////
        !          97581: /
        !          97582: / External References
        !          97583: /
        !          97584: ////////
        !          97585: 
        !          97586:        .globl  nonedev_                / extern void    nonedev();
        !          97587:        .globl  ldrvcon_                / extern CON *   ldrvcon[NDRV];
        !          97588:        .globl  ldrvsel_                / extern saddr_t ldrvsel[NDRV];
        !          97589:        .globl  ldrvics_                / extern saddr_t ldrvics[16];
        !          97590:        .globl  ldrvipc_                / extern void  (*ldrvipc[16])();
        !          97591: 
        !          97592: ////////
        !          97593: /
        !          97594: / Shared Data
        !          97595: /
        !          97596: ////////
        !          97597:        .shrd
        !          97598: ldrvint_:                      / Loadable Driver Interrupt Entry Points.
        !          97599:        .word   ld_intr0
        !          97600:        .word   ld_intr1
        !          97601:        .word   ld_intr2
        !          97602:        .word   ld_intr3
        !          97603:        .word   ld_intr4
        !          97604:        .word   ld_intr5
        !          97605:        .word   ld_intr6
        !          97606:        .word   ld_intr7
        !          97607:        .word   ld_intr8
        !          97608:        .word   ld_intr9
        !          97609:        .word   ld_intr10
        !          97610:        .word   ld_intr11
        !          97611:        .word   ld_intr12
        !          97612:        .word   ld_intr13
        !          97613:        .word   ld_intr14
        !          97614:        .word   ld_intr15
        !          97615: 
        !          97616: ////////
        !          97617: /
        !          97618: / Private Data
        !          97619: /
        !          97620: ////////
        !          97621: 
        !          97622:        .prvd
        !          97623:        .shri
        !          97624: 
        !          97625: ////////
        !          97626: /
        !          97627: / Driver Configuration: Offsets to Function Pointers
        !          97628: /
        !          97629: ////////
        !          97630: 
        !          97631:        C_OPEN=4
        !          97632:        C_CLOSE=6
        !          97633:        C_BLOCK=8
        !          97634:        C_READ=10
        !          97635:        C_WRITE=12
        !          97636:        C_IOCTL=14
        !          97637:        C_POWER=16
        !          97638:        C_TIMER=18
        !          97639:        C_LOAD=20
        !          97640:        C_ULOAD=22
        !          97641:        C_POLL=24
        !          97642: 
        !          97643: ////////
        !          97644: /
        !          97645: / ld_xcall( fp )       - invoke far function.
        !          97646: / int (far *fp)();
        !          97647: /
        !          97648: ////////
        !          97649: 
        !          97650: ld_xcall_:
        !          97651:        cli
        !          97652:        push    bp
        !          97653:        mov     bp, sp
        !          97654:        xcall   4(bp)
        !          97655:        pop     bp
        !          97656:        ret
        !          97657: 
        !          97658: ////////
        !          97659: /
        !          97660: / call a driver function from the kernel
        !          97661: /   sel                - CS selector for the driver
        !          97662: /   fn         - offset in the driver of the function we want
        !          97663: /   arg[1-3]    - optional arguments
        !          97664: /
        !          97665: / ld_call(sel, fn, arg1, arg2, arg3)
        !          97666: / int sel;
        !          97667: / int (*fn)(void);
        !          97668: / int arg1, arg2, arg3;
        !          97669: /
        !          97670: ////////
        !          97671: 
        !          97672: / stack when ld_call() is called:
        !          97673: /      arg3
        !          97674: /      arg2
        !          97675: /      arg1
        !          97676: /      fn
        !          97677: /      sel
        !          97678: /      return IP
        !          97679: 
        !          97680: ld_call_:                      / PARAMETERS (arg[1-3]) MUST BE FOUND AT 4(BP).
        !          97681:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          97682: /      lea     bp, 4(sp)       / this is what the next 2 instructions do
        !          97683:        mov     bp, sp
        !          97684:        add     bp, $4
        !          97685:                                /
        !          97686:        push    0(bp)           / Push sel to allow far call
        !          97687:        push    $DRV_J          /
        !          97688:                                /
        !          97689:        mov     ax, 2(bp)       / Push fn
        !          97690:                                /
        !          97691:        xcall   -8(bp)          / Invoke driver interface, which will
        !          97692:                                /       in turn invoke driver function.
        !          97693:                                /
        !          97694:        lea     sp, -4(bp)      /
        !          97695:        pop     bp              /
        !          97696:        ret                     /
        !          97697: 
        !          97698: ////////
        !          97699: /
        !          97700: /
        !          97701: / ldtimcall( arg, tp )  - service timed far function.
        !          97702: /
        !          97703: ////////
        !          97704: 
        !          97705: ldtimcall_:                            /
        !          97706:        push    bp                      /
        !          97707:        mov     bp, sp                  /
        !          97708:                                        /
        !          97709:        mov     bx, 6(bp)               /
        !          97710:        mov     ax, T_LDRV+2(bx)        /
        !          97711:        push    ax                      / Loadable driver code selector.
        !          97712:        push    $DRV_J                  / Loadable driver invocation offset.
        !          97713:        mov     ax, T_LDRV(bx)          / Desired far function.
        !          97714:                                        /
        !          97715:        xcall   -4(bp)                  /
        !          97716:                                        /
        !          97717:        mov     sp, bp                  /
        !          97718:        pop     bp                      /
        !          97719:        ret
        !          97720: 
        !          97721: ////////
        !          97722: /
        !          97723: / xcalled( f, args )
        !          97724: / int (*f)();
        !          97725: /
        !          97726: /      Input:  AX is pointer to kernel function to be invoked.
        !          97727: /
        !          97728: /      Action: Perform a near call to the specified kernel function,
        !          97729: /              passing 6 words as optional arguments.
        !          97730: /              Perform a far return.
        !          97731: /
        !          97732: /      Notes:  Invoked by far call from loadable device driver.
        !          97733: /
        !          97734: ////////
        !          97735: 
        !          97736: xcalled:                       / 6(bp) = grand-parent IP.
        !          97737:        push    bp              / 4(bp) = parent CS
        !          97738:        mov     bp, sp          / 2(bp) = parent IP
        !          97739:                                / AX    = destination function.
        !          97740:        push    20(bp)  / Arg 7 /
        !          97741:        push    18(bp)  / Arg 6 /
        !          97742:        push    16(bp)  / Arg 5 /
        !          97743:        push    14(bp)  / Arg 4 /
        !          97744:        push    12(bp)  / Arg 3 /
        !          97745:        push    10(bp)  / Arg 2 /
        !          97746:        push     8(bp)  / Arg 1 /
        !          97747:        icall   ax              /
        !          97748:                                /
        !          97749:        mov     sp, bp          / Return to loadable driver.
        !          97750:        pop     bp              /
        !          97751:        xret                    /
        !          97752: 
        !          97753: ////////
        !          97754: /
        !          97755: / ld_open( dev, mode )         - Open Routine.
        !          97756: / dev_t dev;
        !          97757: / int mode;
        !          97758: /
        !          97759: ////////
        !          97760: 
        !          97761: ld_open_:                      / PARAMETERS MUST REMAIN AT 4(BP).
        !          97762:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          97763:        mov     bp, sp          /
        !          97764:                                /
        !          97765:        sub     bx, bx          / Calculate major device number * 2.
        !          97766:        movb    bl, 5(bp)       /
        !          97767:        shl     bx, $1          /
        !          97768:                                /
        !          97769:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          97770:        jcxz    0f              /
        !          97771:        push    cx              /
        !          97772:        push    $DRV_J          / Loadable driver invocation offset.
        !          97773:                                /
        !          97774:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          97775:        or      bx, bx          /
        !          97776:        je      0f              /
        !          97777:                                /
        !          97778:        mov     ax, C_OPEN(bx)  / Identify driver function to be invoked.
        !          97779:        or      ax, ax          /
        !          97780:        je      0f              /
        !          97781:                                /
        !          97782:        xcall   -4(bp)          / Invoke driver interface, which will
        !          97783:                                /       in turn invoke driver function.
        !          97784:                                /
        !          97785:        mov     sp, bp          / Return to caller.
        !          97786:        pop     bp              /
        !          97787:        ret                     /
        !          97788: 
        !          97789: 0:     mov     sp, bp
        !          97790:        pop     bp
        !          97791:        jmp     nonedev_
        !          97792: 
        !          97793: ////////
        !          97794: /
        !          97795: / ld_close( dev )              - Close Routine.
        !          97796: / dev_t dev;
        !          97797: /
        !          97798: ////////
        !          97799: 
        !          97800: ld_close_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          97801:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          97802:        mov     bp, sp          /
        !          97803:                                /
        !          97804:        sub     bx, bx          / Calculate major device number * 2.
        !          97805:        movb    bl, 5(bp)       /
        !          97806:        shl     bx, $1          /
        !          97807:                                /
        !          97808:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          97809:        jcxz    0f              /
        !          97810:        push    cx              /
        !          97811:        push    $DRV_J          / Loadable driver invocation offset.
        !          97812:                                /
        !          97813:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          97814:        or      bx, bx          /
        !          97815:        je      0f              /
        !          97816:                                /
        !          97817:        mov     ax, C_CLOSE(bx) / Identify driver function to be invoked.
        !          97818:        or      ax, ax          /
        !          97819:        je      0f              /
        !          97820:                                /
        !          97821:        xcall   -4(bp)          / Invoke driver interface, which will
        !          97822:                                /       in turn invoke driver function.
        !          97823:                                /
        !          97824:        mov     sp, bp          / Return to caller.
        !          97825:        pop     bp              /
        !          97826:        ret                     /
        !          97827: 
        !          97828: 0:     mov     sp, bp
        !          97829:        pop     bp
        !          97830:        jmp     nonedev_
        !          97831: 
        !          97832: ////////
        !          97833: /
        !          97834: / ld_read( dev, iop )          - Read Routine.
        !          97835: / dev_t dev;
        !          97836: / IO * iop;
        !          97837: /
        !          97838: ////////
        !          97839: 
        !          97840: ld_read_:                      / PARAMETERS MUST REMAIN AT 4(BP).
        !          97841:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          97842:        mov     bp, sp          /
        !          97843:                                /
        !          97844:        sub     bx, bx          / Calculate major device number * 2.
        !          97845:        movb    bl, 5(bp)       /
        !          97846:        shl     bx, $1          /
        !          97847:                                /
        !          97848:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          97849:        jcxz    0f              /
        !          97850:        push    cx              /
        !          97851:        push    $DRV_J          / Loadable driver invocation offset.
        !          97852:                                /
        !          97853:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          97854:        or      bx, bx          /
        !          97855:        je      0f              /
        !          97856:                                /
        !          97857:        mov     ax, C_READ(bx)  / Identify driver function to be invoked.
        !          97858:        or      ax, ax          /
        !          97859:        je      0f              /
        !          97860:                                /
        !          97861:        xcall   -4(bp)          / Invoke driver interface, which will
        !          97862:                                /       in turn invoke driver function.
        !          97863:                                /
        !          97864:        mov     sp, bp          / Return to caller.
        !          97865:        pop     bp              /
        !          97866:        ret                     /
        !          97867: 
        !          97868: 0:     mov     sp, bp
        !          97869:        pop     bp
        !          97870:        jmp     nonedev_
        !          97871: 
        !          97872: ///////
        !          97873: /
        !          97874: / ld_write( dev, iop )         - Write Routine.
        !          97875: / dev_t dev;
        !          97876: / IO * iop;
        !          97877: /
        !          97878: ////////
        !          97879: 
        !          97880: ld_write_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          97881:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          97882:        mov     bp, sp          /
        !          97883:                                /
        !          97884:        sub     bx, bx          / Calculate major device number * 2.
        !          97885:        movb    bl, 5(bp)       /
        !          97886:        shl     bx, $1          /
        !          97887:                                /
        !          97888:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          97889:        jcxz    0f              /
        !          97890:        push    cx              /
        !          97891:        push    $DRV_J          / Loadable driver invocation offset.
        !          97892:                                /
        !          97893:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          97894:        or      bx, bx          /
        !          97895:        je      0f              /
        !          97896:                                /
        !          97897:        mov     ax, C_WRITE(bx) / Identify driver function to be invoked.
        !          97898:        or      ax, ax          /
        !          97899:        je      0f              /
        !          97900:                                /
        !          97901:        xcall   -4(bp)          / Invoke driver interface, which will
        !          97902:                                /       in turn invoke driver function.
        !          97903:                                /
        !          97904:        mov     sp, bp          / Return to caller.
        !          97905:        pop     bp              /
        !          97906:        ret                     /
        !          97907: 
        !          97908: 0:     mov     sp, bp
        !          97909:        pop     bp
        !          97910:        jmp     nonedev_
        !          97911: 
        !          97912: ///////
        !          97913: /
        !          97914: / ld_block( bp )               - Block Routine.
        !          97915: / BUF * bp;
        !          97916: /
        !          97917: ////////
        !          97918: 
        !          97919: ld_block_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          97920:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          97921:        mov     bp, sp          /
        !          97922:                                /
        !          97923:        mov     bx, 4(bp)       / Calculate major device number * 2.
        !          97924:        movb    bl, B_DEV+1(bx) /
        !          97925:        subb    bh, bh          /
        !          97926:        shl     bx, $1          /
        !          97927:                                /
        !          97928:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          97929:        jcxz    0f              /
        !          97930:        push    cx              /
        !          97931:        push    $DRV_J          / Loadable driver invocation offset.
        !          97932:                                /
        !          97933:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          97934:        or      bx, bx          /
        !          97935:        je      0f              /
        !          97936:                                /
        !          97937:        mov     ax, C_BLOCK(bx) / Identify driver function to be invoked.
        !          97938:        or      ax, ax          /
        !          97939:        je      0f              /
        !          97940:                                /
        !          97941:        xcall   -4(bp)          / Invoke driver interface, which will
        !          97942:                                /       in turn invoke driver function.
        !          97943:                                /
        !          97944:        mov     sp, bp          / Return to caller.
        !          97945:        pop     bp              /
        !          97946:        ret                     /
        !          97947: 
        !          97948: 0:     mov     bx, 4(bp)       / bp->b_flag |= BFERR.
        !          97949:        or    B_FLAG(bx),$BFERR /
        !          97950:        mov     sp, bp          /
        !          97951:        pop     bp              /
        !          97952:        jmp     bdone_          / bdone(bp);
        !          97953: 
        !          97954: ////////
        !          97955: /
        !          97956: / ld_ioctl( dev, iop )         - Ioctl Routine.
        !          97957: / dev_t dev;
        !          97958: / IO * iop;
        !          97959: /
        !          97960: ////////
        !          97961: 
        !          97962: ld_ioctl_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          97963:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          97964:        mov     bp, sp          /
        !          97965:                                /
        !          97966:        sub     bx, bx          / Calculate major device number * 2.
        !          97967:        movb    bl, 5(bp)       /
        !          97968:        shl     bx, $1          /
        !          97969:                                /
        !          97970:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          97971:        jcxz    0f              /
        !          97972:        push    cx              /
        !          97973:        push    $DRV_J          / Loadable driver invocation offset.
        !          97974:                                /
        !          97975:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          97976:        or      bx, bx          /
        !          97977:        je      0f              /
        !          97978:                                /
        !          97979:        mov     ax, C_IOCTL(bx) / Identify driver function to be invoked.
        !          97980:        or      ax, ax          /
        !          97981:        je      0f              /
        !          97982:                                /
        !          97983:        xcall   -4(bp)          / Invoke driver interface, which will
        !          97984:                                /       in turn invoke driver function.
        !          97985:                                /
        !          97986:        mov     sp, bp          / Return to caller.
        !          97987:        pop     bp              /
        !          97988:        ret                     /
        !          97989: 
        !          97990: 0:     mov     sp, bp
        !          97991:        pop     bp
        !          97992:        jmp     nonedev_
        !          97993: 
        !          97994: ////////
        !          97995: /
        !          97996: / ld_power( dev )              - Powerfail Routine.
        !          97997: / dev_t dev;
        !          97998: /
        !          97999: ////////
        !          98000: 
        !          98001: ld_power_:                     / PARAMETERS MUST REMAIN AT 4(BP).
        !          98002:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          98003:        mov     bp, sp          /
        !          98004:                                /
        !          98005:        sub     bx, bx          / Calculate major device number * 2.
        !          98006:        movb    bl, 5(bp)       /
        !          98007:        shl     bx, $1          /
        !          98008:                                /
        !          98009:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          98010:        jcxz    0f              /
        !          98011:        push    cx              /
        !          98012:        push    $DRV_J          / Loadable driver invocation offset.
        !          98013:                                /
        !          98014:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          98015:        or      bx, bx          /
        !          98016:        je      0f              /
        !          98017:                                /
        !          98018:        mov     ax, C_POWER(bx) / Identify driver function to be invoked.
        !          98019:        or      ax, ax          /
        !          98020:        je      0f              /
        !          98021:                                /
        !          98022:        xcall   -4(bp)          / Invoke driver interface, which will
        !          98023:                                /       in turn invoke driver function.
        !          98024:                                /
        !          98025:        mov     sp, bp          / Return to caller.
        !          98026:        pop     bp              /
        !          98027:        ret                     /
        !          98028: 
        !          98029: 0:     mov     sp, bp
        !          98030:        pop     bp
        !          98031:        jmp     nonedev_
        !          98032: 
        !          98033: ////////
        !          98034: /
        !          98035: / ld_time( dev )               - Timer Routine.
        !          98036: / dev_t dev;
        !          98037: /
        !          98038: ////////
        !          98039: 
        !          98040: ld_time_:                      / PARAMETERS MUST REMAIN AT 4(BP).
        !          98041:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          98042:        mov     bp, sp          /
        !          98043:                                /
        !          98044:        sub     bx, bx          / Calculate major device number * 2.
        !          98045:        movb    bl, 5(bp)       /
        !          98046:        shl     bx, $1          /
        !          98047:                                /
        !          98048:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          98049:        jcxz    0f              /
        !          98050:        push    cx              /
        !          98051:        push    $DRV_J          / Loadable driver invocation offset.
        !          98052:                                /
        !          98053:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          98054:        or      bx, bx          /
        !          98055:        je      0f              /
        !          98056:                                /
        !          98057:        mov     ax, C_TIMER(bx) / Identify driver function to be invoked.
        !          98058:        or      ax, ax          /
        !          98059:        je      0f              /
        !          98060:                                /
        !          98061:        xcall   -4(bp)          / Invoke driver interface, which will
        !          98062:                                /       in turn invoke driver function.
        !          98063:                                /
        !          98064:        mov     sp, bp          / Return to caller.
        !          98065:        pop     bp              /
        !          98066:        ret                     /
        !          98067: 
        !          98068: 0:     mov     sp, bp
        !          98069:        pop     bp
        !          98070:        jmp     nonedev_
        !          98071: 
        !          98072: ////////
        !          98073: /
        !          98074: / ld_poll( dev, ev, msec )     - Poll Routine.
        !          98075: / dev_t dev;
        !          98076: / int ev;
        !          98077: / int msec;
        !          98078: /
        !          98079: ////////
        !          98080: 
        !          98081: ld_poll_:                      / PARAMETERS MUST REMAIN AT 4(BP).
        !          98082:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          98083:        mov     bp, sp          /
        !          98084:                                /
        !          98085:        sub     bx, bx          / Calculate major device number * 2.
        !          98086:        movb    bl, 5(bp)       /
        !          98087:        shl     bx, $1          /
        !          98088:                                /
        !          98089:        mov     cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
        !          98090:        jcxz    0f              /
        !          98091:        push    cx              /
        !          98092:        push    $DRV_J          / Loadable driver invocation offset.
        !          98093:                                /
        !          98094:        mov     bx, ldrvcon_(bx)/ Identify driver configuration.
        !          98095:        or      bx, bx          /
        !          98096:        je      0f              /
        !          98097:                                /
        !          98098:        mov     ax, C_POLL(bx)  / Identify driver function to be invoked.
        !          98099:        or      ax, ax          /
        !          98100:        je      0f              /
        !          98101:                                /
        !          98102:        xcall   -4(bp)          / Invoke driver interface, which will
        !          98103:                                /       in turn invoke driver function.
        !          98104:                                /
        !          98105:        mov     sp, bp          / Return to caller.
        !          98106:        pop     bp              /
        !          98107:        ret                     /
        !          98108: 
        !          98109: 0:     mov     sp, bp
        !          98110:        pop     bp
        !          98111:        jmp     nonedev_
        !          98112: 
        !          98113: ////////
        !          98114: /
        !          98115: / Loadable Driver Interrupt Entry Points.
        !          98116: /
        !          98117: /      Invoked by Coherent to service specific interrupt.
        !          98118: /      Identifies which loadable driver interrupt vector to be used.
        !          98119: /      Invokes interrupt handler which will do far call to loadable driver.
        !          98120: /
        !          98121: ////////
        !          98122: 
        !          98123: ld_intr0:
        !          98124:        mov     bx, $0          /
        !          98125:        jmp     ld_intr         /
        !          98126: 
        !          98127: ld_intr1:
        !          98128:        mov     bx, $2          /
        !          98129:        jmp     ld_intr         /
        !          98130: 
        !          98131: ld_intr2:
        !          98132:        mov     bx, $4          /
        !          98133:        jmp     ld_intr         /
        !          98134: 
        !          98135: ld_intr3:
        !          98136:        mov     bx, $6          /
        !          98137:        jmp     ld_intr         /
        !          98138: 
        !          98139: ld_intr4:
        !          98140:        mov     bx, $8          /
        !          98141:        jmp     ld_intr         /
        !          98142: 
        !          98143: ld_intr5:
        !          98144:        mov     bx, $10         /
        !          98145:        jmp     ld_intr         /
        !          98146: 
        !          98147: ld_intr6:
        !          98148:        mov     bx, $12         /
        !          98149:        jmp     ld_intr         /
        !          98150: 
        !          98151: ld_intr7:
        !          98152:        mov     bx, $14         /
        !          98153:        jmp     ld_intr         /
        !          98154: 
        !          98155: ld_intr8:
        !          98156:        mov     bx, $16         /
        !          98157:        jmp     ld_intr         /
        !          98158: 
        !          98159: ld_intr9:
        !          98160:        mov     bx, $18         /
        !          98161:        jmp     ld_intr         /
        !          98162: 
        !          98163: ld_intr10:
        !          98164:        mov     bx, $20         /
        !          98165:        jmp     ld_intr         /
        !          98166: 
        !          98167: ld_intr11:
        !          98168:        mov     bx, $22         /
        !          98169:        jmp     ld_intr         /
        !          98170: 
        !          98171: ld_intr12:
        !          98172:        mov     bx, $24         /
        !          98173:        jmp     ld_intr         /
        !          98174: 
        !          98175: ld_intr13:
        !          98176:        mov     bx, $26         /
        !          98177:        jmp     ld_intr         /
        !          98178: 
        !          98179: ld_intr14:
        !          98180:        mov     bx, $28         /
        !          98181:        jmp     ld_intr         /
        !          98182: 
        !          98183: ld_intr15:
        !          98184:        mov     bx, $30         /
        !          98185:        jmp     ld_intr         /
        !          98186: 
        !          98187: ////////
        !          98188: /
        !          98189: / Loadable driver interrupt handler.
        !          98190: /
        !          98191: /
        !          98192: /      Input:  bx = interrupt number * 2.
        !          98193: /
        !          98194: ////////
        !          98195: 
        !          98196: ld_intr:
        !          98197:        push    bp              /
        !          98198:        mov     bp, sp          /
        !          98199:                                /
        !          98200:        mov     cx,ldrvics_(bx) / Prepare driver interface CS:IP.
        !          98201:        jcxz    0f              /
        !          98202:        push    cx              /
        !          98203:        push    $DRV_J          / Loadable driver invocation offset.
        !          98204:                                /
        !          98205:        mov     ax,ldrvipc_(bx) / Identify interrupt handler to be invoked.
        !          98206:        or      ax, ax          /
        !          98207:        je      0f              /
        !          98208:                                /
        !          98209:        xcall   -4(bp)          / Invoke driver interface, which will
        !          98210:                                /       in turn invoke driver function.
        !          98211:                                /
        !          98212: 0:     mov     sp, bp          /
        !          98213:        pop     bp              /
        !          98214:        ret                     /
        !          98215: @
        !          98216: 
        !          98217: 
        !          98218: 1.2.1.1
        !          98219: log
        !          98220: @has kernel printf's for interrupts called
        !          98221: @
        !          98222: text
        !          98223: @a19 3
        !          98224: / Revision 1.2 91/03/01  09:23:04      root
        !          98225: / Part of COHERENT 3.1.0 kernel
        !          98226: / 
        !          98227: a94 2
        !          98228: foo:   .ascii  "I%d %x:%x\n\000"       
        !          98229: 
        !          98230: d674 1
        !          98231: a674 2
        !          98232:        .globl  printf_ / for debugging
        !          98233:        .globl  ld_intr / for debugging
        !          98234: a677 13
        !          98235:        
        !          98236: / Diagnostic call: printf(foo, bx/2, ldrvics[bx], ldrvipc[bx])
        !          98237: push   bx
        !          98238: push   ldrvipc_(bx)
        !          98239: push   ldrvics_(bx)
        !          98240: mov    ax,bx
        !          98241: shr    ax,$1
        !          98242: push   ax
        !          98243: push   $foo
        !          98244: call   printf_
        !          98245: add    sp,$8
        !          98246: pop    bx
        !          98247: / End of diagnostic call       
        !          98248: @
        !          98249: 
        !          98250: 
        !          98251: 1.1
        !          98252: log
        !          98253: @Part of COHERENT 3.0.0 kernel
        !          98254: @
        !          98255: text
        !          98256: @d1 1
        !          98257: a1 1
        !          98258: / $Header: /usr/src/sys/i8086/src/RCS/ldas.s,v 1.1 88/03/24 17:39:39 src Exp $
        !          98259: d3 1
        !          98260: a3 10
        !          98261: /      The  information  contained herein  is a trade secret  of INETCO
        !          98262: /      Systems, and is confidential information.   It is provided under
        !          98263: /      a license agreement,  and may be copied or disclosed  only under
        !          98264: /      the terms of that agreement.   Any reproduction or disclosure of
        !          98265: /      this  material  without  the express  written  authorization  of
        !          98266: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          98267: / 
        !          98268: /      Copyright (c) 1987
        !          98269: /      An unpublished work by INETCO Systems, Ltd.
        !          98270: /      All rights reserved.
        !          98271: a4 3
        !          98272: 
        !          98273: ////////
        !          98274: /
        !          98275: d16 2
        !          98276: d33 1
        !          98277: d57 1
        !          98278: a101 1
        !          98279: four:  .word   4
        !          98280: d139 4
        !          98281: d144 36
        !          98282: d191 1
        !          98283: a191 1
        !          98284:        push    four                    / Loadable driver invocation offset.
        !          98285: d251 1
        !          98286: a251 1
        !          98287:        push    four            /
        !          98288: d290 1
        !          98289: a290 1
        !          98290:        push    four            /
        !          98291: d330 1
        !          98292: a330 1
        !          98293:        push    four            /
        !          98294: d370 1
        !          98295: a370 1
        !          98296:        push    four            /
        !          98297: d410 1
        !          98298: a410 1
        !          98299:        push    four            /
        !          98300: d452 1
        !          98301: a452 1
        !          98302:        push    four            /
        !          98303: d491 1
        !          98304: a491 1
        !          98305:        push    four            /
        !          98306: d530 1
        !          98307: a530 1
        !          98308:        push    four            /
        !          98309: d571 1
        !          98310: a571 1
        !          98311:        push    four            /
        !          98312: d682 1
        !          98313: a682 1
        !          98314:        push    four            /
        !          98315: @
        !          98316: 0707070064030103041004440000030000030000011777770507310722400006100000001077/newbits/kernel/USRSRC/i8086/src/RCS/support.c,vhead     1.1;
        !          98317: branch   ;
        !          98318: access   ;
        !          98319: symbols  ;
        !          98320: locks    ; strict;
        !          98321: comment  @ * @;
        !          98322: 
        !          98323: 
        !          98324: 1.1
        !          98325: date     91.06.04.14.37.52;  author hal;  state Exp;
        !          98326: branches ;
        !          98327: next     ;
        !          98328: 
        !          98329: 
        !          98330: desc
        !          98331: @Export variables needed for polling, e.g. by async drivers.
        !          98332: @
        !          98333: 
        !          98334: 
        !          98335: 
        !          98336: 1.1
        !          98337: log
        !          98338: @Mystery version from dyna - lacks poll_rate & poll_owner
        !          98339: @
        !          98340: text
        !          98341: @#include <al.h>
        !          98342: /*
        !          98343:  * the following kernel resident parts are shared by loadable serial drivers
        !          98344:  *   (see al.h and poll_clk.h)
        !          98345:  */
        !          98346: int    com_usage[NUM_AL_PORTS];        /* COM_UNUSED/COM_IRQ/COM_POLLED */
        !          98347: TTY    *(tp_table[NUM_AL_PORTS]);      /* table of pointers for polling */
        !          98348: @
        !          98349: 0707070064030104671004440000030000030000011777770507310722500005500000062130/newbits/kernel/USRSRC/i8086/src/RCS/as1.s,vhead     1.1;
        !          98350: branch   ;
        !          98351: access   ;
        !          98352: symbols  ;
        !          98353: locks    bin:1.1; strict;
        !          98354: comment  @@;
        !          98355: 
        !          98356: 
        !          98357: 1.1
        !          98358: date     91.06.10.10.36.30;  author bin;  state Exp;
        !          98359: branches ;
        !          98360: next     ;
        !          98361: 
        !          98362: 
        !          98363: desc
        !          98364: @/dev/rfva0
        !          98365: @
        !          98366: 
        !          98367: 
        !          98368: 
        !          98369: 1.1
        !          98370: log
        !          98371: @Initial revision
        !          98372: @
        !          98373: text
        !          98374: @/ $Header: /usr/src/sys/i8086/src/RCS/as1.s,v 1.3 88/08/05 08:32:09 src Exp $
        !          98375: 
        !          98376: / (lgl-
        !          98377: /      The information contained herein is a trade secret of Mark Williams
        !          98378: /      Company, and  is confidential information.  It is provided  under a
        !          98379: /      license agreement,  and may be  copied or disclosed  only under the
        !          98380: /      terms of  that agreement.  Any  reproduction or disclosure  of this
        !          98381: /      material without the express written authorization of Mark Williams
        !          98382: /      Company or persuant to the license agreement is unlawful.
        !          98383: /
        !          98384: /      COHERENT Version 2.3.37
        !          98385: /      Copyright (c) 1982, 1983, 1984.
        !          98386: /      An unpublished work by Mark Williams Company, Chicago.
        !          98387: /      All rights reserved.
        !          98388: / -lgl)
        !          98389: ////////
        !          98390: /
        !          98391: / Machine language assist for
        !          98392: / 8086/8088 Coherent. This contains the parts
        !          98393: / that are common to all machines.
        !          98394: /
        !          98395: / Note that several of the following constants can be invalidated
        !          98396: / by changing the contents of ../h/*proc.h among others,
        !          98397: / or by changing the number of automatic variables in the functions
        !          98398: / called on the paths leading to consave or conrest.  Tread with caution.
        !          98399: /
        !          98400: / $Log:        /usr/src/sys/i8086/src/RCS/as1.s,v $
        !          98401: / Revision 1.3 88/08/05  08:32:09      src
        !          98402: / Kludges for AMD 286 bug have been removed.
        !          98403: / 
        !          98404: / Revision 1.2 88/06/24  16:02:08      src
        !          98405: / Bug: inb/outb did not work properly in split stack/data operation.
        !          98406: / Fix: inb/outb now explicitly reference the stack segment.
        !          98407: / 
        !          98408: / Revision 1.1 88/03/24  17:39:08      src
        !          98409: / Initial revision
        !          98410: / 
        !          98411: / 88/03/10     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          98412: / Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !          98413: / These partial fixes will be removed once all CPU's are replaced.
        !          98414: /
        !          98415: / 88/03/04     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          98416: / tmpcs*/tmpds* temporary variables renamed to sav_*.
        !          98417: / usave/conrest/etc now handle odd byte alignment on stack.
        !          98418: / envrest/conrest now do interrupt return as last instruction.
        !          98419: /
        !          98420: / 87/12/21     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          98421: / fclear(f,n) function added.
        !          98422: /
        !          98423: / 87/12/04     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          98424: / kfcopy(k,f,n) and fkcopy(f,k,n) routines added.
        !          98425: /
        !          98426: / 87/12/03     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          98427: / popf replaced by 'push cs; mov ax,$0f; push ax; iret; 0:' due to popf int bug.
        !          98428: /
        !          98429: / 87/11/05     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !          98430: / slrcopy/srlcopy/sclear renamed plrcopy/prlcopy/pclear and moved to ibm*/as2.s
        !          98431: /
        !          98432: / 87/10/27     Allan Cornish   /usr/src/sys/i8086/src/as1.s
        !          98433: / System stack/data segments now setup in ibm/ibm_at as2.s
        !          98434: /
        !          98435: / 87/02/06     Allan Cornish
        !          98436: / Functions ffword and sfword added to fetch and set far memory.
        !          98437: /
        !          98438: ////////
        !          98439: 
        !          98440: UPASIZE        =       1024                    / Size of uproc and stack
        !          98441: USIZE  =       0x114                   / sizeof(UPROC)
        !          98442: USZ1   =       140                     / Word count for usave, uproc size
        !          98443: UMCSP  =       0x06                    / offset of sp in u_syscon
        !          98444: EFAULT =       14                      / Bad argument
        !          98445: PFLAGS =       0x22                    / Offset into PROC.
        !          98446: PFKERN =       0x80                    / Kernel process flag bit.
        !          98447: SIDEV  =       0x40                    / Device interrupt trap code.
        !          98448: 
        !          98449: ////////
        !          98450: /
        !          98451: / After performing machine specific
        !          98452: / trap vector setup, the startup code jumps
        !          98453: / here. The DS maps the vectors.
        !          98454: /
        !          98455: ////////
        !          98456: 
        !          98457:        .globl  start
        !          98458: 
        !          98459: start:
        !          98460: / Call the machine setup code.
        !          98461: / Call Coherent main.
        !          98462: / On return, send control off to the user
        !          98463: / at its entry point.
        !          98464: 
        !          98465:        mov     sp, $u_+UPASIZE-32      / Stack pointer for init
        !          98466:        call    i8086_                  / Do it.
        !          98467:        sti                             / Interrupts on, and
        !          98468:        call    main_                   / call Coherent mainline.
        !          98469:        cli                             / Interrupts off.
        !          98470:        incb    depth_                  / Set stack depth to user.
        !          98471:        sub     ax, ax                  / User mode IP.
        !          98472:        mov     bx, uds_                / User mode DS, ES, SS
        !          98473:        mov     cx, ucs_                / User mode CS.
        !          98474:        mov     dx, $0x0200             / User mode FL.
        !          98475: 
        !          98476:        mov     ds, bx                  / Map data segment
        !          98477:        mov     es, bx                  / Map extra segment
        !          98478:        mov     ss, bx                  / Map stack segment
        !          98479: 
        !          98480:        mov     sp, $sb-aicodep_        / User's stack
        !          98481:        push    dx                      / Flags
        !          98482:        push    cx                      / CS
        !          98483:        push    ax                      / IP
        !          98484:        iret                            / Go to user state.
        !          98485: 
        !          98486: ////////
        !          98487: /
        !          98488: / Trap and interrupt save.
        !          98489: / These routines will be very familiar to any
        !          98490: / RSX-11M hackers out there; it is just the ever
        !          98491: / common co-routine call. The caller is called back,
        !          98492: / with "bx" pointing to the saved "ax" on the stack,
        !          98493: / with interrupts enabled. The called routine must
        !          98494: / set 16(bx), which was initially the call back address,
        !          98495: / to something non zero in the high byte if it does
        !          98496: / not want an EOI sent to the 8259.
        !          98497: /
        !          98498: / ttsave, tksave, tisave, and tusave could be folded into a single routine
        !          98499: / with many tests and branches, but the frequency of passage through
        !          98500: / this code warrants a minimally branched execution, and special casing
        !          98501: / the interrupted context allows minimal memory references.
        !          98502: /
        !          98503: ////////
        !          98504: 
        !          98505:        .globl  tsave
        !          98506: 
        !          98507: tsave:                         / What level of interrupt ?
        !          98508:        push    ds                      / Save current data base
        !          98509:        mov     ds, cs:cds              / remap to system data space.
        !          98510:        pop     sav_ds                  /
        !          98511:        decb    depth_                  / Adjust stack depth.
        !          98512:        je      tkusave                 / If e, stack switch may be needed.
        !          98513: ttsave:                                / Interrupted within interrupt
        !          98514:        cmp     sp,$u_+USIZE+50         / Check for stack
        !          98515:        jbe     tabort                  / overflow
        !          98516:        push    ss                      / Fake save ss
        !          98517:        push    sp                      / Fake save sp
        !          98518:        push    sav_ds                  / Save ds
        !          98519:        push    bx                      / Save bx
        !          98520: 
        !          98521:        sti                             / More interrupts ok
        !          98522: 
        !          98523:        push    ax                      / Save ax
        !          98524:        push    dx                      / and remainder
        !          98525:        push    cx                      / of machine
        !          98526:        push    es                      / state
        !          98527:        mov     ax,ds                   / Map es
        !          98528:        mov     es,ax                   / to system ds
        !          98529:        mov     bx,sp                   / Load index
        !          98530:        icall   16(bx)                  / and call the caller
        !          98531:        mov     bx,sp                   / Load index
        !          98532:        mov     ax,16(bx)               / fetch trap type
        !          98533:        cmpb    ah, $SIDEV              / see if eoi
        !          98534:        jne     ttkdone                 / can be skipped
        !          98535: 
        !          98536:        cli                             / don't let eoi swamp us
        !          98537:        call    eoi                     / Dismiss interrupt
        !          98538: ttkdone:                       / Common ttsave/tksave finish
        !          98539:        pop     es                      / Restore
        !          98540:        pop     cx                      / the
        !          98541:        pop     dx                      / machine state
        !          98542:        pop     ax                      / state
        !          98543: 
        !          98544:        cli                             / No more interrupts
        !          98545: 
        !          98546:        incb    depth_                  / Reset stack level
        !          98547:        pop     bx                      / Restore the
        !          98548:        pop     ds                      / last parts
        !          98549:        add     sp,$6                   / forget ss, sp, and ra.
        !          98550:        iret                            / Done.
        !          98551: 
        !          98552: tabort:                                / Uarea stack overflowed
        !          98553:        add     sp,$300                 / Make room for death.
        !          98554:        mov     ax,$oops                / Load
        !          98555:        push    ax                      / message
        !          98556:        call    panic_                  / and die.
        !          98557: 
        !          98558: tkusave:                       / Kernel or user process interrupted
        !          98559:        mov     sav_bx,bx               / Save bx in temp
        !          98560:        mov     bx,cprocp_              / Load proc pointer
        !          98561:        test    PFLAGS(bx),$PFKERN      / Kernel process ?
        !          98562:        je      tusave                  / Sorry, go do it all.
        !          98563: tksave:                                / Kernel process interrupted
        !          98564:        push    ss                      / Fake save ss
        !          98565:        push    sp                      / Fake save sp
        !          98566:        push    sav_ds                  / Save ds
        !          98567:        push    sav_bx                  / Save bx
        !          98568: 
        !          98569:        sti                             / More interrupts ok.
        !          98570: 
        !          98571:        cmp     bx,iprocp_              / Is this the idle process ?
        !          98572:        je      tisave                  / Yes, very easy
        !          98573:        push    ax                      / Save the
        !          98574:        push    dx                      / rest of
        !          98575:        push    cx                      / the machine
        !          98576:        push    es                      / state
        !          98577:        mov     ax,ds                   / And map
        !          98578:        mov     es,ax                   / extra to system data
        !          98579:        mov     bx,sp                   / Load index
        !          98580:        icall   16(bx)                  / and call the caller back.
        !          98581:        mov     bx,sp                   / Load index
        !          98582:        mov     ax,16(bx)               / and pull trap type.
        !          98583:        cmpb    ah, $SIDEV              / Machine trap?
        !          98584:        jne     ttkdone                 / Yes, skip dismiss
        !          98585:        call    eoi                     / Dismiss interrupt
        !          98586:        jmp     ttkdone                 / Finish above
        !          98587: 
        !          98588: tisave:                                / Idle process interrupted, nothing to save
        !          98589:        sub     sp,$8                   / Push junk
        !          98590:        mov     bx,sp                   / Load index
        !          98591:        icall   16(bx)                  / and call the caller back.
        !          98592:        mov     bx,sp                   / Load index
        !          98593:        mov     ax,16(bx)               / and pull trap type.
        !          98594:        cmpb    ah, $SIDEV              / Machine trap ?
        !          98595:        jne     0f                      / Yes, skip dismiss.
        !          98596:        call    eoi                     / Dismiss interrupt
        !          98597: 0:
        !          98598:        call    stand_                  / Clock, part 2
        !          98599:        cli                             / No more interrupts
        !          98600: 
        !          98601:        add     sp,$18                  / Pop everything
        !          98602:        incb    depth_                  / Reset level
        !          98603:        iret                            / Done
        !          98604: 
        !          98605: tusave:                                / User process interrupted
        !          98606:        mov     bx, $u_+UPASIZE         / Get base of user area and
        !          98607:        pop     -8(bx)                  / pop the data that
        !          98608:        pop     -6(bx)                  / was pushed onto the user
        !          98609:        pop     -4(bx)                  / stack onto the new
        !          98610:        pop     -2(bx)                  / system stack.
        !          98611:        mov     sav_ss, ss              / Save the old stack segment
        !          98612:        mov     sav_sp, sp              / and stack pointer, then
        !          98613:        mov     ss, sds_                / switch onto the
        !          98614:        lea     sp, -8(bx)              / new stack in the user area.
        !          98615:        push    sav_ss                  / Push old ss
        !          98616:        push    sav_sp                  / Push old sp
        !          98617:        push    sav_ds                  / Push old ds and
        !          98618:        push    sav_bx                  / push old bx.
        !          98619: 
        !          98620:        sti                             / Allow more interrupts.
        !          98621: 
        !          98622:        push    ax                      / Save the
        !          98623:        push    dx                      / remainder of
        !          98624:        push    cx                      / the machine
        !          98625:        push    es                      / state.
        !          98626:        mov     ax, ds                  / Map extra
        !          98627:        mov     es, ax                  / segment to system data.
        !          98628:        mov     bx, sp                  / Load up an index into the stack
        !          98629:        icall   16(bx)                  / and call the caller back.
        !          98630:        mov     bx, sp                  / Load up stack index.
        !          98631:        mov     ax, 16(bx)              / Pull trap type.
        !          98632:        cmpb    ah, $SIDEV              / Is this a machine trap ?
        !          98633:        jne     0f                      / Yes, skip dismiss.
        !          98634:        call    eoi                     / Do the dismiss.
        !          98635: 0:     mov     bx, cprocp_             / Have we become kernel?
        !          98636:        test    PFLAGS(bx), $PFKERN     / If so, do kernel return.
        !          98637:        jne     ttkdone                 /
        !          98638: 
        !          98639:        call    stand_                  / Clock, part 2
        !          98640:        pop     es                      / Restore the
        !          98641:        pop     cx                      / easy part of the
        !          98642:        pop     dx                      / machine
        !          98643:        pop     ax                      / state.
        !          98644: 
        !          98645:        cli                             / Interrupts off.
        !          98646: 
        !          98647:        incb    depth_                  / Adjust stack depth and
        !          98648:        pop     sav_bx                  / Pop off the old bx and
        !          98649:        pop     sav_ds                  / ds into statics, then
        !          98650:        pop     bx                      / map DS:BX over top of what
        !          98651:        pop     ds                      / was the previous stack.
        !          98652:        add     sp, $2                  / Pop ra.
        !          98653:        pop     -6(bx)                  / Copy the IP,
        !          98654:        pop     -4(bx)                  / the CS and the old
        !          98655:        pop     -2(bx)                  / FW onto the user's stack, then
        !          98656:        lea     sp, -6(bx)              / switch back
        !          98657:        mov     bx, ds                  / to the
        !          98658:        mov     ss, bx                  / user's stack.
        !          98659:        mov     ds, cs:cds              /
        !          98660:        mov     bx, sav_bx              / Reload the bx and the
        !          98661:        mov     ds, sav_ds              / ds, then
        !          98662:        iret                            / exit interrupt.
        !          98663: 
        !          98664: ////////
        !          98665: /
        !          98666: / This dummy routine is put in vector
        !          98667: / table slots that are unused. All it does is
        !          98668: / return to the caller.
        !          98669: /
        !          98670: ////////
        !          98671: 
        !          98672:        .globl  vret_
        !          98673: 
        !          98674: vret_: ret
        !          98675: 
        !          98676: ////////
        !          98677: /
        !          98678: / Fetch a word from the user's data space.
        !          98679: /
        !          98680: / getuwd(u)
        !          98681: / char *u;
        !          98682: /
        !          98683: ////////
        !          98684: 
        !          98685:        .globl  getuwd_
        !          98686:        .globl  getupd_
        !          98687: 
        !          98688: getuwd_:
        !          98689: getupd_:
        !          98690:        mov     bx,sp                   / Base pointer
        !          98691:        mov     bx,2(bx)                / Argument
        !          98692:        cmp     bx,udl_                 / In range?
        !          98693:        ja      kuerr                   / No
        !          98694: 
        !          98695:        push    es                      / Save extra map and
        !          98696:        mov     es, uds_                / remap over the user's data.
        !          98697:        mov     ax,es:(bx)              / Get word
        !          98698:        pop     es                      / Restore es.
        !          98699:        ret                             / Return
        !          98700: 
        !          98701: ////////
        !          98702: /
        !          98703: / Fetch a word from the user's code space.
        !          98704: /
        !          98705: / getuwi(u)
        !          98706: / char *u;
        !          98707: /
        !          98708: ////////
        !          98709: 
        !          98710:        .globl  getuwi_
        !          98711: 
        !          98712: getuwi_:
        !          98713:        mov     bx,sp                   / Base pointer
        !          98714:        mov     bx,2(bx)                / Argument
        !          98715:        cmp     bx,ucl_                 / In range?
        !          98716:        ja      kuerr                   / No
        !          98717: 
        !          98718:        push    es                      / Save extra.
        !          98719:        mov     es,ucs_                 / Users data segment
        !          98720:        mov     ax,es:(bx)              / Get word
        !          98721:        pop     es                      / Restore extra.
        !          98722:        ret                             / Return
        !          98723: 
        !          98724: ////////
        !          98725: /
        !          98726: / Fetch a byte from the user's data space.
        !          98727: /
        !          98728: / getubd(u)
        !          98729: / char *u;
        !          98730: /
        !          98731: ////////
        !          98732: 
        !          98733:        .globl  getubd_
        !          98734: 
        !          98735: getubd_:
        !          98736:        mov     bx,sp                   / Base pointer
        !          98737:        mov     bx,2(bx)                / Argument
        !          98738:        cmp     bx,udl_                 / In range?
        !          98739:        ja      kuerr                   / No
        !          98740: 
        !          98741:        push    es                      / Save es.
        !          98742:        mov     es,uds_                 / Users data segment
        !          98743:        movb    al,es:(bx)              / Get word
        !          98744:        pop     es                      / Restore es.
        !          98745:        subb    ah,ah                   / Clear upper half
        !          98746:        ret                             / Return
        !          98747: 
        !          98748: ////////
        !          98749: /
        !          98750: / Store a word into the user's data space.
        !          98751: /
        !          98752: / putuwd(u, w)
        !          98753: / char *u;
        !          98754: / int w;
        !          98755: /
        !          98756: ////////
        !          98757: 
        !          98758:        .globl  putuwd_
        !          98759: 
        !          98760: putuwd_:
        !          98761:        mov     bx,sp                   / Base pointer
        !          98762:        mov     ax,4(bx)                / New value
        !          98763:        mov     bx,2(bx)                / Argument
        !          98764:        cmp     bx,udl_                 / In range?
        !          98765:        ja      kuerr                   / No
        !          98766: 
        !          98767:        push    es                      / Save es.
        !          98768:        mov     es,uds_                 / Users data segment
        !          98769:        mov     es:(bx),ax              / Set value
        !          98770:        pop     es                      / Restore es.
        !          98771:        sub     ax,ax                   / Succesful
        !          98772:        ret                             / Return
        !          98773: 
        !          98774: ////////
        !          98775: /
        !          98776: / Store a word into the user's code space.
        !          98777: /
        !          98778: / putuwi(u, w)
        !          98779: / char *u;
        !          98780: / int w;
        !          98781: /
        !          98782: ////////
        !          98783: 
        !          98784:        .globl  putuwi_
        !          98785: 
        !          98786: putuwi_:
        !          98787:        mov     bx,sp                   / Base pointer
        !          98788:        mov     ax,4(bx)                / New value
        !          98789:        mov     bx,2(bx)                / Argument
        !          98790:        cmp     bx,ucl_                 / In range?
        !          98791:        ja      kuerr                   / No
        !          98792: 
        !          98793:        push    ucs_                    / Get physical address.
        !          98794:        sub     ax, ax                  / DX:AX = phy = vtop( ucs:0 );
        !          98795:        push    ax                      /
        !          98796:        call    vtop_                   /
        !          98797:        add     sp, $4                  /
        !          98798:                                        /
        !          98799:        sub     bx, bx                  / Get writable virtual address.
        !          98800:        push    bx                      / DX:AX = fp = ptov( phy, ucl );
        !          98801:        push    ucl_                    /
        !          98802:        push    dx                      /
        !          98803:        push    ax                      /
        !          98804:        call    ptov_                   /
        !          98805:        add     sp, $8                  /
        !          98806:                                        /
        !          98807:        mov     bx, sp                  /
        !          98808:        mov     ax, 4(bx)               / New value
        !          98809:        mov     bx, 2(bx)               / Argument
        !          98810:        push    es                      / Save ES
        !          98811:        mov     es, dx                  / Users (writable) code segment
        !          98812:        mov     es:(bx), ax             / Set value
        !          98813:        pop     es                      / Restore es
        !          98814:                                        /
        !          98815:        push    dx                      / Release writable virtual address.
        !          98816:        sub     ax, ax                  / vrelse( fp );
        !          98817:        push    ax                      /
        !          98818:        call    vrelse_                 /
        !          98819:        add     sp, $4                  /
        !          98820:                                        /
        !          98821:        sub     ax,ax                   / Succesful
        !          98822:        ret                             / Return
        !          98823: 
        !          98824: ////////
        !          98825: /
        !          98826: / Store a byte into the user's data space.
        !          98827: /
        !          98828: / putubd(u, w)
        !          98829: / char *u;
        !          98830: / int w;
        !          98831: /
        !          98832: ////////
        !          98833: 
        !          98834:        .globl  putubd_
        !          98835: 
        !          98836: putubd_:
        !          98837:        mov     bx,sp                   / Base pointer
        !          98838:        mov     ax,4(bx)                / New value
        !          98839:        mov     bx,2(bx)                / Argument
        !          98840:        cmp     bx,udl_                 / In range?
        !          98841:        ja      kuerr                   / No
        !          98842: 
        !          98843:        push    es                      / Save es.
        !          98844:        mov     es,uds_                 / Users data segment
        !          98845:        movb    es:(bx),al              / Set value
        !          98846:        pop     es                      / Restore es.
        !          98847:        sub     ax,ax                   / Succesful
        !          98848:        ret                             / Return
        !          98849: 
        !          98850: ////////
        !          98851: /
        !          98852: / Block transfer "n" bytes from location
        !          98853: / "k" in the system map to location "u" in the
        !          98854: / user's data space. Return the number of bytes
        !          98855: / transferred.
        !          98856: /
        !          98857: / kucopy(k, u, n)
        !          98858: / char *k;
        !          98859: / char *u;
        !          98860: / int n;
        !          98861: /
        !          98862: ////////
        !          98863: 
        !          98864:        .globl  kucopy_
        !          98865: 
        !          98866: kucopy_:
        !          98867:        mov     bx,sp                   / Base pointer
        !          98868:        mov     ax,4(bx)                / User address
        !          98869:        dec     ax                      / Don't wrap too soon
        !          98870:        add     ax,6(bx)                / Add count
        !          98871:        jc      kuerr                   / Out of bounds
        !          98872:        cmp     ax,udl_                 / In range?
        !          98873:        ja      kuerr                   / No
        !          98874: 
        !          98875:        push    si                      / Save si
        !          98876:        push    di                      / Save di
        !          98877:        push    es                      / Save es.
        !          98878: 
        !          98879:        mov     si,2(bx)                / Kernel address
        !          98880:        mov     di,4(bx)                / User address
        !          98881:        mov     cx,6(bx)                / Count
        !          98882:        mov     ax,cx                   / Move here to return
        !          98883:        mov     es,uds_                 / Map extra segment to user
        !          98884: 
        !          98885:        cld                             / Auto increment
        !          98886:        clc                             /
        !          98887:        rcr     cx, $1                  / Calculate Word count
        !          98888:        rep                             /
        !          98889:        movsw                           / Move words.
        !          98890:        rcl     cx, $1
        !          98891:        rep
        !          98892:        movsb                           / Move odd byte.
        !          98893: 
        !          98894:        pop     es                      / Restore es.
        !          98895:        pop     di                      / Restore di
        !          98896:        pop     si                      / Restore si
        !          98897:        ret                             / Return
        !          98898: 
        !          98899: ////////
        !          98900: /
        !          98901: / Block copy "n" bytes from location "u" in
        !          98902: / the user data space to location "k" in the system
        !          98903: / data space. Return the actual number of bytes
        !          98904: / moved.
        !          98905: /
        !          98906: / ukcopy(u, k, n)
        !          98907: / char *u;
        !          98908: / char *k;
        !          98909: / int n;
        !          98910: /
        !          98911: ////////
        !          98912: 
        !          98913:        .globl  ukcopy_
        !          98914: 
        !          98915: ukcopy_:
        !          98916:        mov     bx,sp                   / Base pointer
        !          98917:        mov     ax,2(bx)                / User address
        !          98918:        dec     ax                      / Don't wrap too soon
        !          98919:        add     ax,6(bx)                / Count
        !          98920:        jc      kuerr                   / Out of bounds
        !          98921:        cmp     ax,udl_                 / In range?
        !          98922:        ja      kuerr                   / No
        !          98923: 
        !          98924:        push    si                      / Save si
        !          98925:        push    di                      / Save di
        !          98926:        push    ds                      / Save ds
        !          98927: 
        !          98928:        mov     si,2(bx)                / User address
        !          98929:        mov     di,4(bx)                / Kernel address
        !          98930:        mov     cx,6(bx)                / Count
        !          98931:        mov     ax,cx                   / Move here to return
        !          98932:        mov     bx, uds_                / Map data segment
        !          98933:        mov     ds, bx                  / avoiding bug in 8088.
        !          98934: 
        !          98935:        cld                             / Auto increment
        !          98936:        clc                             /
        !          98937:        rcr     cx, $1                  / Word count, odd byte in carry.
        !          98938:        rep                             /
        !          98939:        movsw                           / Move words.
        !          98940:        rcl     cx, $1
        !          98941:        rep                             / Move odd byte.
        !          98942:        movsb
        !          98943: 
        !          98944:        pop     ds                      / Restore ds
        !          98945:        pop     di                      / Restore di
        !          98946:        pop     si                      / Restore si
        !          98947:        ret                             / Return
        !          98948: 
        !          98949: ////////
        !          98950: /
        !          98951: / All of the above copy routines jump to
        !          98952: / "kuerr", with the stack untouched, if they detect
        !          98953: / a bounds error on a user address.
        !          98954: /
        !          98955: ////////
        !          98956: 
        !          98957: kuerr:
        !          98958:        mov     bx,$u_                  / Pointer to user area
        !          98959:        movb    (bx),$EFAULT            / Bad parameter error
        !          98960:        sub     ax,ax                   / Didn't copy anything
        !          98961:        ret                             / Return
        !          98962: 
        !          98963: ////////
        !          98964: /
        !          98965: / sfbyte( fp, b )      -- set far byte
        !          98966: / int far * fp;
        !          98967: / int b;
        !          98968: /
        !          98969: ////////
        !          98970: 
        !          98971:        .globl  sfbyte_
        !          98972: 
        !          98973: sfbyte_:push   es              / sfbyte( fp, b )
        !          98974:        push    di              / register int far * fp;        /* ES:DI */
        !          98975:        push    bp              / register int b;               /* AX */
        !          98976:        mov     bp, sp          / {
        !          98977:        les     di, 8(bp)       /
        !          98978:        mov     ax, 12(bp)      /
        !          98979:                                /
        !          98980:        movb    es:(di), al     /       *fp = b;
        !          98981:                                /
        !          98982:        pop     bp              / }
        !          98983:        pop     di
        !          98984:        pop     es
        !          98985:        ret
        !          98986: 
        !          98987: ////////
        !          98988: /
        !          98989: / sfword( fp, w )      -- set far word
        !          98990: / int far * fp;
        !          98991: / int w;
        !          98992: /
        !          98993: ////////
        !          98994: 
        !          98995:        .globl  sfword_
        !          98996: 
        !          98997: sfword_:push   es              / sfword( fp, w )
        !          98998:        push    di              / register int far * fp;        /* ES:DI */
        !          98999:        push    bp              / register int w;               /* AX */
        !          99000:        mov     bp, sp          / {
        !          99001:        les     di, 8(bp)       /
        !          99002:        mov     ax, 12(bp)      /
        !          99003:                                /
        !          99004:        mov     es:(di), ax     /       *fp = w;
        !          99005:                                /
        !          99006:        pop     bp              / }
        !          99007:        pop     di
        !          99008:        pop     es
        !          99009:        ret
        !          99010: 
        !          99011: ////////
        !          99012: /
        !          99013: / ffbyte( fp )         -- fetch far byte
        !          99014: / int far * fp;
        !          99015: /
        !          99016: ////////
        !          99017: 
        !          99018:        .globl  ffbyte_
        !          99019: 
        !          99020: ffbyte_:push   es              / ffbyte( fp )
        !          99021:        push    di              / register int far * fp;        /* ES:DI */
        !          99022:        push    bp              / {
        !          99023:        mov     bp, sp          /
        !          99024:        les     di, 8(bp)       /
        !          99025:                                /
        !          99026:        sub     ax, ax          /
        !          99027:        movb    al, es:(di)     /       return *fp;
        !          99028:                                /
        !          99029:        pop     bp              / }
        !          99030:        pop     di
        !          99031:        pop     es
        !          99032:        ret
        !          99033: 
        !          99034: ////////
        !          99035: /
        !          99036: / ffword( fp )         -- fetch far word
        !          99037: / int far * fp;
        !          99038: /
        !          99039: ////////
        !          99040: 
        !          99041:        .globl  ffword_
        !          99042: 
        !          99043: ffword_:push   es              / ffword( fp )
        !          99044:        push    di              / register int far * fp;        /* ES:DI */
        !          99045:        push    bp              / {
        !          99046:        mov     bp, sp          /
        !          99047:        les     di, 8(bp)       /
        !          99048:                                /
        !          99049:        mov     ax, es:(di)     /       return *fp;
        !          99050:                                /
        !          99051:        pop     bp              / }
        !          99052:        pop     di
        !          99053:        pop     es
        !          99054:        ret
        !          99055: 
        !          99056: ////////
        !          99057: /
        !          99058: / Block transfer "n" bytes from location
        !          99059: / "k" in the system map to location "f"
        !          99060: / in the virtual address space.
        !          99061: / Return the number of bytes / transferred.
        !          99062: /
        !          99063: / kfcopy(k, f, n)
        !          99064: / char *k;
        !          99065: / faddr_t f;
        !          99066: / int n;
        !          99067: /
        !          99068: ////////
        !          99069: 
        !          99070:        .globl  kfcopy_
        !          99071: 
        !          99072: kfcopy_:
        !          99073:        push    si                      / Save si
        !          99074:        push    di                      / Save di
        !          99075:        push    bp                      / Save bp
        !          99076:        mov     bp, sp                  / Base pointer
        !          99077:        push    es                      / Save es.
        !          99078: 
        !          99079:        mov     si, 8(bp)               / Kernel address
        !          99080:        les     di, 10(bp)              / Far address
        !          99081:        mov     cx, 14(bp)              / Count
        !          99082:        mov     ax, cx                  / Move here to return
        !          99083: 
        !          99084:        cld                             / Auto increment
        !          99085:        clc                             /
        !          99086:        rcr     cx, $1                  / Calculate Word count.
        !          99087:        rep                             /
        !          99088:        movsw                           / Move words.
        !          99089:        rcl     cx, $1                  /
        !          99090:        rep                             /
        !          99091:        movsb                           / Move odd byte.
        !          99092:                                        /
        !          99093:        pop     es                      / Restore es.
        !          99094:        pop     bp                      / Restore bp.
        !          99095:        pop     di                      / Restore di
        !          99096:        pop     si                      / Restore si
        !          99097:        ret                             / Return
        !          99098: 
        !          99099: ////////
        !          99100: /
        !          99101: / Block transfer "n" bytes from location
        !          99102: / "f" in the virtual addres sspace to
        !          99103: / location "f" in the system map.
        !          99104: / Return the number of bytes / transferred.
        !          99105: /
        !          99106: / fkcopy(f, k, n)
        !          99107: / faddr_t f;
        !          99108: / char *k;
        !          99109: / int n;
        !          99110: /
        !          99111: ////////
        !          99112: 
        !          99113:        .globl  fkcopy_
        !          99114: 
        !          99115: fkcopy_:
        !          99116:        push    si                      / Save si
        !          99117:        push    di                      / Save di
        !          99118:        push    bp                      / Save bp
        !          99119:        mov     bp, sp                  / Base pointer
        !          99120:        push    ds                      / Save ds.
        !          99121: 
        !          99122:        lds     si, 8(bp)               / Far address
        !          99123:        mov     di, 12(bp)              / Kernel address
        !          99124:        mov     cx, 14(bp)              / Count
        !          99125:        mov     ax, cx                  / Move here to return
        !          99126: 
        !          99127:        cld                             / Auto increment
        !          99128:        clc                             /
        !          99129:        rcr     cx, $1                  / Calculate Word count.
        !          99130:        rep                             /
        !          99131:        movsw                           / Move words.
        !          99132:        rcl     cx, $1                  /
        !          99133:        rep                             /
        !          99134:        movsb                           / Move odd byte.
        !          99135:                                        /
        !          99136:        pop     ds                      / Restore ds.
        !          99137:        pop     bp                      / Restore bp.
        !          99138:        pop     di                      / Restore di
        !          99139:        pop     si                      / Restore si
        !          99140:        ret                             / Return
        !          99141: 
        !          99142: ////////
        !          99143: /
        !          99144: / fclear( fp, n )      - Erase far memory.
        !          99145: / faddr_t fp;
        !          99146: / unsigned n;
        !          99147: /
        !          99148: ////////
        !          99149: 
        !          99150:        .globl  fclear_
        !          99151: 
        !          99152: fclear_:
        !          99153:        push    es                      / Save es
        !          99154:        push    di                      / Save di
        !          99155:        push    bp                      / Save bp
        !          99156:        mov     bp, sp                  / Base pointer
        !          99157: 
        !          99158:        les     di, 8(bp)               / Far address
        !          99159:        mov     cx, 12(bp)              / Count
        !          99160:        sub     ax, ax                  /
        !          99161: 
        !          99162:        cld                             / Auto increment
        !          99163:        clc                             /
        !          99164:        rcr     cx, $1                  / Calculate Word count.
        !          99165:        rep                             /
        !          99166:        stosw                           / Clear words.
        !          99167:        rcl     cx, $1                  /
        !          99168:        rep                             /
        !          99169:        stosb                           / Clear odd byte.
        !          99170:                                        /
        !          99171:        pop     bp                      / Restore bp.
        !          99172:        pop     di                      / Restore di.
        !          99173:        pop     es                      / Restore es.
        !          99174:        ret                             / Return
        !          99175: 
        !          99176: ////////
        !          99177: /
        !          99178: / Profile scaling.
        !          99179: /
        !          99180: ////////
        !          99181: 
        !          99182:        .globl  pscale_
        !          99183: 
        !          99184: pscale_:
        !          99185:        mov     bx,sp                   / Base pointer
        !          99186:        mov     ax,2(bx)                / Multiply
        !          99187:        mul     4(bx)                   /
        !          99188:        mov     ax,dx                   / Get high half
        !          99189:        ret                             / And return
        !          99190: 
        !          99191: ////////
        !          99192: /
        !          99193: / Save the environment of a process
        !          99194: / envsave(p)
        !          99195: / MENV *p;
        !          99196: /
        !          99197: / Save the context of a process
        !          99198: / consave(p)
        !          99199: / MCON *p;
        !          99200: /
        !          99201: ////////
        !          99202: 
        !          99203:        .globl  consave_
        !          99204:        .globl  envsave_
        !          99205: 
        !          99206: envsave_:
        !          99207: consave_:
        !          99208:        mov     cx, di                  / Hide di.
        !          99209:        mov     bx, sp                  / Point bx at the stack and
        !          99210:        mov     di, 2(bx)               / di at the MCON block.
        !          99211:        cld                             / Ensure increment.
        !          99212:        mov     ax, cx                  / Save di
        !          99213:        stosw
        !          99214:        mov     ax, si                  / Save si
        !          99215:        stosw
        !          99216:        mov     ax, bp                  / Save bp
        !          99217:        stosw
        !          99218:        mov     ax, sp                  / Save sp
        !          99219:        stosw
        !          99220:        mov     ax, (bx)                / Save ra as pc
        !          99221:        stosw
        !          99222:        pushf                           / Save fw
        !          99223:        pop     ax
        !          99224:        stosw
        !          99225:        movb    al, depth_              / Save stack depth
        !          99226:        cbw
        !          99227:        stosw
        !          99228:        mov     di, cx                  / Put di back,
        !          99229:        sub     ax, ax                  / indicate a state save and
        !          99230:        ret                             / return to caller.
        !          99231: 
        !          99232: ////////
        !          99233: /
        !          99234: / Restore the environment of a process.
        !          99235: / envrest(p)
        !          99236: / MENV *p;
        !          99237: /
        !          99238: ////////
        !          99239: 
        !          99240:        .globl  envrest_
        !          99241: 
        !          99242: envrest_:
        !          99243:        cli
        !          99244:        cld
        !          99245:        mov     bx,sp                   / Base pointer
        !          99246:        mov     si,2(bx)                / Pointer to context
        !          99247:        lodsw                           / Restore di
        !          99248:        mov     di,ax                   /
        !          99249:        lodsw                           / Restore si
        !          99250:        mov     cx,ax                   / Save for later
        !          99251:        lodsw                           / Restore bp
        !          99252:        mov     bp,ax                   /
        !          99253:        lodsw                           / Restore sp
        !          99254:        mov     sp,ax                   /
        !          99255:        mov     bx,ax                   / Our frame
        !          99256:        push    cs                      / Push current CS
        !          99257:        lodsw                           / Restore pc
        !          99258:        push    ax                      /
        !          99259:        lodsw                           / Restore flags
        !          99260:        mov     (bx),ax                 / Stack now in form PSW,CS,IP.
        !          99261:        lodsw                           / Restore stack depth
        !          99262:        cli                             / No more interrupts
        !          99263:        movb    depth_, al
        !          99264:        mov     si,cx                   / Restore si
        !          99265:        mov     ax,$1                   / We are restoring
        !          99266:        iret                            / Return through PSW,CS,IP.
        !          99267: 
        !          99268: ////////
        !          99269: /
        !          99270: / Restore the context of a process.
        !          99271: / Called with interrupts disabled from dispatch.
        !          99272: / conrest(u, o)
        !          99273: / saddr_t u;
        !          99274: /
        !          99275: ////////
        !          99276: 
        !          99277:        .globl  conrest_
        !          99278: 
        !          99279: conrest_:
        !          99280:        decb    depth_                  / Falsify user/system state
        !          99281:        sti                             / Interrupts ok here
        !          99282:                        / Save current uarea
        !          99283:        call    usave_                  / Save the uarea in its segment.
        !          99284:                        / Copy in new uarea
        !          99285:        mov     bx,sp                   / Base pointer
        !          99286:        mov     ax, 2(bx)               / Fetch uarea saddr_t
        !          99287:        mov     bx, 4(bx)               / Fetch syscon offset
        !          99288:        mov     uasa_, ax               / Save uarea saddr_t
        !          99289:        mov     cx,$USZ1                / uproc size
        !          99290: /      mov     es,sds_                 / system data segment
        !          99291:        mov     di,$u_                  / system data uarea offset
        !          99292:        mov     ds,ax                   / uarea segment
        !          99293:        sub     si,si                   / uarea offset
        !          99294:        mov     sp,UMCSP(bx)            / new stack
        !          99295:        cld                             / increment
        !          99296:        rep                             / repeat
        !          99297:        movsw                           / copy uproc
        !          99298:        mov     di,sp                   / stack offset in system data
        !          99299:        and     di,$~1                  / ensure word alignment
        !          99300:        mov     cx,$u_+UPASIZE          / compute byte
        !          99301:        sub     cx,di                   / count
        !          99302:        mov     si,$UPASIZE             / compute offset
        !          99303:        sub     si,cx                   / in segment
        !          99304:        shr     cx,$1                   / make word count
        !          99305:        rep                             / repeat
        !          99306:        movsw                           / copy stack
        !          99307:                        / Clean up
        !          99308:        mov     ax, es                  / Restore data
        !          99309:        mov     ds, ax                  / segment
        !          99310:                        / Now restore context
        !          99311:        add     bx, $u_                 / convert to address
        !          99312:        mov     si, bx                  / Get source index for restore
        !          99313:        lodsw                           / Restore di
        !          99314:        mov     di,ax                   /
        !          99315:        lodsw                           / Restore si
        !          99316:        mov     cx,ax                   / Save for later
        !          99317:        lodsw                           / Restore bp
        !          99318:        mov     bp,ax                   /
        !          99319:        lodsw                           / Restore sp
        !          99320:        mov     sp,ax                   /
        !          99321:        mov     bx,ax                   / Our frame
        !          99322:        push    cs                      / Push current CS
        !          99323:        lodsw                           / Restore pc
        !          99324:        push    ax                      /
        !          99325:        lodsw                           / Restore flags
        !          99326:        mov     (bx),ax                 / Stack now in form PSW,CS,IP.
        !          99327:        lodsw                           / Restore stack depth
        !          99328:        cli                             / No more interrupts
        !          99329:        movb    depth_, al
        !          99330:        mov     si,cx                   / Restore si
        !          99331:        mov     ax,$1                   / We are restoring
        !          99332:        iret                            / Return through PSW,CS,IP.
        !          99333: 
        !          99334: ////////
        !          99335: / usave()
        !          99336: / Save uarea in segment.
        !          99337: / Knowing that ds points to the system data segment
        !          99338: / and that es should map there also.
        !          99339: / And guaranteed not to step on ax or bx for conrest
        !          99340: /
        !          99341:        .globl  usave_
        !          99342: 0:     ret
        !          99343: usave_:
        !          99344:        cmp     uasa_, $0               /
        !          99345:        je      0b
        !          99346:        push    es                      / Save es
        !          99347:        push    si                      / Save si
        !          99348:        push    di                      / Save di
        !          99349:        mov     cx,$USZ1                / count
        !          99350:        sub     di,di                   / uarea segment offset
        !          99351:        mov     es,uasa_                / uarea segment
        !          99352:        mov     si,$u_                  / system data offset
        !          99353: /      mov     ds,sds_                 / system data segment
        !          99354:        cld                             / increment
        !          99355:        rep                             / repeat
        !          99356:        movsw                           / copy uproc
        !          99357:        mov     si,sp                   / stack offset in system data
        !          99358:        and     si,$~1                  / ensure word alignment
        !          99359:        mov     cx,$u_+UPASIZE          / compute byte
        !          99360:        sub     cx,si                   / count
        !          99361:        mov     di,$UPASIZE             / compute offset
        !          99362:        sub     di,cx                   / in segment
        !          99363:        shr     cx,$1                   / make word count
        !          99364:        rep                             / repeat
        !          99365:        movsw                           / copy stack
        !          99366:        pop     di                      / Restore di
        !          99367:        pop     si                      / Restore si
        !          99368:        pop     es                      / Restore extra
        !          99369:        ret
        !          99370: 
        !          99371: / Save useful registers.
        !          99372: /
        !          99373:        .globl  msysgen_
        !          99374: /
        !          99375: / msysgen(p)
        !          99376: / MGEN *p;
        !          99377: /
        !          99378: msysgen_:
        !          99379:        ret                             / Nothing useful to save
        !          99380: 
        !          99381: / Disable interrupts.  Previous value is returned.
        !          99382: /
        !          99383:        .globl  sphi_
        !          99384: 
        !          99385: sphi_:
        !          99386:        pushf                           / Save flags
        !          99387:        pop     ax                      / Return current value
        !          99388:        cli                             / Disable interrupts
        !          99389:        ret                             / And return
        !          99390: 
        !          99391: / Enable interrupts.  Previous value is returned.
        !          99392: /
        !          99393:        .globl  splo_
        !          99394: 
        !          99395: splo_:
        !          99396:        pushf
        !          99397:        pop     ax
        !          99398:        sti
        !          99399:        ret
        !          99400: 
        !          99401: / Change interrupt flag.  Previous value is returned.
        !          99402: /
        !          99403:        .globl  spl_
        !          99404: 
        !          99405: spl_:
        !          99406:        pop     ax                      / ip
        !          99407:        pop     bx                      / psw
        !          99408:        push    bx
        !          99409:        push    bx                      / push psw, cs, ip for iret
        !          99410:        push    cs
        !          99411:        push    ax
        !          99412:        pushf                           / old psw
        !          99413:        pop     ax
        !          99414:        iret
        !          99415: 
        !          99416: ////////
        !          99417: /
        !          99418: / Idle routine.
        !          99419: / Enable interupts, and wait for something to
        !          99420: / happen. Does not do anything to the 8259, bacause
        !          99421: / this will be set up correctly.
        !          99422: /
        !          99423: ////////
        !          99424: 
        !          99425:        .globl  _idle_
        !          99426: 
        !          99427: _idle_:        sti                             / Interupts on.
        !          99428:        hlt                             / Wait for an interrupt
        !          99429:        ret                             / and return.
        !          99430: 
        !          99431: ////////
        !          99432: /
        !          99433: / The world is indeed grim.
        !          99434: / Halt. Keep the interrupts on so that the
        !          99435: / keyboard can get int.
        !          99436: /
        !          99437: ////////
        !          99438: 
        !          99439:        .globl  halt_
        !          99440: 
        !          99441: halt_: sti                             / Be safe,
        !          99442: 0:
        !          99443:        hlt                             / and halt.
        !          99444:        jmp     0b                      / Paranoid, yes sir.
        !          99445: 
        !          99446: ////////
        !          99447: /
        !          99448: / Basic port level I/O.
        !          99449: /
        !          99450: / int  inb(port);
        !          99451: / int  outb(port, data);
        !          99452: /
        !          99453: ////////
        !          99454: 
        !          99455:        .globl  inb_
        !          99456:        .globl  outb_
        !          99457: 
        !          99458: inb_:  mov     bx, sp
        !          99459:        mov     dx, ss:2(bx)
        !          99460:        sub     ax, ax
        !          99461:        inb     al, dx
        !          99462:        ret
        !          99463: 
        !          99464: outb_: mov     bx, sp
        !          99465:        mov     dx, ss:2(bx)
        !          99466:        mov     ax, ss:4(bx)
        !          99467:        outb    dx, al
        !          99468:        ret
        !          99469: 
        !          99470: ////////
        !          99471: /
        !          99472: / Routines to move data to and from
        !          99473: / the system auxiliary segment.
        !          99474: /
        !          99475: ////////
        !          99476: 
        !          99477:        .globl  ageti_
        !          99478: 
        !          99479: ageti_:
        !          99480:        mov     bx,sp                   / Base pointer
        !          99481:        mov     bx,2(bx)                / Pointer
        !          99482:        push    es                      / Save extra mapping and
        !          99483:        mov     es, sas_                / remap.
        !          99484:        mov     ax,es:(bx)              / Get value
        !          99485:        pop     es                      / Restore es and
        !          99486:        ret                             / Return
        !          99487: 
        !          99488:        .globl  aputp_
        !          99489:        .globl  aputi_
        !          99490: 
        !          99491: aputp_:
        !          99492: aputi_:
        !          99493:        mov     bx,sp                   / Base pointer
        !          99494:        mov     ax,4(bx)                / Value
        !          99495:        mov     bx,2(bx)                / Pointer
        !          99496:        push    es                      / Save extra base and
        !          99497:        mov     es, sas_                / remap.
        !          99498:        mov     es:(bx),ax              / Set value
        !          99499:        pop     es                      / Restore extra base
        !          99500:        ret                             / Return
        !          99501: 
        !          99502:        .globl  aputc_
        !          99503: 
        !          99504: aputc_:
        !          99505:        mov     bx,sp                   / Base pointer
        !          99506:        mov     ax,4(bx)                / Value
        !          99507:        mov     bx,2(bx)                / Pointer
        !          99508:        push    es                      / Save es and
        !          99509:        mov     es, sas_                / remap.
        !          99510:        movb    es:(bx),al              / Set value
        !          99511:        pop     es                      / Restore es and
        !          99512:        ret                             / Return
        !          99513: 
        !          99514: ////////
        !          99515: /
        !          99516: / Data. 
        !          99517: / A small number of variables must be
        !          99518: / in the code segment. All of these variables have
        !          99519: / something to do with the interrupt linkage; when you
        !          99520: / get an interrupt the only thing that is valid is
        !          99521: / the code segment.
        !          99522: /
        !          99523: ////////
        !          99524: 
        !          99525:        .globl  cds
        !          99526: 
        !          99527:        .shri
        !          99528: cds:   .blkw   1                       / Copy of "sds_".
        !          99529: 
        !          99530:        .globl  u_
        !          99531:        .globl  depth_, sas_,   scs_,   sds_,   ucs_
        !          99532:        .globl  ucl_,   uds_,   udl_
        !          99533: 
        !          99534:        .bssd
        !          99535:        .even
        !          99536: u_:    .blkb   UPASIZE
        !          99537: 
        !          99538:        .prvd
        !          99539: oops:  .ascii  "stack overflow"
        !          99540:        .byte   0
        !          99541: 
        !          99542: depth_:        .byte   0                       / System state.
        !          99543: 
        !          99544:        .even
        !          99545: sas_:  .blkw   1                       / System auxiliary segment.
        !          99546: scs_:  .blkw   1                       / System code segment.
        !          99547: sds_:  .blkw   1                       / System data segment.
        !          99548: ucs_:  .blkw   1                       / User code segment.
        !          99549: ucl_:  .blkw   1                       / User code limit.
        !          99550: uds_:  .blkw   1                       / User data segment.
        !          99551: udl_:  .blkw   1                       / User data limit.
        !          99552: sav_ds:        .blkw   1                       / Four scratch words
        !          99553: sav_bx:        .blkw   1
        !          99554: sav_ss:        .blkw   1
        !          99555: sav_sp:        .blkw   1
        !          99556: 
        !          99557: ////////
        !          99558: /
        !          99559: / This is the image of the init process.
        !          99560: / It gets copied into a user segment when the system
        !          99561: / is first brought up. It must be in the data segment, because
        !          99562: / that is how it is used, and it must be dephased in a funny
        !          99563: / way because it is executed at location 0.
        !          99564: /
        !          99565: ////////
        !          99566: 
        !          99567:        .globl  aicodep_                / Position of code.
        !          99568:        .globl  aicodes_                / Size of code.
        !          99569:        .globl  aidatap_                / Position of data.
        !          99570:        .globl  aidatas_                / Size of data.
        !          99571: 
        !          99572:        .shrd
        !          99573: aicodep_:
        !          99574:        sub     ax,ax                   / No environment
        !          99575:        push    ax
        !          99576:        mov     ax,$argl-aidatap_       / Argument list
        !          99577:        push    ax
        !          99578:        mov     ax,$fn-aidatap_         / File name
        !          99579:        push    ax
        !          99580:        sub     sp,$2                   / Dummy word for exec
        !          99581:        sys     11                      / Sys exec
        !          99582:        jmp     .                       / This should not return
        !          99583: aicodes_ = .-aicodep_
        !          99584: 
        !          99585: aidatap_:
        !          99586:        .word   0                       /
        !          99587:        .word   0                       / Errno
        !          99588:        .word   0                       /
        !          99589:        .word   0                       /
        !          99590:        .word   0                       /
        !          99591:        .word   0                       /
        !          99592:        .word   0                       /
        !          99593:        .word   0                       /
        !          99594: argl:  .word   fn-aidatap_             / argv[0] = "/etc/init";
        !          99595:        .word   a1-aidatap_             / argv[1] = "";
        !          99596:        .word   0                       / argv[2] = NULL;
        !          99597: 
        !          99598: fn:    .ascii  "/etc/init\000"
        !          99599: a1:    .byte   0
        !          99600: 
        !          99601:        .even
        !          99602:        .blkb   64
        !          99603: sb:
        !          99604: aidatas_ = .-aidatap_
        !          99605: @
        !          99606: 0707070064030104501004440000030000030000011777770507310723200005700000010474/newbits/kernel/USRSRC/i8086/src/RCS/clist.s,vhead     1.2;
        !          99607: branch   ;
        !          99608: access   ;
        !          99609: symbols  ;
        !          99610: locks    bin:1.2; strict;
        !          99611: comment  @@;
        !          99612: 
        !          99613: 
        !          99614: 1.2
        !          99615: date     91.06.20.14.39.15;  author bin;  state Exp;
        !          99616: branches ;
        !          99617: next     1.1;
        !          99618: 
        !          99619: 1.1
        !          99620: date     91.06.10.10.36.37;  author bin;  state Exp;
        !          99621: branches ;
        !          99622: next     ;
        !          99623: 
        !          99624: 
        !          99625: desc
        !          99626: @initial version prov by hal
        !          99627: @
        !          99628: 
        !          99629: 
        !          99630: 1.2
        !          99631: log
        !          99632: @update provided by hal
        !          99633: @
        !          99634: text
        !          99635: @/ $Header: /usr/src/sys/i8086/src/RCS/clist.s,v 1.1 88/03/24 17:39:16 src Exp $
        !          99636: 
        !          99637: / (lgl-
        !          99638: /      The information contained herein is a trade secret of Mark Williams
        !          99639: /      Company, and  is confidential information.  It is provided  under a
        !          99640: /      license agreement,  and may be  copied or disclosed  only under the
        !          99641: /      terms of  that agreement.  Any  reproduction or disclosure  of this
        !          99642: /      material without the express written authorization of Mark Williams
        !          99643: /      Company or persuant to the license agreement is unlawful.
        !          99644: /
        !          99645: /      COHERENT Version 2.3.37
        !          99646: /      Copyright (c) 1982, 1983, 1984.
        !          99647: /      An unpublished work by Mark Williams Company, Chicago.
        !          99648: /      All rights reserved.
        !          99649: / -lgl)
        !          99650: ////////
        !          99651: /
        !          99652: / i8086 coherent clist hack.
        !          99653: / cltinit, getq and putq have been tuned.
        !          99654: / the remaining functions are as produced by cc -S coh/clist.c
        !          99655: / with NCPCL substituted
        !          99656: /
        !          99657: / $Log:        /usr/src/sys/i8086/src/RCS/clist.s,v $
        !          99658: / Revision 1.1 88/03/24  17:39:16      src
        !          99659: / Initial revision
        !          99660: / 
        !          99661: 
        !          99662: #include <sys/const.h>
        !          99663: 
        !          99664:        .shri
        !          99665: L10001:        .word   NCPCL+2
        !          99666:        .globl  cltinit_
        !          99667: cltinit_:
        !          99668:        push    si
        !          99669:        push    di
        !          99670:        push    bp
        !          99671:        mov     bp, sp
        !          99672:        sub     sp, $0x0C
        !          99673: 
        !          99674:        pushf                   / s =
        !          99675:        cli                     / sphi()
        !          99676:        sub     di, di
        !          99677:        mov     ax, NCLIST_
        !          99678:        imul    cs:L10001
        !          99679:        mov     -0x0C(bp), ax
        !          99680:        add     ax, clistp_
        !          99681:        mov     -0x04(bp), ax
        !          99682: 
        !          99683: L3:    sub     -0x04(bp), $NCPCL+2
        !          99684:        mov     ax, -0x04(bp)
        !          99685:        cmp     ax, clistp_
        !          99686:        jb      L2
        !          99687: 
        !          99688: L10002:        mov     si, -0x04(bp)
        !          99689:        mov     (si), di
        !          99690:        mov     di, si
        !          99691:        jmp     L3
        !          99692: 
        !          99693: L2:    mov     cltfree_, di
        !          99694:        call    spl_
        !          99695:        add     sp, $0x02
        !          99696: 
        !          99697:        mov     sp, bp
        !          99698:        pop     bp
        !          99699:        pop     di
        !          99700:        pop     si
        !          99701:        ret
        !          99702: 
        !          99703:        .globl  getq_
        !          99704: 
        !          99705: getq_:
        !          99706:        mov     dx, si
        !          99707:        push    bp
        !          99708:        mov     bp, sp
        !          99709: 
        !          99710:        mov     bp, 4(bp)       / bp = cqp
        !          99711:        sub     ax, ax          / ax = 0
        !          99712:        cmp     (bp), ax        / if (cqp->cq_cc == 0)
        !          99713:        jne     0f
        !          99714:        dec     ax              / return (-1)
        !          99715:        jmp     2f
        !          99716: 
        !          99717: 0:     pushf                   / s =
        !          99718:        cli                     / sphi()
        !          99719:        mov     si, 6(bp)       / si = op = cqp->cq_op
        !          99720:        mov     bx, 8(bp)       / bx = ox = cqp->cq_ox
        !          99721:        movb    al, 2(bx,si)    / ax = op->cl_ch[ox]
        !          99722:        dec     (bp)            / if (--cqp->cq_cc == 0)
        !          99723:        je      0f
        !          99724:        inc     bx              / ++ox
        !          99725:        cmp     bx, $NCPCL      / if (ox == NCPL)
        !          99726:        jne     1f
        !          99727: 
        !          99728: 0:     sub     bx, bx          / ox = 0;
        !          99729:        mov     cx, (si)        / cx = np = op->cl_fp
        !          99730:        mov     6(bp), cx       / cqp->cq_op = np
        !          99731:        cmp     cx, bx          / if (np == 0)
        !          99732:        jne     0f
        !          99733:        mov     2(bp), bx       / cqp->cq_ip = 0
        !          99734:        mov     4(bp), bx       / cqp->cq_ix = 0
        !          99735: 
        !          99736: 0:     mov     cx, cltfree_    / cx = tmp = cltfree
        !          99737:        mov     (si), cx        / op->cl_fp = tmp
        !          99738:        mov     cltfree_, si    / cltfree = op
        !          99739:        cmp     cltwant_, bx    / if (cltwant != 0)
        !          99740:        je      1f
        !          99741:        mov     cltwant_, bx    / cltwant = 0
        !          99742:        mov     cx, $cltwant_   / wakeup(&cltwant)
        !          99743:        push    bx      / save
        !          99744:        push    dx      / save
        !          99745:        push    ax      / save
        !          99746:        push    cx
        !          99747:        call    wakeup_
        !          99748:        pop     cx      / clear stack
        !          99749:        pop     ax      / restore
        !          99750:        pop     dx      / restore
        !          99751:        pop     bx      / restore
        !          99752: 
        !          99753: 1:     mov     8(bp), bx       / cqp->cq_ox = ox
        !          99754:        mov     cx, ax
        !          99755:        call    spl_            / spl(s)
        !          99756:        add     sp, $2
        !          99757:        mov     ax, cx
        !          99758: 
        !          99759: 2:     pop     bp
        !          99760:        mov     si, dx
        !          99761:        ret
        !          99762: 
        !          99763:        .globl  putq_
        !          99764: 
        !          99765: putq_:
        !          99766:        mov     dx, si
        !          99767:        push    bp
        !          99768:        mov     bp, sp
        !          99769: 
        !          99770:        mov     cx, 6(bp)       / cx = c
        !          99771:        mov     bp, 4(bp)       / bp = cqp
        !          99772:        sub     ax, ax          / ax = 0
        !          99773:        pushf                   / s =
        !          99774:        cli                     / sphi()
        !          99775:        mov     si, 2(bp)       / si = ip = cqp->cq_ip
        !          99776:        mov     bx, 4(bp)       / bx = ix = cqp->cq_ix
        !          99777:        cmp     bx, ax          / if (ix == 0)
        !          99778:        jne     2f
        !          99779:        mov     si, cltfree_    / ip = cltfree
        !          99780:        cmp     si, ax          / if (ip == 0)
        !          99781:        jne     0f
        !          99782:        call    spl_            / spl(s)
        !          99783:        add     sp, $2
        !          99784:        mov     ax, $-1         / return (-1)
        !          99785:        jmp     3f
        !          99786: 
        !          99787: 0:     mov     bx, (si)        / tmp = ip->cl_fp
        !          99788:        mov     cltfree_, bx    / cltfree = tmp
        !          99789:        mov     (si), ax        / ip->cl_fp = 0
        !          99790:        mov     bx, 2(bp)       / np = cqp->cq_ip
        !          99791:        cmp     bx, ax          / if (np == 0)
        !          99792:        jne     0f
        !          99793:        mov     6(bp), si       / cqp->cq_op = ip
        !          99794:        jmp     1f
        !          99795: 
        !          99796: 0:     mov     (bx), si        / np->cl_fp = ip
        !          99797: 
        !          99798: 1:     mov     2(bp), si       / cqp->cq_ip = ip
        !          99799:        mov     bx, ax          / bx = ix = cqp->cq_ix = 0
        !          99800: 
        !          99801: 2:     movb    2(bx,si), cl    / ip->cl_ch[ix] = c
        !          99802:        inc     bx              / ix++
        !          99803:        cmp     bx, $NCPCL      / if (ix == NCPCL)
        !          99804:        jne     0f
        !          99805:        mov     bx, ax          / ix = 0
        !          99806: 
        !          99807: 0:     mov     4(bp), bx       / cqp->cq_ix = ix
        !          99808:        inc     (bp)            / cqp->cq_cc++
        !          99809:        call    spl_            / spl(s)
        !          99810:        add     sp, $2
        !          99811:        mov     ax, cx          / return (c)
        !          99812: 
        !          99813: 3:     pop     bp
        !          99814:        mov     si, dx
        !          99815:        ret
        !          99816: 
        !          99817:        .globl  clrq_
        !          99818: 
        !          99819: clrq_:
        !          99820:        push    si
        !          99821:        push    di
        !          99822:        push    bp
        !          99823:        mov     bp, sp
        !          99824: 
        !          99825:        mov     si, 0x08(bp)
        !          99826:        call    sphi_
        !          99827:        mov     di, ax
        !          99828: 
        !          99829: L18:   push    si
        !          99830:        call    getq_
        !          99831:        add     sp, $0x02
        !          99832:        or      ax, ax
        !          99833:        jge     L18
        !          99834:        push    di
        !          99835:        call    spl_
        !          99836:        add     sp, $0x02
        !          99837: 
        !          99838:        pop     bp
        !          99839:        pop     di
        !          99840:        pop     si
        !          99841:        ret
        !          99842: 
        !          99843:        .globl  waitq_
        !          99844: 
        !          99845: waitq_:
        !          99846:        push    si
        !          99847:        push    di
        !          99848:        push    bp
        !          99849:        mov     bp, sp
        !          99850: 
        !          99851: L21:   cmp     cltfree_, $0x00
        !          99852:        jne     L19
        !          99853:        mov     cltwant_, $0x01
        !          99854:        sub     ax, ax
        !          99855:        push    ax
        !          99856:        push    ax
        !          99857:        mov     ax, $0x0100
        !          99858:        push    ax
        !          99859:        mov     ax, $cltwant_
        !          99860:        push    ax
        !          99861:        call    sleep_
        !          99862:        add     sp, $0x08
        !          99863:        jmp     L21
        !          99864: 
        !          99865: L19:   pop     bp
        !          99866:        pop     di
        !          99867:        pop     si
        !          99868:        ret
        !          99869: @
        !          99870: 
        !          99871: 
        !          99872: 1.1
        !          99873: log
        !          99874: @Initial revision
        !          99875: @
        !          99876: text
        !          99877: @@
        !          99878: 0707070064030104651004440000030000030000011777770507310723300006000000000762/newbits/kernel/USRSRC/i8086/src/RCS/cs_sel.s,vhead     1.1;
        !          99879: branch   ;
        !          99880: access   ;
        !          99881: symbols  ;
        !          99882: locks    bin:1.1; strict;
        !          99883: comment  @@;
        !          99884: 
        !          99885: 
        !          99886: 1.1
        !          99887: date     91.06.10.10.36.38;  author bin;  state Exp;
        !          99888: branches ;
        !          99889: next     ;
        !          99890: 
        !          99891: 
        !          99892: desc
        !          99893: @initial version prov by hal
        !          99894: @
        !          99895: 
        !          99896: 
        !          99897: 
        !          99898: 1.1
        !          99899: log
        !          99900: @Initial revision
        !          99901: @
        !          99902: text
        !          99903: @////////
        !          99904: /
        !          99905: / Get cs selector - return 0 if in kernel, CS if not in kernel.
        !          99906: /
        !          99907: / This version is for resident drivers.
        !          99908: / There is a different version (cs_self.s) for loadable drivers.
        !          99909: /
        !          99910: / int  cs_sel();
        !          99911: /
        !          99912: ////////
        !          99913: 
        !          99914:        .globl  cs_sel_
        !          99915: cs_sel_:
        !          99916:        sub     ax, ax
        !          99917:        ret
        !          99918: @
        !          99919: 0707070064030104631004440000030000030000011777770507310723400005700000012370/newbits/kernel/USRSRC/i8086/src/RCS/defer.s,vhead     1.2;
        !          99920: branch   ;
        !          99921: access   ;
        !          99922: symbols  ;
        !          99923: locks    bin:1.2; strict;
        !          99924: comment  @@;
        !          99925: 
        !          99926: 
        !          99927: 1.2
        !          99928: date     91.06.20.14.39.31;  author bin;  state Exp;
        !          99929: branches ;
        !          99930: next     1.1;
        !          99931: 
        !          99932: 1.1
        !          99933: date     91.06.10.10.36.39;  author bin;  state Exp;
        !          99934: branches ;
        !          99935: next     ;
        !          99936: 
        !          99937: 
        !          99938: desc
        !          99939: @initial version prov by hal
        !          99940: @
        !          99941: 
        !          99942: 
        !          99943: 1.2
        !          99944: log
        !          99945: @update provided by hal
        !          99946: @
        !          99947: text
        !          99948: @/ $Header: /usr/src/sys/i8086/src/RCS/defer.s,v 1.2 88/04/04 17:05:05 src Exp $
        !          99949: /
        !          99950: /      The  information  contained herein  is a trade secret  of INETCO
        !          99951: /      Systems, and is confidential information.   It is provided under
        !          99952: /      a license agreement,  and may be copied or disclosed  only under
        !          99953: /      the terms of that agreement.   Any reproduction or disclosure of
        !          99954: /      this  material  without  the express  written  authorization  of
        !          99955: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          99956: /
        !          99957: /      Copyright (c) 1986
        !          99958: /      An unpublished work by INETCO Systems, Ltd.
        !          99959: /      All rights reserved.
        !          99960: /
        !          99961: 
        !          99962: ////////
        !          99963: /
        !          99964: / Defer a function [from interrupt level] for later execution
        !          99965: /
        !          99966: /      defer( f, a )   - defer a function [usually from interrupt level]
        !          99967: /      defend()        - execute deferred functions
        !          99968: /
        !          99969: / $Log:        /usr/src/sys/i8086/src/RCS/defer.s,v $
        !          99970: / Revision 1.2 88/04/04  17:05:05      src
        !          99971: / ldefer/ldefend functions now allow deferred functions from loadable drivers.
        !          99972: / 
        !          99973: / Revision 1.1 88/03/24  17:39:20      src
        !          99974: / Initial revision
        !          99975: / 
        !          99976: / 86/11/19     Allan Cornish           /usr/src/sys/i8086/src/defer.s
        !          99977: / defer(func,arg) and defend() functions ported to Coherent from RTX.
        !          99978: /
        !          99979: ////////
        !          99980: 
        !          99981:        .globl  defend_
        !          99982:        .globl  defer_
        !          99983:        .globl  ldefer
        !          99984: 
        !          99985:        .bssd
        !          99986: defunc:        .blkw   128             / static void (*defunc[128])();
        !          99987: defarg:        .blkw   128             / static char * defarg[128];
        !          99988: defqix:        .blkw   1               / static int defqix;
        !          99989: defqox:        .blkw   1               / static int defqox;
        !          99990: ldcseg:        .blkw   128             / static saddr_t ldcseg[128];
        !          99991: ldfunc:        .blkw   128             / static void (*ldfunc[128])();
        !          99992:        .shri
        !          99993: 
        !          99994: ////////
        !          99995: /
        !          99996: / void
        !          99997: / defer( f, a )                -- defer a function [usually from interrupt level]
        !          99998: / int (*f)();
        !          99999: / char *a;
        !          100000: /
        !          100001: /      Input:  f = pointer to function to be deferred.
        !          100002: /              a = argument to pass to function when it is invoked.
        !          100003: /
        !          100004: /      Action: Schedule function 'f' to be invoked with argument 'a'
        !          100005: /              during the transition from interrupt service level back
        !          100006: /              to user mode.
        !          100007: /
        !          100008: /      Return: None.
        !          100009: /
        !          100010: /      Notes:  13 instructions executed.  Interrupt latency = 7 instructions.
        !          100011: /              Only 127 functions can be deferred at any one time.
        !          100012: /              Exceeding this limit will cause loss of ALL deferred functions.
        !          100013: /
        !          100014: ////////
        !          100015: 
        !          100016: defer_:                                /
        !          100017:        pop     ax              / Convert IP into PSW,CS,IP to allow iret.
        !          100018:        pushf                   /
        !          100019:        push    cs              /
        !          100020:        push    ax              /
        !          100021:        mov     bx, sp          / defer( f, a )
        !          100022:        mov     ax, ss:6(bx)    / register int (*f)();          /* AX */
        !          100023:        mov     dx, ss:8(bx)    / register char *a;             /* DX */
        !          100024:                                / {
        !          100025:                                /       register int x;         /* BX */
        !          100026:                                /
        !          100027:        cli                     /       sphi();
        !          100028:        mov     bx, defqix      /       x = defqix;
        !          100029:        mov     defunc(bx), ax  /       defunc[x] = f;
        !          100030:        mov     defarg(bx), dx  /       defarg[x] = a;
        !          100031:        addb    defqix, $2      /       defqix++;
        !          100032: //     sti                     /       splo();
        !          100033:        iret                    / }
        !          100034: 
        !          100035: ////////
        !          100036: /
        !          100037: / void
        !          100038: / defend( )            -- evaluate deferred functions
        !          100039: /
        !          100040: /      Action: Evaluate all deferred functions.
        !          100041: /
        !          100042: /      Notes:  Should be called periodically by busy-wait device drivers.
        !          100043: /              4 + (n * 7) instructions executed, where n = # deferred func.
        !          100044: ////////
        !          100045: 
        !          100046: defend_:                       / defend()
        !          100047:                                / {
        !          100048:                                /
        !          100049:        mov     bx, defqox      /       register int x = defqox;    /* BX */
        !          100050:                                /
        !          100051:        cmp     bx, defqix      /       if ( x != defqix ) {
        !          100052:        je      1f              /
        !          100053:                                /               do {
        !          100054: 0:     addb    defqox, $2      /                       defqox++;
        !          100055:                                /
        !          100056:        push    defarg(bx)      /                       (*defunc[x])
        !          100057:        icall   defunc(bx)      /                               (defarg[x]);
        !          100058:        add     sp, $2          /
        !          100059:                                /
        !          100060:        mov     bx, defqox      /                       x = defqox;
        !          100061:        cmp     bx, defqix      /
        !          100062:        jne     0b              /               } while ( x != defqix );
        !          100063:                                /       }
        !          100064: 1:     ret                     / }
        !          100065: 
        !          100066: ////////
        !          100067: /
        !          100068: / void
        !          100069: / ldefer( f, a )       -- defer a far function [usually from interrupt level]
        !          100070: / int (far*f)();
        !          100071: / char *a;
        !          100072: /
        !          100073: /      Input:  f = pointer to loadable driver function to be deferred.
        !          100074: /              a = argument to pass to function when it is invoked.
        !          100075: /
        !          100076: /      Action: Schedule loadable driver function 'f' to be invoked with
        !          100077: /              argument 'a' during the transition from interrupt service
        !          100078: /              level back to user mode.
        !          100079: /
        !          100080: /      Return: None.
        !          100081: /
        !          100082: /      Notes:  16 instructions executed.  Interrupt latency = 8 instructions.
        !          100083: /              Only 127 functions can be deferred at any one time.
        !          100084: /              Exceeding this limit will cause loss of ALL deferred functions.
        !          100085: /
        !          100086: ////////
        !          100087: 
        !          100088: ldefer:                                /
        !          100089:        pop     ax              / Convert IP into PSW,CS,IP to allow iret.
        !          100090:        pushf                   /
        !          100091:        push    cs              /
        !          100092:        push    ax              /
        !          100093:        mov     bx, sp          / defer( f, a )
        !          100094:        mov     ax, ss:6(bx)    / register int (*f)();          /* CX:AX */
        !          100095:        mov     cx, ss:8(bx)    /
        !          100096:        mov     dx, ss:10(bx)   / register char *a;             /* DX */
        !          100097:                                / {
        !          100098:                                /       register int x;         /* BX */
        !          100099:                                /
        !          100100:        cli                     /       sphi();
        !          100101:        mov     bx, defqix      /       x = defqix;
        !          100102:        mov     ldfunc(bx), ax  /       ldfunc[x] = FP_OFF(f);
        !          100103:        mov     ldcseg(bx), cx  /       ldcseg[x] = FP_SEL(f);
        !          100104:        mov     defunc(bx),$ldefend/    defunc[x] = ldefend;
        !          100105:        mov     defarg(bx), dx  /       defarg[x] = a;
        !          100106:        addb    defqix, $2      /       defqix++;
        !          100107: //     sti                     /       splo();
        !          100108:        iret                    / }
        !          100109: 
        !          100110: ////////
        !          100111: /
        !          100112: / static void
        !          100113: / ldefend( )           -- evaluate deferred far function
        !          100114: /
        !          100115: /      Action: Evaluate deferred far function.
        !          100116: /
        !          100117: /      Notes:  Only called by defend().  Register BX contains driver's defqox.
        !          100118: /
        !          100119: ////////
        !          100120: 
        !          100121: ldefend:                       / PARAMETERS MUST REMAIN AT 4(BP).
        !          100122:        push    bp              / DRIVER RESIDENT CODE RELIES ON THIS.
        !          100123:        mov     bp, sp          /
        !          100124:                                /
        !          100125:        mov     ax, ldfunc(bx)  / AX = Driver function to be invoked.
        !          100126:                                /
        !          100127:        push    ldcseg(bx)      / Define driver entry point.
        !          100128:        push    four            /
        !          100129:                                /
        !          100130:        xcall   -4(bp)          / Invoke driver entry point, which will
        !          100131:                                /       in turn invoke the deferred function.
        !          100132:                                /
        !          100133:        mov     sp, bp          / Return to caller.
        !          100134:        pop     bp              /
        !          100135:        ret                     /
        !          100136: 
        !          100137:        .prvd
        !          100138: four:  .word   4
        !          100139:        .shri
        !          100140: @
        !          100141: 
        !          100142: 
        !          100143: 1.1
        !          100144: log
        !          100145: @Initial revision
        !          100146: @
        !          100147: text
        !          100148: @@
        !          100149: 0707070064030104661004440000030000030000011777770507310723500006100000004300/newbits/kernel/USRSRC/i8086/src/RCS/clocked.c,vhead     1.2;
        !          100150: branch   ;
        !          100151: access   ;
        !          100152: symbols  ;
        !          100153: locks    bin:1.2; strict;
        !          100154: comment  @ * @;
        !          100155: 
        !          100156: 
        !          100157: 1.2
        !          100158: date     91.06.20.14.39.27;  author bin;  state Exp;
        !          100159: branches ;
        !          100160: next     1.1;
        !          100161: 
        !          100162: 1.1
        !          100163: date     91.06.10.10.36.46;  author bin;  state Exp;
        !          100164: branches ;
        !          100165: next     ;
        !          100166: 
        !          100167: 
        !          100168: desc
        !          100169: @initial version prov by hal
        !          100170: @
        !          100171: 
        !          100172: 
        !          100173: 1.2
        !          100174: log
        !          100175: @update provided by hal
        !          100176: @
        !          100177: text
        !          100178: @/*
        !          100179:  * clocked.c - support routines for alternate clock rate
        !          100180:  *
        !          100181:  *  altclk_in(hz, fn) - install routine with specified rate
        !          100182:  *                      "hz" should be a multiple of system rate of 100 Hz
        !          100183:  *                     return 0 if completed ok, -1 otherwise
        !          100184:  *
        !          100185:  *  altclk_out()      - uninstall alternate clock routine and restore system rate
        !          100186:  *                     return old value of "altclk"
        !          100187:  *
        !          100188:  *  altclk_rate(hz)   - set clock interrupt rate
        !          100189:  *                     new rate must be an even multiple of system rate "HZ"
        !          100190:  *                     return 0 if completed ok, -1 otherwise
        !          100191:  *
        !          100192:  *  History:
        !          100193:  *    90/08/08 hws     initial version, works with hs.c modified for com[1-4]
        !          100194:  *    90/08/14 hws     make it more like a Unix system call
        !          100195:  */
        !          100196: 
        !          100197: #include       <sys/coherent.h>                /* altclk */
        !          100198: #include       <sys/const.h>           /* HZ */
        !          100199: 
        !          100200: #define        PIT     0x40            /* 8253 port */
        !          100201: #define        TMR0_M3 0x36            /* timer 0, mode 3 */
        !          100202: 
        !          100203: #if 0
        !          100204:                                /* nominal IBM rate is 1.1900 MHz */
        !          100205: #define        SYS_HZ  1190000L        /* rate of input clock to timer 0 */
        !          100206: #else
        !          100207:                                /* current kernel rate is 1.1932 MHz */
        !          100208: #define        SYS_HZ  1193200L        /* rate of input clock to timer 0 */
        !          100209: #endif
        !          100210: 
        !          100211: typedef int (*PFI)();          /* pointer to function returning int */
        !          100212: 
        !          100213: altclk_rate(hz)
        !          100214: unsigned int hz;
        !          100215: {
        !          100216:        int s;                  /* to save CPU irpt flag */
        !          100217:        unsigned int interval;  /* period for hz, in units of 1.19 MHz ticks */
        !          100218:        int ret;
        !          100219: 
        !          100220:        if (hz >= HZ && hz % HZ == 0) {         /* can't go slower than HZ! */
        !          100221:                interval = SYS_HZ/hz;
        !          100222:                s = sphi();                     /* disable irpts */
        !          100223:                outb(PIT+3, TMR0_M3);
        !          100224:                outb(PIT, interval & 0xff);
        !          100225:                outb(PIT, interval >> 8);       /* unsigned shift */
        !          100226:                spl(s);                         /* restore previous irpt state */
        !          100227:                ret = 0;
        !          100228:        } else {
        !          100229:                ret = -1;
        !          100230:        }
        !          100231:        return ret;
        !          100232: }
        !          100233: 
        !          100234: int altclk_in(hz, fn)
        !          100235: int hz;
        !          100236: PFI fn;
        !          100237: {
        !          100238:        int ret;
        !          100239: 
        !          100240:        if ((ret = altclk_rate(hz)) == 0)
        !          100241:                altclk = fn;
        !          100242:        return ret;
        !          100243: }
        !          100244: 
        !          100245: PFI altclk_out()
        !          100246: {
        !          100247:        PFI ret;
        !          100248: 
        !          100249:        ret = altclk;
        !          100250:        if (ret) {
        !          100251:                altclk_rate(HZ);
        !          100252:                altclk = 0;
        !          100253:        }
        !          100254:        return ret;
        !          100255: }
        !          100256: @
        !          100257: 
        !          100258: 
        !          100259: 1.1
        !          100260: log
        !          100261: @Initial revision
        !          100262: @
        !          100263: text
        !          100264: @d20 1
        !          100265: a20 1
        !          100266: #include       "coherent.h"            /* altclk */
        !          100267: @
        !          100268: 0707070064030104641004440000030000030000011777770507310723500006100000010521/newbits/kernel/USRSRC/i8086/src/RCS/dmalock.c,vhead     1.2;
        !          100269: branch   ;
        !          100270: access   ;
        !          100271: symbols  ;
        !          100272: locks    bin:1.2; strict;
        !          100273: comment  @ * @;
        !          100274: 
        !          100275: 
        !          100276: 1.2
        !          100277: date     91.06.20.14.39.37;  author bin;  state Exp;
        !          100278: branches ;
        !          100279: next     1.1;
        !          100280: 
        !          100281: 1.1
        !          100282: date     91.06.10.10.36.47;  author bin;  state Exp;
        !          100283: branches ;
        !          100284: next     ;
        !          100285: 
        !          100286: 
        !          100287: desc
        !          100288: @initial version prov by hal
        !          100289: @
        !          100290: 
        !          100291: 
        !          100292: 1.2
        !          100293: log
        !          100294: @update provided by hal
        !          100295: @
        !          100296: text
        !          100297: @/* $Header: /usr/src/sys/i8086/src/RCS/dmalock.c,v 1.1 89/06/30 16:21:26 src Exp $
        !          100298:  *
        !          100299:  *     The  information  contained herein  is a trade secret  of INETCO
        !          100300:  *     Systems, Ltd, and is  confidential information.   It is provided
        !          100301:  *     under a license agreement,  and may be copied or disclosed  only
        !          100302:  *     under  the  terms  of  that  agreement.    Any  reproduction  or
        !          100303:  *     disclosure  of  this   material   without  the  express  written
        !          100304:  *     authorization of INETCO Systems, Ltd. or persuant to the license
        !          100305:  *     agreement is unlawful.
        !          100306:  *
        !          100307:  *     Copyright (c) 1989
        !          100308:  *     An unpublished work by INETCO Systems, Ltd.
        !          100309:  *     All rights reserved.
        !          100310:  *
        !          100311:  * $Description: $
        !          100312:  *     Routines to lock/unlock the DMA controller chip.
        !          100313:  *
        !          100314:  * $Author: src $
        !          100315:  *
        !          100316:  * $Creation: June 21, 1989 $
        !          100317:  *
        !          100318:  * $Log:       /usr/src/sys/i8086/src/RCS/dmalock.c,v $
        !          100319:  * Revision 1.1        89/06/30  16:21:26      src
        !          100320:  * Initial revision
        !          100321:  * 
        !          100322:  */
        !          100323: 
        !          100324: #include <sys/timeout.h>
        !          100325: 
        !          100326: typedef void (* vfp_t)();              /* Void function pointer type.       */
        !          100327: 
        !          100328: /*
        !          100329:  * If the following variable is non-zero, DMA controller locking is enabled,
        !          100330:  * allowing at access to only one DMA channel at a time.
        !          100331:  */
        !          100332: int DMALCK = 1;
        !          100333: 
        !          100334: static TIM * dmatail = (TIM *)0;       /* DMA deferred function queue tail. */
        !          100335: static TIM * dmahead = (TIM *)0;       /* DMA deferred function queue head. */
        !          100336: 
        !          100337: /*
        !          100338:  * int
        !          100339:  * dmalock( dfp, fun, arg )
        !          100340:  * TIM * dfp;
        !          100341:  * vfp_t fun;
        !          100342:  * int  arg;
        !          100343:  *
        !          100344:  *     Inputs: dfp  = Deferred function structure pointer.
        !          100345:  *             fun  = Function to call if request is deferred.
        !          100346:  *             arg  = Argument to pass to function.
        !          100347:  *
        !          100348:  *     Action: Either locks DMA controller immediately or defers function
        !          100349:  *             call until lock can be granted.
        !          100350:  *
        !          100351:  *     Return: 0 = Lock granted or -1 = Lock deferred.
        !          100352:  *
        !          100353:  *     Notes:  DMA controller locking was introduced to cure a bug on the
        !          100354:  *             NCR DMA controller, where overlapped DMA caused problems.
        !          100355:  *             No action is taken if DMA locking is disabled.
        !          100356:  */
        !          100357: 
        !          100358: int
        !          100359: dmalock( dfp, fun, arg )
        !          100360: register TIM  * dfp;
        !          100361: vfp_t          fun;
        !          100362: int            arg;
        !          100363: {
        !          100364:        register int s;         /* Interrupt mask state. */
        !          100365: 
        !          100366:        /*
        !          100367:         * If DMA locking is disabled, allow functions to proceed.
        !          100368:         */
        !          100369:        if ( DMALCK == 0 )
        !          100370:                return( 0 );
        !          100371: 
        !          100372:        /*
        !          100373:         * Record function and argument to be invoked upon dmaunlock.
        !          100374:         */
        !          100375:        dfp->t_func = fun;
        !          100376:        dfp->t_farg = arg;
        !          100377:        dfp->t_next = (TIM *)0;
        !          100378: 
        !          100379:        s = sphi();
        !          100380: 
        !          100381:        /*
        !          100382:         * If the queue is empty, put our structure at the head.
        !          100383:         */
        !          100384:        if ( dmahead == (TIM *)0 ) {
        !          100385:                dmahead = dfp;
        !          100386:                dmatail = dfp;
        !          100387:                spl( s );
        !          100388:                return( 0 );
        !          100389:        }
        !          100390: 
        !          100391:        /*
        !          100392:         * PARANOIA:    If our structure is already at the head of the queue,
        !          100393:         *              print a message and return.
        !          100394:         */
        !          100395:        if ( dmahead == dfp ) {
        !          100396:                spl( s );
        !          100397:                printf( "dmalock: driver attempting to doubly lock DMA controller.\n" );
        !          100398:                return( 0 );
        !          100399:        }
        !          100400: 
        !          100401:        /*
        !          100402:         * Append to tail of DMA deferred function queue.
        !          100403:         */
        !          100404:        dmatail->t_next = dfp;
        !          100405:        dmatail         = dfp;
        !          100406:        spl( s );
        !          100407:        return( -1 );
        !          100408: }
        !          100409: 
        !          100410: /*
        !          100411:  * void
        !          100412:  * dmaunlock( dfp )
        !          100413:  * TIM * dfp;
        !          100414:  *
        !          100415:  *     Inputs: dfp = Deferred function structure pointer.
        !          100416:  *
        !          100417:  *     Action: Unlocks the DMA controller and calls the next deferred
        !          100418:  *             function, if any.
        !          100419:  *
        !          100420:  *     Notes:  No action is taken if the deferred function structure pointer
        !          100421:  *             is not the same as the one used to lock the DMA controller.
        !          100422:  */
        !          100423: 
        !          100424: void
        !          100425: dmaunlock( dfp )
        !          100426: register TIM * dfp;
        !          100427: {
        !          100428:        register TIM *  qp;     /* Temporary function queue pointer.    */
        !          100429:        register int    s;      /* Interrupt mask state.                */
        !          100430: 
        !          100431:        s = sphi();
        !          100432: 
        !          100433:        /*
        !          100434:         * If the DMA controller is not locked, return.
        !          100435:         */
        !          100436:        if ( dmahead == (TIM *)0 ) {
        !          100437:                spl( s );
        !          100438:                return;
        !          100439:        }
        !          100440: 
        !          100441:        /*
        !          100442:         * If our lock is not the one holding the DMA controller:
        !          100443:         */
        !          100444:        if ( dmahead != dfp ) {
        !          100445: 
        !          100446:                /*
        !          100447:                 * Look for us in queue.
        !          100448:                 */
        !          100449:                for ( qp = dmahead; qp != dmatail; qp = qp->t_next )
        !          100450: 
        !          100451:                        /*
        !          100452:                         * If found, remove us.
        !          100453:                         */
        !          100454:                        if ( qp->t_next == dfp ) {
        !          100455:                                qp->t_next = dfp->t_next;
        !          100456: 
        !          100457:                                if ( dmatail == dfp )
        !          100458:                                        dmatail = qp;
        !          100459: 
        !          100460:                                break;
        !          100461:                        }
        !          100462: 
        !          100463:                spl( s );
        !          100464:                return;
        !          100465:        }
        !          100466: 
        !          100467:        /*
        !          100468:         * If there are no functions waiting for us, empty queue and return.
        !          100469:         */
        !          100470:        if ( dmahead == dmatail ) {
        !          100471:                dmahead = (TIM *)0;
        !          100472:                spl( s );
        !          100473:                return;
        !          100474:        }
        !          100475: 
        !          100476:        /*
        !          100477:         * Remove us and execute next deferred function.
        !          100478:         */
        !          100479:        dmahead = dmahead->t_next;
        !          100480:        spl( s );
        !          100481:        (*dmahead->t_func)( dmahead->t_farg, dmahead );
        !          100482: }
        !          100483: 
        !          100484: @
        !          100485: 
        !          100486: 
        !          100487: 1.1
        !          100488: log
        !          100489: @Initial revision
        !          100490: @
        !          100491: text
        !          100492: @@
        !          100493: 0707070064030104621004440000030000030000011777770507310723600005600000044253/newbits/kernel/USRSRC/i8086/src/RCS/exec.c,vhead     1.2;
        !          100494: branch   ;
        !          100495: access   ;
        !          100496: symbols  ;
        !          100497: locks    bin:1.2; strict;
        !          100498: comment  @ * @;
        !          100499: 
        !          100500: 
        !          100501: 1.2
        !          100502: date     91.06.20.14.39.41;  author bin;  state Exp;
        !          100503: branches ;
        !          100504: next     1.1;
        !          100505: 
        !          100506: 1.1
        !          100507: date     91.06.10.10.36.49;  author bin;  state Exp;
        !          100508: branches ;
        !          100509: next     ;
        !          100510: 
        !          100511: 
        !          100512: desc
        !          100513: @initial version prov by hal
        !          100514: @
        !          100515: 
        !          100516: 
        !          100517: 1.2
        !          100518: log
        !          100519: @update provided by hal
        !          100520: @
        !          100521: text
        !          100522: @/* $Header: /usr/src/sys/i8086/src/RCS/exec.c,v 1.1 88/03/24 17:39:26 src Exp $ */
        !          100523: /* (lgl-
        !          100524:  *     The information contained herein is a trade secret of Mark Williams
        !          100525:  *     Company, and  is confidential information.  It is provided  under a
        !          100526:  *     license agreement,  and may be  copied or disclosed  only under the
        !          100527:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          100528:  *     material without the express written authorization of Mark Williams
        !          100529:  *     Company or persuant to the license agreement is unlawful.
        !          100530:  *
        !          100531:  *     COHERENT Version 2.3.37
        !          100532:  *     Copyright (c) 1982, 1983, 1984.
        !          100533:  *     An unpublished work by Mark Williams Company, Chicago.
        !          100534:  *     All rights reserved.
        !          100535:  -lgl) */
        !          100536: /*
        !          100537:  * This file contains a special version
        !          100538:  * of "sys exec" for the i8086. This version has
        !          100539:  * no driver load code in it (save space) and has
        !          100540:  * special load code so that the text of a shared
        !          100541:  * and separated image can be shared.
        !          100542:  * Loadable kernel processes are partially supported:
        !          100543:  * the process text and data must be ld'ed with the system
        !          100544:  * and the l.out executed must have no loadable or allocateable
        !          100545:  * segments.
        !          100546:  *
        !          100547:  * $Log:       /usr/src/sys/i8086/src/RCS/exec.c,v $
        !          100548:  * Revision 1.1        88/03/24  17:39:26      src
        !          100549:  * Initial revision
        !          100550:  * 
        !          100551:  * 88/01/21    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          100552:  * Segments are now de-associated from processes before freeing the segment.
        !          100553:  *
        !          100554:  * 87/12/03    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          100555:  * ld_start() now reverts to kernel mode [depth=0] from user mode [depth=1].
        !          100556:  *
        !          100557:  * 87/11/25    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          100558:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          100559:  *
        !          100560:  * 87/11/14    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          100561:  * Init code+data now split into icodep/icodes and idatap/idatas.
        !          100562:  *
        !          100563:  * 87/11/05    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          100564:  * New seg struct now used to allow extended addressing.
        !          100565:  *
        !          100566:  * 87/10/09    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          100567:  * pload() now handles new format [separate code] loadable device drivers.
        !          100568:  *
        !          100569:  * 87/10/08    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !          100570:  * Exsread() initializes the (IO).io_flag field to 0.
        !          100571:  */
        !          100572: #include <sys/coherent.h>
        !          100573: #include <acct.h>
        !          100574: #include <sys/buf.h>
        !          100575: #include <canon.h>
        !          100576: #include <sys/con.h>
        !          100577: #include <errno.h>
        !          100578: #include <sys/filsys.h>
        !          100579: #include <sys/ino.h>
        !          100580: #include <sys/inode.h>
        !          100581: #include <l.out.h>
        !          100582: #include <sys/proc.h>
        !          100583: #include <sys/sched.h>
        !          100584: #include <sys/seg.h>
        !          100585: #include <signal.h>
        !          100586: #include <sys/uproc.h>
        !          100587: #include <sys/i8086.h>
        !          100588: 
        !          100589: /*
        !          100590:  * Sizes.
        !          100591:  */
        !          100592: #define        sh      ((fsize_t)sizeof(struct ldheader))
        !          100593: #define si     lssize[L_SHRI]
        !          100594: #define pi     lssize[L_PRVI]
        !          100595: #define bi     lssize[L_BSSI]
        !          100596: #define sd     lssize[L_SHRD]
        !          100597: #define pd     lssize[L_PRVD]
        !          100598: #define bd     lssize[L_BSSD]
        !          100599: 
        !          100600: /*
        !          100601:  * Segments.
        !          100602:  */
        !          100603: #define upsp   pp->p_segp[SIUSERP]
        !          100604: #define sssp   pp->p_segp[SISTACK]
        !          100605: #define        sisp    pp->p_segp[SISTEXT]
        !          100606: #define pisp   pp->p_segp[SIPTEXT]
        !          100607: #define pdsp   pp->p_segp[SIPDATA]
        !          100608: 
        !          100609: /*
        !          100610:  * Loadable driver initiation point.
        !          100611:  */
        !          100612: static
        !          100613: ld_start()
        !          100614: {
        !          100615:        register SEG * sp;
        !          100616:        register int ret;
        !          100617: 
        !          100618:        /*
        !          100619:         * Kernel processes start by default at user level.
        !          100620:         * Revert to kernel level.
        !          100621:         */
        !          100622:        if ( depth == 1 )
        !          100623:                depth--;
        !          100624: 
        !          100625:        /*
        !          100626:         * Initialize memory references.
        !          100627:         */
        !          100628:        u.u_btime = timer.t_time;
        !          100629:        sproto();
        !          100630:        segload();
        !          100631: 
        !          100632: 
        !          100633:        /*
        !          100634:         * Invoke the driver if it has a shared or private code segment.
        !          100635:         */
        !          100636:        ret = 100;
        !          100637:        if ( (sp = SELF->p_segp[SISTEXT]) || (sp = SELF->p_segp[SIPTEXT]) ) {
        !          100638:                ret = ld_xcall( sp->s_faddr );
        !          100639:        }
        !          100640: 
        !          100641:        uexit( ret );
        !          100642: }
        !          100643: 
        !          100644: /*
        !          100645:  * Set up the first process, a small programme which will exec
        !          100646:  * the init programme.
        !          100647:  */
        !          100648: eveinit(sp)
        !          100649: SEG *sp;
        !          100650: {
        !          100651:        register PROC *pp;
        !          100652:        SELF = pp = eprocp;
        !          100653: 
        !          100654:        /*
        !          100655:         * Record user area.
        !          100656:         */
        !          100657:        pp->p_segp[SIUSERP] = sp;
        !          100658: 
        !          100659:        /*
        !          100660:         * Allocate, record, initialize code segment, make it executable.
        !          100661:         */
        !          100662:        if ((sp=salloc((fsize_t)icodes, 0)) == NULL)
        !          100663:                panic("eveinit(code)");
        !          100664:        pp->p_segp[SIPTEXT] = sp;
        !          100665:        kfcopy( icodep, sp->s_faddr, icodes );
        !          100666:        sp->s_flags |= SFTEXT;
        !          100667:        vremap(sp);
        !          100668: 
        !          100669:        /*
        !          100670:         * Allocate, record, and initialize data segment.
        !          100671:         */
        !          100672:        if ((sp=salloc((fsize_t)idatas, 0)) == NULL)
        !          100673:                panic("eveinit(data)");
        !          100674:        pp->p_segp[SIPDATA] = sp;
        !          100675:        kfcopy( idatap, sp->s_faddr, idatas );
        !          100676: 
        !          100677:        /*
        !          100678:         * Allocate and record stack segment.
        !          100679:         */
        !          100680:        if ((sp=salloc((fsize_t)UPASIZE, SFDOWN)) == NULL)
        !          100681:                panic("eveinit()");
        !          100682:        pp->p_segp[SISTACK] = sp;
        !          100683: 
        !          100684:        /*
        !          100685:         * Start process.
        !          100686:         */
        !          100687:        u.u_argp = 0;
        !          100688:        if (sproto() == 0)
        !          100689:                panic("eveinit()");
        !          100690:        segload();
        !          100691: }
        !          100692: 
        !          100693: /*
        !          100694:  * Load a driver which has already been linked into the system image.
        !          100695:  */
        !          100696: pload( np )
        !          100697: char * np;
        !          100698: {
        !          100699:        register INODE * ip;
        !          100700:        register PROC  * cpp;
        !          100701:        struct seg     * sp;
        !          100702:        fsize_t         lssize[NUSEG];          /* Segment sizes */
        !          100703:        int             lflag;                  /* l_flags from l.out */
        !          100704:        vaddr_t         pc;                     /* l_entry from l.out */
        !          100705:        int             r;                      /* Flag for "exload" */
        !          100706:        int             s;
        !          100707:        extern char     end[];
        !          100708: 
        !          100709: 
        !          100710:        if (super() == 0) {
        !          100711:                return( -1 );
        !          100712:        }
        !          100713: 
        !          100714:        /*
        !          100715:         * Coalesce memory BEFORE loading driver, since it can't be moved.
        !          100716:         */
        !          100717:        krunch(10000);
        !          100718: 
        !          100719:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL) {
        !          100720:                return( -1 );
        !          100721:        }
        !          100722: 
        !          100723:        /*
        !          100724:         * New format loadable drivers must have separate code/data.
        !          100725:         * It must have executable code, but no initialized data.
        !          100726:         * Uninitialized data must match the kernel data size.
        !          100727:         */
        !          100728:        if ( ((lflag & (LF_KER|LF_SHR|LF_SEP)) != (LF_SEP|LF_KER))
        !          100729:          || (si==0) || (sd!=0) || (pd!=0) || (bd != (int)end) ) {
        !          100730:                u.u_error = EBADFMT;
        !          100731:                idetach(ip);
        !          100732:                return( -1 );
        !          100733:        }
        !          100734: 
        !          100735:        /*
        !          100736:         * Allocate and initialize driver code segment.
        !          100737:         * NOTE: Must be system segment to prevent relocation.
        !          100738:         */
        !          100739:        sp = ssalloc(&r, ip, SFTEXT|SFHIGH|SFNSWP|SFSYST, si+pi+bi, sh, si+pi);
        !          100740: 
        !          100741:        /*
        !          100742:         * Release driver object file.
        !          100743:         */
        !          100744:        idetach(ip);
        !          100745: 
        !          100746:        if ( r < 0 ) {
        !          100747:                u.u_error = ENOMEM;
        !          100748:                return( -1 );
        !          100749:        }
        !          100750: 
        !          100751:        /*
        !          100752:         * Spawn kernel process to service driver.
        !          100753:         */
        !          100754:        if ((cpp = process(ld_start)) == NULL ) {
        !          100755:                u.u_error = ENOMEM;
        !          100756:                sfree(sp);
        !          100757:                return( -1 );
        !          100758:        }
        !          100759: 
        !          100760:        /*
        !          100761:         * Record the basename of the loaded driver.
        !          100762:         */
        !          100763:        kscopy( u.u_direct.d_name, cpp->p_segp[SIUSERP],
        !          100764:                offset(uproc,u_comm[0]), sizeof(u.u_comm) );
        !          100765: 
        !          100766:        /*
        !          100767:         * Record the driver code segment in the process's private code.
        !          100768:         */
        !          100769:        cpp->p_segp[SIPTEXT] = sp;
        !          100770:        cpp->p_cval = CVCHILD;
        !          100771:        cpp->p_sval = SVCHILD;
        !          100772:        cpp->p_rval = RVCHILD;
        !          100773:        cpp->p_ppid = 1;
        !          100774: 
        !          100775:        /*
        !          100776:         * Make the process executable.
        !          100777:         */
        !          100778:        s = sphi();
        !          100779:        setrun( cpp );
        !          100780:        spl( s );
        !          100781: 
        !          100782:        /*
        !          100783:         * Return driver process id.
        !          100784:         */
        !          100785:        return( cpp->p_pid );
        !          100786: }
        !          100787: 
        !          100788: /*
        !          100789:  * Given a major number, undo the previous function.
        !          100790:  */
        !          100791: puload(m)
        !          100792: int m;
        !          100793: {
        !          100794:        register CON *cp;
        !          100795:        register DRV *dp;
        !          100796: 
        !          100797:        dp = &drvl[m];
        !          100798:        lock(dp->d_gate);
        !          100799:        if (m>=drvn || (cp=dp->d_conp)==NULL) {
        !          100800:                u.u_error = ENXIO;
        !          100801:                goto ret;
        !          100802:        }
        !          100803:        (*cp->c_uload)();
        !          100804:        if ( ! u.u_error)
        !          100805:                dp->d_conp = NULL;
        !          100806: ret:
        !          100807:        unlock(dp->d_gate);
        !          100808:        return (0);
        !          100809: }
        !          100810: 
        !          100811: /*
        !          100812:  * Pass control to an image in a file.
        !          100813:  * Make sure the format is acceptable. Release
        !          100814:  * the old segments. Read in the new ones. Some special
        !          100815:  * care is taken so that shared and (more important) shared
        !          100816:  * and separated images can be run on the 8086.
        !          100817:  */
        !          100818: pexece(np, argp, envp)
        !          100819: char   *np;
        !          100820: char   *argp[];
        !          100821: char   *envp[];
        !          100822: {
        !          100823:        register INODE  *ip;                    /* Load file INODE */
        !          100824:        register PROC   *pp;                    /* A cheap copy of SELF */
        !          100825:        register SEG    *ssp;                   /* New stack segment */
        !          100826:        register SEG    *segp;
        !          100827:        register fsize_t        ss;                     /* Segment size temp. */
        !          100828:        register int    i;                      /* For looping over segments */
        !          100829:        int             r;                      /* Flag for "exload" */
        !          100830:        int             lflag;                  /* l_flags from l.out */
        !          100831:        vaddr_t         pc;                     /* l_entry from l.out */
        !          100832:        vaddr_t         sp;                     /* Initial stack pointer */
        !          100833:        fsize_t         lssize[NUSEG];          /* Segment sizes */
        !          100834:        fsize_t         codsize;                /* Total if CS segment  */
        !          100835:        fsize_t         datsize;                /* Total of DS segment  */
        !          100836:        extern fsize_t  exround();              /* Paragraph rounder */
        !          100837: 
        !          100838:        pp = SELF;
        !          100839:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL) {
        !          100840:                return;
        !          100841:        }
        !          100842: 
        !          100843:        if ( (lflag & LF_SEP) == 0 ) {
        !          100844:                u.u_error = EBADFMT;
        !          100845:                idetach(ip);
        !          100846:                return;
        !          100847:        }
        !          100848: 
        !          100849:        /*
        !          100850:         * Kernel processes are now supported through the sload() system call.
        !          100851:         * 87/10/09     Allan Cornish.
        !          100852:         */
        !          100853:        if ((lflag&LF_KER) != 0) {
        !          100854:                u.u_error = EBADFMT;
        !          100855:                idetach(ip);
        !          100856:                return;
        !          100857:        }
        !          100858: 
        !          100859:        /*
        !          100860:         * If a shared and separated image
        !          100861:         * has stuff in segments that makes it impossible
        !          100862:         * to share, give an error immediately so that we don't
        !          100863:         * lose the parent.
        !          100864:         */
        !          100865:        lflag &= LF_SHR|LF_SEP;
        !          100866: 
        !          100867:        if (lflag==(LF_SHR|LF_SEP) && (pi!=0 || bi!=0)) {
        !          100868:                u.u_error = EBADFMT;
        !          100869:                idetach(ip);
        !          100870:                return;
        !          100871:        }
        !          100872: 
        !          100873:        if ((ssp=exstack(&sp, argp, envp)) == NULL) {
        !          100874:                idetach(ip);
        !          100875:                return;
        !          100876:        }
        !          100877: 
        !          100878:        switch (lflag) {
        !          100879:        case LF_SEP:
        !          100880:                codsize = si+pi+bi;
        !          100881:                datsize = ssp->s_size+sd+pd+bd;
        !          100882:                break;
        !          100883:        case LF_SHR|LF_SEP:
        !          100884:                codsize = si;
        !          100885:                datsize = ssp->s_size+exround(sd)+pd+bd;
        !          100886:                break;
        !          100887:        }
        !          100888:        codsize = (codsize+(BSIZE-1)) & ~(BSIZE-1);
        !          100889:        datsize = (datsize+(BSIZE-1)) & ~(BSIZE-1);
        !          100890:        if ( (codsize >= MAXU) || (datsize >= MAXU) ) {
        !          100891:                u.u_error = E2BIG;
        !          100892:                idetach(ip);
        !          100893:                return;
        !          100894:        }
        !          100895: 
        !          100896:        /*
        !          100897:         * At this point the file has been
        !          100898:         * validated as an object module, and the
        !          100899:         * argument list has been built. Release all of
        !          100900:         * the original segments. At this point we have
        !          100901:         * committed to the new image. A "sys exec" that
        !          100902:         * gets an I/O error is doomed.
        !          100903:         * NOTE: User-area segment is NOT released.
        !          100904:         *       Segment pointer in proc is erased BEFORE invoking sfree().
        !          100905:         */
        !          100906:        for ( i = 1; i < NUSEG; ++i ) {
        !          100907:                if ((segp = pp->p_segp[i]) != NULL) {
        !          100908:                        pp->p_segp[i] = NULL;
        !          100909:                        sfree(segp);
        !          100910:                }
        !          100911:        }
        !          100912: 
        !          100913:        /*
        !          100914:         * Read in the loadable segments.
        !          100915:         */
        !          100916:        sssp = ssp;
        !          100917:        switch (lflag) {
        !          100918:        case 0:
        !          100919:                ss = si+pi+sd+pd;
        !          100920:                pdsp = ssalloc(&r, ip, 0, ss+bi+bd, sh, ss);
        !          100921:                if (r < 0)
        !          100922:                        goto out;
        !          100923:                break;
        !          100924: 
        !          100925:        case LF_SHR:
        !          100926:                ss = exround(si+sd);
        !          100927:                pdsp = ssalloc(&r, ip, 0, ss+pi+pd+bi+bd, sh, si);
        !          100928:                if (r < 0)
        !          100929:                        goto out;
        !          100930:                if (exsread(pdsp, ip, sd, sh+si+pi, si) == NULL)
        !          100931:                        goto out;
        !          100932:                if (exsread(pdsp, ip, pi, sh+si, ss) == NULL)
        !          100933:                        goto out;
        !          100934:                if (exsread(pdsp, ip, pd, sh+si+pi+sd, ss+pi) == NULL)
        !          100935:                        goto out;
        !          100936:                break;
        !          100937: 
        !          100938:        case LF_SEP:
        !          100939:                pisp = ssalloc(&r, ip, SFTEXT, si+pi+bi, sh, si+pi);
        !          100940:                if (r < 0)
        !          100941:                        goto out;
        !          100942:                pdsp = ssalloc(&r, ip, 0, sd+pd+bd, sh+si+pi, sd+pd);
        !          100943:                if (r < 0)
        !          100944:                        goto out;
        !          100945:                break;
        !          100946: 
        !          100947:        case LF_SHR|LF_SEP:
        !          100948:                /* pi=0, bi=0 */
        !          100949:                sisp = ssalloc(&r, ip, SFSHRX|SFTEXT, si, sh, si);
        !          100950:                if (r < 0)
        !          100951:                        goto out;
        !          100952:                ss = exround(sd);
        !          100953:                pdsp = ssalloc(&r, ip, 0, ss+pd+bd, sh+si, sd);
        !          100954:                if (r<0 || exsread(pdsp, ip, pd, sh+si+sd, ss) == NULL)
        !          100955:                        goto out;
        !          100956:        }
        !          100957:        if (sproto() == 0)
        !          100958:                 goto out;
        !          100959: #if 0
        !          100960:        if ( (datsize != pdsp->s_size) ||
        !          100961:             ( (lflag==LF_SEP) && (codsize != pisp->s_size) ) ||
        !          100962:             ( (lflag==(LF_SEP|LF_SHR)) && (codsize != sisp->s_size) ) ) {
        !          100963:                printf("\nExec ERROR:  codsize: 0x%X  datsize: 0x%X\n", 
        !          100964:                                        codsize, datsize);
        !          100965:                printf(
        !          100966:                "pdsp->s_size: 0x%X  pisp->s_size: 0x%X  sisp->s_size: 0x%X\n",
        !          100967:                        pdsp->s_size, pisp->s_size, sisp->s_size);
        !          100968:        }
        !          100969: #endif
        !          100970:        /*
        !          100971:         * The new image is read in
        !          100972:         * and mapped. Perform the final grunge
        !          100973:         * (set-uid stuff, accounting, loading up
        !          100974:         * registers, etc).
        !          100975:         */
        !          100976:        u.u_flag &= ~AFORK;
        !          100977:        kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm));
        !          100978:        if (iaccess(ip, IPR) == 0) {    /* Can't read ? no dump or trace */
        !          100979:                pp->p_flags |= PFNDMP;
        !          100980:                pp->p_flags &= ~PFTRAC;
        !          100981:        }
        !          100982:        if (iaccess(ip, IPW) == 0)      /* Can't write ? no trace */
        !          100983:                pp->p_flags &= ~PFTRAC;
        !          100984:        if ((ip->i_mode&ISUID) != 0) {  /* Set user id ? no trace */
        !          100985:                pp->p_uid = u.u_uid = ip->i_uid;
        !          100986:                pp->p_flags &= ~PFTRAC;
        !          100987:        }
        !          100988:        if ((ip->i_mode&ISGID) != 0) {  /* Set group id ? no trace */
        !          100989:                u.u_gid = ip->i_gid;
        !          100990:                pp->p_flags &= ~PFTRAC;
        !          100991:        }
        !          100992:        for (i=0; i<NSIG; ++i)
        !          100993:                if (u.u_sfunc[i] != SIG_IGN)
        !          100994:                        u.u_sfunc[i] = SIG_DFL;
        !          100995:        if ((pp->p_flags&PFTRAC) != 0)  /* Being traced */
        !          100996:                sendsig(SIGTRAP, pp);
        !          100997:        idetach(ip);
        !          100998:        msetusr(pc, sp);
        !          100999:        segload();
        !          101000:        return (0);
        !          101001: 
        !          101002:        /*
        !          101003:         * We did not make it.
        !          101004:         * Release the INODE for the load
        !          101005:         * file, and return through the "sys exit"
        !          101006:         * code with a "SIGSYS", or with the signal actually received
        !          101007:         * if we are aborting due to interrupted exec.
        !          101008:         */
        !          101009: out:
        !          101010:        idetach(ip);
        !          101011:        if (u.u_error == EINTR)
        !          101012:                pexit(nondsig());
        !          101013:        pexit(SIGSYS);
        !          101014: }
        !          101015: 
        !          101016: /*
        !          101017:  * Open an l.out, make sure it is an l.out and executable and return the
        !          101018:  * appropriate information.
        !          101019:  */
        !          101020: INODE *
        !          101021: exlopen(np, ssizep, flagp, pcp)
        !          101022: char *np;
        !          101023: fsize_t *ssizep;
        !          101024: int *flagp;
        !          101025: vaddr_t *pcp;
        !          101026: {
        !          101027:        register INODE *ip;
        !          101028:        register struct ldheader *ldp;
        !          101029:        register int n;
        !          101030:        register BUF *bp;
        !          101031:        int m;
        !          101032: 
        !          101033:        /*
        !          101034:         * Make sure the file is really an executable l.out and read the
        !          101035:         * header in.
        !          101036:         */
        !          101037:        if (ftoi(np, 'r') != 0)
        !          101038:                return (NULL);
        !          101039:        ip = u.u_cdiri;
        !          101040:        if (iaccess(ip, IPE) == 0) {
        !          101041:                idetach(ip);
        !          101042:                return (NULL);
        !          101043:        }
        !          101044:        if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) {
        !          101045:                u.u_error = EACCES;
        !          101046:                idetach(ip);
        !          101047:                return (NULL);
        !          101048:        }
        !          101049:        if ((bp=vread(ip, (daddr_t)0)) == NULL) {
        !          101050:                u.u_error = EBADFMT;
        !          101051:                idetach(ip);
        !          101052:                return (NULL);
        !          101053:        }
        !          101054: 
        !          101055:        /*
        !          101056:         * Copy everything we need from the l.out header and check magic
        !          101057:         * number and machine type.
        !          101058:         */
        !          101059:        ldp = FP_OFF(bp->b_faddr);
        !          101060:        m = ldp->l_magic;
        !          101061:        canint(m);
        !          101062:        if (m != L_MAGIC) {
        !          101063:                u.u_error = ENOEXEC;
        !          101064:                brelease(bp);
        !          101065:                idetach(ip);
        !          101066:                return (NULL);
        !          101067:        }
        !          101068:        m = ldp->l_machine;
        !          101069:        canint(m);
        !          101070:        if (m != mactype) {
        !          101071:                u.u_error = EBADFMT;
        !          101072:                brelease(bp);
        !          101073:                idetach(ip);
        !          101074:                return (NULL);
        !          101075:        }
        !          101076:        kkcopy(ldp->l_ssize, ssizep, NXSEG*sizeof(fsize_t));
        !          101077:        for (n=0; n<NXSEG; n++)
        !          101078:                cansize(ssizep[n]);
        !          101079:        *flagp = ldp->l_flag;
        !          101080:        canint(*flagp);
        !          101081:        *pcp = ldp->l_entry;
        !          101082:        canvaddr(*pcp);
        !          101083:        brelease(bp);
        !          101084:        return (ip);
        !          101085: }
        !          101086: 
        !          101087: /*
        !          101088:  * Given a segment `sp', read `ss' bytes from the inode `ip' starting
        !          101089:  * at seek address `sa' into offset `so' in the segment.
        !          101090:  */
        !          101091: SEG *
        !          101092: exsread(sp, ip, ss, sa, so)
        !          101093: register SEG *sp;
        !          101094: INODE *ip;
        !          101095: fsize_t ss;
        !          101096: fsize_t sa;
        !          101097: fsize_t so;
        !          101098: {
        !          101099:        while (ss > 0) {
        !          101100:                u.u_io.io_seg = IOPHY;
        !          101101:                u.u_io.io_seek = sa;
        !          101102:                u.u_io.io_phys = sp->s_paddr + so;
        !          101103:                u.u_io.io_flag = 0;
        !          101104:                if (ss >= 4096) {
        !          101105:                        u.u_io.io_ioc = 4096;
        !          101106:                        ss -= 4096;
        !          101107:                } else {
        !          101108:                        u.u_io.io_ioc = ss;
        !          101109:                        ss = 0;
        !          101110:                }
        !          101111:                sp->s_lrefc++;
        !          101112:                iread(ip, &u.u_io);
        !          101113:                sp->s_lrefc--;
        !          101114:                if (nondsig()) {
        !          101115:                        u.u_error = EINTR;
        !          101116:                        break;
        !          101117:                }
        !          101118:                sa += 4096;
        !          101119:                so += 4096;
        !          101120:        }
        !          101121:        if (u.u_error == 0)
        !          101122:                return (sp);
        !          101123:        return (NULL);
        !          101124: }
        !          101125: 
        !          101126: /*
        !          101127:  * Given a pointer to a list of arguments and a pointer to a list of
        !          101128:  * environments, return a stack with the arguments and environments on it.
        !          101129:  */
        !          101130: SEG *
        !          101131: exstack(iusp, argp, envp)
        !          101132: char **iusp;           /* Back patch sp value */
        !          101133: char *argp[];          /* Arguments for new process */
        !          101134: char *envp[];          /* Environments for new process */
        !          101135: {
        !          101136:        SEG *sp;                /* Stack segment pointer */
        !          101137:        struct adata {          /* Storage for arg and env data */
        !          101138:                char    **up;           /* User vector pointer */
        !          101139:                int     np;             /* Number of pointers in vector */
        !          101140:                int     nc;             /* Number of characters in strings */
        !          101141:        } arg, env;
        !          101142:        struct sdata {          /* To keep segment pointers */
        !          101143:                vaddr_t base;           /* Top of segment virtual */
        !          101144:                vaddr_t ap;             /* Argc, argv, envp pointer */
        !          101145:                vaddr_t vp;             /* Argv[i], envp[i] pointer */
        !          101146:                vaddr_t cp;             /* Argv[i][j], envp[i][j] pointer */
        !          101147:        } aux, stk;
        !          101148:        aold_t aold;                    /* Auxiliary map storage */
        !          101149:        register char **usrvp;          /* Vector pointer into user seg */
        !          101150:        register char *usrcp;           /* Character pointer into user seg */
        !          101151:        register int c;                 /* Character fetched from user */
        !          101152:        register int chrsz;             /* Size of strings */
        !          101153:        register struct adata *adp;     /* Arg and env scanner */
        !          101154:        register int vecsz;             /* Size of vectors */
        !          101155:        register int stksz;             /* Size of stack argument region */
        !          101156: 
        !          101157:        /* Validate and evaluate size of args and envs */
        !          101158:        arg.up = argp;
        !          101159:        env.up = envp;
        !          101160:        chrsz = 0;
        !          101161:        vecsz = 0;
        !          101162:        for (adp = &arg; ; adp = &env) {
        !          101163:                adp->np = 0;
        !          101164:                adp->nc = 0;
        !          101165:                if (excount(adp->up, &adp->np, &adp->nc) == 0)
        !          101166:                        return (NULL);
        !          101167:                chrsz += adp->nc * sizeof(char);
        !          101168:                vecsz += adp->np * sizeof(char *);
        !          101169:                if (adp == &env)
        !          101170:                        break;
        !          101171:        }
        !          101172: 
        !          101173:        /* Calculate stack size and allocate it */
        !          101174:        chrsz = roundu(chrsz, sizeof(int));
        !          101175:        stksz = sizeof(int)             /* argc */
        !          101176:                + sizeof(char **)       /* argv */
        !          101177:                + sizeof(char **)       /* envp */
        !          101178:                + vecsz                 /* argv[i] and envp[i] */
        !          101179:                + chrsz                 /* *argv[i] and *envp[i] */
        !          101180:                + sizeof(int)           /* Mystery zero word */
        !          101181:                + sizeof(char *)        /* Splimit for z8000 */
        !          101182:                + sizeof(int);          /* errno */
        !          101183:        stksz += ISTSIZE;
        !          101184:        if (stksz > MADSIZE) {
        !          101185:                u.u_error = E2BIG;
        !          101186:                return (NULL);
        !          101187:        }
        !          101188:        if ((sp=salloc((fsize_t)stksz, SFDOWN)) == NULL)
        !          101189:                return (NULL);
        !          101190:        stksz -= ISTSIZE;
        !          101191: 
        !          101192:        /*
        !          101193:         * Initialize segment data.
        !          101194:         */
        !          101195:        asave(aold);
        !          101196: 
        !          101197:        abase(FP_SEL(sp->s_faddr));
        !          101198:        aux.base = sp->s_size;
        !          101199:        aux.ap = aux.base - stksz;
        !          101200:        aux.vp = aux.ap + sizeof(int) + 2*sizeof(char **);
        !          101201:        aux.cp = aux.vp + vecsz;
        !          101202: 
        !          101203:        stk.base = ISTVIRT;
        !          101204:        stk.ap = stk.base - stksz;
        !          101205:        stk.vp = stk.ap + sizeof(int) + 2*sizeof(char **);
        !          101206:        stk.cp = stk.vp + vecsz;
        !          101207: 
        !          101208:        /*
        !          101209:         * Write argc.
        !          101210:         */
        !          101211:        aputi((int *)aux.ap, arg.np-1);
        !          101212:        aux.ap += sizeof(int);
        !          101213: 
        !          101214:        /*
        !          101215:         * Arguments and environments.
        !          101216:         */
        !          101217:        for (adp = &arg; ; adp = &env) {
        !          101218: 
        !          101219:                /* Write argv or envp */
        !          101220:                aputp((char ***)aux.ap, (char **)stk.vp);
        !          101221:                aux.ap += sizeof(char **);
        !          101222:                if ((usrvp = adp->up) != NULL) {
        !          101223: 
        !          101224:                        /* Write argv[i] or envp[i] */
        !          101225:                        while ((usrcp = getupd(usrvp++)) != NULL) {
        !          101226:                                aputp((char **)aux.vp, (char *)stk.cp);
        !          101227:                                aux.vp += sizeof(char *);
        !          101228:                                stk.vp += sizeof(char *);
        !          101229: 
        !          101230:                                /* Write argv[i][j] or envp[i][j] */
        !          101231:                                do {
        !          101232:                                        c = getubd(usrcp++);
        !          101233:                                        aputc((char *)aux.cp, c);
        !          101234:                                        aux.cp += sizeof(char);
        !          101235:                                        stk.cp += sizeof(char);
        !          101236:                                } while (c != '\0');
        !          101237:                        }
        !          101238:                }
        !          101239: 
        !          101240:                /* Write argv[argc] or envp[envc] */
        !          101241:                aputp((char **)aux.vp, NULL);
        !          101242:                aux.vp += sizeof(char *);
        !          101243:                stk.vp += sizeof(char *);
        !          101244:                if (adp == &env)
        !          101245:                        break;
        !          101246:        }
        !          101247: 
        !          101248:        /*
        !          101249:         * Clear out the slop.
        !          101250:         */
        !          101251:        aux.base -= sizeof(int);
        !          101252:        aputi((int *) aux.base, 0);             /* errno */
        !          101253:        aux.base -= sizeof(char *);
        !          101254:        aputp((char **) aux.base, (char *)stk.base - sp->s_size + SOVSIZE);
        !          101255:        aux.base -= sizeof(int);
        !          101256:        aputi((int *) aux.base, 0);             /* mystery word */
        !          101257: 
        !          101258:        arest(aold);
        !          101259: 
        !          101260:        /*
        !          101261:         * Patch some values and return.
        !          101262:         */
        !          101263:        *iusp = stk.ap;         /* Patch initial usp */
        !          101264:        u.u_argc = arg.np-1;
        !          101265:        u.u_argp = stk.vp;      /* Points after NULL of envs */
        !          101266:        return (sp);
        !          101267: }
        !          101268: 
        !          101269: /*
        !          101270:  * Given a pointer to a list of arguments, a pointer to an argument count
        !          101271:  * and a pointer to a byte count, update incrementally the argument count
        !          101272:  * and the byte count.
        !          101273:  */
        !          101274: excount(usrvp, nap, nbp)
        !          101275: register char **usrvp;
        !          101276: int *nap;
        !          101277: int *nbp;
        !          101278: {
        !          101279:        register char *usrcp;
        !          101280:        register int c;
        !          101281:        register unsigned nb;
        !          101282:        register unsigned na;
        !          101283: 
        !          101284:        na = 1;
        !          101285:        nb = 0;
        !          101286:        if (usrvp != NULL) {
        !          101287:                for (;;) {
        !          101288:                        usrcp = getupd(usrvp++);
        !          101289:                        if (u.u_error)
        !          101290:                                return (0);
        !          101291:                        if (usrcp == NULL)
        !          101292:                                break;
        !          101293:                        na++;
        !          101294:                        for (;;) {
        !          101295:                                c = getubd(usrcp++);
        !          101296:                                if (u.u_error)
        !          101297:                                        return (0);
        !          101298:                                nb++;
        !          101299:                                if (c == '\0')
        !          101300:                                        break;
        !          101301:                        }
        !          101302:                }
        !          101303:        }
        !          101304:        *nap += na;
        !          101305:        *nbp += nb;
        !          101306:        return (1);
        !          101307: }
        !          101308: 
        !          101309: /*
        !          101310:  * Round up a size to a paragraph
        !          101311:  * (mod 16) boundry.
        !          101312:  * This is really mod 512 to make swapping work
        !          101313:  */
        !          101314: fsize_t
        !          101315: exround(s)
        !          101316: fsize_t        s;
        !          101317: {
        !          101318:        return ((s+15)&~0x0F);
        !          101319: }
        !          101320: @
        !          101321: 
        !          101322: 
        !          101323: 1.1
        !          101324: log
        !          101325: @Initial revision
        !          101326: @
        !          101327: text
        !          101328: @d66 1
        !          101329: a66 1
        !          101330: #include <i8086.h>
        !          101331: @
        !          101332: 0707070064030104611004440000030000030000011777770507310724300006000000010526/newbits/kernel/USRSRC/i8086/src/RCS/krunch.c,vhead     1.2;
        !          101333: branch   ;
        !          101334: access   ;
        !          101335: symbols  ;
        !          101336: locks    bin:1.2; strict;
        !          101337: comment  @ * @;
        !          101338: 
        !          101339: 
        !          101340: 1.2
        !          101341: date     91.06.20.14.39.59;  author bin;  state Exp;
        !          101342: branches ;
        !          101343: next     1.1;
        !          101344: 
        !          101345: 1.1
        !          101346: date     91.06.10.10.36.54;  author bin;  state Exp;
        !          101347: branches ;
        !          101348: next     ;
        !          101349: 
        !          101350: 
        !          101351: desc
        !          101352: @initial version prov by hal
        !          101353: @
        !          101354: 
        !          101355: 
        !          101356: 1.2
        !          101357: log
        !          101358: @update provided by hal
        !          101359: @
        !          101360: text
        !          101361: @/* $Header: /usr/src/sys/i8086/src/RCS/krunch.c,v 1.1 88/03/24 17:39:33 src Exp $ */
        !          101362: /*
        !          101363:  *     The  information  contained herein  is a trade secret  of INETCO
        !          101364:  *     Systems, and is confidential information.   It is provided under
        !          101365:  *     a license agreement,  and may be copied or disclosed  only under
        !          101366:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          101367:  *     this  material  without  the express  written  authorization  of
        !          101368:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          101369:  *
        !          101370:  *     Copyright (c) 1987.
        !          101371:  *     An unpublished work by INETCO Systems, Ltd.
        !          101372:  *     All rights reserved.
        !          101373:  */
        !          101374: 
        !          101375: /*
        !          101376:  * Coherent.
        !          101377:  * Segment crunch.
        !          101378:  *
        !          101379:  * $Log:       /usr/src/sys/i8086/src/RCS/krunch.c,v $
        !          101380:  * Revision 1.1        88/03/24  17:39:33      src
        !          101381:  * Initial revision
        !          101382:  * 
        !          101383:  * 87/12/02    Allan Cornish   /usr/src/sys/i8086/src/krunch.c
        !          101384:  * krunch() now locks/unlocks segment gate.
        !          101385:  *
        !          101386:  * 87/11/26    Allan Cornish   /usr/src/sys/i8086/src/krunch.c
        !          101387:  * krunch() now called to merge unused memory by moving segments.
        !          101388:  */
        !          101389: #include <sys/coherent.h>
        !          101390: #include <sys/i8086.h>
        !          101391: #include <sys/proc.h>
        !          101392: #include <sys/seg.h>
        !          101393: 
        !          101394: /*
        !          101395:  * Time interval in clock ticks between krunch attempts: default 2 seconds.
        !          101396:  */
        !          101397: int KRUNCH = 200;
        !          101398: 
        !          101399: /**
        !          101400:  *
        !          101401:  * krunch( n )
        !          101402:  * int n;
        !          101403:  *
        !          101404:  *     Input:  n = maximum number of segments to be moved.
        !          101405:  *
        !          101406:  *     Action: Scan the segmentation list, looking for unused memory
        !          101407:  *             immediately below unlocked application segments,
        !          101408:  *             moving the segment down into the unused memory.
        !          101409:  */
        !          101410: krunch( n )
        !          101411: int n;
        !          101412: {
        !          101413:        register SEG *sp;
        !          101414:        paddr_t paddr;
        !          101415:        saddr_t osel;
        !          101416:        static TIM tim;
        !          101417:        int s;
        !          101418: 
        !          101419:        if ( depth != 0 ) {
        !          101420:                printf("krunch(%d,depth=%d) ", n, depth );      /** DEBUG **/
        !          101421:                return;
        !          101422:        }
        !          101423: 
        !          101424:        /*
        !          101425:         * Do not crunch segment list if swapper is active.
        !          101426:         */
        !          101427:        if ( (KRUNCH == 0) || (sexflag != 0) )
        !          101428:                return;
        !          101429: 
        !          101430:        /*
        !          101431:         * Segment count of 0 indicates a request to schedule delayed krunch(1).
        !          101432:         */
        !          101433:        if ( n <= 0 ) {
        !          101434:                if ( tim.t_last != NULL )
        !          101435:                        timeout( &tim, KRUNCH, krunch, 1 );
        !          101436:                return;
        !          101437:        }
        !          101438: 
        !          101439:        /*
        !          101440:         * Segmentation is locked - retry later.
        !          101441:         */
        !          101442:        s = sphi();
        !          101443:        if ( locked(seglink) ) {
        !          101444:                timeout( &tim, KRUNCH, krunch, n );
        !          101445:                spl(s);
        !          101446:                return;
        !          101447:        }
        !          101448:        lock(seglink);
        !          101449:        spl(s);
        !          101450: 
        !          101451: #if EBUG > 1
        !          101452:        printf("krunch(%d) ", n );
        !          101453: #endif
        !          101454: 
        !          101455:        for ( paddr = corebot, sp = &segmq;
        !          101456:              (sp = sp->s_forw) != &segmq ;
        !          101457:              paddr = sp->s_paddr + sp->s_size ) {
        !          101458: 
        !          101459:                /*
        !          101460:                 * No hole exists.
        !          101461:                 */
        !          101462:                if ( paddr == sp->s_paddr )
        !          101463:                        continue;
        !          101464: 
        !          101465: #if EBUG > 1
        !          101466:                printf("hole(p=%X,n=%X) seg(p=%X,n=%X,f=%x,u=%x,l=%x) ",
        !          101467:                        paddr,
        !          101468:                        sp->s_paddr - paddr,
        !          101469:                        sp->s_paddr,
        !          101470:                        sp->s_size,
        !          101471:                        sp->s_flags & (SFSYST|SFHIGH),
        !          101472:                        sp->s_urefc,
        !          101473:                        sp->s_lrefc );
        !          101474: #endif
        !          101475: 
        !          101476:                /*
        !          101477:                 * Don't try to shuffle high segments into low memory.
        !          101478:                 */
        !          101479:                if ( sp->s_flags & SFHIGH )
        !          101480:                        break;
        !          101481: 
        !          101482:                /*
        !          101483:                 * System segment.
        !          101484:                 */
        !          101485:                if ( sp->s_flags & SFSYST )
        !          101486:                        continue;
        !          101487: 
        !          101488:                /*
        !          101489:                 * Segment may be in process of being swapped in/out.
        !          101490:                 */
        !          101491:                if ( (sp->s_flags & SFCORE) == 0 )
        !          101492:                        continue;
        !          101493: 
        !          101494:                /*
        !          101495:                 * Segment is locked for I/O.
        !          101496:                 */
        !          101497:                if ( sp->s_lrefc != sp->s_urefc )
        !          101498:                        continue;
        !          101499: 
        !          101500: #if EBUG > 0
        !          101501:                printf("move(dst=%X,src=%X,len=%X) ",
        !          101502:                        paddr, sp->s_paddr,sp->s_size );
        !          101503: #endif
        !          101504:                /*
        !          101505:                 * Remember previous virtual address.
        !          101506:                 */
        !          101507:                osel = FP_SEL(sp->s_faddr);
        !          101508: 
        !          101509:                /*
        !          101510:                 * Shift segment into the hole.
        !          101511:                 */
        !          101512:                plrcopy( sp->s_paddr, paddr, sp->s_size );
        !          101513:                sp->s_paddr = paddr;
        !          101514:                vremap( sp );
        !          101515: 
        !          101516: #if EBUG > 0
        !          101517:                if ( FP_SEL(sp->s_faddr) != osel ) {
        !          101518:                        printf("krunch: osel=%x nsel=%x\n",
        !          101519:                                osel, FP_SEL(sp->s_faddr) );
        !          101520:                }
        !          101521: #endif
        !          101522: 
        !          101523:                /*
        !          101524:                 * Ensure user segmentation is updated.
        !          101525:                 * We may have moved the current process.
        !          101526:                 */
        !          101527:                if ( (SELF->p_pid != 0) && ((ucs == osel) || (uds == osel)) )
        !          101528:                        segload();
        !          101529:                if ( uasa == osel )
        !          101530:                        uasa = FP_SEL(sp->s_faddr);
        !          101531: 
        !          101532:                /*
        !          101533:                 * Crunch count reached.
        !          101534:                 */
        !          101535:                if ( --n <= 0 )
        !          101536:                        break;
        !          101537:        }
        !          101538: 
        !          101539:        /*
        !          101540:         * Cancel timer if all low memory holes eliminated.
        !          101541:         */
        !          101542:        if ( (KRUNCH == 0) || (sp == &segmq) || (sp->s_flags & SFHIGH) )
        !          101543:                timeout( &tim, 0, NULL, 0 );
        !          101544: 
        !          101545:        /*
        !          101546:         * Attempt to crunch another segment in KRUNCH clock ticks.
        !          101547:         */
        !          101548:        else
        !          101549:                timeout( &tim, KRUNCH, krunch, 1 );
        !          101550: 
        !          101551:        unlock(seglink);
        !          101552: 
        !          101553: #if EBUG > 0
        !          101554:        printf("\n");
        !          101555: #endif
        !          101556: }
        !          101557: @
        !          101558: 
        !          101559: 
        !          101560: 1.1
        !          101561: log
        !          101562: @Initial revision
        !          101563: @
        !          101564: text
        !          101565: @d29 1
        !          101566: a29 1
        !          101567: #include <coherent.h>
        !          101568: @
        !          101569: 0707070064030104601004440000030000030000011777770507310724400005400000004676/newbits/kernel/USRSRC/i8086/src/RCS/ld.c,vhead     1.2;
        !          101570: branch   ;
        !          101571: access   ;
        !          101572: symbols  ;
        !          101573: locks    bin:1.2; strict;
        !          101574: comment  @ * @;
        !          101575: 
        !          101576: 
        !          101577: 1.2
        !          101578: date     91.06.20.14.40.05;  author bin;  state Exp;
        !          101579: branches ;
        !          101580: next     1.1;
        !          101581: 
        !          101582: 1.1
        !          101583: date     91.06.10.10.36.56;  author bin;  state Exp;
        !          101584: branches ;
        !          101585: next     ;
        !          101586: 
        !          101587: 
        !          101588: desc
        !          101589: @initial version prov by hal
        !          101590: @
        !          101591: 
        !          101592: 
        !          101593: 1.2
        !          101594: log
        !          101595: @update provided by hal
        !          101596: @
        !          101597: text
        !          101598: @/* $Header: /usr/src/sys/i8086/src/RCS/ld.c,v 1.1 88/03/24 17:39:36 src Exp $
        !          101599:  *
        !          101600:  *     The  information  contained herein  is a trade secret  of INETCO
        !          101601:  *     Systems, and is confidential information.   It is provided under
        !          101602:  *     a license agreement,  and may be copied or disclosed  only under
        !          101603:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          101604:  *     this  material  without  the express  written  authorization  of
        !          101605:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          101606:  *
        !          101607:  *     Copyright (c) 1986
        !          101608:  *     An unpublished work by INETCO Systems, Ltd.
        !          101609:  *     All rights reserved.
        !          101610:  */
        !          101611: 
        !          101612: /*
        !          101613:  * Pseudo-Device Interface to Loadable Drivers.
        !          101614:  *
        !          101615:  * $Log:       /usr/src/sys/i8086/src/RCS/ld.c,v $
        !          101616:  * Revision 1.1        88/03/24  17:39:36      src
        !          101617:  * Initial revision
        !          101618:  * 
        !          101619:  * 87/12/08    Allan Cornish   /usr/src/sys/i8086/src/ld.c
        !          101620:  * Block device interface added to loadable drivers.
        !          101621:  *
        !          101622:  * 87/10/25    Allan Cornish           /usr/src/sys/i8086/drv/ld.c
        !          101623:  * Initial version.
        !          101624:  */
        !          101625: 
        !          101626: #include       <sys/coherent.h>
        !          101627: #include       <sys/fdisk.h>
        !          101628: #include       <sys/buf.h>
        !          101629: #include       <sys/con.h>
        !          101630: #include       <sys/stat.h>
        !          101631: #include       <sys/uproc.h>
        !          101632: #include       <errno.h>
        !          101633: 
        !          101634: /*
        !          101635:  * Driver configuration.
        !          101636:  */
        !          101637: void   ld_open();
        !          101638: void   ld_close();
        !          101639: void   ld_read();
        !          101640: void   ld_write();
        !          101641: void   ld_block();
        !          101642: int    ld_ioctl();
        !          101643: void   ld_power();
        !          101644: void   ld_time();
        !          101645: int    ld_poll();
        !          101646: void   nulldev();
        !          101647: void   nonedev();
        !          101648: 
        !          101649: /*
        !          101650:  * Loadable driver: Pseudeo-device configuration.
        !          101651:  */
        !          101652: CON ldrvpsy = {
        !          101653:        DFCHR|DFBLK|DFPOL,              /* Flags */
        !          101654:        0,                              /* Major index */
        !          101655:        ld_open,                        /* Open */
        !          101656:        ld_close,                       /* Close */
        !          101657:        ld_block,                       /* Block */
        !          101658:        ld_read,                        /* Read */
        !          101659:        ld_write,                       /* Write */
        !          101660:        ld_ioctl,                       /* Ioctl */
        !          101661:        ld_power,                       /* Powerfail */
        !          101662:        ld_time,                        /* Timeout */
        !          101663:        nulldev,                        /* Load */
        !          101664:        nulldev,                        /* Unload */
        !          101665:        ld_poll                         /* Poll */
        !          101666: };
        !          101667: 
        !          101668: /*
        !          101669:  * Loadable driver: Code selectors.
        !          101670:  */
        !          101671: saddr_t ldrvsel[NDRV];
        !          101672: 
        !          101673: /*
        !          101674:  * Loadable driver: Pointers to driver configuration table.
        !          101675:  */
        !          101676: CON * ldrvcon[NDRV];
        !          101677: 
        !          101678: /*
        !          101679:  * Loadable driver: Selector referencing interrupt handler's code segment.
        !          101680:  */
        !          101681: saddr_t ldrvics[16];
        !          101682: 
        !          101683: /*
        !          101684:  * Loadable driver: Pointers to interrupt handlers within the loadable driver.
        !          101685:  */
        !          101686: void (*ldrvipc[16])();
        !          101687: @
        !          101688: 
        !          101689: 
        !          101690: 1.1
        !          101691: log
        !          101692: @Initial revision
        !          101693: @
        !          101694: text
        !          101695: @d29 1
        !          101696: a29 1
        !          101697: #include       <coherent.h>
        !          101698: @
        !          101699: 0707070064030104571004440000030000030000011777770507310724400005500000013432/newbits/kernel/USRSRC/i8086/src/RCS/md1.c,vhead     1.2;
        !          101700: branch   ;
        !          101701: access   ;
        !          101702: symbols  ;
        !          101703: locks    bin:1.2; strict;
        !          101704: comment  @ * @;
        !          101705: 
        !          101706: 
        !          101707: 1.2
        !          101708: date     91.06.20.14.40.17;  author bin;  state Exp;
        !          101709: branches ;
        !          101710: next     1.1;
        !          101711: 
        !          101712: 1.1
        !          101713: date     91.06.10.10.36.57;  author bin;  state Exp;
        !          101714: branches ;
        !          101715: next     ;
        !          101716: 
        !          101717: 
        !          101718: desc
        !          101719: @initial version prov by hal
        !          101720: @
        !          101721: 
        !          101722: 
        !          101723: 1.2
        !          101724: log
        !          101725: @update provided by hal
        !          101726: @
        !          101727: text
        !          101728: @/* $Header: /usr/src/sys/i8086/src/RCS/md1.c,v 1.2 88/08/05 15:34:26 src Exp $ */
        !          101729: /* (lgl-
        !          101730:  *     The information contained herein is a trade secret of Mark Williams
        !          101731:  *     Company, and  is confidential information.  It is provided  under a
        !          101732:  *     license agreement,  and may be  copied or disclosed  only under the
        !          101733:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          101734:  *     material without the express written authorization of Mark Williams
        !          101735:  *     Company or persuant to the license agreement is unlawful.
        !          101736:  *
        !          101737:  *     COHERENT Version 2.3.37
        !          101738:  *     Copyright (c) 1982, 1983, 1984.
        !          101739:  *     An unpublished work by Mark Williams Company, Chicago.
        !          101740:  *     All rights reserved.
        !          101741:  -lgl) */
        !          101742: /*
        !          101743:  * 8086/8088 Coherent.
        !          101744:  * All machines.
        !          101745:  * Machine dependent stuff.
        !          101746:  *
        !          101747:  * $Log:       /usr/src/sys/i8086/src/RCS/md1.c,v $
        !          101748:  * Revision 1.2        88/08/05  15:34:26      src
        !          101749:  * mproto(), segload(), and msetsys() functions simplified.
        !          101750:  * 
        !          101751:  * Revision 1.1        88/03/24  17:39:43      src
        !          101752:  * Initial revision
        !          101753:  * 
        !          101754:  * 88/03/10    Allan Cornish           /usr/src/sys/coh/proc.c
        !          101755:  * Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !          101756:  * These partial fixes will be removed once all CPU's are replaced.
        !          101757:  *
        !          101758:  * 88/02/13    Allan Cornish           /usr/src/sys/i8086/src/md1.c
        !          101759:  * segload() now checks for regl[OIP] being system code segment.
        !          101760:  * iAPX-286 protected mode interrupt gates enable interrupts momentarily.
        !          101761:  *
        !          101762:  * 88/01/21    Allan Cornish           /usr/src/sys/i8086/src/md1.c
        !          101763:  * Segments are now de-associated from processes before freeing the segment.
        !          101764:  *
        !          101765:  * 87/11/05    Allan Cornish           /usr/src/sys/i8086/src/md1.c
        !          101766:  * New seg struct now used to allow extended addressing.
        !          101767:  *
        !          101768:  * 87/09/21    Allan Cornish   /usr/src/sys/i8086/src/md1.c
        !          101769:  * mproto() and setload() modified to support loadable driver processes.
        !          101770:  */
        !          101771: #include <sys/coherent.h>
        !          101772: #include <sys/i8086.h>
        !          101773: #include <sys/clist.h>
        !          101774: #include <errno.h>
        !          101775: #include <sys/inode.h>
        !          101776: #include <sys/proc.h>
        !          101777: #include <sys/seg.h>
        !          101778: #include <signal.h>
        !          101779: #include <sys/uproc.h>
        !          101780: 
        !          101781: /*
        !          101782:  * Calculate segmentation for a
        !          101783:  * new program. If there is a stack segment
        !          101784:  * present merge it into the data segment and
        !          101785:  * relocate the argument list.
        !          101786:  * Make sure that the changes are reflected in the u.u_segl array
        !          101787:  * which sproto sets up.
        !          101788:  */
        !          101789: mproto()
        !          101790: {
        !          101791:        register PROC   *pp;
        !          101792:        register SEG    *dsp;
        !          101793:        register SEG    *ssp;
        !          101794:        register SEG    *csp;
        !          101795:        fsize_t         ds;
        !          101796:        fsize_t         ss;
        !          101797:        unsigned int    so;
        !          101798:        unsigned int    *up;
        !          101799:        unsigned int    v;
        !          101800: 
        !          101801:        pp = SELF;
        !          101802: 
        !          101803:        dsp = pp->p_segp[SIPDATA];
        !          101804: 
        !          101805:        if ( ((pp->p_flags & PFKERN) == 0)
        !          101806:          && ((ssp=pp->p_segp[SISTACK]) != NULL) ) {
        !          101807:                ds = dsp->s_size;
        !          101808:                ss = ssp->s_size;
        !          101809:                so = ds + ss;
        !          101810:                if (seggrow(dsp, (fsize_t)so) == 0)
        !          101811:                        return (0);
        !          101812:                plrcopy( ssp->s_paddr, dsp->s_paddr + ds, ss);
        !          101813:                pp->p_segp[SISTACK] = NULL;
        !          101814:                sfree(ssp);
        !          101815:                u.u_sproto.mp_svb = ds;
        !          101816:                u.u_sproto.mp_svl = so;
        !          101817:                if (u.u_argp != NULL) {
        !          101818:                        abase(FP_SEL(dsp->s_faddr));
        !          101819:                        up = u.u_argp += so;
        !          101820:                        --up;
        !          101821:                        while (ageti(--up) != NULL)
        !          101822:                                ;
        !          101823:                        up -= 2+u.u_argc;
        !          101824:                        while ((v=ageti(up)) != NULL)
        !          101825:                                aputi(up++, v+so);
        !          101826:                        while ((v=ageti(++up)) != NULL)
        !          101827:                                aputi(up, v+so);
        !          101828:                }
        !          101829:                return (sproto());      /* Recurse to fix u.u_segl */
        !          101830:        }
        !          101831: 
        !          101832:        /*
        !          101833:         * Shared code, private code, or kernel code [csp == NULL].
        !          101834:         * NOTE: Combined code/data no longer supported.
        !          101835:         */
        !          101836:        if ( (csp = pp->p_segp[SISTEXT]) == NULL )
        !          101837:                csp = pp->p_segp[SIPTEXT];
        !          101838: 
        !          101839:        /*
        !          101840:         * Special case if no code/data segment specified.
        !          101841:         */
        !          101842:        u.u_sproto.mp_cbp = (csp != NULL) ? &FP_SEL(csp->s_faddr) : &scs;
        !          101843:        u.u_sproto.mp_dbp = (dsp != NULL) ? &FP_SEL(dsp->s_faddr) : &sds;
        !          101844:        u.u_sproto.mp_csl = (csp != NULL) ? csp->s_size - 1 : 0;
        !          101845:        u.u_sproto.mp_dsl = (dsp != NULL) ? dsp->s_size - 1 : 0;
        !          101846: 
        !          101847:        return (1);
        !          101848: }
        !          101849: 
        !          101850: /*
        !          101851:  * Load up segmentation registers.
        !          101852:  */
        !          101853: segload()
        !          101854: {
        !          101855:        register unsigned *ip;
        !          101856:        register unsigned s;
        !          101857: 
        !          101858:        ucs = *u.u_sproto.mp_cbp;
        !          101859:        uds = *u.u_sproto.mp_dbp;
        !          101860:        ucl =  u.u_sproto.mp_csl;
        !          101861:        udl =  u.u_sproto.mp_dsl;
        !          101862: 
        !          101863:        ip = regl;
        !          101864:        ip[OCS] = ucs;
        !          101865:        ip[ODS] = s = uds;
        !          101866:        ip[OES] = s;
        !          101867:        ip[OSS] = s;
        !          101868: }
        !          101869: 
        !          101870: /*
        !          101871:  * Set up a new process.
        !          101872:  */
        !          101873: msetusr(ip, sp)
        !          101874: vaddr_t sp;
        !          101875: vaddr_t ip;
        !          101876: {
        !          101877:        regl[OIP] = ip;
        !          101878:        regl[OSP] = sp + u.u_sproto.mp_svl;
        !          101879: }
        !          101880: 
        !          101881: /*
        !          101882:  * Set up initial context for a system process.
        !          101883:  * System processes run at depth 1, just like any
        !          101884:  * user process. This is necessary to make sure that
        !          101885:  * the machine state save is correctly handled, just
        !          101886:  * in case the clock hits a kernel process executing
        !          101887:  * out of the IBM ROM.
        !          101888:  */
        !          101889: msetsys(mp, fn, us)
        !          101890: register MCON *mp;
        !          101891: int (*fn)();
        !          101892: saddr_t us;
        !          101893: {
        !          101894:        mp->mc_sp = (int)(&u) + UPASIZE - 32;
        !          101895:        mp->mc_pc = fn;
        !          101896:        mp->mc_fw = 0;
        !          101897:        mp->mc_depth = 1;
        !          101898: }
        !          101899: 
        !          101900: /*
        !          101901:  * Set the given address in the user area to the given value if it is
        !          101902:  * okay to do so.
        !          101903:  */
        !          101904: msetuof(a, v)
        !          101905: register int a;
        !          101906: {
        !          101907:        if (a<UPASIZE+OBP*2 || a>UPASIZE+OFW*2)
        !          101908:                return (0);
        !          101909:        if (a == UPASIZE+OCS*2)
        !          101910:                return (0);
        !          101911:        if (a == UPASIZE+ODS*2)
        !          101912:                return (0);
        !          101913:        if (a == UPASIZE+OES*2)
        !          101914:                return (0);
        !          101915:        if (a == UPASIZE+OSS*2)
        !          101916:                return (0);
        !          101917:        if (a == UPASIZE+OID*2)         /* Protect trap id */
        !          101918:                return (0);
        !          101919:        if (a == UPASIZE+ORA*2)
        !          101920:                return (0);             /* Protect trap return link */
        !          101921:        *((int *)((int)&u+a)) = v;
        !          101922:        return (1);
        !          101923: }
        !          101924: 
        !          101925: /*
        !          101926:  * Cause a signal routine to be executed.
        !          101927:  */
        !          101928: msigint(n, f)
        !          101929: {
        !          101930:        register int *usp;
        !          101931: 
        !          101932:        usp = regl[OSP];
        !          101933:        putuwd(--usp, regl[OFW]);
        !          101934:        putuwd(--usp, regl[OIP]);
        !          101935:        putuwd(--usp, n);
        !          101936:        regl[OFW] &= ~MFTTB;
        !          101937:        regl[OIP] = f;
        !          101938:        regl[OSP] = usp;
        !          101939:        if (n != SIGTRAP)
        !          101940:                u.u_sfunc[n-1] = SIG_DFL;
        !          101941: }
        !          101942: 
        !          101943: /*
        !          101944:  * Cause the next instruction to single step.
        !          101945:  */
        !          101946: msigsin()
        !          101947: {
        !          101948:        regl[OFW] |= MFTTB;
        !          101949: }
        !          101950: 
        !          101951: /*
        !          101952:  * Fix up context.
        !          101953:  */
        !          101954: mfixcon(pp)
        !          101955: PROC *pp;
        !          101956: {
        !          101957: }
        !          101958: 
        !          101959: /*
        !          101960:  * Idle kernel process.
        !          101961:  */
        !          101962: idle()
        !          101963: {
        !          101964:        for (;;) {
        !          101965:                disflag = 1;
        !          101966:                _idle();
        !          101967:        }
        !          101968: }
        !          101969: @
        !          101970: 
        !          101971: 
        !          101972: 1.1
        !          101973: log
        !          101974: @Initial revision
        !          101975: @
        !          101976: text
        !          101977: @d44 3
        !          101978: a46 3
        !          101979: #include <coherent.h>
        !          101980: #include <i8086.h>
        !          101981: #include <clist.h>
        !          101982: @
        !          101983: 0707070064030104561004440000030000030000011777770507310724600005700000010120/newbits/kernel/USRSRC/i8086/src/RCS/mmain.c,vhead     1.2;
        !          101984: branch   ;
        !          101985: access   ;
        !          101986: symbols  ;
        !          101987: locks    bin:1.2; strict;
        !          101988: comment  @ * @;
        !          101989: 
        !          101990: 
        !          101991: 1.2
        !          101992: date     91.06.20.14.40.23;  author bin;  state Exp;
        !          101993: branches ;
        !          101994: next     1.1;
        !          101995: 
        !          101996: 1.1
        !          101997: date     91.06.10.10.36.58;  author bin;  state Exp;
        !          101998: branches ;
        !          101999: next     ;
        !          102000: 
        !          102001: 
        !          102002: desc
        !          102003: @initial version prov by hal
        !          102004: @
        !          102005: 
        !          102006: 
        !          102007: 1.2
        !          102008: log
        !          102009: @update provided by hal
        !          102010: @
        !          102011: text
        !          102012: @/* $Header: /usr/src/sys/i8086/src/RCS/mmain.c,v 1.2 88/08/05 15:43:42 src Exp $ */
        !          102013: /* (lgl-
        !          102014:  *     The information contained herein is a trade secret of Mark Williams
        !          102015:  *     Company, and  is confidential information.  It is provided  under a
        !          102016:  *     license agreement,  and may be  copied or disclosed  only under the
        !          102017:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          102018:  *     material without the express written authorization of Mark Williams
        !          102019:  *     Company or persuant to the license agreement is unlawful.
        !          102020:  *
        !          102021:  *     COHERENT Version 2.3.37
        !          102022:  *     Copyright (c) 1982, 1983, 1984.
        !          102023:  *     An unpublished work by Mark Williams Company, Chicago.
        !          102024:  *     All rights reserved.
        !          102025:  -lgl) */
        !          102026: /*
        !          102027:  * 8086/8088 Coherent.
        !          102028:  * All machines.
        !          102029:  * Machine dependent stuff.
        !          102030:  *
        !          102031:  * $Log:       /usr/src/sys/i8086/src/RCS/mmain.c,v $
        !          102032:  * Revision 1.2        88/08/05  15:43:42      src
        !          102033:  * Bug:        Spawning large number of processes would cause system to crash.
        !          102034:  * Fix:        Kernel alloc space no longer overlaps loadable driver data.
        !          102035:  * 
        !          102036:  * Revision 1.1        88/03/24  17:39:46      src
        !          102037:  * Initial revision
        !          102038:  * 
        !          102039:  * 88/02/24    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          102040:  * corebot is now aligned on a 512 byte boundary.
        !          102041:  *
        !          102042:  * 87/11/30    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          102043:  * Check for kernel data space > 64 Kbytes now done AFTER rounding up.
        !          102044:  *
        !          102045:  * 87/11/21    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          102046:  * Use of bruc/ctob macros eliminated since no longer valid in protected mode.
        !          102047:  *
        !          102048:  * 87/11/14    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          102049:  * Init code+data now split into icodep/icodes and idatap/idatas.
        !          102050:  *
        !          102051:  * 87/11/12    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          102052:  * Corebot/coretop now paddr_t rather than saddr_t to support protected mode.
        !          102053:  *
        !          102054:  * 87/10/05    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          102055:  * Loadable driver data slot allocation added.
        !          102056:  *
        !          102057:  * 87/05/08    Allan Cornish           /usr/src/sys/i8086/src/mmain.c
        !          102058:  * Ctob(sds) is now cast as ctob((paddr_t)sds) to avoid address truncation.
        !          102059:  *
        !          102060:  * 86/07/23    Allan Cornish
        !          102061:  * Added check for kernel data space exceeding 64 Kbytes.
        !          102062:  */
        !          102063: #include <sys/coherent.h>
        !          102064: #include <sys/i8086.h>
        !          102065: #include <sys/clist.h>
        !          102066: #include <errno.h>
        !          102067: #include <sys/inode.h>
        !          102068: #include <sys/proc.h>
        !          102069: #include <sys/seg.h>
        !          102070: #include <signal.h>
        !          102071: #include <sys/uproc.h>
        !          102072: #include <sys/buf.h>
        !          102073: 
        !          102074: saddr_t uasa;  /* Currently active uarea */
        !          102075: 
        !          102076: /*
        !          102077:  * General initialisation.
        !          102078:  */
        !          102079: i8086()
        !          102080: {
        !          102081:        register unsigned allocp;
        !          102082:        extern vaddr_t  aicodep;
        !          102083:        extern vaddr_t  aicodes;
        !          102084:        extern vaddr_t  aidatap;
        !          102085:        extern vaddr_t  aidatas;
        !          102086:        extern vaddr_t  etext;
        !          102087:        extern vaddr_t  end;
        !          102088:        auto faddr_t    fp;
        !          102089:        long datsize;
        !          102090:        unsigned bsize, csize, isize, ssize;
        !          102091: 
        !          102092:        /*
        !          102093:         * Set up memory bases.
        !          102094:         * Align the buffers modulo BSIZE (512) in the physical space,
        !          102095:         * so that any machines that have only 16 bit DMA counters will
        !          102096:         * work out.
        !          102097:         */
        !          102098:        datsize = (long)&end;
        !          102099:        datsize += ALLSIZE;
        !          102100:        datsize += NBUF * sizeof(BUF);
        !          102101:        datsize += ssize = NSLOT*(sizeof(int) + slotsz);
        !          102102:        datsize += isize = NINODE*sizeof(INODE);
        !          102103:        datsize += csize = NCLIST*sizeof(CLIST);
        !          102104:        datsize += bsize = NBUF*BSIZE;
        !          102105:        datsize = (datsize + 511) & ~511;
        !          102106:        if ( datsize >= 0x10000L )
        !          102107:                panic("Kernel data exceeds 64 Kbytes");
        !          102108: 
        !          102109:        blockp  = datsize - bsize - ((sds&0x1F)<<4);
        !          102110:        clistp  = (unsigned)blockp - csize;
        !          102111:        inodep  = (unsigned)clistp - isize;
        !          102112:        slotp   = (unsigned)inodep - ssize;
        !          102113:        allocp = &end;
        !          102114:        blockp += (sds << 4L);
        !          102115:        if ((unsigned)allocp > (unsigned)slotp)
        !          102116:                panic("No alloc space");
        !          102117:        corebot = ((sds << 4L) + datsize + 511) & ~511;
        !          102118:        asize = (unsigned)slotp - allocp;
        !          102119:        msize = (coretop-holetop+holebot-corebot) / 1024;
        !          102120:        allkp = setarena(allocp, asize);
        !          102121:        icodep = (char *)&aicodep;
        !          102122:        icodes = (int)&aicodes;
        !          102123:        idatap = (char *)&aidatap;
        !          102124:        idatas = (int)&aidatas;
        !          102125:        fp = ptov( corebot, (fsize_t) UPASIZE );
        !          102126:        uasa   = FP_SEL(fp);
        !          102127: }
        !          102128: 
        !          102129: @
        !          102130: 
        !          102131: 
        !          102132: 1.1
        !          102133: log
        !          102134: @Initial revision
        !          102135: @
        !          102136: text
        !          102137: @d52 3
        !          102138: a54 3
        !          102139: #include <coherent.h>
        !          102140: #include <i8086.h>
        !          102141: #include <clist.h>
        !          102142: d57 1
        !          102143: a57 1
        !          102144: #include <proc.h>
        !          102145: @
        !          102146: 0707070064030104551004440000030000030000011777770507310724700005500000012700/newbits/kernel/USRSRC/i8086/src/RCS/tab.c,vhead     1.2;
        !          102147: branch   ;
        !          102148: access   ;
        !          102149: symbols  ;
        !          102150: locks    bin:1.2; strict;
        !          102151: comment  @ * @;
        !          102152: 
        !          102153: 
        !          102154: 1.2
        !          102155: date     91.06.20.14.40.29;  author bin;  state Exp;
        !          102156: branches ;
        !          102157: next     1.1;
        !          102158: 
        !          102159: 1.1
        !          102160: date     91.06.10.10.37.00;  author bin;  state Exp;
        !          102161: branches ;
        !          102162: next     ;
        !          102163: 
        !          102164: 
        !          102165: desc
        !          102166: @initial version prov by hal
        !          102167: @
        !          102168: 
        !          102169: 
        !          102170: 1.2
        !          102171: log
        !          102172: @update provided by hal
        !          102173: @
        !          102174: text
        !          102175: @/* $Header: /usr/src/sys/i8086/src/RCS/tab.c,v 1.1 88/03/24 17:39:50 src Exp $ */
        !          102176: /* (lgl-
        !          102177:  *     The information contained herein is a trade secret of Mark Williams
        !          102178:  *     Company, and  is confidential information.  It is provided  under a
        !          102179:  *     license agreement,  and may be  copied or disclosed  only under the
        !          102180:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          102181:  *     material without the express written authorization of Mark Williams
        !          102182:  *     Company or persuant to the license agreement is unlawful.
        !          102183:  *
        !          102184:  *     COHERENT Version 2.3.37
        !          102185:  *     Copyright (c) 1982, 1983, 1984.
        !          102186:  *     An unpublished work by Mark Williams Company, Chicago.
        !          102187:  *     All rights reserved.
        !          102188:  -lgl) */
        !          102189: /*
        !          102190:  * Coherent.
        !          102191:  * Tables for the Intel 8086.
        !          102192:  *
        !          102193:  * $Log:       /usr/src/sys/i8086/src/RCS/tab.c,v $
        !          102194:  * Revision 1.1        88/03/24  17:39:50      src
        !          102195:  * Initial revision
        !          102196:  * 
        !          102197:  * 87/08/14    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          102198:  * Added tick() as system call 73.
        !          102199:  *
        !          102200:  * 87/07/08    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          102201:  * Added alarm2() as system call 72.
        !          102202:  *
        !          102203:  * 86/11/21    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          102204:  * Added msgctl(), msgget(), msgrcv(), msgsnd() as system calls 68 to 71.
        !          102205:  *
        !          102206:  * 86/11/19    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          102207:  * Added fcntl() and poll() as system calls 66 and 67.
        !          102208:  *
        !          102209:  * 85/07/09    Allan Cornish
        !          102210:  * Added getpgrp() as system call 63.
        !          102211:  */
        !          102212: #include <sys/coherent.h>
        !          102213: #include <sys/i8086.h>
        !          102214: #include <sys/systab.h>
        !          102215: 
        !          102216: /*
        !          102217:  * System call functions.
        !          102218:  */
        !          102219: int    unone();
        !          102220: int    unull();
        !          102221: int    uexit();
        !          102222: int    ufork();
        !          102223: int    uread();
        !          102224: int    uwrite();
        !          102225: int    uopen();
        !          102226: int    uclose();
        !          102227: int    uwait();
        !          102228: int    ucreat();
        !          102229: int    ulink();
        !          102230: int    uunlink();
        !          102231: int    uexece();
        !          102232: int    uchdir();
        !          102233: int    umknod();
        !          102234: int    uchmod();
        !          102235: int    uchown();
        !          102236: char   *ubrk();
        !          102237: int    ustat();
        !          102238: long   ulseek();
        !          102239: int    ugetpid();
        !          102240: int    umount();
        !          102241: int    uumount();
        !          102242: int    usetuid();
        !          102243: int    ugetuid();
        !          102244: int    ustime();
        !          102245: int    uptrace();
        !          102246: int    ualarm();
        !          102247: int    ufstat();
        !          102248: int    upause();
        !          102249: int    uutime();
        !          102250: int    ustty();
        !          102251: int    ugtty();
        !          102252: int    uaccess();
        !          102253: int    unice();
        !          102254: int    uftime();
        !          102255: int    uftime();
        !          102256: int    usync();
        !          102257: int    ukill();
        !          102258: int    udup();
        !          102259: int    upipe();
        !          102260: int    utimes();
        !          102261: int    uprofil();
        !          102262: long   uunique();
        !          102263: int    usetgid();
        !          102264: int    ugetgid();
        !          102265: int    (*usignal())();
        !          102266: int    usload();
        !          102267: int    usuload();
        !          102268: int    uacct();
        !          102269: int    ulock();
        !          102270: int    uioctl();
        !          102271: int    ugetegid();
        !          102272: int    uumask();
        !          102273: int    uchroot();
        !          102274: int    usetpgrp();
        !          102275: int    ugetpgrp();
        !          102276: int    ugeteuid();
        !          102277: int    ufcntl();
        !          102278: int    upoll();
        !          102279: long   ualarm2();
        !          102280: long   utick();
        !          102281: 
        !          102282: /*
        !          102283:  * System call table.
        !          102284:  */
        !          102285: struct systab sysitab[NMICALL] ={
        !          102286:        0,  INT,        unone,                  /*  0 = ??? */
        !          102287:        2,  INT,        uexit,                  /*  1 = exit */
        !          102288:        0,  INT,        ufork,                  /*  2 = fork */
        !          102289:        6,  INT,        uread,                  /*  3 = read */
        !          102290:        6,  INT,        uwrite,                 /*  4 = write */
        !          102291:        4,  INT,        uopen,                  /*  5 = open */
        !          102292:        2,  INT,        uclose,                 /*  6 = close */
        !          102293:        2,  INT,        uwait,                  /*  7 = wait */
        !          102294:        4,  INT,        ucreat,                 /*  8 = creat */
        !          102295:        4,  INT,        ulink,                  /*  9 = link */
        !          102296:        2,  INT,        uunlink,                /* 10 = unlink */
        !          102297:        6,  INT,        uexece,                 /* 11 = exec */
        !          102298:        2,  INT,        uchdir,                 /* 12 = chdir */
        !          102299:        0,  INT,        unone,                  /* 13 = ??? */
        !          102300:        6,  INT,        umknod,                 /* 14 = mknod */
        !          102301:        4,  INT,        uchmod,                 /* 15 = chmod */
        !          102302:        6,  INT,        uchown,                 /* 16 = chown */
        !          102303:        2,  INT,        ubrk,                   /* 17 = break */
        !          102304:        4,  INT,        ustat,                  /* 18 = stat */
        !          102305:        8,  LONG,       ulseek,                 /* 19 = lseek */
        !          102306:        0,  INT,        ugetpid,                /* 20 = getpid */
        !          102307:        6,  INT,        umount,                 /* 21 = mount */
        !          102308:        2,  INT,        uumount,                /* 22 = umount */
        !          102309:        2,  INT,        usetuid,                /* 23 = setuid */
        !          102310:        0,  INT,        ugetuid,                /* 24 = getuid */
        !          102311:        2,  INT,        ustime,                 /* 25 = stime */
        !          102312:        8,  INT,        uptrace,                /* 26 = ptrace */
        !          102313:        2,  INT,        ualarm,                 /* 27 = alarm */
        !          102314:        4,  INT,        ufstat,                 /* 28 = fstat */
        !          102315:        0,  INT,        upause,                 /* 29 = pause */
        !          102316:        4,  INT,        uutime,                 /* 30 = utime */
        !          102317:        0,  INT,        unone,                  /* 31 = ??? */
        !          102318:        0,  INT,        unone,                  /* 32 = ??? */
        !          102319:        4,  INT,        uaccess,                /* 33 = access */
        !          102320:        2,  INT,        unice,                  /* 34 = nice */
        !          102321:        2,  INT,        uftime,                 /* 35 = ftime */
        !          102322:        0,  INT,        usync,                  /* 36 = sync */
        !          102323:        4,  INT,        ukill,                  /* 37 = kill */
        !          102324:        0,  INT,        unone,                  /* 38 = ??? */
        !          102325:        0,  INT,        unone,                  /* 39 = ??? */
        !          102326:        0,  INT,        unone,                  /* 40 = ??? */
        !          102327:        4,  INT,        udup,                   /* 41 = dup */
        !          102328:        2,  INT,        upipe,                  /* 42 = pipe */
        !          102329:        2,  INT,        utimes,                 /* 43 = times */
        !          102330:        8,  INT,        uprofil,                /* 44 = profil */
        !          102331:        0,  LONG,       uunique,                /* 45 = unique */
        !          102332:        2,  INT,        usetgid,                /* 46 = setgid */
        !          102333:        0,  INT,        ugetgid,                /* 47 = getgid */
        !          102334:        4,  INT,        usignal,                /* 48 = signal */
        !          102335:        0,  INT,        unone,                  /* 49 = ??? */
        !          102336:        0,  INT,        unone,                  /* 50 = ??? */
        !          102337:        2,  INT,        uacct,                  /* 51 = acct */
        !          102338:        0,  INT,        unull,                  /* 52 = ??? (phys) */
        !          102339:        0,  INT,        ulock,                  /* 53 = lock */
        !          102340:        6,  INT,        uioctl,                 /* 54 = ioctl */
        !          102341:        0,  INT,        unone,                  /* 55 = ??? (mpx) */
        !          102342:        0,  INT,        ugetegid,               /* 56 = getegid */
        !          102343:        0,  INT,        ugeteuid,               /* 57 = geteuid */
        !          102344:        0,  INT,        unone,                  /* 58 = ??? */
        !          102345:        0,  INT,        unone,                  /* 59 = ??? */
        !          102346:        2,  INT,        uumask,                 /* 60 = umask */
        !          102347:        2,  INT,        uchroot,                /* 61 = chroot */
        !          102348:        0,  INT,        usetpgrp,               /* 62 = setpgrp */
        !          102349:        0,  INT,        ugetpgrp,               /* 63 = getpgrp */
        !          102350:        2,  INT,        usload,                 /* 64 = sload */
        !          102351:        2,  INT,        usuload,                /* 65 = suload */
        !          102352:        6,  INT,        ufcntl,                 /* 66 = fcntl */
        !          102353:        8,  INT,        upoll,                  /* 67 = poll */
        !          102354:        0,  INT,        unone,                  /* 68 (was 6, msgctl) */
        !          102355:        0,  INT,        unone,                  /* 69 (was 6, msgget) */
        !          102356:        0,  INT,        unone,                  /* 70 (was 12, msgrcv) */
        !          102357:        0,  INT,        unone,                  /* 71 (was 8, msgsnd) */
        !          102358:        4,  LONG,       ualarm2,                /* 72 = alarm2 */
        !          102359:        0,  LONG,       utick                   /* 73 = tick  */
        !          102360: };
        !          102361: @
        !          102362: 
        !          102363: 
        !          102364: 1.1
        !          102365: log
        !          102366: @Initial revision
        !          102367: @
        !          102368: text
        !          102369: @d38 3
        !          102370: a40 3
        !          102371: #include <coherent.h>
        !          102372: #include <i8086.h>
        !          102373: #include <systab.h>
        !          102374: @
        !          102375: 0707070064030104541004440000030000030000011777770507310725100005600000013351/newbits/kernel/USRSRC/i8086/src/RCS/trap.c,vhead     1.2;
        !          102376: branch   ;
        !          102377: access   ;
        !          102378: symbols  ;
        !          102379: locks    bin:1.2; strict;
        !          102380: comment  @ * @;
        !          102381: 
        !          102382: 
        !          102383: 1.2
        !          102384: date     91.06.20.14.40.35;  author bin;  state Exp;
        !          102385: branches ;
        !          102386: next     1.1;
        !          102387: 
        !          102388: 1.1
        !          102389: date     91.06.10.10.37.02;  author bin;  state Exp;
        !          102390: branches ;
        !          102391: next     ;
        !          102392: 
        !          102393: 
        !          102394: desc
        !          102395: @initial version prov by hal
        !          102396: @
        !          102397: 
        !          102398: 
        !          102399: 1.2
        !          102400: log
        !          102401: @update provided by hal
        !          102402: @
        !          102403: text
        !          102404: @/* $Header: /usr/src/sys/i8086/src/RCS/trap.c,v 1.1 88/03/24 17:39:53 src Exp $ */
        !          102405: /* (lgl-
        !          102406:  *     The information contained herein is a trade secret of Mark Williams
        !          102407:  *     Company, and  is confidential information.  It is provided  under a
        !          102408:  *     license agreement,  and may be  copied or disclosed  only under the
        !          102409:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          102410:  *     material without the express written authorization of Mark Williams
        !          102411:  *     Company or persuant to the license agreement is unlawful.
        !          102412:  *
        !          102413:  *     COHERENT Version 2.3.37
        !          102414:  *     Copyright (c) 1982, 1983, 1984.
        !          102415:  *     An unpublished work by Mark Williams Company, Chicago.
        !          102416:  *     All rights reserved.
        !          102417:  -lgl) */
        !          102418: /*
        !          102419:  * Trap handler.
        !          102420:  * 8086/8088 Coherent, IBM PC.
        !          102421:  *
        !          102422:  * $Log:       /usr/src/sys/i8086/src/RCS/trap.c,v $
        !          102423:  * Revision 1.1        88/03/24  17:39:53      src
        !          102424:  * Initial revision
        !          102425:  * 
        !          102426:  * 88/03/06    Allan Cornish           /usr/src/sys/i8086/src/trap.c
        !          102427:  * Exception diagnostistics extended.
        !          102428:  *
        !          102429:  * 87/11/02    Allan Cornish           /usr/src/sys/i8086/src/trap.c
        !          102430:  * iAPX 286 exception traps added.
        !          102431:  */
        !          102432: #include <sys/coherent.h>
        !          102433: #include <sys/i8086.h>
        !          102434: #include <sys/systab.h>
        !          102435: #include <errno.h>
        !          102436: #include <sys/proc.h>
        !          102437: #include <sys/seg.h>
        !          102438: #include <signal.h>
        !          102439: #include <sys/uproc.h>
        !          102440: 
        !          102441: #ifndef        EBUG
        !          102442: #define        EBUG 1
        !          102443: #endif
        !          102444: 
        !          102445: /*
        !          102446:  * Trap handler.
        !          102447:  * The arguments are the registers,
        !          102448:  * saved on the stack by machine code. This call
        !          102449:  * is different from most C calls in that the registers
        !          102450:  * get copied back; if you change a "trap" parameter then
        !          102451:  * the machine register will be altered when the trap is
        !          102452:  * dismissed.
        !          102453:  */
        !          102454: trap(es, cx, dx, ax, bx, ds, usp, uss, id, ip, cs, fw)
        !          102455: unsigned es, cx, dx, ax, bx, ds, usp, uss, id, ip, cs, fw;
        !          102456: {
        !          102457:        register struct systab  *stp;
        !          102458:        register int    syscall;
        !          102459:        register int    callnum;
        !          102460:        register int    sigcode;
        !          102461:        long            l;
        !          102462: 
        !          102463:        if ( (id >> 8) == SINMI )
        !          102464:                panic( "Parity error: cs=%x ip=%x\n", cs, ip );
        !          102465: 
        !          102466:        if (depth != 0) {
        !          102467: #if EBUG > 0
        !          102468:                faddr_t fp;
        !          102469:                FP_SEL(fp) = ax;  printf("ax "); vprint(fp);
        !          102470:                FP_SEL(fp) = cs;  printf("cs "); vprint(fp);
        !          102471:                FP_SEL(fp) = ds;  printf("ds "); vprint(fp);
        !          102472:                FP_SEL(fp) = es;  printf("es "); vprint(fp);
        !          102473:                FP_SEL(fp) = uss; printf("ss "); vprint(fp);
        !          102474: #endif
        !          102475:                panic("system trap: id=%x ip=%x ax=%x", id, ip, ax);
        !          102476:        }
        !          102477: 
        !          102478:        if ((SELF->p_flags&PFKERN) != 0) {
        !          102479: #if EBUG > 0
        !          102480:                faddr_t fp;
        !          102481:                FP_SEL(fp) = ax;  printf("ax "); vprint(fp);
        !          102482:                FP_SEL(fp) = cs;  printf("cs "); vprint(fp);
        !          102483:                FP_SEL(fp) = ds;  printf("ds "); vprint(fp);
        !          102484:                FP_SEL(fp) = es;  printf("es "); vprint(fp);
        !          102485:                FP_SEL(fp) = uss; printf("ss "); vprint(fp);
        !          102486: #endif
        !          102487:                panic("pid%d: kernel process trap: id=%x, ip=%x ax=%d",
        !          102488:                        SELF->p_pid, id, ip, ax);
        !          102489:        }
        !          102490: 
        !          102491:        /*
        !          102492:         * System call.
        !          102493:         */
        !          102494:        if ( (id >> 8) == SISYS ) {
        !          102495:                u.u_error = 0;
        !          102496:                sigcode = 0;
        !          102497:                syscall = getuwi(ip-2);
        !          102498:                if (u.u_error != 0 || (syscall&0xFF) != 0xCD) {
        !          102499:                        sigcode = SIGSYS;
        !          102500:                        goto trapend;
        !          102501:                }
        !          102502:                callnum = (syscall>>8) & 0x7F;
        !          102503:                if (callnum >= NMICALL) {
        !          102504:                        sigcode = SIGSYS;
        !          102505:                        goto trapend;
        !          102506:                }
        !          102507:                stp = &sysitab[callnum];
        !          102508:                ukcopy(usp+2, u.u_args, stp->s_alen);
        !          102509:                if (u.u_error != 0) {
        !          102510:                        sigcode = SIGSYS;
        !          102511:                        goto trapend;
        !          102512:                }
        !          102513:                u.u_io.io_seg = IOUSR;
        !          102514:                if (envsave(&u.u_sigenv) != 0)
        !          102515:                        u.u_error = EINTR;
        !          102516:                else if ( stp->s_alen <= (3 * sizeof(int)) ) {
        !          102517:                        l = (*(long(*)())stp->s_func)(u.u_args[0],
        !          102518:                                                      u.u_args[1],
        !          102519:                                                      u.u_args[2] );
        !          102520:                        ax = ((struct l *) &l)->l_lo;
        !          102521:                        dx = ((struct l *) &l)->l_hi;
        !          102522:                }
        !          102523:                else {
        !          102524:                        l = (*(long(*)())stp->s_func)(u.u_args[0],
        !          102525:                                                      u.u_args[1],
        !          102526:                                                      u.u_args[2],
        !          102527:                                                      u.u_args[3],
        !          102528:                                                      u.u_args[4],
        !          102529:                                                      u.u_args[5]);
        !          102530:                        ax = ((struct l *) &l)->l_lo;
        !          102531:                        dx = ((struct l *) &l)->l_hi;
        !          102532:                }
        !          102533:                if (u.u_error != 0) {
        !          102534:                        ax = -1;
        !          102535:                        dx = -1;
        !          102536:                        putuwd(MUERR, u.u_error);
        !          102537:                        if (u.u_error == EFAULT)
        !          102538:                                sigcode = SIGSYS;
        !          102539:                }
        !          102540:        }
        !          102541: 
        !          102542:        /*
        !          102543:         * Trap.
        !          102544:         */
        !          102545:        else switch (id>>8) {
        !          102546: 
        !          102547:        case SIDIV:
        !          102548:                sigcode = SIGDIVE;
        !          102549:                break;
        !          102550: 
        !          102551:        case SISST:
        !          102552:                sigcode = SIGTRAP;
        !          102553:                break;
        !          102554: 
        !          102555:        case SIBPT:
        !          102556:                sigcode = SIGTRAP;
        !          102557:                break;
        !          102558: 
        !          102559:        case SIOVF:
        !          102560:                sigcode = SIGOVFL;
        !          102561:                break;
        !          102562: 
        !          102563:        case SIBND:
        !          102564:                /*
        !          102565:                 * Bound
        !          102566:                 */
        !          102567:                sigcode = SIGOVFL;
        !          102568:                break;
        !          102569: 
        !          102570:        case SIOP:
        !          102571:                /*
        !          102572:                 * Invalid opcode
        !          102573:                 */
        !          102574:                sigcode = SIGSEGV;
        !          102575:                break;
        !          102576: 
        !          102577:        case SIXNP:
        !          102578:                /*
        !          102579:                 * Processor extension not available
        !          102580:                 */
        !          102581:                sigcode = SIGSEGV;
        !          102582:                break;
        !          102583: 
        !          102584:        case SIDBL:
        !          102585:                /*
        !          102586:                 * Double exception
        !          102587:                 */
        !          102588:                panic("double exception: cs=%x ip=%x", cs, ip);
        !          102589:                sigcode = SIGSEGV;
        !          102590:                break;
        !          102591: 
        !          102592:        case SIXS:
        !          102593:                /*
        !          102594:                 * Processor extension segment overrun
        !          102595:                 */
        !          102596:                sigcode = SIGSEGV;
        !          102597:                break;
        !          102598: 
        !          102599:        case SITS:
        !          102600:                /*
        !          102601:                 * Invalid task state segment
        !          102602:                 */
        !          102603:                panic("invalid tss: cs=%x ip=%x", cs, ip);
        !          102604:                sigcode = SIGSEGV;
        !          102605:                break;
        !          102606: 
        !          102607:        case SINP:
        !          102608:                /*
        !          102609:                 * Segment not present
        !          102610:                 */
        !          102611:                sigcode = SIGSEGV;
        !          102612:                break;
        !          102613: 
        !          102614:        case SISS:
        !          102615:                /*
        !          102616:                 * Stack segment overrun/not present
        !          102617:                 */
        !          102618:                sigcode = SIGKILL;
        !          102619:                break;
        !          102620: 
        !          102621:        case SIGP:
        !          102622:                /*
        !          102623:                 * General protection.
        !          102624:                 */
        !          102625:                sigcode = SIGSEGV;
        !          102626:                break;
        !          102627: 
        !          102628:        default:
        !          102629:                panic("user trap: id=%x ip=%x\n", id, ip );
        !          102630:        }
        !          102631: 
        !          102632: trapend:
        !          102633:        if ( sigcode != 0 ) {
        !          102634:                if ( sigcode == SIGSEGV ) {
        !          102635: #if EBUG > 0
        !          102636:                        faddr_t fp;
        !          102637:                        FP_SEL(fp) = ax;  printf("\tax "); vprint(fp);
        !          102638:                        FP_SEL(fp) = cs;  printf("\tcs "); vprint(fp);
        !          102639:                        FP_SEL(fp) = ds;  printf("\tds "); vprint(fp);
        !          102640:                        FP_SEL(fp) = es;  printf("\tes "); vprint(fp);
        !          102641:                        FP_SEL(fp) = uss; printf("\tss "); vprint(fp);
        !          102642:                        printf("user trap: SEGV id=%x ax=%x pid=%d\n",
        !          102643:                                id, ax, SELF->p_pid );
        !          102644:                        printf("\tip=%x sp=%x\n", ip, usp );
        !          102645: 
        !          102646:                        /*
        !          102647:                         * Force core dump.
        !          102648:                         */
        !          102649:                        u.u_sfunc[SIGSEGV] = SIG_DFL;
        !          102650: #endif
        !          102651:                }
        !          102652:                sendsig(sigcode, SELF);
        !          102653:        }
        !          102654: }
        !          102655: @
        !          102656: 
        !          102657: 
        !          102658: 1.1
        !          102659: log
        !          102660: @Initial revision
        !          102661: @
        !          102662: text
        !          102663: @d29 3
        !          102664: a31 3
        !          102665: #include <coherent.h>
        !          102666: #include <i8086.h>
        !          102667: #include <systab.h>
        !          102668: d33 1
        !          102669: a33 1
        !          102670: #include <proc.h>
        !          102671: @
        !          102672: 0707070064030104521004440000030000030000011777770507310725200006100000012415/newbits/kernel/USRSRC/i8086/src/RCS/tab.c.310,vhead     1.1;
        !          102673: branch   ;
        !          102674: access   ;
        !          102675: symbols  ;
        !          102676: locks    bin:1.1; strict;
        !          102677: comment  @@;
        !          102678: 
        !          102679: 
        !          102680: 1.1
        !          102681: date     91.06.10.10.37.04;  author bin;  state Exp;
        !          102682: branches ;
        !          102683: next     ;
        !          102684: 
        !          102685: 
        !          102686: desc
        !          102687: @initial version prov by hal
        !          102688: @
        !          102689: 
        !          102690: 
        !          102691: 
        !          102692: 1.1
        !          102693: log
        !          102694: @Initial revision
        !          102695: @
        !          102696: text
        !          102697: @/* $Header: /usr/src/sys/i8086/src/RCS/tab.c,v 1.1 88/03/24 17:39:50 src Exp $ */
        !          102698: /* (lgl-
        !          102699:  *     The information contained herein is a trade secret of Mark Williams
        !          102700:  *     Company, and  is confidential information.  It is provided  under a
        !          102701:  *     license agreement,  and may be  copied or disclosed  only under the
        !          102702:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          102703:  *     material without the express written authorization of Mark Williams
        !          102704:  *     Company or persuant to the license agreement is unlawful.
        !          102705:  *
        !          102706:  *     COHERENT Version 2.3.37
        !          102707:  *     Copyright (c) 1982, 1983, 1984.
        !          102708:  *     An unpublished work by Mark Williams Company, Chicago.
        !          102709:  *     All rights reserved.
        !          102710:  -lgl) */
        !          102711: /*
        !          102712:  * Coherent.
        !          102713:  * Tables for the Intel 8086.
        !          102714:  *
        !          102715:  * $Log:       /usr/src/sys/i8086/src/RCS/tab.c,v $
        !          102716:  * Revision 1.1        88/03/24  17:39:50      src
        !          102717:  * Initial revision
        !          102718:  * 
        !          102719:  * 87/08/14    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          102720:  * Added tick() as system call 73.
        !          102721:  *
        !          102722:  * 87/07/08    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          102723:  * Added alarm2() as system call 72.
        !          102724:  *
        !          102725:  * 86/11/21    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          102726:  * Added msgctl(), msgget(), msgrcv(), msgsnd() as system calls 68 to 71.
        !          102727:  *
        !          102728:  * 86/11/19    Allan Cornish           /usr/src/sys/i8086/src/tab.c
        !          102729:  * Added fcntl() and poll() as system calls 66 and 67.
        !          102730:  *
        !          102731:  * 85/07/09    Allan Cornish
        !          102732:  * Added getpgrp() as system call 63.
        !          102733:  */
        !          102734: #include <coherent.h>
        !          102735: #include <i8086.h>
        !          102736: #include <systab.h>
        !          102737: 
        !          102738: /*
        !          102739:  * System call functions.
        !          102740:  */
        !          102741: int    unone();
        !          102742: int    unull();
        !          102743: int    uexit();
        !          102744: int    ufork();
        !          102745: int    uread();
        !          102746: int    uwrite();
        !          102747: int    uopen();
        !          102748: int    uclose();
        !          102749: int    uwait();
        !          102750: int    ucreat();
        !          102751: int    ulink();
        !          102752: int    uunlink();
        !          102753: int    uexece();
        !          102754: int    uchdir();
        !          102755: int    umknod();
        !          102756: int    uchmod();
        !          102757: int    uchown();
        !          102758: char   *ubrk();
        !          102759: int    ustat();
        !          102760: long   ulseek();
        !          102761: int    ugetpid();
        !          102762: int    umount();
        !          102763: int    uumount();
        !          102764: int    usetuid();
        !          102765: int    ugetuid();
        !          102766: int    ustime();
        !          102767: int    uptrace();
        !          102768: int    ualarm();
        !          102769: int    ufstat();
        !          102770: int    upause();
        !          102771: int    uutime();
        !          102772: int    ustty();
        !          102773: int    ugtty();
        !          102774: int    uaccess();
        !          102775: int    unice();
        !          102776: int    uftime();
        !          102777: int    uftime();
        !          102778: int    usync();
        !          102779: int    ukill();
        !          102780: int    udup();
        !          102781: int    upipe();
        !          102782: int    utimes();
        !          102783: int    uprofil();
        !          102784: long   uunique();
        !          102785: int    usetgid();
        !          102786: int    ugetgid();
        !          102787: int    (*usignal())();
        !          102788: int    usload();
        !          102789: int    usuload();
        !          102790: int    uacct();
        !          102791: int    ulock();
        !          102792: int    uioctl();
        !          102793: int    ugetegid();
        !          102794: int    uumask();
        !          102795: int    uchroot();
        !          102796: int    usetpgrp();
        !          102797: int    ugetpgrp();
        !          102798: int    ugeteuid();
        !          102799: int    ufcntl();
        !          102800: int    upoll();
        !          102801: int    umsgctl();
        !          102802: int    umsgget();
        !          102803: int    umsgrcv();
        !          102804: int    umsgsnd();
        !          102805: long   ualarm2();
        !          102806: long   utick();
        !          102807: 
        !          102808: /*
        !          102809:  * System call table.
        !          102810:  */
        !          102811: struct systab sysitab[NMICALL] ={
        !          102812:        0,  INT,        unone,                  /*  0 = ??? */
        !          102813:        2,  INT,        uexit,                  /*  1 = exit */
        !          102814:        0,  INT,        ufork,                  /*  2 = fork */
        !          102815:        6,  INT,        uread,                  /*  3 = read */
        !          102816:        6,  INT,        uwrite,                 /*  4 = write */
        !          102817:        4,  INT,        uopen,                  /*  5 = open */
        !          102818:        2,  INT,        uclose,                 /*  6 = close */
        !          102819:        2,  INT,        uwait,                  /*  7 = wait */
        !          102820:        4,  INT,        ucreat,                 /*  8 = creat */
        !          102821:        4,  INT,        ulink,                  /*  9 = link */
        !          102822:        2,  INT,        uunlink,                /* 10 = unlink */
        !          102823:        6,  INT,        uexece,                 /* 11 = exec */
        !          102824:        2,  INT,        uchdir,                 /* 12 = chdir */
        !          102825:        0,  INT,        unone,                  /* 13 = ??? */
        !          102826:        6,  INT,        umknod,                 /* 14 = mknod */
        !          102827:        4,  INT,        uchmod,                 /* 15 = chmod */
        !          102828:        6,  INT,        uchown,                 /* 16 = chown */
        !          102829:        2,  INT,        ubrk,                   /* 17 = break */
        !          102830:        4,  INT,        ustat,                  /* 18 = stat */
        !          102831:        8,  LONG,       ulseek,                 /* 19 = lseek */
        !          102832:        0,  INT,        ugetpid,                /* 20 = getpid */
        !          102833:        6,  INT,        umount,                 /* 21 = mount */
        !          102834:        2,  INT,        uumount,                /* 22 = umount */
        !          102835:        2,  INT,        usetuid,                /* 23 = setuid */
        !          102836:        0,  INT,        ugetuid,                /* 24 = getuid */
        !          102837:        2,  INT,        ustime,                 /* 25 = stime */
        !          102838:        8,  INT,        uptrace,                /* 26 = ptrace */
        !          102839:        2,  INT,        ualarm,                 /* 27 = alarm */
        !          102840:        4,  INT,        ufstat,                 /* 28 = fstat */
        !          102841:        0,  INT,        upause,                 /* 29 = pause */
        !          102842:        4,  INT,        uutime,                 /* 30 = utime */
        !          102843:        0,  INT,        unone,                  /* 31 = ??? */
        !          102844:        0,  INT,        unone,                  /* 32 = ??? */
        !          102845:        4,  INT,        uaccess,                /* 33 = access */
        !          102846:        2,  INT,        unice,                  /* 34 = nice */
        !          102847:        2,  INT,        uftime,                 /* 35 = ftime */
        !          102848:        0,  INT,        usync,                  /* 36 = sync */
        !          102849:        4,  INT,        ukill,                  /* 37 = kill */
        !          102850:        0,  INT,        unone,                  /* 38 = ??? */
        !          102851:        0,  INT,        unone,                  /* 39 = ??? */
        !          102852:        0,  INT,        unone,                  /* 40 = ??? */
        !          102853:        4,  INT,        udup,                   /* 41 = dup */
        !          102854:        2,  INT,        upipe,                  /* 42 = pipe */
        !          102855:        2,  INT,        utimes,                 /* 43 = times */
        !          102856:        8,  INT,        uprofil,                /* 44 = profil */
        !          102857:        0,  LONG,       uunique,                /* 45 = unique */
        !          102858:        2,  INT,        usetgid,                /* 46 = setgid */
        !          102859:        0,  INT,        ugetgid,                /* 47 = getgid */
        !          102860:        4,  INT,        usignal,                /* 48 = signal */
        !          102861:        0,  INT,        unone,                  /* 49 = ??? */
        !          102862:        0,  INT,        unone,                  /* 50 = ??? */
        !          102863:        2,  INT,        uacct,                  /* 51 = acct */
        !          102864:        0,  INT,        unull,                  /* 52 = ??? (phys) */
        !          102865:        0,  INT,        ulock,                  /* 53 = lock */
        !          102866:        6,  INT,        uioctl,                 /* 54 = ioctl */
        !          102867:        0,  INT,        unone,                  /* 55 = ??? (mpx) */
        !          102868:        0,  INT,        ugetegid,               /* 56 = getegid */
        !          102869:        0,  INT,        ugeteuid,               /* 57 = geteuid */
        !          102870:        0,  INT,        unone,                  /* 58 = ??? */
        !          102871:        0,  INT,        unone,                  /* 59 = ??? */
        !          102872:        2,  INT,        uumask,                 /* 60 = umask */
        !          102873:        2,  INT,        uchroot,                /* 61 = chroot */
        !          102874:        0,  INT,        usetpgrp,               /* 62 = setpgrp */
        !          102875:        0,  INT,        ugetpgrp,               /* 63 = getpgrp */
        !          102876:        2,  INT,        usload,                 /* 64 = sload */
        !          102877:        2,  INT,        usuload,                /* 65 = suload */
        !          102878:        6,  INT,        ufcntl,                 /* 66 = fcntl */
        !          102879:        8,  INT,        upoll,                  /* 67 = poll */
        !          102880:        6,  INT,        umsgctl,                /* 68 = msgctl */
        !          102881:        6,  INT,        umsgget,                /* 69 = msgget */
        !          102882:        12, INT,        umsgrcv,                /* 70 = msgrcv */
        !          102883:        8,  INT,        umsgsnd,                /* 71 = msgsnd */
        !          102884:        4,  LONG,       ualarm2,                /* 72 = alarm2 */
        !          102885:        0,  LONG,       utick                   /* 73 = tick  */
        !          102886: };
        !          102887: @
        !          102888: 0707070064030112060407550000030000030000011777770507310725400005100000000000/newbits/kernel/USRSRC/i8086/src/objects0707070064030112040407550000000000000000011777770507310725400004500000000000/newbits/kernel/USRSRC/i8086/objects0707070064030147540407550000030000030000011777770507310725400003300000000000/newbits/kernel/USRSRC/coh0707070064030110751006440000030000030000011777770507310725400004300000004473/newbits/kernel/USRSRC/coh/alloc.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/alloc.c,v 1.4 91/07/24 07:48:16 bin Exp Locker: bin $ */
        !          102889: /* (lgl-
        !          102890:  *     The information contained herein is a trade secret of Mark Williams
        !          102891:  *     Company, and  is confidential information.  It is provided  under a
        !          102892:  *     license agreement,  and may be  copied or disclosed  only under the
        !          102893:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          102894:  *     material without the express written authorization of Mark Williams
        !          102895:  *     Company or persuant to the license agreement is unlawful.
        !          102896:  *
        !          102897:  *     COHERENT Version 2.3.37
        !          102898:  *     Copyright (c) 1982, 1983, 1984.
        !          102899:  *     An unpublished work by Mark Williams Company, Chicago.
        !          102900:  *     All rights reserved.
        !          102901:  -lgl) */
        !          102902: /*
        !          102903:  * Coherent.
        !          102904:  * Storage allocator.
        !          102905:  *
        !          102906:  * $Log:       alloc.c,v $
        !          102907:  * Revision 1.4  91/07/24  07:48:16  bin
        !          102908:  * initial version prov by hal
        !          102909:  * 
        !          102910:  * Revision 1.1        88/03/24  16:13:25      src
        !          102911:  * Initial revision
        !          102912:  * 
        !          102913:  */
        !          102914: #include <sys/coherent.h>
        !          102915: #include <sys/alloc.h>
        !          102916: #include <errno.h>
        !          102917: #include <sys/proc.h>
        !          102918: #include <sys/uproc.h>
        !          102919: 
        !          102920: /*
        !          102921:  * Create an arena.
        !          102922:  */
        !          102923: ALL *
        !          102924: setarena(cp, n)
        !          102925: register char *cp;
        !          102926: {
        !          102927:        register ALL *ap1;
        !          102928:        register ALL *ap2;
        !          102929: 
        !          102930:        if ((char *)(ap1=align(cp)) < (char *)cp)
        !          102931:                ap1++;
        !          102932:        if ((ap2=align(&cp[n])-1) < ap1)
        !          102933:                panic("Arena %o too small", (int) cp);
        !          102934:        ap1->a_link = (char *)ap2;
        !          102935:        ap2->a_link = (char *)ap1;
        !          102936:        setused(ap2);
        !          102937:        return (ap1);
        !          102938: }
        !          102939: 
        !          102940: /*
        !          102941:  * Allocate `l' bytes of memory.
        !          102942:  */
        !          102943: char *
        !          102944: alloc(apq, l)
        !          102945: ALL *apq;
        !          102946: unsigned l;
        !          102947: {
        !          102948:        register ALL *ap;
        !          102949:        register ALL *ap1;
        !          102950:        register ALL *ap2;
        !          102951:        register unsigned i;
        !          102952:        register unsigned n;
        !          102953:        register unsigned s;
        !          102954: 
        !          102955:        n = 1 + (l + sizeof(ALL) - 1) / sizeof(ALL);
        !          102956:        for (i=0; i<2; i++) {
        !          102957:                for (ap1=apq; link(ap1)!=apq; ap1=link(ap1)) {
        !          102958:                        if (ap1 == NULL)
        !          102959:                                panic("Corrupt arena");
        !          102960:                        if (tstfree(ap1)) {
        !          102961:                               for (ap2=link(ap1); tstfree(ap2); ap2=link(ap2))
        !          102962:                                        if (ap2 == apq)
        !          102963:                                                break;
        !          102964:                                ap1->a_link = (char *)ap2;
        !          102965:                                if ((s=ap2-ap1) >= n) {
        !          102966:                                        if (s > n) {
        !          102967:                                                if (i == 0)
        !          102968:                                                        continue;
        !          102969:                                                ap = &ap1[n];
        !          102970:                                                ap->a_link = (char *)ap2;
        !          102971:                                                ap1->a_link = (char *)ap;
        !          102972:                                        }
        !          102973:                                        setused(ap1);
        !          102974:                                        kclear((char *)ap1->a_data, l);
        !          102975:                                        return (ap1->a_data);
        !          102976:                                }
        !          102977:                        }
        !          102978:                }
        !          102979:        }
        !          102980:        u.u_error = EKSPACE;
        !          102981:        return (NULL);
        !          102982: }
        !          102983: 
        !          102984: /*
        !          102985:  * Free memory.
        !          102986:  */
        !          102987: free(cp)
        !          102988: char *cp;
        !          102989: {
        !          102990:        register ALL *ap;
        !          102991:        extern char end;
        !          102992: 
        !          102993:        ap = ((ALL *)cp) - 1;
        !          102994:        if (ap<(ALL *)&end || tstfree(ap))
        !          102995:                panic("Bad free %o\n", (unsigned)cp);
        !          102996:        setfree(ap);
        !          102997: }
        !          102998: 0707070064030110741006440000030000030000011777770507310725400004100000031655/newbits/kernel/USRSRC/coh/bio.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/bio.c,v 1.4 91/07/24 07:49:45 bin Exp Locker: bin $ */
        !          102999: /* (lgl-
        !          103000:  *     The information contained herein is a trade secret of Mark Williams
        !          103001:  *     Company, and  is confidential information.  It is provided  under a
        !          103002:  *     license agreement,  and may be  copied or disclosed  only under the
        !          103003:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          103004:  *     material without the express written authorization of Mark Williams
        !          103005:  *     Company or persuant to the license agreement is unlawful.
        !          103006:  *
        !          103007:  *     COHERENT Version 2.3.37
        !          103008:  *     Copyright (c) 1982, 1983, 1984.
        !          103009:  *     An unpublished work by Mark Williams Company, Chicago.
        !          103010:  *     All rights reserved.
        !          103011:  -lgl) */
        !          103012: /*
        !          103013:  * Coherent.
        !          103014:  * Buffered I/O.
        !          103015:  *
        !          103016:  * $Log:       bio.c,v $
        !          103017:  * Revision 1.4  91/07/24  07:49:45  bin
        !          103018:  * update prov by hal
        !          103019:  * 
        !          103020:  * 
        !          103021:  * Revision 1.1        88/03/24  16:13:29      src
        !          103022:  * Initial revision
        !          103023:  * 
        !          103024:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/bio.c
        !          103025:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          103026:  *
        !          103027:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/bio.c
        !          103028:  * New seg struct now used to allow extended addressing.
        !          103029:  *
        !          103030:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/bio.c
        !          103031:  * ioreq() now only wakes &stimer if the swap timer is active.
        !          103032:  *
        !          103033:  * 86/12/12    Allan Cornish           /usr/src/sys/coh/bio.c
        !          103034:  * Added 3rd arg to dpoll() to specify blocking poll if non-zero.
        !          103035:  *
        !          103036:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/bio.c
        !          103037:  * Added dpoll() routine to perform device polls [System V.3 compatible].
        !          103038:  *
        !          103039:  * 86/07/24    Allan Cornish           /usr/src/sys/coh/bio.c
        !          103040:  * Added check in devinit() for null dp->d_conp->c_load function pointer.
        !          103041:  */
        !          103042: #include <sys/coherent.h>
        !          103043: #include <sys/buf.h>
        !          103044: #include <sys/con.h>
        !          103045: #include <errno.h>
        !          103046: #include <sys/io.h>
        !          103047: #include <sys/proc.h>
        !          103048: #include <sys/sched.h>
        !          103049: #include <sys/seg.h>
        !          103050: #include <sys/stat.h>
        !          103051: #include <sys/uproc.h>
        !          103052: 
        !          103053: /*
        !          103054:  * Initialise buffer headers.
        !          103055:  */
        !          103056: bufinit()
        !          103057: {
        !          103058:        register BUF *bp;
        !          103059:        faddr_t f;
        !          103060:        paddr_t p;
        !          103061: 
        !          103062:        FP_SEL(f) = sds;
        !          103063:        FP_OFF(f) = 0;
        !          103064:        p = blockp;
        !          103065:        FP_OFF(f) = blockp - vtop(f);
        !          103066: 
        !          103067:        bufl = kalloc(NBUF * sizeof(BUF));
        !          103068:        if (bufl == NULL)
        !          103069:                panic("bufinit: no space for BUF's");
        !          103070: 
        !          103071:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          103072:                bp->b_dev = NODEV;
        !          103073:                bp->b_faddr = f;
        !          103074:                bp->b_paddr = p;
        !          103075:                FP_OFF(f) += BSIZE;
        !          103076:                p += BSIZE;
        !          103077:        }
        !          103078: }
        !          103079: 
        !          103080: /*
        !          103081:  * Synchronise the buffer cache.
        !          103082:  */
        !          103083: bsync()
        !          103084: {
        !          103085:        register BUF *bp;
        !          103086: 
        !          103087:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          103088:                if ((bp->b_flag&BFMOD) == 0)
        !          103089:                        continue;
        !          103090:                lock(bp->b_gate);
        !          103091:                if ((bp->b_flag&BFMOD) != 0)
        !          103092:                        bwrite(bp, 1);
        !          103093:                unlock(bp->b_gate);
        !          103094:        }
        !          103095: }
        !          103096: 
        !          103097: /*
        !          103098:  * Synchronise all block for a particular device in the buffer cache
        !          103099:  * and invalidate all references.
        !          103100:  */
        !          103101: bflush(dev)
        !          103102: register dev_t dev;
        !          103103: {
        !          103104:        register BUF *bp;
        !          103105: 
        !          103106:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          103107:                if (bp->b_dev != dev)
        !          103108:                        continue;
        !          103109:                lock(bp->b_gate);
        !          103110:                if (bp->b_dev == dev) {
        !          103111:                        if ((bp->b_flag&BFMOD) != 0)
        !          103112:                                bwrite(bp, 1);
        !          103113:                        bp->b_dev = NODEV;
        !          103114:                }
        !          103115:                unlock(bp->b_gate);
        !          103116:        }
        !          103117: }
        !          103118: 
        !          103119: /*
        !          103120:  * Return a buffer containing the given block from the given device.
        !          103121:  * If `f' is not set, the read is asynchronous and no buffer is returned.
        !          103122:  */
        !          103123: BUF *
        !          103124: bread(dev, bno, f)
        !          103125: dev_t dev;
        !          103126: daddr_t bno;
        !          103127: register int f;
        !          103128: {
        !          103129:        register BUF *bp;
        !          103130:        register int s;
        !          103131: 
        !          103132:        bp = bclaim(dev, bno);
        !          103133:        if ((bp->b_flag&BFNTP) != 0) {
        !          103134:                if (f != 0)
        !          103135:                        bp->b_flag &= ~BFASY;
        !          103136:                else {
        !          103137:                        bp->b_flag |= BFASY;
        !          103138:                        bumap(bp);
        !          103139:                }
        !          103140:                bp->b_req = BREAD;
        !          103141:                bp->b_count = BSIZE;
        !          103142:                s = sphi();
        !          103143:                dblock(dev, bp);
        !          103144:                if (f == 0) {
        !          103145:                        spl(s);
        !          103146:                        return (NULL);
        !          103147:                }
        !          103148:                while ((bp->b_flag&BFNTP) != 0)
        !          103149:                        sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          103150:                spl(s);
        !          103151:                if ((bp->b_flag&BFERR) != 0) {
        !          103152:                        u.u_error = bp->b_err ? bp->b_err : EIO;
        !          103153:                        brelease(bp);
        !          103154:                        return (NULL);
        !          103155:                }
        !          103156:                if (bp->b_resid == BSIZE) {
        !          103157:                        brelease(bp);
        !          103158:                        return (NULL);
        !          103159:                }
        !          103160:        }
        !          103161:        if (f == 0) {
        !          103162:                brelease(bp);
        !          103163:                return (NULL);
        !          103164:        }
        !          103165:        u.u_block++;
        !          103166:        return (bp);
        !          103167: }
        !          103168: 
        !          103169: /*
        !          103170:  * If the requested buffer is in the buffer cache, return a pointer to
        !          103171:  * it.  If not, pick an empty buffer, set it up and return it.
        !          103172:  */
        !          103173: BUF *
        !          103174: bclaim(dev, bno)
        !          103175: dev_t dev;
        !          103176: daddr_t bno;
        !          103177: {
        !          103178:        register BUF *bp;
        !          103179:        register BUF *bp1;
        !          103180:        register unsigned seqn;
        !          103181:        register int s;
        !          103182: 
        !          103183: again:
        !          103184:        bp1 = NULL;
        !          103185:        seqn = 0;
        !          103186:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          103187:                if (bp->b_bno == bno  &&  bp->b_dev == dev) {
        !          103188:                        lock(bp->b_gate);
        !          103189:                        if (bp->b_bno != bno  ||  bp->b_dev != dev) {
        !          103190:                                unlock(bp->b_gate);
        !          103191:                                goto again;
        !          103192:                        }
        !          103193:                        if ((bp->b_flag&BFERR) != 0)
        !          103194:                                bp->b_flag |= BFNTP;
        !          103195:                        bsmap(bp);
        !          103196:                        return (bp);
        !          103197:                }
        !          103198:                if (locked(bp->b_gate) == 0) {
        !          103199:                        if (bufseqn-bp->b_seqn >= seqn) {
        !          103200:                                bp1 = bp;
        !          103201:                                seqn = bufseqn - bp->b_seqn;
        !          103202:                        }
        !          103203:                }
        !          103204:        }
        !          103205:        if (bp1 == NULL) {
        !          103206:                s = sphi();
        !          103207:                for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          103208:                        if (locked(bp->b_gate) == 0) {
        !          103209:                                if (bufseqn-bp->b_seqn >= seqn) {
        !          103210:                                        bp1 = bp;
        !          103211:                                        seqn = bufseqn - bp->b_seqn;
        !          103212:                                }
        !          103213:                        }
        !          103214:                }
        !          103215:                if (bp1 == NULL) {
        !          103216:                        bufneed = 1;
        !          103217:                        sleep((char *)&bufneed, CVBLKIO, IVBLKIO, SVBLKIO);
        !          103218:                        spl(s);
        !          103219:                        goto again;
        !          103220:                }
        !          103221:                spl(s);
        !          103222:        }
        !          103223:        bp = bp1;
        !          103224:        lock(bp->b_gate);
        !          103225:        if ((bp->b_flag&BFMOD) != 0) {
        !          103226:                bwrite(bp, 0);
        !          103227:                goto again;
        !          103228:        }
        !          103229:        bp->b_flag = BFNTP;
        !          103230:        bp->b_dev = dev;
        !          103231:        bp->b_bno = bno;
        !          103232:        bsmap(bp);
        !          103233:        return (bp);
        !          103234: }
        !          103235: 
        !          103236: /*
        !          103237:  * Write the given buffer out.  If `f' is set, the write is synchronous,
        !          103238:  * otherwise asynchronous.  This routine must be called with the buffer
        !          103239:  * gate locked.
        !          103240:  */
        !          103241: bwrite(bp, f)
        !          103242: register BUF *bp;
        !          103243: {
        !          103244:        register int s;
        !          103245: 
        !          103246:        if (f != 0)
        !          103247:                bp->b_flag &= ~BFASY;
        !          103248:        else {
        !          103249:                bp->b_flag |= BFASY;
        !          103250:                bumap(bp);
        !          103251:        }
        !          103252:        bp->b_flag |= BFNTP;
        !          103253:        bp->b_req = BWRITE;
        !          103254:        bp->b_count = BSIZE;
        !          103255:        s = sphi();
        !          103256:        dblock(bp->b_dev, bp);
        !          103257:        if (f == 0) {
        !          103258:                spl(s);
        !          103259:                return;
        !          103260:        }
        !          103261:        while ((bp->b_flag&BFNTP) != 0)
        !          103262:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          103263:        spl(s);
        !          103264: }
        !          103265: 
        !          103266: /*
        !          103267:  * This is called by the driver when I/O has completed on a buffer.
        !          103268:  */
        !          103269: bdone(bp)
        !          103270: register BUF *bp;
        !          103271: {
        !          103272:        if (bp->b_req == BWRITE)
        !          103273:                bp->b_flag &= ~BFMOD;
        !          103274:        if (bp->b_req == BREAD) {
        !          103275:                if ((bp->b_flag&BFERR) != 0)
        !          103276:                        bp->b_dev = NODEV;
        !          103277:        }
        !          103278:        if ((bp->b_flag&BFASY) != 0) {
        !          103279:                bp->b_flag &= ~BFASY;
        !          103280:                brelease(bp);
        !          103281:        }
        !          103282:        bp->b_flag &= ~BFNTP;
        !          103283:        wakeup((char *)bp);
        !          103284: }
        !          103285: 
        !          103286: /*
        !          103287:  * Release the given buffer.
        !          103288:  */
        !          103289: brelease(bp)
        !          103290: register BUF *bp;
        !          103291: {
        !          103292:        if ((bp->b_flag&BFERR) == 0)
        !          103293:                bp->b_seqn = bufseqn++;
        !          103294:        else {
        !          103295:                bp->b_flag &= ~BFERR;
        !          103296:                bp->b_dev = NODEV;
        !          103297:        }
        !          103298:        bp->b_flag &= ~BFNTP;
        !          103299:        bumap(bp);
        !          103300:        unlock(bp->b_gate);
        !          103301:        if (bufneed != 0) {
        !          103302:                bufneed = 0;
        !          103303:                wakeup((char *)&bufneed);
        !          103304:        }
        !          103305: }
        !          103306: 
        !          103307: /*
        !          103308:  * Map the given buffer.
        !          103309:  */
        !          103310: bsmap(bp)
        !          103311: register BUF *bp;
        !          103312: {
        !          103313:        bsave(bp->b_map);
        !          103314:        bp->b_flag |= BFMAP;
        !          103315:        bmapv(bconv(bp->b_paddr));
        !          103316: }
        !          103317: 
        !          103318: /*
        !          103319:  * Unmap the given buffer.
        !          103320:  */
        !          103321: bumap(bp)
        !          103322: register BUF *bp;
        !          103323: {
        !          103324:        if ((bp->b_flag&BFMAP) == 0)
        !          103325:                return;
        !          103326:        bp->b_flag &= ~BFMAP;
        !          103327:        brest(bp->b_map);
        !          103328: }
        !          103329: 
        !          103330: /*
        !          103331:  * Read data from the I/O segment into kernel space.
        !          103332:  */
        !          103333: ioread(iop, v, n)
        !          103334: register IO *iop;
        !          103335: register char *v;
        !          103336: register unsigned n;
        !          103337: {
        !          103338:        switch (iop->io_seg) {
        !          103339:        case IOSYS:
        !          103340:                iop->io_base += kkcopy(iop->io_base, v, n);
        !          103341:                break;
        !          103342:        case IOUSR:
        !          103343:                iop->io_base += ukcopy(iop->io_base, v, n);
        !          103344:                break;
        !          103345:        case IOPHY:
        !          103346:                iop->io_phys += pkcopy(iop->io_phys, v, n);
        !          103347:                break;
        !          103348:        }
        !          103349:        iop->io_ioc -= n;
        !          103350: }
        !          103351: 
        !          103352: /*
        !          103353:  * Write data from kernel space to the I/O segment.
        !          103354:  */
        !          103355: iowrite(iop, v, n)
        !          103356: register IO *iop;
        !          103357: register char *v;
        !          103358: register unsigned n;
        !          103359: {
        !          103360:        switch (iop->io_seg) {
        !          103361:        case IOSYS:
        !          103362:                iop->io_base += kkcopy(v, iop->io_base, n);
        !          103363:                break;
        !          103364:        case IOUSR:
        !          103365:                iop->io_base += kucopy(v, iop->io_base, n);
        !          103366:                break;
        !          103367:        case IOPHY:
        !          103368:                iop->io_phys += kpcopy(v, iop->io_phys, n);
        !          103369:                break;
        !          103370:        }
        !          103371:        iop->io_ioc -= n;
        !          103372: }
        !          103373: 
        !          103374: /*
        !          103375:  * Get a character from the I/O segment.
        !          103376:  */
        !          103377: iogetc(iop)
        !          103378: register IO *iop;
        !          103379: {
        !          103380:        register int c;
        !          103381: 
        !          103382:        if (iop->io_ioc == 0)
        !          103383:                return (-1);
        !          103384:        --iop->io_ioc;
        !          103385:        if (iop->io_seg == IOSYS)
        !          103386:                c = *iop->io_base++ & 0377;
        !          103387:        else {
        !          103388:                c = getubd(iop->io_base++);
        !          103389:                if (u.u_error)
        !          103390:                        return (-1);
        !          103391:        }
        !          103392:        return (c);
        !          103393: }
        !          103394: 
        !          103395: /*
        !          103396:  * Put a character using the I/O segment.
        !          103397:  */
        !          103398: ioputc(c, iop)
        !          103399: register IO *iop;
        !          103400: {
        !          103401:        if (iop->io_ioc == 0)
        !          103402:                return (-1);
        !          103403:        --iop->io_ioc;
        !          103404:        if (iop->io_seg == IOSYS)
        !          103405:                *iop->io_base++ = c;
        !          103406:        else {
        !          103407:                putubd(iop->io_base++, c);
        !          103408:                if (u.u_error)
        !          103409:                        return (-1);
        !          103410:        }
        !          103411:        return (c);
        !          103412: }
        !          103413: 
        !          103414: /*
        !          103415:  * Given a buffer pointer, an I/O structure, a device, request type, and
        !          103416:  * a flags word, check the I/O structure and perform the I/O request.
        !          103417:  */
        !          103418: ioreq(bp, iop, dev, req, f)
        !          103419: register BUF *bp;
        !          103420: register IO *iop;
        !          103421: dev_t dev;
        !          103422: {
        !          103423:        register SEG *sp;
        !          103424:        register int n;
        !          103425:        register int s;
        !          103426:        register CON *cp;
        !          103427:        dold_t dold;
        !          103428: 
        !          103429:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103430:                return;
        !          103431:        lock(bp->b_gate);
        !          103432:        n = cp->c_flag; /* n should do something with that flag */
        !          103433:        drest(dold);
        !          103434:        sp = NULL;
        !          103435:        if (iop != NULL) {
        !          103436:                if ((f&BFBLK) != 0) {
        !          103437:                        if (blocko(iop->io_seek) != 0) {
        !          103438:                                u.u_error = EIO;
        !          103439:                                goto out;
        !          103440:                        }
        !          103441:                }
        !          103442:                if ((f&BFIOC) != 0) {
        !          103443:                        if ((sp=iomapvp(iop, bp)) == NULL) {
        !          103444:                                u.u_error = EIO;
        !          103445:                                goto out;
        !          103446:                        }
        !          103447:                }
        !          103448:        }
        !          103449:        bp->b_flag = f|BFNTP;
        !          103450:        bp->b_req = req;
        !          103451:        bp->b_dev = dev;
        !          103452:        if (iop != NULL) {
        !          103453:                bp->b_bno = blockn(iop->io_seek);
        !          103454:                bp->b_count = iop->io_ioc;
        !          103455:        }
        !          103456:        if (sp != NULL) {
        !          103457:                bp->b_faddr = ptov( bp->b_paddr, (fsize_t) bp->b_count );
        !          103458:                sp->s_lrefc++;
        !          103459:        }
        !          103460:        s = sphi();
        !          103461:        dblock(dev, bp);
        !          103462:        while ((bp->b_flag&BFNTP) != 0)
        !          103463:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          103464:        spl(s);
        !          103465:        if (sp != NULL) {
        !          103466:                vrelse( bp->b_faddr );
        !          103467:                sp->s_lrefc--;
        !          103468:        }
        !          103469:        if (stimer.t_last != 0)
        !          103470:                wakeup((char *)&stimer);
        !          103471:        if ((bp->b_flag&BFERR) != 0) {
        !          103472:                u.u_error = bp->b_err ? bp->b_err : EIO;
        !          103473:                goto out;
        !          103474:        }
        !          103475:        if (iop != NULL) {
        !          103476:                n = iop->io_ioc - bp->b_resid;
        !          103477:                iop->io_seek += n;
        !          103478:                iop->io_ioc -= n;
        !          103479:        }
        !          103480: out:
        !          103481:        unlock(bp->b_gate);
        !          103482: }
        !          103483: 
        !          103484: /*
        !          103485:  * Given an I/O structure and a buffer header, see if the addresses
        !          103486:  * in the I/O structure are valid and set up the buffer header.
        !          103487:  */
        !          103488: SEG *
        !          103489: iomapvp(iop, bp)
        !          103490: register IO *iop;
        !          103491: register BUF *bp;
        !          103492: {
        !          103493:        register SR *srp;
        !          103494:        register SEG *sp;
        !          103495:        register vaddr_t b;
        !          103496: 
        !          103497:        if (iop->io_seg != IOUSR)
        !          103498:                panic("Raw I/O from non user");
        !          103499:        for (srp=u.u_segl; srp<&u.u_segl[NUSEG]; srp++) {
        !          103500:                if ((sp=srp->sr_segp) == NULL)
        !          103501:                        continue;
        !          103502:                if ((srp->sr_flag&SRFDATA) == 0)
        !          103503:                        continue;
        !          103504: /* Yet another bug in the 8000 C compiler
        !          103505:                if ((long)(b=iop->io_base) < (long)srp->sr_base)
        !          103506: */
        !          103507:                if ((b=iop->io_base) < srp->sr_base)
        !          103508:                        continue;
        !          103509:                if ((long)b+iop->io_ioc > (long)srp->sr_base + sp->s_size)
        !          103510:                        continue;
        !          103511:                bp->b_paddr = sp->s_paddr + (vaddr_t) (b - srp->sr_base);
        !          103512:                return (sp);
        !          103513:        }
        !          103514:        return (NULL);
        !          103515: }
        !          103516: 
        !          103517: /*
        !          103518:  * Initialise devices.
        !          103519:  */
        !          103520: devinit()
        !          103521: {
        !          103522:        register DRV *dp;
        !          103523:        register int mind;
        !          103524: 
        !          103525:        for ( dp = drvl, mind = 0; mind < drvn; mind++, dp++ ) {
        !          103526:                if ((dp->d_conp != NULL) && (dp->d_conp->c_load != NULL)) {
        !          103527:                        (*dp->d_conp->c_load)();
        !          103528:                }
        !          103529:        }
        !          103530: }
        !          103531: 
        !          103532: /*
        !          103533:  * Open a device.
        !          103534:  */
        !          103535: dopen(dev, m, f)
        !          103536: register dev_t dev;
        !          103537: {
        !          103538:        register CON *cp;
        !          103539:        dold_t dold;
        !          103540: 
        !          103541:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103542:                return;
        !          103543:        if ((cp->c_flag&f) == 0) {
        !          103544:                u.u_error = ENXIO;
        !          103545:                return;
        !          103546:        }
        !          103547:        (*cp->c_open)(dev, m);
        !          103548:        drest(dold);
        !          103549: }
        !          103550: 
        !          103551: /*
        !          103552:  * Close a device.
        !          103553:  */
        !          103554: dclose(dev)
        !          103555: register dev_t dev;
        !          103556: {
        !          103557:        register CON *cp;
        !          103558:        dold_t dold;
        !          103559: 
        !          103560:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103561:                return;
        !          103562:        (*cp->c_close)(dev);
        !          103563:        drest(dold);
        !          103564: }
        !          103565: 
        !          103566: /*
        !          103567:  * Call the block entry point of a device.
        !          103568:  */
        !          103569: dblock(dev, bp)
        !          103570: dev_t dev;
        !          103571: BUF *bp;
        !          103572: {
        !          103573:        register CON *cp;
        !          103574:        dold_t dold;
        !          103575: 
        !          103576:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103577:                return;
        !          103578:        (*cp->c_block)(bp);
        !          103579:        drest(dold);
        !          103580: }
        !          103581: 
        !          103582: /*
        !          103583:  * Read from a device.
        !          103584:  */
        !          103585: dread(dev, iop)
        !          103586: register dev_t dev;
        !          103587: register IO *iop;
        !          103588: {
        !          103589:        register CON *cp;
        !          103590:        dold_t dold;
        !          103591: 
        !          103592:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103593:                return;
        !          103594:        (*cp->c_read)(dev, iop);
        !          103595:        drest(dold);
        !          103596: }
        !          103597: 
        !          103598: /*
        !          103599:  * Write to a device.
        !          103600:  */
        !          103601: dwrite(dev, iop)
        !          103602: register dev_t dev;
        !          103603: register IO *iop;
        !          103604: {
        !          103605:        register CON *cp;
        !          103606:        dold_t dold;
        !          103607: 
        !          103608:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103609:                return;
        !          103610:        (*cp->c_write)(dev, iop);
        !          103611:        drest(dold);
        !          103612: }
        !          103613: 
        !          103614: /*
        !          103615:  * Call the ioctl function for a device.
        !          103616:  */
        !          103617: dioctl(dev, com, vec)
        !          103618: register dev_t dev;
        !          103619: union ioctl *vec;
        !          103620: {
        !          103621:        register CON *cp;
        !          103622:        dold_t dold;
        !          103623: 
        !          103624:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103625:                return;
        !          103626:        (*cp->c_ioctl)(dev, com, vec);
        !          103627:        drest(dold);
        !          103628: }
        !          103629: 
        !          103630: /*
        !          103631:  * Call the powerfail entry point of a device.
        !          103632:  */
        !          103633: dpower(dev)
        !          103634: register dev_t dev;
        !          103635: {
        !          103636:        register CON *cp;
        !          103637:        dold_t dold;
        !          103638: 
        !          103639:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103640:                return;
        !          103641:        (*cp->c_power)(dev);
        !          103642:        drest(dold);
        !          103643: }
        !          103644: 
        !          103645: /*
        !          103646:  * Call the timeout entry point of a device.
        !          103647:  */
        !          103648: dtime(dev)
        !          103649: register dev_t dev;
        !          103650: {
        !          103651:        register CON *cp;
        !          103652:        dold_t dold;
        !          103653: 
        !          103654:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103655:                return;
        !          103656:        (*cp->c_timer)(dev);
        !          103657:        drest(dold);
        !          103658: }
        !          103659: 
        !          103660: /*
        !          103661:  * Poll a device.
        !          103662:  */
        !          103663: dpoll(dev, ev, msec)
        !          103664: register dev_t dev;
        !          103665: int ev;
        !          103666: int msec;
        !          103667: {
        !          103668:        register CON *cp;
        !          103669:        dold_t dold;
        !          103670: 
        !          103671:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103672:                return POLLNVAL;
        !          103673: 
        !          103674:        if ( cp->c_flag & DFPOL )
        !          103675:                ev = (*cp->c_poll)(dev, ev, msec);
        !          103676:        else
        !          103677:                ev = POLLNVAL;
        !          103678: 
        !          103679:        drest(dold);
        !          103680:        return ev;
        !          103681: }
        !          103682: 
        !          103683: /*
        !          103684:  * Given a device, return the flags word.
        !          103685:  */
        !          103686: dflag(dev)
        !          103687: dev_t dev;
        !          103688: {
        !          103689:        register CON *cp;
        !          103690:        register int f;
        !          103691:        dold_t dold;
        !          103692: 
        !          103693:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          103694:                return (DFERR);
        !          103695:        f = cp->c_flag;
        !          103696:        drest(dold);
        !          103697:        return (f);
        !          103698: }
        !          103699: 
        !          103700: /*
        !          103701:  * Given a device, and a pointer to a driver map save area, save the
        !          103702:  * current map in the driver map save area and map in the new device,
        !          103703:  * returning a pointer to the configuration entry for that device.
        !          103704:  */
        !          103705: CON *
        !          103706: drvmap(dev, doldp)
        !          103707: dev_t dev;
        !          103708: dold_t *doldp;
        !          103709: {
        !          103710:        register DRV *dp;
        !          103711:        register unsigned m;
        !          103712: 
        !          103713:        if ((m=major(dev)) >= drvn) {
        !          103714:                u.u_error = ENXIO;
        !          103715:                return (NULL);
        !          103716:        }
        !          103717:        dp = &drvl[m];
        !          103718:        if (locked(dp->d_gate)) {
        !          103719:                u.u_error = ENXIO;
        !          103720:                return (NULL);
        !          103721:        }
        !          103722:        if (dp->d_conp == NULL) {
        !          103723:                u.u_error = ENXIO;
        !          103724:                return (NULL);
        !          103725:        }
        !          103726:        dsave(*doldp);
        !          103727:        if (dp->d_map != 0)
        !          103728:                dmapv(dp->d_map);
        !          103729:        return (dp->d_conp);
        !          103730: }
        !          103731: 
        !          103732: /*
        !          103733:  * Non existant device.
        !          103734:  */
        !          103735: nonedev()
        !          103736: {
        !          103737:        u.u_error = ENXIO;
        !          103738: }
        !          103739: 
        !          103740: /*
        !          103741:  * Null device.
        !          103742:  */
        !          103743: nulldev()
        !          103744: {
        !          103745: }
        !          103746: 0707070064030103071006440000030000030000011777770507310725700004300000005623/newbits/kernel/USRSRC/coh/clist.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/clist.c,v 1.4 91/07/24 07:50:03 bin Exp Locker: bin $ */
        !          103747: /* (lgl-
        !          103748:  *     The information contained herein is a trade secret of Mark Williams
        !          103749:  *     Company, and  is confidential information.  It is provided  under a
        !          103750:  *     license agreement,  and may be  copied or disclosed  only under the
        !          103751:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          103752:  *     material without the express written authorization of Mark Williams
        !          103753:  *     Company or persuant to the license agreement is unlawful.
        !          103754:  *
        !          103755:  *     COHERENT Version 2.3.37
        !          103756:  *     Copyright (c) 1982, 1983, 1984.
        !          103757:  *     An unpublished work by Mark Williams Company, Chicago.
        !          103758:  *     All rights reserved.
        !          103759:  -lgl) */
        !          103760: /*
        !          103761:  * Coherent.
        !          103762:  * Character list management.
        !          103763:  *
        !          103764:  * $Log:       clist.c,v $
        !          103765:  * Revision 1.4  91/07/24  07:50:03  bin
        !          103766:  * update prov by hal
        !          103767:  * 
        !          103768:  * 
        !          103769:  * Revision 1.1        88/03/24  16:13:33      src
        !          103770:  * Initial revision
        !          103771:  * 
        !          103772:  */
        !          103773: #include <sys/coherent.h>
        !          103774: #include <clist.h>
        !          103775: #include <sched.h>
        !          103776: 
        !          103777: /*
        !          103778:  * Initialise character list queues.
        !          103779:  */
        !          103780: cltinit()
        !          103781: {
        !          103782:        register cmap_t cm;
        !          103783:        register cmap_t lm;
        !          103784:        register paddr_t p;
        !          103785:        register int s;
        !          103786:        cold_t om;
        !          103787: 
        !          103788:        s = sphi();
        !          103789:        csave(om);
        !          103790:        lm = 0;
        !          103791:        for (p = clistp+NCLIST*sizeof(CLIST); (p-=sizeof(CLIST)) >= clistp; ) {
        !          103792:                cm = cconv(p);
        !          103793:                cmapv(cm);
        !          103794:                cvirt(cm)->cl_fp = lm;
        !          103795:                lm = cm;
        !          103796:        }
        !          103797:        cltfree = lm;
        !          103798:        crest(om);
        !          103799:        spl(s);
        !          103800: }
        !          103801: 
        !          103802: /*
        !          103803:  * Get a character from the given queue.
        !          103804:  */
        !          103805: getq(cqp)
        !          103806: register CQUEUE *cqp;
        !          103807: {
        !          103808:        register cmap_t op;
        !          103809:        register cmap_t np;
        !          103810:        register int ox;
        !          103811:        register int c;
        !          103812:        register int s;
        !          103813:        cold_t om;
        !          103814: 
        !          103815:        if (cqp->cq_cc == 0)
        !          103816:                return (-1);
        !          103817:        s = sphi();
        !          103818:        op = cqp->cq_op;
        !          103819:        ox = cqp->cq_ox;
        !          103820:        csave(om);
        !          103821:        cmapv(op);
        !          103822:        c = cvirt(op)->cl_ch[ox]&0377;
        !          103823:        crest(om);
        !          103824:        if (--cqp->cq_cc==0 || ++cqp->cq_ox==NCPCL) {
        !          103825:                cqp->cq_ox = 0;
        !          103826:                cmapv(op);
        !          103827:                np = cvirt(op)->cl_fp;
        !          103828:                cvirt(op)->cl_fp = cltfree;
        !          103829:                crest(om);
        !          103830:                cqp->cq_op = np;
        !          103831:                cltfree = op;
        !          103832:                if (np == 0) {
        !          103833:                        cqp->cq_ip = 0;
        !          103834:                        cqp->cq_ix = 0;
        !          103835:                }
        !          103836:                if (cltwant) {
        !          103837:                        cltwant = 0;
        !          103838:                        wakeup((char *)&cltwant);
        !          103839:                }
        !          103840:        }
        !          103841:        spl(s);
        !          103842:        return (c);
        !          103843: }
        !          103844: 
        !          103845: /*
        !          103846:  * Put a character on the given queue.
        !          103847:  */
        !          103848: putq(cqp, c)
        !          103849: register CQUEUE *cqp;
        !          103850: {
        !          103851:        register cmap_t ip;
        !          103852:        register int ix;
        !          103853:        register int s;
        !          103854:        register cmap_t np;
        !          103855:        cold_t om;
        !          103856: 
        !          103857:        s = sphi();
        !          103858:        ip = cqp->cq_ip;
        !          103859:        csave(om);
        !          103860:        if ((ix=cqp->cq_ix) == 0) {
        !          103861:                if ((ip=cltfree) == 0) {
        !          103862:                        spl(s);
        !          103863:                        return (-1);
        !          103864:                }
        !          103865:                cmapv(ip);
        !          103866:                cltfree = cvirt(ip)->cl_fp;
        !          103867:                cvirt(ip)->cl_fp = 0;
        !          103868:                crest(om);
        !          103869:                if ((np=cqp->cq_ip) == 0)
        !          103870:                        cqp->cq_op = ip;
        !          103871:                else {
        !          103872:                        cmapv(np);
        !          103873:                        cvirt(np)->cl_fp = ip;
        !          103874:                        crest(om);
        !          103875:                }
        !          103876:                cqp->cq_ip = ip;
        !          103877:        }
        !          103878:        cmapv(ip);
        !          103879:        cvirt(ip)->cl_ch[ix] = c;
        !          103880:        crest(om);
        !          103881:        if (++cqp->cq_ix == NCPCL)
        !          103882:                cqp->cq_ix = 0;
        !          103883:        cqp->cq_cc++;
        !          103884:        spl(s);
        !          103885:        return (c);
        !          103886: }
        !          103887: 
        !          103888: /*
        !          103889:  * Clear a character queue.
        !          103890:  */
        !          103891: clrq(cqp)
        !          103892: register CQUEUE *cqp;
        !          103893: {
        !          103894:        register int s;
        !          103895: 
        !          103896:        s = sphi();
        !          103897:        while (getq(cqp) >= 0)
        !          103898:                ;
        !          103899:        spl(s);
        !          103900: }
        !          103901: 
        !          103902: /*
        !          103903:  * Wait for more character queues to become available.
        !          103904:  */
        !          103905: waitq()
        !          103906: {
        !          103907:        while (cltfree == 0) {
        !          103908:                cltwant = 1;
        !          103909:                sleep((char *)&cltwant, CVCLIST, IVCLIST, SVCLIST);
        !          103910:        }
        !          103911: }
        !          103912: 0707070064030147511006440000030000030000011777770507310726000004300000014376/newbits/kernel/USRSRC/coh/clock.c/* $Header: /x/usr/src/sys/coh/RCS/clock.c,v 1.2 91/06/20 14:12:44 hal Exp $ */
        !          103913: /* (lgl-
        !          103914:  *     The information contained herein is a trade secret of Mark Williams
        !          103915:  *     Company, and  is confidential information.  It is provided  under a
        !          103916:  *     license agreement,  and may be  copied or disclosed  only under the
        !          103917:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          103918:  *     material without the express written authorization of Mark Williams
        !          103919:  *     Company or persuant to the license agreement is unlawful.
        !          103920:  *
        !          103921:  *     COHERENT Version 2.3.37
        !          103922:  *     Copyright (c) 1982, 1983, 1984.
        !          103923:  *     An unpublished work by Mark Williams Company, Chicago.
        !          103924:  *     All rights reserved.
        !          103925:  -lgl) */
        !          103926: /*
        !          103927:  * Coherent.
        !          103928:  * Clock.
        !          103929:  * The clock comes in two parts.  There is the routine `clock' which
        !          103930:  * gets called every tick at high priority.  It does the minimum it
        !          103931:  * can and returns as soon as possible.  The second routine, `stand',
        !          103932:  * gets called whenever we are about to return from an interrupt to
        !          103933:  * user mode a low priority.  It can look at flags that the clock set
        !          103934:  * and do the things the clock really wanted to do but didn't have time.
        !          103935:  * Stand is truly the kernel of the system.
        !          103936:  *
        !          103937:  * 90/08/13    Hal Snyder              /usr/src/sys/coh/clock.c
        !          103938:  * Add external altclk to allow polled device drivers.
        !          103939:  * (extern'ed in coherent.h)
        !          103940:  * 
        !          103941:  * 87/10/26    Allan cornish           /usr/src/sys/coh/clock.c
        !          103942:  * Timed functions are now invoked with TIM * tp as second argument.
        !          103943:  * This facilitates the use of timed functions within loadable drivers.
        !          103944:  *
        !          103945:  * 87/07/07    Allan Cornish           /usr/src/sys/coh/clock.c
        !          103946:  * Clocks static variable added - incremented by clock, decremented by stand().
        !          103947:  * Lbolt variable added - clock ticks since startup - incremented by stand().
        !          103948:  * Support for multiple timing queues ported from RTX.
        !          103949:  *
        !          103950:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/clock.c
        !          103951:  * stand() now only wakes &stimer if swap timer is active.
        !          103952:  *
        !          103953:  * 86/11/24    Allan Cornish           /usr/src/sys/coh/clock.c
        !          103954:  * Added support for new t_last field in tim struct.
        !          103955:  *
        !          103956:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/clock.c
        !          103957:  * Stand() calls defend() to execute functions deferred from interrupt level.
        !          103958:  */
        !          103959: #include <sys/coherent.h>
        !          103960: #include <sys/con.h>
        !          103961: #include <sys/proc.h>
        !          103962: #include <sys/sched.h>
        !          103963: #include <sys/stat.h>
        !          103964: #include <sys/timeout.h>
        !          103965: #include <sys/uproc.h>
        !          103966: #include <sys/mdata.h>
        !          103967: 
        !          103968: int (*altclk)();       /* pointer to higher-speed clock function */
        !          103969: int altsel;    /* if nonzero, CS for LOADABLE driver owning altclk() */
        !          103970: 
        !          103971: static int clocks;
        !          103972: 
        !          103973: /*
        !          103974:  * This routine is called once every tick (1/HZ seconds).
        !          103975:  * It gets called with the programme counter that was interrupted
        !          103976:  * a flag telling whether we were in user or kernel mode and the
        !          103977:  * previous priority we were in.
        !          103978:  */
        !          103979: clock(pc, umode)
        !          103980: vaddr_t pc;
        !          103981: {
        !          103982:        register PROC *pp;
        !          103983:        /*
        !          103984:         * Ignore clock interrupts till we are ready.
        !          103985:         */
        !          103986:        if (batflag == 0)
        !          103987:                return;
        !          103988: 
        !          103989:        /*
        !          103990:         * Hook for alternate clock interrupt;
        !          103991:         * Call polling function ("altclk") if there is one.
        !          103992:         *
        !          103993:         * For near function, "altsel" is 0 and "altclk" is offset.
        !          103994:         * For far function, "altsel" is the CS selector and "altclk"
        !          103995:         * is the offset.
        !          103996:         *
        !          103997:         * Since the polling function ends with a near rather than
        !          103998:         * far return, far invocation is via ld_call() (ldas.s) which uses
        !          103999:         * the despatch routine at CS:4 (ld.s) in any loadable driver.
        !          104000:         */
        !          104001:        if (altclk) {
        !          104002:                if (altsel) {   /* will do far call to altclk fn */
        !          104003:                        if (ld_call(altsel, altclk))
        !          104004:                                return;
        !          104005:                } else
        !          104006:                        if ((*altclk)())
        !          104007:                                return;
        !          104008:        }
        !          104009: 
        !          104010:        /*
        !          104011:         * Update timers.  Decrement time slice.
        !          104012:         */
        !          104013:        utimer += 1;
        !          104014:        clocks += 1;
        !          104015:        timer.t_tick += 1;
        !          104016:        quantum -= 1;
        !          104017: 
        !          104018:        /*
        !          104019:         * Give processes their schedule values per tick.
        !          104020:         */
        !          104021:        if (procq.p_lforw->p_cval > CVCLOCK) {
        !          104022:                procq.p_lforw->p_cval -= CVCLOCK;
        !          104023:                procq.p_cval += CVCLOCK;
        !          104024:        }
        !          104025: 
        !          104026:        /*
        !          104027:         * Tax current process and update his times.
        !          104028:         */
        !          104029:        pp = SELF;
        !          104030:        pp->p_cval >>= 1;
        !          104031:        if (umode == 0)
        !          104032:                pp->p_stime++;
        !          104033:        else {
        !          104034:                pp->p_utime++;
        !          104035:                u.u_ppc = pc;
        !          104036:        }
        !          104037: }
        !          104038: 
        !          104039: /*
        !          104040:  * Do everything the clock wanted to do but couldn't as it would have
        !          104041:  * taken too long.
        !          104042:  * Also perform any system bookkeeping required at regular intervals.
        !          104043:  */
        !          104044: stand()
        !          104045: {
        !          104046:        int s;
        !          104047: 
        !          104048:        u.u_error = 0;
        !          104049: 
        !          104050:        /*
        !          104051:         * Update the clock.
        !          104052:         */
        !          104053:        while (timer.t_tick >= HZ) {
        !          104054:                timer.t_time++;
        !          104055:                timer.t_tick -= HZ;
        !          104056:                outflag = 1;
        !          104057:        }
        !          104058: 
        !          104059:        /*
        !          104060:         * Check expiration of quantum.
        !          104061:         */
        !          104062:        if (quantum <= 0) {
        !          104063:                quantum = 0;
        !          104064:                disflag = 1;
        !          104065:        }
        !          104066: 
        !          104067:        /*
        !          104068:         * Check the timed function queue if necessary.
        !          104069:         */
        !          104070:        if ( clocks > 0 )
        !          104071:        do {
        !          104072:                register TIM * np;
        !          104073:                register TIM * tp;
        !          104074: 
        !          104075:                /*
        !          104076:                 * Update [serviced] clock ticks since startup.
        !          104077:                 */
        !          104078:                lbolt++;
        !          104079: 
        !          104080:                /*
        !          104081:                 * Remove timing list from queue, creating new temporary queue.
        !          104082:                 */
        !          104083:                tp = (TIM *) &timq[ lbolt % nel(timq) ];
        !          104084:                s  = sphi();
        !          104085: 
        !          104086:                /*
        !          104087:                 * Scan timing list.
        !          104088:                 */
        !          104089:                for ( np = tp->t_next; tp = np; ) {
        !          104090: 
        !          104091:                        /*
        !          104092:                         * Remember next function in timing list.
        !          104093:                         * NOTE: Must be done before function is invoked,
        !          104094:                         *       since it may start a new timer.
        !          104095:                         */
        !          104096:                        np = tp->t_next;
        !          104097: 
        !          104098:                        /*
        !          104099:                         * Function has not timed out: leave it on timing list.
        !          104100:                         */
        !          104101:                        if ( tp->t_lbolt != lbolt )
        !          104102:                                continue;
        !          104103: 
        !          104104:                        /*
        !          104105:                         * Remove function from timing list.
        !          104106:                         */
        !          104107:                        if ( tp->t_last->t_next = tp->t_next )
        !          104108:                                tp->t_next->t_last = tp->t_last;
        !          104109:                        tp->t_last = NULL;
        !          104110: 
        !          104111:                        /*
        !          104112:                         * Invoke function.
        !          104113:                         */
        !          104114:                        spl(s);
        !          104115:                        (*tp->t_func)( tp->t_farg, tp );
        !          104116:                        sphi();
        !          104117:                }
        !          104118: 
        !          104119:                spl( s );
        !          104120: 
        !          104121:        } while ( --clocks > 0 );
        !          104122: 
        !          104123:        /*
        !          104124:         * Timeout any devices.
        !          104125:         */
        !          104126:        if (outflag) {
        !          104127:                register int n;
        !          104128: 
        !          104129:                outflag = 0;
        !          104130:                for (n=0; n<drvn; n++) {
        !          104131:                        if (drvl[n].d_time == 0)
        !          104132:                                continue;
        !          104133:                        s = sphi();
        !          104134:                        dtime((dev_t)makedev(n, 0));
        !          104135:                        spl(s);
        !          104136:                }
        !          104137:        }
        !          104138: 
        !          104139:        /*
        !          104140:         * Do profiling.
        !          104141:         */
        !          104142:        if (u.u_pscale != 0) {
        !          104143:                register unsigned p;
        !          104144:                register vaddr_t a;
        !          104145: 
        !          104146:                p = u.u_pscale;
        !          104147:                a = (int *)u.u_pbase +
        !          104148:                    pscale(u.u_ppc-u.u_pofft, p/sizeof (int));
        !          104149:                if (a < u.u_pbend)
        !          104150:                        putuwd(a, getuwd(a)+1);
        !          104151:        }
        !          104152: 
        !          104153:        /*
        !          104154:         * Check for signals and execute them.
        !          104155:         */
        !          104156:        if (SELF->p_ssig)
        !          104157:                actvsig();
        !          104158: 
        !          104159:        /*
        !          104160:         * Execute deferred functions.
        !          104161:         */
        !          104162:        defend();
        !          104163: 
        !          104164:        /*
        !          104165:         * Should we dispatch?
        !          104166:         */
        !          104167:        if ((SELF->p_flags&PFDISP) != 0) {
        !          104168:                SELF->p_flags &= ~PFDISP;
        !          104169:                disflag = 1;
        !          104170:                if ( stimer.t_last != 0 )
        !          104171:                        wakeup((char *)&stimer);
        !          104172:        }
        !          104173: 
        !          104174: #ifdef QWAKEUP
        !          104175:        /*
        !          104176:         * Dispatch pending wakeups.
        !          104177:         */
        !          104178:        while (ntowake)
        !          104179:                wakeup2();
        !          104180: 
        !          104181: #endif
        !          104182:        /*
        !          104183:         * Redispatch.
        !          104184:         * This used to be a function call in tsave,
        !          104185:         * expanded in line here.
        !          104186:         */
        !          104187:        if (disflag) {
        !          104188:                register PROC *pp;
        !          104189: 
        !          104190: #ifndef QWAKEUP
        !          104191:                s=sphi();
        !          104192: #endif
        !          104193:                if ((pp=SELF)!=iprocp)
        !          104194:                        setrun(pp);
        !          104195:                dispatch();
        !          104196: #ifndef QWAKEUP
        !          104197:                spl(s);
        !          104198: #endif
        !          104199:        }
        !          104200: }
        !          104201: 0707070064030110731006440000030000030000011777770507310726200004200000031434/newbits/kernel/USRSRC/coh/exec.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/exec.c,v 1.4 91/07/24 07:50:20 bin Exp Locker: bin $ */
        !          104202: /* (lgl-
        !          104203:  *     The information contained herein is a trade secret of Mark Williams
        !          104204:  *     Company, and  is confidential information.  It is provided  under a
        !          104205:  *     license agreement,  and may be  copied or disclosed  only under the
        !          104206:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          104207:  *     material without the express written authorization of Mark Williams
        !          104208:  *     Company or persuant to the license agreement is unlawful.
        !          104209:  *
        !          104210:  *     COHERENT Version 2.3.37
        !          104211:  *     Copyright (c) 1982, 1983, 1984.
        !          104212:  *     An unpublished work by Mark Williams Company, Chicago.
        !          104213:  *     All rights reserved.
        !          104214:  -lgl) */
        !          104215: /*
        !          104216:  * Coherent.
        !          104217:  * Exec and driver load code.
        !          104218:  *
        !          104219:  * $Log:       exec.c,v $
        !          104220:  * Revision 1.4  91/07/24  07:50:20  bin
        !          104221:  * update prov by hal
        !          104222:  * 
        !          104223:  * 
        !          104224:  * Revision 1.1        88/03/24  16:13:39      src
        !          104225:  * Initial revision
        !          104226:  * 
        !          104227:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/exec.c
        !          104228:  * Exsread() initializes the (new) (IO).io_flag field to 0.
        !          104229:  */
        !          104230: #include <sys/coherent.h>
        !          104231: #include <acct.h>
        !          104232: #include <sys/buf.h>
        !          104233: #include <canon.h>
        !          104234: #include <sys/con.h>
        !          104235: #include <errno.h>
        !          104236: #include <sys/filsys.h>
        !          104237: #include <sys/ino.h>
        !          104238: #include <sys/inode.h>
        !          104239: #include <l.out.h>
        !          104240: #include <sys/proc.h>
        !          104241: #include <sys/seg.h>
        !          104242: #include <signal.h>
        !          104243: #include <sys/uproc.h>
        !          104244: 
        !          104245: /*
        !          104246:  * Sizes.
        !          104247:  */
        !          104248: #define        sh      ((fsize_t)sizeof(struct ldheader))
        !          104249: #define si     lssize[L_SHRI]
        !          104250: #define pi     lssize[L_PRVI]
        !          104251: #define bi     lssize[L_BSSI]
        !          104252: #define sd     lssize[L_SHRD]
        !          104253: #define pd     lssize[L_PRVD]
        !          104254: #define bd     lssize[L_BSSD]
        !          104255: 
        !          104256: /*
        !          104257:  * Segments.
        !          104258:  */
        !          104259: #define upsp   pp->p_segp[SIUSERP]
        !          104260: #define sssp   pp->p_segp[SISTACK]
        !          104261: #define        sisp    pp->p_segp[SISTEXT]
        !          104262: #define pisp   pp->p_segp[SIPTEXT]
        !          104263: #define sdsp   pp->p_segp[SISDATA]
        !          104264: #define pdsp   pp->p_segp[SIPDATA]
        !          104265: 
        !          104266: /*
        !          104267:  * Set up the first process, a small programme which will exec
        !          104268:  * the init programme.
        !          104269:  */
        !          104270: eveinit(sp)
        !          104271: SEG *sp;
        !          104272: {
        !          104273:        register PROC *pp;
        !          104274: 
        !          104275:        SELF = pp = eprocp;
        !          104276:        pp->p_segp[SIUSERP] = sp;
        !          104277:        if ((sp=salloc((fsize_t)icodes, 0)) == NULL)
        !          104278:                panic("eveinit()");
        !          104279:        pp->p_segp[SIPDATA] = sp;
        !          104280:        kscopy(icodep, sp, 0, icodes);
        !          104281:        if ((sp=salloc((fsize_t)UPASIZE, SFDOWN)) == NULL)
        !          104282:                panic("eveinit()");
        !          104283:        pp->p_segp[SISTACK] = sp;
        !          104284:        u.u_argp = 0;
        !          104285:        if (sproto() == 0)
        !          104286:                panic("eveinit()");
        !          104287:        segload();
        !          104288: }
        !          104289: 
        !          104290: /*
        !          104291:  * Given a major number, a file containing a device driver and a configuration
        !          104292:  * pointer, load the driver on the major number.
        !          104293:  */
        !          104294: pload(m, np, cp)
        !          104295: char *np;
        !          104296: CON *cp;
        !          104297: {
        !          104298:        register INODE *ip;
        !          104299:        register SEG *sp;
        !          104300:        register DRV *dp;
        !          104301:        register fsize_t ss;
        !          104302:        dold_t dold;
        !          104303:        int lflag;
        !          104304:        int r;
        !          104305:        vaddr_t pc;
        !          104306:        fsize_t lssize[NUSEG];
        !          104307: 
        !          104308:        if (m >= drvn) {
        !          104309:                u.u_error = ENXIO;
        !          104310:                return;
        !          104311:        }
        !          104312:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
        !          104313:                return;
        !          104314:        ss = pi+si+pd+sd;
        !          104315:        sp = ssalloc(&r, ip, SFSHRX, ss+bi+bd, sh, ss);
        !          104316:        idetach(ip);
        !          104317:        if (r < 0)
        !          104318:                return;
        !          104319:        dp = &drvl[m];
        !          104320:        lock(dp->d_gate);
        !          104321:        if (dp->d_conp != NULL) {
        !          104322:                unlock(dp->d_gate);
        !          104323:                sfree(sp);
        !          104324:                u.u_error = EDBUSY;
        !          104325:                return;
        !          104326:        }
        !          104327:        dp->d_time = 0;
        !          104328:        dp->d_conp = cp;
        !          104329:        dp->d_segp = sp;
        !          104330:        dp->d_map = sp->s_mbase;
        !          104331:        dsave(dold);
        !          104332:        dmapv(dp->d_map);
        !          104333:        (*cp->c_load)();
        !          104334:        drest(dold);
        !          104335:        unlock(dp->d_gate);
        !          104336: }
        !          104337: 
        !          104338: /*
        !          104339:  * Given a major number, undo the previous function.
        !          104340:  */
        !          104341: puload(m)
        !          104342: int m;
        !          104343: {
        !          104344:        register CON *cp;
        !          104345:        register DRV *dp;
        !          104346:        dold_t dold;
        !          104347: 
        !          104348:        dp = &drvl[m];
        !          104349:        lock(dp->d_gate);
        !          104350:        if (m>=drvn || dp->d_segp==NULL || (cp=dp->d_conp)==NULL) {
        !          104351:                u.u_error = ENXIO;
        !          104352:                goto ret;
        !          104353:        }
        !          104354:        dsave(dold);
        !          104355:        dmapv(dp->d_map);
        !          104356:        (*cp->c_uload)();
        !          104357:        drest(dold);
        !          104358:        if (u.u_error)
        !          104359:                goto ret;
        !          104360:        sfree(dp->d_segp);
        !          104361:        dp->d_conp = NULL;
        !          104362:        dp->d_segp = NULL;
        !          104363:        dp->d_map = 0;
        !          104364: ret:
        !          104365:        unlock(dp->d_gate);
        !          104366:        return (0);
        !          104367: }
        !          104368: 
        !          104369: /*
        !          104370:  * Given the name of an executable l.out, a null terminated argument
        !          104371:  * list and a null terminated environment list, execute the l.out with the
        !          104372:  * given arguments and environments.
        !          104373:  */
        !          104374: pexece(np, argp, envp)
        !          104375: char   *np;
        !          104376: char   *argp[];
        !          104377: char   *envp[];
        !          104378: {
        !          104379:        register INODE  *ip;                    /* Load file INODE */
        !          104380:        register PROC   *pp;                    /* A cheap copy of SELF */
        !          104381:        register SEG    *ssp;                   /* New stack segment */
        !          104382:        register fsize_t        ss;                     /* Segment size temp. */
        !          104383:        register int    kprocflag;              /* Set if kernal process */
        !          104384:        register int    i;                      /* For looping over segments */
        !          104385:        int             r;                      /* Flag for "exload" */
        !          104386:        int             lflag;                  /* l_flags from l.out */
        !          104387:        vaddr_t         pc;                     /* l_entry from l.out */
        !          104388:        vaddr_t         sp;                     /* Initial stack pointer */
        !          104389:        fsize_t         lssize[NUSEG];          /* Segment sizes */
        !          104390: 
        !          104391:        pp = SELF;
        !          104392:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
        !          104393:                return;
        !          104394:        if ((lflag&LF_KER) != 0) {
        !          104395:                pp->p_flags |= PFKERN;
        !          104396:                kprocflag = 1;
        !          104397:                ssp = NULL;
        !          104398:                if (super() == 0) {
        !          104399:                        idetach(ip);
        !          104400:                        return;
        !          104401:                }
        !          104402:        } else {
        !          104403:                kprocflag = 0;
        !          104404:                if ((ssp=exstack(&sp, argp, envp)) == NULL) {
        !          104405:                        idetach(ip);
        !          104406:                        return;
        !          104407:                }
        !          104408:        }
        !          104409:        /*
        !          104410:         * At this point the file has been
        !          104411:         * validated as an object module, and the
        !          104412:         * argument list has been build. Release all of
        !          104413:         * the original segments. At this point we have
        !          104414:         * committed to the new image. A "sys exec" that
        !          104415:         * gets an I/O error is doomed.
        !          104416:         */
        !          104417:        for (i=1; i<NUSEG; ++i) {
        !          104418:                if (pp->p_segp[i] != NULL) {
        !          104419:                        sfree(pp->p_segp[i]);
        !          104420:                        pp->p_segp[i] = NULL;
        !          104421:                }
        !          104422:        }
        !          104423:        sssp = ssp;
        !          104424:        /*
        !          104425:         * Read in load module.
        !          104426:         */
        !          104427:        switch (lflag&(LF_SHR|LF_SEP)) {
        !          104428:        case 0:
        !          104429:                ss = si+pi+sd+pd;
        !          104430:                pdsp = ssalloc(&r, ip, kprocflag?SFHIGH:0, ss+bi+bd, sh, ss);
        !          104431:                if (r < 0)
        !          104432:                        goto out;
        !          104433:                break;
        !          104434: 
        !          104435:        case LF_SHR:
        !          104436:                sdsp = ssalloc(&r, ip, SFSHRX, si+sd, sh, si);
        !          104437:                if (r < 0)
        !          104438:                        goto out;
        !          104439:                if (r == 0) {
        !          104440:                        if (exsread(sdsp, ip, sd, sh+si+pi, si) == 0)
        !          104441:                                goto out;
        !          104442:                }
        !          104443:                pdsp = ssalloc(&r, ip, 0, pi+pd+bi+bd, sh+si, pi);
        !          104444:                if (r < 0)
        !          104445:                        goto out;
        !          104446:                if (r == 0) {
        !          104447:                        if (exsread(pdsp, ip, pd, sh+si+pi+sd, pi) == 0)
        !          104448:                                goto out;
        !          104449:                }
        !          104450:                break;
        !          104451: 
        !          104452:        case LF_SEP:
        !          104453:                pisp = ssalloc(&r, ip, SFTEXT, si+pi+bi, sh, si+pi);
        !          104454:                if (r < 0)
        !          104455:                        goto out;
        !          104456:                pdsp = ssalloc(&r, ip, 0, sd+pd+bd, sh+si+bi, sd+pd);
        !          104457:                if (r < 0)
        !          104458:                        goto out;
        !          104459:                break;
        !          104460: 
        !          104461:        case LF_SHR|LF_SEP:
        !          104462:                sisp = ssalloc(&r, ip, SFSHRX|SFTEXT, si, sh, si);
        !          104463:                if (r < 0)
        !          104464:                        goto out;
        !          104465:                pisp = ssalloc(&r, ip, SFTEXT, pi+bi, sh+si, pi);
        !          104466:                if (r < 0)
        !          104467:                        goto out;
        !          104468:                sdsp = ssalloc(&r, ip, SFSHRX, sd, sh+si+pi, sd);
        !          104469:                if (r < 0)
        !          104470:                        goto out;
        !          104471:                pdsp = ssalloc(&r, ip, 0, pd+bd, sh+si+pi+pd, pd);
        !          104472:                if (r < 0)
        !          104473:                        goto out;
        !          104474:        }
        !          104475:        if (sproto() == 0)
        !          104476:                goto out;
        !          104477:        /*
        !          104478:         * The new image is read in
        !          104479:         * and mapped. Perform the final grunge
        !          104480:         * (set-uid stuff, accounting, loading up
        !          104481:         * registers, etc).
        !          104482:         */
        !          104483:        u.u_flag &= ~AFORK;
        !          104484:        kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm));
        !          104485:        if (iaccess(ip, IPR) == 0)
        !          104486:                pp->p_flags |= PFNDMP;
        !          104487:        if ((ip->i_mode&ISUID) != 0)
        !          104488:                pp->p_uid = u.u_uid = ip->i_uid;
        !          104489:        if ((ip->i_mode&ISGID) != 0)
        !          104490:                u.u_gid = ip->i_gid;
        !          104491:        for (i=0; i<NSIG; ++i) {
        !          104492:                if (u.u_sfunc[i] != SIG_IGN)
        !          104493:                        u.u_sfunc[i] = SIG_DFL;
        !          104494:        }
        !          104495:        if ((pp->p_flags&PFTRAC) != 0)
        !          104496:                sendsig(SIGTRAP, pp);
        !          104497:        idetach(ip);
        !          104498:        msetusr(pc, sp);
        !          104499:        segload();
        !          104500:        return (0);
        !          104501: 
        !          104502:        /*
        !          104503:         * We did not make it.
        !          104504:         * Release the INODE for the load
        !          104505:         * file, and return through the "sys exit"
        !          104506:         * code. A better exit status should be
        !          104507:         * chosen!
        !          104508:         */
        !          104509: out:
        !          104510:        idetach(ip);
        !          104511:        pexit(0);
        !          104512: }
        !          104513: 
        !          104514: /*
        !          104515:  * Open an l.out, make sure it is an l.out and executable and return the
        !          104516:  * appropriate information.
        !          104517:  */
        !          104518: INODE *
        !          104519: exlopen(np, ssizep, flagp, pcp)
        !          104520: char *np;
        !          104521: fsize_t *ssizep;
        !          104522: int *flagp;
        !          104523: vaddr_t *pcp;
        !          104524: {
        !          104525:        register INODE *ip;
        !          104526:        register struct ldheader *ldp;
        !          104527:        register int n;
        !          104528:        register BUF *bp;
        !          104529:        int m;
        !          104530: 
        !          104531:        /*
        !          104532:         * Make sure the file is really an executable l.out and read the
        !          104533:         * header in.
        !          104534:         */
        !          104535:        if (ftoi(np, 'r') != 0)
        !          104536:                return (NULL);
        !          104537:        ip = u.u_cdiri;
        !          104538:        if (iaccess(ip, IPE) == 0) {
        !          104539:                idetach(ip);
        !          104540:                return (NULL);
        !          104541:        }
        !          104542:        if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) {
        !          104543:                u.u_error = EACCES;
        !          104544:                idetach(ip);
        !          104545:                return (NULL);
        !          104546:        }
        !          104547:        if ((bp=vread(ip, (daddr_t)0)) == NULL) {
        !          104548:                u.u_error = EBADFMT;
        !          104549:                idetach(ip);
        !          104550:                return (NULL);
        !          104551:        }
        !          104552: 
        !          104553:        /*
        !          104554:         * Copy everything we need from the l.out header and check magic
        !          104555:         * number and machine type.
        !          104556:         */
        !          104557:        ldp = bp->b_vaddr;
        !          104558:        m = ldp->l_magic;
        !          104559:        canint(m);
        !          104560:        if (m != L_MAGIC) {
        !          104561:                u.u_error = ENOEXEC;
        !          104562:                brelease(bp);
        !          104563:                idetach(ip);
        !          104564:                return (NULL);
        !          104565:        }
        !          104566:        m = ldp->l_machine;
        !          104567:        canint(m);
        !          104568:        if (m != mactype) {
        !          104569:                u.u_error = EBADFMT;
        !          104570:                brelease(bp);
        !          104571:                idetach(ip);
        !          104572:                return (NULL);
        !          104573:        }
        !          104574:        kkcopy(ldp->l_ssize, ssizep, NXSEG*sizeof(fsize_t));
        !          104575:        for (n=0; n<NXSEG; n++)
        !          104576:                cansize(ssizep[n]);
        !          104577:        *flagp = ldp->l_flag;
        !          104578:        canint(*flagp);
        !          104579:        *pcp = ldp->l_entry;
        !          104580:        canvaddr(*pcp);
        !          104581:        brelease(bp);
        !          104582:        return (ip);
        !          104583: }
        !          104584: 
        !          104585: /*
        !          104586:  * Given a segment `sp', read `ss' bytes from the inode `ip' starting
        !          104587:  * at seek address `sa' into offset `so' in the segment.
        !          104588:  */
        !          104589: SEG *
        !          104590: exsread(sp, ip, ss, sa, so)
        !          104591: register SEG *sp;
        !          104592: INODE *ip;
        !          104593: fsize_t sa;
        !          104594: fsize_t ss;
        !          104595: fsize_t so;
        !          104596: {
        !          104597:        u.u_io.io_seg = IOPHY;
        !          104598:        u.u_io.io_ioc = ss;
        !          104599:        u.u_io.io_seek = sa;
        !          104600:        u.u_io.io_phys = ctob((paddr_t)sp->s_mbase) + so;
        !          104601:        u.u_io.io_flag = 0;
        !          104602:        iread(ip, &u.u_io);
        !          104603:        return (u.u_error==0);
        !          104604: }
        !          104605: 
        !          104606: /*
        !          104607:  * Given a pointer to a list of arguments and a pointer to a list of
        !          104608:  * environments, return a stack with the arguments and environments on it.
        !          104609:  */
        !          104610: SEG *
        !          104611: exstack(iusp, argp, envp)
        !          104612: char **iusp;           /* Back patch sp value */
        !          104613: char *argp[];          /* Arguments for new process */
        !          104614: char *envp[];          /* Environments for new process */
        !          104615: {
        !          104616:        SEG *sp;                /* Stack segment pointer */
        !          104617:        struct adata {          /* Storage for arg and env data */
        !          104618:                char    **up;           /* User vector pointer */
        !          104619:                int     np;             /* Number of pointers in vector */
        !          104620:                int     nc;             /* Number of characters in strings */
        !          104621:        } arg, env;
        !          104622:        struct sdata {          /* To keep segment pointers */
        !          104623:                vaddr_t base;           /* Top of segment virtual */
        !          104624:                vaddr_t ap;             /* Argc, argv, envp pointer */
        !          104625:                vaddr_t vp;             /* Argv[i], envp[i] pointer */
        !          104626:                vaddr_t cp;             /* Argv[i][j], envp[i][j] pointer */
        !          104627:        } aux, stk;
        !          104628:        aold_t aold;                    /* Auxiliary map storage */
        !          104629:        register char **usrvp;          /* Vector pointer into user seg */
        !          104630:        register char *usrcp;           /* Character pointer into user seg */
        !          104631:        register int c;                 /* Character fetched from user */
        !          104632:        register int chrsz;             /* Size of strings */
        !          104633:        register struct adata *adp;     /* Arg and env scanner */
        !          104634:        register int vecsz;             /* Size of vectors */
        !          104635:        register int stksz;             /* Size of stack argument region */
        !          104636: 
        !          104637:        /* Validate and evaluate size of args and envs */
        !          104638:        arg.up = argp;
        !          104639:        env.up = envp;
        !          104640:        chrsz = 0;
        !          104641:        vecsz = 0;
        !          104642:        for (adp = &arg; ; adp = &env) {
        !          104643:                adp->np = 0;
        !          104644:                adp->nc = 0;
        !          104645:                if (excount(adp->up, &adp->np, &adp->nc) == 0)
        !          104646:                        return (NULL);
        !          104647:                chrsz += adp->nc * sizeof(char);
        !          104648:                vecsz += adp->np * sizeof(char *);
        !          104649:                if (adp == &env)
        !          104650:                        break;
        !          104651:        }
        !          104652: 
        !          104653:        /* Calculate stack size and allocate it */
        !          104654:        chrsz = roundu(chrsz, sizeof(int));
        !          104655:        stksz = sizeof(int)             /* argc */
        !          104656:                + sizeof(char **)       /* argv */
        !          104657:                + sizeof(char **)       /* envp */
        !          104658:                + vecsz                 /* argv[i] and envp[i] */
        !          104659:                + chrsz                 /* *argv[i] and *envp[i] */
        !          104660:                + sizeof(int)           /* Mystery zero word */
        !          104661:                + sizeof(char *)        /* Splimit for z8000 */
        !          104662:                + sizeof(int);          /* errno */
        !          104663:        stksz += ISTSIZE;
        !          104664:        if (stksz > MADSIZE) {
        !          104665:                u.u_error = E2BIG;
        !          104666:                return (NULL);
        !          104667:        }
        !          104668:        if ((sp=salloc((fsize_t)stksz, SFDOWN)) == NULL)
        !          104669:                return (NULL);
        !          104670:        stksz -= ISTSIZE;
        !          104671: 
        !          104672:        /*
        !          104673:         * Initialize segment data.
        !          104674:         */
        !          104675:        asave(aold);
        !          104676: 
        !          104677:        aux.base = abase(sp->s_mbase) + ctob(sp->s_size);
        !          104678:        aux.ap = aux.base - stksz;
        !          104679:        aux.vp = aux.ap + sizeof(int) + 2*sizeof(char **);
        !          104680:        aux.cp = aux.vp + vecsz;
        !          104681: 
        !          104682:        stk.base = ISTVIRT;
        !          104683:        stk.ap = stk.base - stksz;
        !          104684:        stk.vp = stk.ap + sizeof(int) + 2*sizeof(char **);
        !          104685:        stk.cp = stk.vp + vecsz;
        !          104686: 
        !          104687:        /*
        !          104688:         * Write argc.
        !          104689:         */
        !          104690:        aputi((int *)aux.ap, arg.np-1);
        !          104691:        aux.ap += sizeof(int);
        !          104692: 
        !          104693:        /*
        !          104694:         * Arguments and environments.
        !          104695:         */
        !          104696:        for (adp = &arg; ; adp = &env) {
        !          104697: 
        !          104698:                /* Write argv or envp */
        !          104699:                aputp((char ***)aux.ap, (char **)stk.vp);
        !          104700:                aux.ap += sizeof(char **);
        !          104701:                if ((usrvp = adp->up) != NULL) {
        !          104702: 
        !          104703:                        /* Write argv[i] or envp[i] */
        !          104704:                        while ((usrcp = getupd(usrvp++)) != NULL) {
        !          104705:                                aputp((char **)aux.vp, (char *)stk.cp);
        !          104706:                                aux.vp += sizeof(char *);
        !          104707:                                stk.vp += sizeof(char *);
        !          104708: 
        !          104709:                                /* Write argv[i][j] or envp[i][j] */
        !          104710:                                do {
        !          104711:                                        c = getubd(usrcp++);
        !          104712:                                        aputc((char *)aux.cp, c);
        !          104713:                                        aux.cp += sizeof(char);
        !          104714:                                        stk.cp += sizeof(char);
        !          104715:                                } while (c != '\0');
        !          104716:                        }
        !          104717:                }
        !          104718: 
        !          104719:                /* Write argv[argc] or envp[envc] */
        !          104720:                aputp((char **)aux.vp, NULL);
        !          104721:                aux.vp += sizeof(char *);
        !          104722:                stk.vp += sizeof(char *);
        !          104723:                if (adp == &env)
        !          104724:                        break;
        !          104725:        }
        !          104726: 
        !          104727:        /*
        !          104728:         * Clear out the slop.
        !          104729:         */
        !          104730:        aux.base -= sizeof(int);
        !          104731:        aputi((int *) aux.base, 0);             /* errno */
        !          104732:        aux.base -= sizeof(char *);
        !          104733:        aputp((char **) aux.base, (char *)stk.base-ctob(sp->s_size)+SOVSIZE);
        !          104734:        aux.base -= sizeof(int);
        !          104735:        aputi((int *) aux.base, 0);             /* mystery word */
        !          104736: 
        !          104737:        arest(aold);
        !          104738: 
        !          104739:        /*
        !          104740:         * Patch some values and return.
        !          104741:         */
        !          104742:        *iusp = stk.ap;         /* Patch initial usp */
        !          104743:        u.u_argc = arg.np-1;
        !          104744:        u.u_argp = stk.vp;      /* Points after NULL of envs */
        !          104745:        return (sp);
        !          104746: }
        !          104747: 
        !          104748: /*
        !          104749:  * Given a pointer to a list of arguments, a pointer to an argument count
        !          104750:  * and a pointer to a byte count, update incrementally the argument count
        !          104751:  * and the byte count.
        !          104752:  */
        !          104753: excount(usrvp, nap, nbp)
        !          104754: register char **usrvp;
        !          104755: int *nap;
        !          104756: int *nbp;
        !          104757: {
        !          104758:        register char *usrcp;
        !          104759:        register int c;
        !          104760:        register unsigned nb;
        !          104761:        register unsigned na;
        !          104762: 
        !          104763:        na = 1;
        !          104764:        nb = 0;
        !          104765:        if (usrvp != NULL) {
        !          104766:                for (;;) {
        !          104767:                        usrcp = getupd(usrvp++);
        !          104768:                        if (u.u_error)
        !          104769:                                return (0);
        !          104770:                        if (usrcp == NULL)
        !          104771:                                break;
        !          104772:                        na++;
        !          104773:                        for (;;) {
        !          104774:                                c = getubd(usrcp++);
        !          104775:                                if (u.u_error)
        !          104776:                                        return (0);
        !          104777:                                nb++;
        !          104778:                                if (c == '\0')
        !          104779:                                        break;
        !          104780:                        }
        !          104781:                }
        !          104782:        }
        !          104783:        *nap += na;
        !          104784:        *nbp += nb;
        !          104785:        return (1);
        !          104786: }
        !          104787: 0707070064030147521006440000030000030000011777770507310726500004000000006425/newbits/kernel/USRSRC/coh/fd.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/fd.c,v 1.4 91/07/24 07:50:35 bin Exp Locker: bin $ */
        !          104788: /* (lgl-
        !          104789:  *     The information contained herein is a trade secret of Mark Williams
        !          104790:  *     Company, and  is confidential information.  It is provided  under a
        !          104791:  *     license agreement,  and may be  copied or disclosed  only under the
        !          104792:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          104793:  *     material without the express written authorization of Mark Williams
        !          104794:  *     Company or persuant to the license agreement is unlawful.
        !          104795:  *
        !          104796:  *     COHERENT Version 2.3.37
        !          104797:  *     Copyright (c) 1982, 1983, 1984.
        !          104798:  *     An unpublished work by Mark Williams Company, Chicago.
        !          104799:  *     All rights reserved.
        !          104800:  -lgl) */
        !          104801: /*
        !          104802:  * Coherent.
        !          104803:  * File descriptor routines.
        !          104804:  *
        !          104805:  * $Log:       fd.c,v $
        !          104806:  * Revision 1.4  91/07/24  07:50:35  bin
        !          104807:  * update prov by hal
        !          104808:  * 
        !          104809:  * 
        !          104810:  * Revision 1.1        88/03/24  16:13:43      src
        !          104811:  * Initial revision
        !          104812:  * 
        !          104813:  */
        !          104814: #include <sys/coherent.h>
        !          104815: #include <errno.h>
        !          104816: #include <sys/fd.h>
        !          104817: #include <sys/inode.h>
        !          104818: #include <sys/uproc.h>
        !          104819: 
        !          104820: /*
        !          104821:  * Given a file number, return the file descriptor.
        !          104822:  */
        !          104823: FD *
        !          104824: fdget(fd)
        !          104825: register unsigned fd;
        !          104826: {
        !          104827:        register FD *fdp;
        !          104828: 
        !          104829:        if (fd>=NUFILE || (fdp=u.u_filep[fd])==NULL) {
        !          104830:                u.u_error = EBADF;
        !          104831:                return (NULL);
        !          104832:        }
        !          104833:        return (fdp);
        !          104834: }
        !          104835: 
        !          104836: /*
        !          104837:  * Duplicate a file descriptor number.  This has the same calling
        !          104838:  * sequence as the dup2 system call and even uses the silly DUP2 bit.
        !          104839:  */
        !          104840: fddup(ofd, nfd)
        !          104841: register unsigned ofd;
        !          104842: register unsigned nfd;
        !          104843: {
        !          104844:        register FD *fdp;
        !          104845: 
        !          104846:        if ((fdp=fdget(ofd&~DUP2)) == NULL)
        !          104847:                return (-1);
        !          104848:        if ((ofd&DUP2) != 0) {
        !          104849:                if (nfd >= NUFILE) {
        !          104850:                        u.u_error = EBADF;
        !          104851:                        return (-1);
        !          104852:                }
        !          104853:                ofd &= ~DUP2;
        !          104854:                if (ofd == nfd)
        !          104855:                        return (nfd);
        !          104856:                if (u.u_filep[nfd] != NULL) {
        !          104857:                        fdclose(nfd);
        !          104858:                        if (u.u_error)
        !          104859:                                return (-1);
        !          104860:                }
        !          104861:        } else {
        !          104862:                for (nfd=0; nfd<NUFILE; nfd++)
        !          104863:                        if (u.u_filep[nfd] == NULL)
        !          104864:                                break;
        !          104865:                if (nfd == NUFILE) {
        !          104866:                        u.u_error = EMFILE;
        !          104867:                        return (-1);
        !          104868:                }
        !          104869:        }
        !          104870:        u.u_filep[nfd] = fdp;
        !          104871:        fdp->f_refc++;
        !          104872:        return (nfd);
        !          104873: }
        !          104874: 
        !          104875: /*
        !          104876:  * Given an inode, and a mode containing permission flags, open the
        !          104877:  * inode with the appropriate permissions and return a file descriptor
        !          104878:  * containing it.
        !          104879:  */
        !          104880: fdopen(ip, mode)
        !          104881: register INODE *ip;
        !          104882: {
        !          104883:        register FD **fdpp;
        !          104884:        register FD *fdp;
        !          104885: 
        !          104886:        for (fdpp=u.u_filep; fdpp<&u.u_filep[NUFILE]; fdpp++) {
        !          104887:                if (*fdpp != NULL)
        !          104888:                        continue;
        !          104889:                if ((fdp=kalloc(sizeof(FD))) == NULL)
        !          104890:                        return (-1);
        !          104891:                iopen(ip, mode);
        !          104892:                if (u.u_error) {
        !          104893:                        kfree(fdp);
        !          104894:                        return (-1);
        !          104895:                }
        !          104896:                fdp->f_flag = mode;
        !          104897:                fdp->f_refc = 1;
        !          104898:                fdp->f_seek = 0;
        !          104899:                fdp->f_ip = ip;
        !          104900:                *fdpp = fdp;
        !          104901:                return (fdpp-u.u_filep);
        !          104902:        }
        !          104903:        u.u_error = EMFILE;
        !          104904:        return (-1);
        !          104905: }
        !          104906: 
        !          104907: /*
        !          104908:  * Close the given file number.
        !          104909:  */
        !          104910: fdclose(fd)
        !          104911: register unsigned fd;
        !          104912: {
        !          104913:        register FD *fdp;
        !          104914: 
        !          104915:        if (fd>=NUFILE || (fdp=u.u_filep[fd])==NULL) {
        !          104916:                u.u_error = EBADF;
        !          104917:                return;
        !          104918:        }
        !          104919:        u.u_filep[fd] = NULL;
        !          104920:        if (fdp->f_refc == 0)
        !          104921:                panic("fdclose()");
        !          104922:        if (--fdp->f_refc == 0) {
        !          104923:                iclose(fdp->f_ip);
        !          104924:                kfree(fdp);
        !          104925:        }
        !          104926: }
        !          104927: 
        !          104928: /*
        !          104929:  * Assuming we have made a copy of the user area, increment the reference
        !          104930:  * of all open files.  (used in fork).
        !          104931:  */
        !          104932: fdadupl()
        !          104933: {
        !          104934:        register FD **fdpp;
        !          104935:        register FD *fdp;
        !          104936: 
        !          104937:        for (fdpp=u.u_filep; fdpp<&u.u_filep[NUFILE]; fdpp++) {
        !          104938:                if ((fdp=*fdpp) == NULL)
        !          104939:                        continue;
        !          104940:                fdp->f_refc++;
        !          104941:        }
        !          104942: }
        !          104943: 
        !          104944: /*
        !          104945:  * Close all open files in the current process.
        !          104946:  */
        !          104947: fdaclose()
        !          104948: {
        !          104949:        register int fd;
        !          104950: 
        !          104951:        for (fd=0; fd<NUFILE; fd++) {
        !          104952:                if (u.u_filep[fd] == NULL)
        !          104953:                        continue;
        !          104954:                fdclose(fd);
        !          104955:        }
        !          104956: }
        !          104957: 0707070064030103701006440000030000030000011777770507310726500004100000034033/newbits/kernel/USRSRC/coh/fs1.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/fs1.c,v 1.5 91/07/24 07:50:40 bin Exp Locker: bin $ */
        !          104958: /* (lgl-
        !          104959:  *     The information contained herein is a trade secret of Mark Williams
        !          104960:  *     Company, and  is confidential information.  It is provided  under a
        !          104961:  *     license agreement,  and may be  copied or disclosed  only under the
        !          104962:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          104963:  *     material without the express written authorization of Mark Williams
        !          104964:  *     Company or persuant to the license agreement is unlawful.
        !          104965:  *
        !          104966:  *     COHERENT Version 2.3.37
        !          104967:  *     Copyright (c) 1982, 1983, 1984.
        !          104968:  *     An unpublished work by Mark Williams Company, Chicago.
        !          104969:  *     All rights reserved.
        !          104970:  -lgl) */
        !          104971: /*
        !          104972:  * Coherent.
        !          104973:  * Filesystem (mostly handling of in core inodes).
        !          104974:  *
        !          104975:  * $Log:       fs1.c,v $
        !          104976:  * Revision 1.5  91/07/24  07:50:40  bin
        !          104977:  * update prov by hal
        !          104978:  * 
        !          104979:  * 
        !          104980:  * Revision 1.1        88/03/24  16:13:47      src
        !          104981:  * Initial revision
        !          104982:  * 
        !          104983:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/fs1.c
        !          104984:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          104985:  *
        !          104986:  * 86/12/13    Allan Cornish           /usr/src/sys/coh/fs1.c
        !          104987:  * isync() no longer updates the disk image of a character device inode.
        !          104988:  *
        !          104989:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/fs1.c
        !          104990:  * idirent() initializes the (new) (IO).io_flag field to 0.
        !          104991:  */
        !          104992: #include <sys/coherent.h>
        !          104993: #include <sys/buf.h>
        !          104994: #include <canon.h>
        !          104995: #include <sys/dir.h>
        !          104996: #include <errno.h>
        !          104997: #include <sys/filsys.h>
        !          104998: #include <sys/ino.h>
        !          104999: #include <sys/inode.h>
        !          105000: #include <sys/io.h>
        !          105001: #include <sys/mount.h>>
        !          105002: #include <sys/stat.h>
        !          105003: #include <sys/uproc.h>
        !          105004: 
        !          105005: /*
        !          105006:  * Get character for `ftoi' depending on what space the characters are
        !          105007:  * coming from.
        !          105008:  */
        !          105009: #define ftoic(p)       (u.u_io.io_seg==IOSYS ? *p : getubd(p))
        !          105010: 
        !          105011: /*
        !          105012:  * Map the given filename to an inode.  If an error is encountered,
        !          105013:  * `u.u_error' is set.  `u.u_error' is always returned.  As this routine
        !          105014:  * needs to set several things, depending on the type of access, `t',
        !          105015:  * there are places in the processes' user area reserved for this routine
        !          105016:  * to set.  These are defined in the user process structure.  The seek
        !          105017:  * position is always set to the position of the directory entry of the
        !          105018:  * child if the child exists or the first free position if it doesn't.
        !          105019:  *  'r' =>  Reference.  A pointer to the child's inode is returned locked.
        !          105020:  *  'c' =>  Create.  If the child exists, a pointer to the inode is returned
        !          105021:  *          locked.  Otherwise if the parent directory exists, a pointer to
        !          105022:  *          the parent directory is returned locked.  Otherwise, an error.
        !          105023:  *  'u' =>  Unlink.  The parent directory is returned unlocked.  The child's
        !          105024:  *          inode number is returned.  The seek position is also set.
        !          105025:  */
        !          105026: ftoi(np, t)
        !          105027: char *np;
        !          105028: {
        !          105029:        register INODE *cip;
        !          105030:        register char *cp;
        !          105031:        register int c;
        !          105032:        register struct direct *dp;
        !          105033:        register BUF *bp;
        !          105034:        fsize_t cseek, fseek, s;
        !          105035:        int fflag, mflag;
        !          105036:        dev_t dev;
        !          105037:        ino_t ino;
        !          105038:        daddr_t b;
        !          105039: 
        !          105040:        u.u_cdirn = 0;
        !          105041:        u.u_cdiri = NULL;
        !          105042:        u.u_pdiri = NULL;
        !          105043:        if ((c=ftoic(np++)) != '/')
        !          105044:                cip = u.u_cdir;
        !          105045:        else {
        !          105046:                c = ftoic(np++);
        !          105047:                cip = u.u_rdir;
        !          105048:        }
        !          105049:        while (c == '/')
        !          105050:                c = ftoic(np++);
        !          105051:        ilock(cip);
        !          105052:        cip->i_refc++;
        !          105053:        if (c == '\0') {
        !          105054:                if (t == 'r') {
        !          105055:                        u.u_cdiri = cip;
        !          105056:                        return (u.u_error);
        !          105057:                }
        !          105058:                u.u_error = ENOENT;
        !          105059:                idetach(cip);
        !          105060:                return (u.u_error);
        !          105061:        }
        !          105062:        for (;;) {
        !          105063:                cp = u.u_direct.d_name;
        !          105064:                while (c!='/' && c!='\0') {
        !          105065:                        if (cp < &u.u_direct.d_name[DIRSIZ])
        !          105066:                                *cp++ = c;
        !          105067:                        c = ftoic(np++);
        !          105068:                }
        !          105069:                while (c == '/')
        !          105070:                        c = ftoic(np++);
        !          105071:                while (cp < &u.u_direct.d_name[DIRSIZ])
        !          105072:                        *cp++ = '\0';
        !          105073:                if ((cip->i_mode&IFMT) != IFDIR)
        !          105074:                        u.u_error = ENOTDIR;
        !          105075:                else
        !          105076:                        iaccess(cip, IPE);
        !          105077:                if (u.u_error) {
        !          105078:                        idetach(cip);
        !          105079:                        return (u.u_error);
        !          105080:                }
        !          105081:                cp = u.u_direct.d_name;
        !          105082:                if (cip->i_ino==ROOTIN && cip->i_dev!=rootdev)
        !          105083:                        if (*cp++=='.' && *cp++=='.' && *cp++=='\0')
        !          105084:                                cip = ftoim(cip);
        !          105085:                b = 0;
        !          105086:                fflag = 0;
        !          105087:                mflag = 0;
        !          105088:                cseek = 0;
        !          105089:                s = cip->i_size;
        !          105090:                while (s > 0) {
        !          105091:                        if ((bp=vread(cip, b++)) == NULL) {
        !          105092:                                idetach(cip);
        !          105093:                                return (u.u_error);
        !          105094:                        }
        !          105095:                        dp = FP_OFF(bp->b_faddr);
        !          105096:                        while (dp < FP_OFF(bp->b_faddr)+BSIZE) {
        !          105097:                                if ((s-=sizeof(*dp)) < 0)
        !          105098:                                        break;
        !          105099:                                if ((ino=dp->d_ino) == 0) {
        !          105100:                                        if (fflag == 0) {
        !          105101:                                                fflag++;
        !          105102:                                                fseek = cseek;
        !          105103:                                        }
        !          105104:                                } else {
        !          105105:                                        if (direq(dp)) {
        !          105106:                                                canino(ino);
        !          105107:                                                mflag = 1;
        !          105108:                                                s = 0;
        !          105109:                                                break;
        !          105110:                                        }
        !          105111:                                }
        !          105112:                                cseek += sizeof(*dp);
        !          105113:                                dp++;
        !          105114:                        }
        !          105115:                        brelease(bp);
        !          105116:                }
        !          105117:                dev = cip->i_dev;
        !          105118:                if (fflag == 0)
        !          105119:                        fseek = cseek;
        !          105120:                if (mflag == 0) {
        !          105121:                        if (c=='\0' && t=='c') {
        !          105122:                                u.u_pdiri = cip;
        !          105123:                                u.u_io.io_seek = fseek;
        !          105124:                        } else {
        !          105125:                                u.u_error = ENOENT;
        !          105126:                                idetach(cip);
        !          105127:                        }
        !          105128:                        return (u.u_error);
        !          105129:                }
        !          105130:                if (c == '\0') {
        !          105131:                        if (t == 'u') {
        !          105132:                                u.u_cdirn = ino;
        !          105133:                                u.u_pdiri = cip;
        !          105134:                                u.u_io.io_seek = cseek;
        !          105135:                                return (u.u_error);
        !          105136:                        }
        !          105137:                        idetach(cip);
        !          105138:                        u.u_cdiri = iattach(dev, ino);
        !          105139:                        return (u.u_error);
        !          105140:                }
        !          105141:                idetach(cip);
        !          105142:                if ((cip=iattach(dev, ino)) == NULL)
        !          105143:                        return (u.u_error);
        !          105144:        }
        !          105145: }
        !          105146: 
        !          105147: /*
        !          105148:  * Given an inode which is the root of a file system, return the inode
        !          105149:  * on which the file system was mounted.
        !          105150:  */
        !          105151: INODE *
        !          105152: ftoim(ip)
        !          105153: register INODE *ip;
        !          105154: {
        !          105155:        register MOUNT *mp;
        !          105156: 
        !          105157:        for (mp=mountp; mp!=NULL; mp=mp->m_next) {
        !          105158:                if (mp->m_dev == ip->i_dev) {
        !          105159:                        idetach(ip);
        !          105160:                        ip = mp->m_ip;
        !          105161:                        ilock(ip);
        !          105162:                        ip->i_refc++;
        !          105163:                        break;
        !          105164:                }
        !          105165:        }
        !          105166:        return (ip);
        !          105167: }
        !          105168: 
        !          105169: /*
        !          105170:  * Compare the string in `u.u_direct.d_name' with the name in the
        !          105171:  * given directory pointer.
        !          105172:  */
        !          105173: direq(dp)
        !          105174: struct direct *dp;
        !          105175: {
        !          105176:        register char *cp1, *cp2;
        !          105177:        register unsigned n;
        !          105178: 
        !          105179:        if (dp->d_ino == 0)
        !          105180:                return (0);
        !          105181:        cp1 = dp->d_name;
        !          105182:        cp2 = u.u_direct.d_name;
        !          105183:        n = DIRSIZ;
        !          105184:        do {
        !          105185:                if (*cp1++ != *cp2++)
        !          105186:                        return (0);
        !          105187:        } while (--n);
        !          105188:        return (1);
        !          105189: }
        !          105190: 
        !          105191: /*
        !          105192:  * Make an inode of the given mode and device.  The parent directory,
        !          105193:  * name and such stuff is set by ftoi.
        !          105194:  */
        !          105195: INODE *
        !          105196: imake(mode, rdev)
        !          105197: unsigned mode;
        !          105198: dev_t rdev;
        !          105199: {
        !          105200:        register INODE *ip;
        !          105201: 
        !          105202:        ip = NULL;
        !          105203:        mode &= ~u.u_umask;
        !          105204:        if ((mode&ISVTXT)!=0 && super()==0)
        !          105205:                goto det;
        !          105206:        if (iaccess(u.u_pdiri, IPW) == 0)
        !          105207:                goto det;
        !          105208:        if ((ip=ialloc(u.u_pdiri->i_dev, mode)) == NULL)
        !          105209:                goto det;
        !          105210:        ip->i_nlink = 1;
        !          105211:        ip->i_a.i_rdev = rdev;
        !          105212:        idirent(ip->i_ino);
        !          105213:        iamc(ip);       /* creat/mknod - atime/mtime/ctime */
        !          105214: det:
        !          105215:        idetach(u.u_pdiri);
        !          105216:        return (ip);
        !          105217: }
        !          105218: 
        !          105219: /*
        !          105220:  * Write a directory entry out.  Everything necessary has been conveniently
        !          105221:  * set by `ftoi', except the new inode number of this directory entry.
        !          105222:  */
        !          105223: idirent(ino)
        !          105224: {
        !          105225:        u.u_direct.d_ino = ino;
        !          105226:        canino(u.u_direct.d_ino);
        !          105227:        u.u_io.io_ioc  = sizeof (struct direct);
        !          105228:        u.u_io.io_base = &u.u_direct;
        !          105229:        u.u_io.io_seg  = IOSYS;
        !          105230:        u.u_io.io_flag = 0;
        !          105231:        iwrite(u.u_pdiri, &u.u_io);
        !          105232: }
        !          105233: 
        !          105234: /*
        !          105235:  * Return a pointer to a locked inode in core containing the given
        !          105236:  * inode number and device.
        !          105237:  */
        !          105238: INODE *
        !          105239: iattach(dev, ino)
        !          105240: {
        !          105241:        register INODE *ip;
        !          105242:        register INODE *fip;
        !          105243:        register unsigned lrt;
        !          105244:        register MOUNT *mp;
        !          105245: 
        !          105246:        for (;;) {
        !          105247:                fip = NULL;
        !          105248:                for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          105249:                        if (ip->i_ino==ino && ip->i_dev==dev)
        !          105250:                                break;
        !          105251:                        if (ip->i_refc == 0) {
        !          105252:                                if (fip==NULL || ip->i_lrt<lrt) {
        !          105253:                                        fip = ip;
        !          105254:                                        lrt = ip->i_lrt;
        !          105255:                                }
        !          105256:                        }
        !          105257:                }
        !          105258:                if (ip < inodep) {
        !          105259:                        if ((ip=fip) == NULL) {
        !          105260:                                devmsg(dev, "Inode table overflow");
        !          105261: /*DEBUG*/
        !          105262: { char cmd[11];int i;
        !          105263: for(i=0;i<10&&u.u_comm[i];i++)
        !          105264:     cmd[i]=u.u_comm[i];
        !          105265: cmd[i]='\0';
        !          105266: printf("cmd=%s time=%lu\n",cmd, u.u_btime);
        !          105267: }
        !          105268:                                u.u_error = ENFILE;
        !          105269:                                return (NULL);
        !          105270:                        }
        !          105271:                        ilock(ip);
        !          105272:                        if (ip->i_refc != 0) {
        !          105273:                                iunlock(ip);
        !          105274:                                continue;
        !          105275:                        }
        !          105276:                        ip->i_dev = dev;
        !          105277:                        ip->i_ino = ino;
        !          105278:                        ip->i_refc = 1;
        !          105279:                        ip->i_lrt = timer.t_time;
        !          105280:                        if (icopydm(ip) == 0) {
        !          105281:                                ip->i_ino = 0;
        !          105282:                                ip->i_refc = 0;
        !          105283:                                iunlock(ip);
        !          105284:                                return (NULL);
        !          105285:                        }
        !          105286:                        return (ip);
        !          105287:                }
        !          105288:                if ((ip->i_flag&IFMNT) != 0) {
        !          105289:                        for (mp=mountp; mp!=NULL; mp=mp->m_next) {
        !          105290:                                if (mp->m_ip == ip) {
        !          105291:                                        ino = ROOTIN;
        !          105292:                                        dev = mp->m_dev;
        !          105293:                                        break;
        !          105294:                                }
        !          105295:                        }
        !          105296:                        continue;
        !          105297:                }
        !          105298:                ilock(ip);
        !          105299:                if (ip->i_ino!=ino || ip->i_dev!=dev) {
        !          105300:                        iunlock(ip);
        !          105301:                        continue;
        !          105302:                }
        !          105303:                if (ip->i_refc < 0)
        !          105304:                        panic("ialloc(%p), ip");
        !          105305:                ip->i_refc++;
        !          105306:                ip->i_lrt = timer.t_time;
        !          105307:                return (ip);
        !          105308:        }
        !          105309: }
        !          105310: 
        !          105311: /*
        !          105312:  * Given a locked inode, deaccess it.
        !          105313:  */
        !          105314: idetach(ip)
        !          105315: register INODE *ip;
        !          105316: {
        !          105317:        if (ilocked(ip)==0 || ip->i_refc<=0)
        !          105318:                panic("idetach(%p)", ip);
        !          105319:        if (--ip->i_refc == 0) {
        !          105320:                if ((ip->i_flag&(IFACC|IFMOD|IFCRT)) != 0
        !          105321:                 || ip->i_nlink == 0)
        !          105322:                        icopymd(ip);
        !          105323:        }
        !          105324:        iunlock(ip);
        !          105325: }
        !          105326: 
        !          105327: /*
        !          105328:  * Given a inode which isn't locked, lock it and then deaccess.
        !          105329:  */
        !          105330: ldetach(ip)
        !          105331: register INODE *ip;
        !          105332: {
        !          105333:        ilock(ip);
        !          105334:        idetach(ip);
        !          105335: }
        !          105336: 
        !          105337: /*
        !          105338:  * A specialized routine for finding whether the given inode may be unlinked.
        !          105339:  * Quite simple you say, but we already have an inode locked and could run
        !          105340:  * into gating problems if we were to lock another.  So we look through the
        !          105341:  * cache to see if the inode is there.  If it is, we can easily tell.  If it
        !          105342:  * isn't, `icopydm' is called with a static.  This routine is only used by
        !          105343:  * `uunlink'.
        !          105344:  */
        !          105345: iucheck(dev, ino)
        !          105346: register dev_t dev;
        !          105347: register ino_t ino;
        !          105348: {
        !          105349:        register INODE *ip;
        !          105350:        INODE inode;
        !          105351: 
        !          105352:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          105353:                if (ip->i_ino==ino && ip->i_dev==dev)
        !          105354:                        break;
        !          105355:        }
        !          105356:        if (ip < inodep) {
        !          105357:                ip = &inode;
        !          105358:                ip->i_dev = dev;
        !          105359:                ip->i_ino = ino;
        !          105360:                if (icopydm(ip) == 0)
        !          105361:                        return (0);
        !          105362:        }
        !          105363:        if ((ip->i_mode&IFMT) == IFDIR) {
        !          105364:                if (super() == 0)
        !          105365:                        return (0);
        !          105366:        }
        !          105367:        return (1);
        !          105368: }
        !          105369: 
        !          105370: /*
        !          105371:  * Copy an inode from disk to memory performing canonization.
        !          105372:  */
        !          105373: icopydm(ip)
        !          105374: register INODE *ip;
        !          105375: {
        !          105376:        register struct dinode *dip;
        !          105377:        register BUF *bp;
        !          105378:        register ino_t ino;
        !          105379:        struct dinode dinode;
        !          105380:        vaddr_t v;
        !          105381: 
        !          105382:        ip->i_flag = 0;
        !          105383:        ino = ip->i_ino;
        !          105384: 
        !          105385:        if ((bp=bread(ip->i_dev, (daddr_t)iblockn(ino), 1)) == NULL)
        !          105386:                return (0);
        !          105387: 
        !          105388:        dip = &dinode;
        !          105389:        v = (char *)((struct dinode *)FP_OFF(bp->b_faddr) + iblocko(ino));
        !          105390:        kkcopy( v, dip, sizeof(dinode));
        !          105391:        brelease(bp);
        !          105392:        ip->i_mode = dip->di_mode;
        !          105393:        canshort(ip->i_mode);
        !          105394:        ip->i_nlink = dip->di_nlink;
        !          105395:        canshort(ip->i_nlink);
        !          105396:        ip->i_uid = dip->di_uid;
        !          105397:        canshort(ip->i_uid);
        !          105398:        ip->i_gid = dip->di_gid;
        !          105399:        canshort(ip->i_gid);
        !          105400:        ip->i_size = dip->di_size;
        !          105401:        cansize(ip->i_size);
        !          105402: 
        !          105403:        switch (ip->i_mode&IFMT) {
        !          105404:        case IFBLK:
        !          105405:        case IFCHR:
        !          105406:                ip->i_a.i_rdev = dip->di_a.di_rdev;
        !          105407:                candev(ip->i_a.i_rdev);
        !          105408:                break;
        !          105409:        case IFREG:
        !          105410:        case IFDIR:
        !          105411:                l3tol(ip->i_a.i_addr, dip->di_a.di_addb, NADDR);
        !          105412:                break;
        !          105413:        case IFPIPE:
        !          105414:                l3tol(ip->i_pipe, dip->di_addp, ND);
        !          105415:                ip->i_pnc = dip->di_pnc;
        !          105416:                canint(ip->i_pnc);
        !          105417:                ip->i_prx = dip->di_prx;
        !          105418:                canint(ip->i_prx);
        !          105419:                ip->i_pwx = dip->di_pwx;
        !          105420:                canint(ip->i_pwx);
        !          105421:                break;
        !          105422:        default:
        !          105423:                kclear(&ip->i_a, sizeof(ip->i_a));
        !          105424:                break;
        !          105425:        }
        !          105426: 
        !          105427:        ip->i_atime = dip->di_atime;
        !          105428:        cantime(ip->i_atime);
        !          105429:        ip->i_mtime = dip->di_mtime;
        !          105430:        cantime(ip->i_mtime);
        !          105431:        ip->i_ctime = dip->di_ctime;
        !          105432:        cantime(ip->i_ctime);
        !          105433:        return (1);
        !          105434: }
        !          105435: 
        !          105436: /*
        !          105437:  * Copy an inode from memory back on to disk performing canonization.
        !          105438:  */
        !          105439: icopymd(ip)
        !          105440: register INODE *ip;
        !          105441: {
        !          105442:        register struct dinode *dip;
        !          105443:        register BUF *bp;
        !          105444:        register ino_t ino;
        !          105445:        struct dinode dinode;
        !          105446:        vaddr_t v;
        !          105447: 
        !          105448:        if (getment(ip->i_dev, 0) == NULL)
        !          105449:                return;
        !          105450: 
        !          105451:        ino = ip->i_ino;
        !          105452:        if (ip->i_refc==0 && ip->i_nlink==0 && ino!=BADFIN && ino!=ROOTIN) {
        !          105453:                iclear(ip);
        !          105454:                ip->i_lrt = 0;
        !          105455:                ip->i_mode = 0;
        !          105456:                ifree(ip->i_dev, ino);
        !          105457:        }
        !          105458: 
        !          105459:        dip = &dinode;
        !          105460:        dip->di_mode = ip->i_mode;
        !          105461:        canshort(dip->di_mode);
        !          105462:        dip->di_nlink = ip->i_nlink;
        !          105463:        canshort(dip->di_nlink);
        !          105464:        dip->di_uid = ip->i_uid;
        !          105465:        canshort(dip->di_uid);
        !          105466:        dip->di_gid = ip->i_gid;
        !          105467:        canshort(dip->di_gid);
        !          105468:        dip->di_size = ip->i_size;
        !          105469:        cansize(dip->di_size);
        !          105470: 
        !          105471:        switch (ip->i_mode&IFMT) {
        !          105472:        case IFBLK:
        !          105473:        case IFCHR:
        !          105474:                dip->di_a.di_rdev = ip->i_a.i_rdev;
        !          105475:                candev(dip->di_a.di_rdev);
        !          105476:                break;
        !          105477:        case IFREG:
        !          105478:        case IFDIR:
        !          105479:                ltol3(dip->di_addr, ip->i_a.i_addr, NADDR);
        !          105480:                break;
        !          105481:        case IFPIPE:
        !          105482:                ltol3(dip->di_addp, ip->i_pipe, ND);
        !          105483:                dip->di_pnc = ip->i_pnc;
        !          105484:                canshort(dip->di_pnc);
        !          105485:                dip->di_prx = ip->i_prx;
        !          105486:                canshort(dip->di_prx);
        !          105487:                dip->di_pwx = ip->i_pwx;
        !          105488:                canshort(dip->di_pwx);
        !          105489:                break;
        !          105490:        default:
        !          105491:                kclear(&dip->di_a, sizeof(dip->di_a));
        !          105492:                break;
        !          105493:        }
        !          105494: 
        !          105495:        dip->di_atime = ip->i_atime;
        !          105496:        cantime(dip->di_atime);
        !          105497:        dip->di_mtime = ip->i_mtime;
        !          105498:        cantime(dip->di_mtime);
        !          105499:        dip->di_ctime = ip->i_ctime;
        !          105500:        cantime(dip->di_ctime);
        !          105501: 
        !          105502:        if ((bp=bread(ip->i_dev, (daddr_t)iblockn(ino), 1)) == NULL)
        !          105503:                return;
        !          105504: 
        !          105505:        v = (char *)((struct dinode *)FP_OFF(bp->b_faddr) + iblocko(ino));
        !          105506:        kkcopy(dip, v, sizeof(dinode));
        !          105507:        bp->b_flag |= BFMOD;
        !          105508:        brelease(bp);
        !          105509:        ip->i_flag &= ~(IFACC|IFMOD|IFCRT);
        !          105510: }
        !          105511: 
        !          105512: /*
        !          105513:  * Copy all relevant inodes out on device `dev'.
        !          105514:  */
        !          105515: isync(dev)
        !          105516: register dev_t dev;
        !          105517: {
        !          105518:        register INODE *ip;
        !          105519: 
        !          105520:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          105521:                if (ip->i_refc == 0)
        !          105522:                        continue;
        !          105523:                if (ip->i_dev != dev)
        !          105524:                        continue;
        !          105525:                if ( (ip->i_mode & IFMT) == IFCHR )
        !          105526:                        continue;
        !          105527:                if ((ip->i_flag&(IFACC|IFMOD|IFCRT)) == 0)
        !          105528:                        continue;
        !          105529:                icopymd(ip);
        !          105530:        }
        !          105531: }
        !          105532: 
        !          105533: /*
        !          105534:  * Clear the given inode and all space associated with it.
        !          105535:  */
        !          105536: iclear(ip)
        !          105537: register INODE *ip;
        !          105538: {
        !          105539:        register int n;
        !          105540:        register daddr_t b;
        !          105541: 
        !          105542:        switch (ip->i_mode&IFMT) {
        !          105543:        case IFPIPE:
        !          105544:                ip->i_pnc = 0;
        !          105545:                ip->i_prx = 0;
        !          105546:                ip->i_pwx = 0;
        !          105547:                n = ND;
        !          105548:                break;
        !          105549:        case IFDIR:
        !          105550:        case IFREG:
        !          105551:                n = NADDR;
        !          105552:                break;
        !          105553:        default:
        !          105554:                return;
        !          105555:        }
        !          105556:        while (n > ND) {
        !          105557:                if ((b=ip->i_a.i_addr[--n]) != 0)
        !          105558:                        indfree(ip->i_dev, b, 1+n-ND);
        !          105559:        }
        !          105560:        while (n > 0) {
        !          105561:                if ((b=ip->i_a.i_addr[--n]) != 0)
        !          105562:                        bfree(ip->i_dev, b);
        !          105563:        }
        !          105564:        ip->i_size = 0;
        !          105565:        kclear(ip->i_a.i_addr, sizeof(ip->i_a.i_addr));
        !          105566:        iamc(ip);       /* creat/pipe - atime/mtime/ctime */
        !          105567: }
        !          105568: 
        !          105569: /*
        !          105570:  * Copy the appropriate information from the inode to the stat buffer.
        !          105571:  */
        !          105572: istat(ip, sbp)
        !          105573: register INODE *ip;
        !          105574: register struct stat *sbp;
        !          105575: {
        !          105576:        sbp->st_dev = ip->i_dev;
        !          105577:        sbp->st_ino = ip->i_ino;
        !          105578:        sbp->st_mode = ip->i_mode;
        !          105579:        sbp->st_nlink = ip->i_nlink;
        !          105580:        sbp->st_uid = ip->i_uid;
        !          105581:        sbp->st_gid = ip->i_gid;
        !          105582:        sbp->st_rdev = NODEV;
        !          105583:        sbp->st_size = ip->i_size;
        !          105584:        sbp->st_atime = ip->i_atime;
        !          105585:        sbp->st_mtime = ip->i_mtime;
        !          105586:        sbp->st_ctime = ip->i_ctime;
        !          105587:        switch (ip->i_mode&IFMT) {
        !          105588:        case IFBLK:
        !          105589:        case IFCHR:
        !          105590:                sbp->st_rdev = ip->i_a.i_rdev;
        !          105591:                sbp->st_size = 0;
        !          105592:                break;
        !          105593:        case IFPIPE:
        !          105594:                sbp->st_size = ip->i_pnc;
        !          105595:                break;
        !          105596:        }
        !          105597: }
        !          105598: 
        !          105599: /*
        !          105600:  * See if it is possible to access the given inode with the bits in
        !          105601:  * the given mode.
        !          105602:  * If the mode includes writing, and i_refc is > 1, then check for
        !          105603:  * shared text problems.
        !          105604:  */
        !          105605: iaccess(ip, mode)
        !          105606: register INODE *ip;
        !          105607: register int mode;
        !          105608: {
        !          105609:        if ((imode(ip, u.u_uid, u.u_gid)&mode) != mode) {
        !          105610:                u.u_error = EACCES;
        !          105611:                return (0);
        !          105612:        }
        !          105613:        if ((mode&IPW) != 0 && ip->i_refc > 1 && sbusy(ip)) {
        !          105614:                u.u_error = ETXTBSY;
        !          105615:                return (0);
        !          105616:        }
        !          105617:        return (1);
        !          105618: }
        !          105619: 
        !          105620: /*
        !          105621:  * Get the maximum allowable mode on a file.
        !          105622:  */
        !          105623: imode(ip, uid, gid)
        !          105624: register INODE *ip;
        !          105625: {
        !          105626:        if (uid == 0)
        !          105627:                return (IPR|IPW|IPE);
        !          105628:        if (uid == ip->i_uid)
        !          105629:                return ((ip->i_mode>>6)&07);
        !          105630:        if (gid == ip->i_gid)
        !          105631:                return ((ip->i_mode>>3)&07);
        !          105632:        return (ip->i_mode&07);
        !          105633: }
        !          105634: 0707070064030103671006440000030000030000011777770507310727100004100000024166/newbits/kernel/USRSRC/coh/fs2.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/fs2.c,v 1.4 91/07/24 07:50:55 bin Exp Locker: bin $ */
        !          105635: /* (lgl-
        !          105636:  *     The information contained herein is a trade secret of Mark Williams
        !          105637:  *     Company, and  is confidential information.  It is provided  under a
        !          105638:  *     license agreement,  and may be  copied or disclosed  only under the
        !          105639:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          105640:  *     material without the express written authorization of Mark Williams
        !          105641:  *     Company or persuant to the license agreement is unlawful.
        !          105642:  *
        !          105643:  *     COHERENT Version 2.3.37
        !          105644:  *     Copyright (c) 1982, 1983, 1984.
        !          105645:  *     An unpublished work by Mark Williams Company, Chicago.
        !          105646:  *     All rights reserved.
        !          105647:  -lgl) */
        !          105648: /*
        !          105649:  * Coherent.
        !          105650:  * Filesystem (disk inodes).
        !          105651:  *
        !          105652:  * $Log:       fs2.c,v $
        !          105653:  * Revision 1.4  91/07/24  07:50:55  bin
        !          105654:  * update prov by hal
        !          105655:  * 
        !          105656:  * 
        !          105657:  * Revision 1.1        88/03/24  16:13:51      src
        !          105658:  * Initial revision
        !          105659:  * 
        !          105660:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/fs2.c
        !          105661:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          105662:  *
        !          105663:  * 87/04/29    Allan Cornish           /usr/src/sys/coh/fs2.c
        !          105664:  * Fsminit panic messages now specify the root major and minor device.
        !          105665:  *
        !          105666:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/fs2.c
        !          105667:  * setacct() initializes the (new) (IO).io_flag field to 0.
        !          105668:  *
        !          105669:  * 85/08/08    Allan Cornish
        !          105670:  * ialloc() erroneously did a brelease(NULL) if bclaim() returned NULL.
        !          105671:  * also, sbp->s_fmod was set BEFORE the in-core inode table was updated.
        !          105672:  * This created a critical race with msync() (called by sync system call).
        !          105673:  *
        !          105674:  * 85/04/17    Allan Cornish
        !          105675:  * eliminated test for rootdev in msync()
        !          105676:  */
        !          105677: #include <sys/coherent.h>
        !          105678: #include <acct.h>
        !          105679: #include <sys/buf.h>
        !          105680: #include <canon.h>
        !          105681: #include <sys/con.h>
        !          105682: #include <errno.h>
        !          105683: #include <sys/filsys.h>
        !          105684: #include <sys/ino.h>
        !          105685: #include <sys/inode.h>
        !          105686: #include <sys/io.h>
        !          105687: #include <sys/mount.h>
        !          105688: #include <sys/proc.h>
        !          105689: #include <sys/stat.h>
        !          105690: #include <sys/uproc.h>
        !          105691: 
        !          105692: /*
        !          105693:  * Initialise filesystem.
        !          105694:  */
        !          105695: fsminit()
        !          105696: {
        !          105697:        register MOUNT *mp;
        !          105698: 
        !          105699:        /*
        !          105700:         * Mount the root file system.
        !          105701:         */
        !          105702:        if ( (mp = fsmount(rootdev, ronflag)) == NULL )
        !          105703:                panic(  "fsminit: no rootdev(%d,%d)",
        !          105704:                        major(rootdev), minor(rootdev) );
        !          105705: 
        !          105706:        /*
        !          105707:         * Set system time from the super block.
        !          105708:         */
        !          105709:        timer.t_time = mp->m_super.s_time;
        !          105710: 
        !          105711:        /*
        !          105712:         * Access the root directory.
        !          105713:         */
        !          105714:        if ( (u.u_rdir = iattach(rootdev, ROOTIN)) == NULL )
        !          105715:                panic(  "fsminit: no / on rootdev(%d,%d)",
        !          105716:                        major(rootdev), minor(rootdev) );
        !          105717: 
        !          105718:        /*
        !          105719:         * Record current directory.
        !          105720:         */
        !          105721:        u.u_cdir = u.u_rdir;
        !          105722:        u.u_cdir->i_refc++;
        !          105723:        iunlock(u.u_rdir);
        !          105724: }
        !          105725: 
        !          105726: /*
        !          105727:  * Mount the given device.
        !          105728:  */
        !          105729: MOUNT *
        !          105730: fsmount(dev, f)
        !          105731: register dev_t dev;
        !          105732: {
        !          105733:        register MOUNT *mp;
        !          105734:        register BUF *bp;
        !          105735: 
        !          105736:        if ((mp=kalloc(sizeof(MOUNT))) == NULL)
        !          105737:                return (NULL);
        !          105738:        dopen(dev, (f?IPR:IPR|IPW), DFBLK);
        !          105739:        if (u.u_error != 0) {
        !          105740:                kfree(mp);
        !          105741:                return (NULL);
        !          105742:        }
        !          105743:        if ((bp=bread(dev, (daddr_t)SUPERI, 1)) == NULL) {
        !          105744:                dclose(dev);
        !          105745:                kfree(mp);
        !          105746:                return (NULL);
        !          105747:        }
        !          105748:        kkcopy(FP_OFF(bp->b_faddr), &mp->m_super, sizeof(struct filsys));
        !          105749:        brelease(bp);
        !          105750:        cansuper(&mp->m_super);
        !          105751:        mp->m_ip = NULL;
        !          105752:        mp->m_dev = dev;
        !          105753:        mp->m_flag = f;
        !          105754:        mp->m_super.s_fmod = 0;
        !          105755:        mp->m_next = mountp;
        !          105756:        mountp = mp;
        !          105757:        return (mp);
        !          105758: }
        !          105759: 
        !          105760: /*
        !          105761:  * Canonize a super block.
        !          105762:  */
        !          105763: cansuper(fsp)
        !          105764: register struct filsys *fsp;
        !          105765: {
        !          105766:        register int i;
        !          105767: 
        !          105768:        canint(fsp->s_isize);
        !          105769:        candaddr(fsp->s_fsize);
        !          105770:        canshort(fsp->s_nfree);
        !          105771:        for (i=0; i<NICFREE; i++)
        !          105772:                candaddr(fsp->s_free[i]);
        !          105773:        canshort(fsp->s_ninode);
        !          105774:        for (i=0; i<NICINOD; i++)
        !          105775:                canino(fsp->s_inode[i]);
        !          105776:        cantime(fsp->s_time);
        !          105777:        candaddr(fsp->s_tfree);
        !          105778:        canino(fsp->s_tinode);
        !          105779:        canshort(fsp->s_m);
        !          105780:        canshort(fsp->s_n);
        !          105781:        canlong(fsp->s_unique);
        !          105782: }
        !          105783: 
        !          105784: /*
        !          105785:  * Given a pointer to a mount entry, write out all inodes on that device.
        !          105786:  */
        !          105787: msync(mp)
        !          105788: register MOUNT *mp;
        !          105789: {
        !          105790:        register struct filsys *sbp;
        !          105791:        register BUF *bp;
        !          105792: 
        !          105793:        if ((mp->m_flag&MFRON) != 0)
        !          105794:                return;
        !          105795:        isync(mp->m_dev);
        !          105796:        sbp = &mp->m_super;
        !          105797:        if (sbp->s_fmod==0)
        !          105798:                return;
        !          105799:        bp = bclaim(mp->m_dev, (daddr_t)SUPERI);
        !          105800:        sbp->s_time = timer.t_time;
        !          105801:        sbp->s_fmod = 0;
        !          105802:        kkcopy(sbp, FP_OFF(bp->b_faddr), sizeof(*sbp));
        !          105803:        cansuper(FP_OFF(bp->b_faddr));
        !          105804:        bwrite(bp, 1);
        !          105805:        brelease(bp);
        !          105806: }
        !          105807: 
        !          105808: /*
        !          105809:  * Return the mount entry for the given device.  If `f' is not set
        !          105810:  * and the device is read only, don't set the error status.
        !          105811:  */
        !          105812: MOUNT *
        !          105813: getment(dev, f)
        !          105814: register dev_t dev;
        !          105815: {
        !          105816:        register MOUNT *mp;
        !          105817: 
        !          105818:        for (mp=mountp; mp!=NULL; mp=mp->m_next) {
        !          105819:                if (mp->m_dev != dev)
        !          105820:                        continue;
        !          105821:                if ((mp->m_flag&MFRON) != 0) {
        !          105822:                        if (f != 0)
        !          105823:                                u.u_error = EROFS;
        !          105824:                        return (NULL);
        !          105825:                }
        !          105826:                return (mp);
        !          105827:        }
        !          105828:        panic("getment: dev=0x%x", dev);
        !          105829: }
        !          105830: 
        !          105831: /*
        !          105832:  * Allocate a new inode with the given mode.  The returned inode is locked.
        !          105833:  */
        !          105834: INODE *
        !          105835: ialloc(dev, mode)
        !          105836: dev_t dev;
        !          105837: unsigned mode;
        !          105838: {
        !          105839:        register struct dinode *dip;
        !          105840:        register struct filsys *sbp;
        !          105841:        register ino_t *inop;
        !          105842:        register ino_t ino;
        !          105843:        register BUF *bp;
        !          105844:        register daddr_t b;
        !          105845:        register struct dinode *dipe;
        !          105846:        register ino_t *inope;
        !          105847:        register MOUNT *mp;
        !          105848:        register INODE *ip;
        !          105849: 
        !          105850:        if ((mp=getment(dev, 1)) == NULL)
        !          105851:                return (NULL);
        !          105852:        sbp = &mp->m_super;
        !          105853:        for (;;) {
        !          105854:                lock(mp->m_ilock);
        !          105855:                if (sbp->s_ninode == 0) {
        !          105856:                        ino = 1;
        !          105857:                        inop = sbp->s_inode;
        !          105858:                        inope = &sbp->s_inode[NICINOD];
        !          105859:                        for (b=INODEI; b<sbp->s_isize; b++) {
        !          105860:                                if (bad(dev, b)) {
        !          105861:                                        ino += INOPB;
        !          105862:                                        continue;
        !          105863:                                }
        !          105864:                                if ((bp=bread(dev, b, 1)) == NULL) {
        !          105865:                                        ino += INOPB;
        !          105866:                                        continue;
        !          105867:                                }
        !          105868:                                dip = FP_OFF(bp->b_faddr);
        !          105869:                                dipe = &dip[INOPB];
        !          105870:                                for (; dip<dipe; dip++, ino++) {
        !          105871:                                        if (dip->di_mode != 0)
        !          105872:                                                continue;
        !          105873:                                        if (inop >= inope)
        !          105874:                                                break;
        !          105875:                                        *inop++ = ino;
        !          105876:                                }
        !          105877:                                brelease(bp);
        !          105878:                                if (inop >= inope)
        !          105879:                                        break;
        !          105880:                        }
        !          105881:                        sbp->s_ninode = inop - sbp->s_inode;
        !          105882:                        if (sbp->s_ninode == 0) {
        !          105883:                                sbp->s_tinode = 0;
        !          105884:                                unlock(mp->m_ilock);
        !          105885:                                devmsg(dev, "Out of inodes");
        !          105886:                                u.u_error = ENOSPC;
        !          105887:                                return (NULL);
        !          105888:                        }
        !          105889:                }
        !          105890:                ino = sbp->s_inode[--sbp->s_ninode];
        !          105891:                --sbp->s_tinode;
        !          105892:                sbp->s_fmod = 1;
        !          105893:                unlock(mp->m_ilock);
        !          105894:                if ((ip=iattach(dev, ino)) != NULL) {
        !          105895:                        if (ip->i_mode != 0) {
        !          105896:                                devmsg(dev, "Inode %u busy", ino);
        !          105897:                                idetach(ip);
        !          105898:                                continue;
        !          105899:                        }
        !          105900:                        ip->i_flag = 0;
        !          105901:                        ip->i_mode = mode;
        !          105902:                        ip->i_nlink = 0;
        !          105903:                        ip->i_uid = u.u_uid;
        !          105904:                        ip->i_gid = u.u_gid;
        !          105905:                }
        !          105906:                return (ip);
        !          105907:        }
        !          105908: }
        !          105909: 
        !          105910: /*
        !          105911:  * Free the inode `ino' on device `dev'.
        !          105912:  */
        !          105913: ifree(dev, ino)
        !          105914: dev_t dev;
        !          105915: ino_t ino;
        !          105916: {
        !          105917:        register struct filsys *sbp;
        !          105918:        register MOUNT *mp;
        !          105919: 
        !          105920:        if ((mp=getment(dev, 1)) == NULL)
        !          105921:                return;
        !          105922:        lock(mp->m_ilock);
        !          105923:        sbp = &mp->m_super;
        !          105924:        sbp->s_fmod = 1;
        !          105925:        if (sbp->s_ninode < NICINOD)
        !          105926:                sbp->s_inode[sbp->s_ninode++] = ino;
        !          105927:        sbp->s_tinode++;
        !          105928:        unlock(mp->m_ilock);
        !          105929: }
        !          105930: 
        !          105931: /*
        !          105932:  * Free all blocks in the indirect block `b' on the device `dev'.
        !          105933:  * `l' is the level of indirection.
        !          105934:  */
        !          105935: indfree(dev, b, l)
        !          105936: dev_t dev;
        !          105937: daddr_t b;
        !          105938: register unsigned l;
        !          105939: {
        !          105940:        register int i;
        !          105941:        register BUF *bp;
        !          105942:        daddr_t * dp;
        !          105943:        daddr_t b1;
        !          105944: 
        !          105945:        if (b == 0)
        !          105946:                return;
        !          105947:        if (l-->0 && (bp=bread(dev, b, 1))!=NULL) {
        !          105948:                i = NBN;
        !          105949:                while (i-- > 0) {
        !          105950:                        dp = FP_OFF(bp->b_faddr);
        !          105951: 
        !          105952:                        if ((b1 = dp[i]) == 0)
        !          105953:                                continue;
        !          105954:                        candaddr(b1);
        !          105955:                        if (l == 0)
        !          105956:                                bfree(dev, b1);
        !          105957:                        else
        !          105958:                                indfree(dev, b1, l);
        !          105959:                }
        !          105960:                brelease(bp);
        !          105961:        }
        !          105962:        bfree(dev, b);
        !          105963: }
        !          105964: 
        !          105965: /*
        !          105966:  * Allocate a block from the filesystem mounted of device `dev'.
        !          105967:  */
        !          105968: daddr_t
        !          105969: balloc(dev)
        !          105970: dev_t dev;
        !          105971: {
        !          105972:        register struct filsys *sbp;
        !          105973:        register struct fblk *fbp;
        !          105974:        register daddr_t b;
        !          105975:        register BUF *bp;
        !          105976:        register MOUNT *mp;
        !          105977: 
        !          105978:        if ((mp=getment(dev, 1)) == NULL)
        !          105979:                return (0);
        !          105980:        lock(mp->m_flock);
        !          105981:        sbp = &mp->m_super;
        !          105982:        if (sbp->s_nfree == 0) {
        !          105983: enospc:
        !          105984:                sbp->s_nfree = 0;
        !          105985:                devmsg(dev, "Out of space");
        !          105986:                u.u_error = ENOSPC;
        !          105987:                b = 0;
        !          105988:        } else {
        !          105989:                sbp->s_fmod = 1;
        !          105990:                if ((b=sbp->s_free[--sbp->s_nfree]) == 0)
        !          105991:                        goto enospc;
        !          105992:                if (sbp->s_nfree == 0) {
        !          105993:                        if (b >= sbp->s_fsize
        !          105994:                         || b < sbp->s_isize
        !          105995:                         || (bp = bread(dev, b, 1)) == NULL) {
        !          105996: ebadflist:
        !          105997:                                devmsg(dev, "Bad free list");
        !          105998:                                goto enospc;
        !          105999:                        }
        !          106000:                        fbp = FP_OFF(bp->b_faddr);
        !          106001:                        sbp->s_nfree = fbp->df_nfree;
        !          106002:                        canshort(sbp->s_nfree);
        !          106003:                        if ((unsigned)sbp->s_nfree > NICFREE)
        !          106004:                                goto ebadflist;
        !          106005:                        kkcopy(fbp->df_free, sbp->s_free, sizeof(sbp->s_free));
        !          106006:                        canndaddr(sbp->s_free, sbp->s_nfree);
        !          106007:                        brelease(bp);
        !          106008:                }
        !          106009:                --sbp->s_tfree;
        !          106010:                if (b >= sbp->s_fsize || b < sbp->s_isize)
        !          106011:                        goto ebadflist;
        !          106012:        }
        !          106013:        unlock(mp->m_flock);
        !          106014:        return (b);
        !          106015: }
        !          106016: 
        !          106017: /*
        !          106018:  * Free the block `b' on the device `dev'.
        !          106019:  */
        !          106020: bfree(dev, b)
        !          106021: dev_t dev;
        !          106022: daddr_t b;
        !          106023: {
        !          106024:        register struct filsys *sbp;
        !          106025:        register struct fblk *fbp;
        !          106026:        register BUF *bp;
        !          106027:        register MOUNT *mp;
        !          106028: 
        !          106029:        if ((mp=getment(dev, 1)) == NULL)
        !          106030:                return;
        !          106031:        sbp = &mp->m_super;
        !          106032:        if (b>=sbp->s_fsize || b<sbp->s_isize) {
        !          106033:                devmsg(dev, "Bad block %u (free)", (unsigned)b);
        !          106034:                return;
        !          106035:        }
        !          106036:        lock(mp->m_flock);
        !          106037:        if (sbp->s_nfree == 0 || sbp->s_nfree == NICFREE) {
        !          106038:                bp = bclaim(dev, b);
        !          106039:                fbp = FP_OFF(bp->b_faddr);
        !          106040:                kclear(fbp, BSIZE);
        !          106041:                fbp->df_nfree = sbp->s_nfree;
        !          106042:                canshort(fbp->df_nfree);
        !          106043:                kkcopy(sbp->s_free, fbp->df_free, sizeof(fbp->df_free));
        !          106044:                canndaddr(fbp->df_free, sbp->s_nfree);
        !          106045:                bp->b_flag |= BFMOD;
        !          106046:                brelease(bp);
        !          106047:                sbp->s_nfree = 0;
        !          106048:        }
        !          106049:        sbp->s_free[sbp->s_nfree++] = b;
        !          106050:        sbp->s_tfree++;
        !          106051:        sbp->s_fmod = 1;
        !          106052:        unlock(mp->m_flock);
        !          106053: }
        !          106054: 
        !          106055: /*
        !          106056:  * Determine if the given block is bad.
        !          106057:  */
        !          106058: bad(dev, b)
        !          106059: dev_t dev;
        !          106060: daddr_t b;
        !          106061: {
        !          106062:        register INODE *ip;
        !          106063:        register BUF *bp;
        !          106064:        register int i;
        !          106065:        register int m;
        !          106066:        register int n;
        !          106067:        daddr_t l;
        !          106068: 
        !          106069:        if ((ip=iattach(dev, 1)) == NULL)
        !          106070:                panic("bad()");
        !          106071:        n = blockn(ip->i_size);
        !          106072:        if ((m=n) > ND)
        !          106073:                m = ND;
        !          106074:        for (i=0; i<m; i++) {
        !          106075:                --n;
        !          106076:                if (b == ip->i_a.i_addr[i]) {
        !          106077:                        idetach(ip);
        !          106078:                        return (1);
        !          106079:                }
        !          106080:        }
        !          106081:        l = ip->i_a.i_addr[ND];
        !          106082:        idetach(ip);
        !          106083:        if (n == 0)
        !          106084:                return (0);
        !          106085:        if ((bp=bread(dev, l, 1)) == NULL)
        !          106086:                return (0);
        !          106087:        if ((m=n) > NBN)
        !          106088:                m = NBN;
        !          106089:        for (i=0; i<m; i++) {
        !          106090:                l = ((daddr_t *)bp)[i];
        !          106091:                candaddr(l);
        !          106092:                if (b == l) {
        !          106093:                        brelease(bp);
        !          106094:                        return (1);
        !          106095:                }
        !          106096:        }
        !          106097:        brelease(bp);
        !          106098:        return (0);
        !          106099: }
        !          106100: 
        !          106101: /*
        !          106102:  * Canonize `n' disk addresses.
        !          106103:  */
        !          106104: canndaddr(dp, n)
        !          106105: register daddr_t *dp;
        !          106106: register int n;
        !          106107: {
        !          106108:        while (n--) {
        !          106109:                candaddr(*dp);
        !          106110:                dp++;
        !          106111:        }
        !          106112: }
        !          106113: 
        !          106114: /*
        !          106115:  * Write out an accounting record.
        !          106116:  */
        !          106117: setacct()
        !          106118: {
        !          106119:        register PROC *pp;
        !          106120:        struct acct acct;
        !          106121:        IO acctio;
        !          106122: 
        !          106123:        if (acctip == NULL)
        !          106124:                return;
        !          106125:        pp = SELF;
        !          106126:        kkcopy(u.u_comm, acct.ac_comm, 10);
        !          106127:        acct.ac_utime = ltoc(pp->p_utime);
        !          106128:        acct.ac_stime = ltoc(pp->p_stime);
        !          106129:        acct.ac_etime = ltoc(timer.t_time - u.u_btime);
        !          106130:        acct.ac_btime = u.u_btime;
        !          106131:        acct.ac_uid = u.u_uid;
        !          106132:        acct.ac_gid = u.u_gid;
        !          106133:        acct.ac_mem = 0;
        !          106134:        acct.ac_io = ltoc(u.u_block);
        !          106135:        acct.ac_tty = pp->p_ttdev;
        !          106136:        acct.ac_flag = u.u_flag;
        !          106137:        ilock(acctip);
        !          106138:        acctio.io_seek = acctip->i_size;
        !          106139:        acctio.io_ioc  = sizeof (acct);
        !          106140:        acctio.io_base = &acct;
        !          106141:        acctio.io_seg  = IOSYS;
        !          106142:        acctio.io_flag = 0;
        !          106143:        iwrite(acctip, &acctio);
        !          106144:        iunlock(acctip);
        !          106145:        u.u_error = 0;
        !          106146: }
        !          106147: 0707070064030103331006440000030000030000011777770507310727300004100000022066/newbits/kernel/USRSRC/coh/fs3.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/fs3.c,v 1.4 91/07/24 07:51:06 bin Exp Locker: bin $ */
        !          106148: /* (lgl-
        !          106149:  *     The information contained herein is a trade secret of Mark Williams
        !          106150:  *     Company, and  is confidential information.  It is provided  under a
        !          106151:  *     license agreement,  and may be  copied or disclosed  only under the
        !          106152:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          106153:  *     material without the express written authorization of Mark Williams
        !          106154:  *     Company or persuant to the license agreement is unlawful.
        !          106155:  *
        !          106156:  *     COHERENT Version 2.3.37
        !          106157:  *     Copyright (c) 1982, 1983, 1984.
        !          106158:  *     An unpublished work by Mark Williams Company, Chicago.
        !          106159:  *     All rights reserved.
        !          106160:  -lgl) */
        !          106161: /*
        !          106162:  * Coherent.
        !          106163:  * Filesystem (I/O).
        !          106164:  *
        !          106165:  * $Log:       fs3.c,v $
        !          106166:  * Revision 1.4  91/07/24  07:51:06  bin
        !          106167:  * update prov by hal
        !          106168:  * 
        !          106169:  * 
        !          106170:  * Revision 1.1        88/03/24  16:13:54      src
        !          106171:  * Initial revision
        !          106172:  * 
        !          106173:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/fs3.c
        !          106174:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          106175:  *
        !          106176:  * 86/02/01    Allan Cornish
        !          106177:  * Added code to fwrite() to avoid needless writing of pipe blocks.
        !          106178:  * Throughput on 6 Mhz AT rose from 30 Kbytes/sec to 79 Kbytes/sec.
        !          106179:  */
        !          106180: #include <sys/coherent.h>
        !          106181: #include <sys/buf.h>
        !          106182: #include <canon.h>
        !          106183: #include <sys/con.h>
        !          106184: #include <errno.h>
        !          106185: #include <sys/filsys.h>
        !          106186: #include <sys/mount.h>
        !          106187: #include <sys/io.h>
        !          106188: #include <sys/ino.h>
        !          106189: #include <sys/inode.h>
        !          106190: #include <sys/uproc.h>
        !          106191: #include <sys/stat.h>
        !          106192: 
        !          106193: /*
        !          106194:  * Given an inode, open it.
        !          106195:  */
        !          106196: iopen(ip, mode)
        !          106197: register INODE *ip;
        !          106198: {
        !          106199:        register int type;
        !          106200: 
        !          106201:        type = ip->i_mode & IFMT;
        !          106202:        switch (type) {
        !          106203:        case IFCHR:
        !          106204:        case IFBLK:
        !          106205:                iunlock(ip);
        !          106206:                dopen(ip->i_a.i_rdev, mode, type==IFCHR ? DFCHR : DFBLK);
        !          106207:                ilock(ip);
        !          106208:                break;
        !          106209:        case IFDIR:
        !          106210:                if ((mode&IPW) != 0) {
        !          106211:                        if (super() == 0)
        !          106212:                                return;
        !          106213:                        if (mode == IPW) {
        !          106214:                                u.u_error = EISDIR;
        !          106215:                                return;
        !          106216:                        }
        !          106217:                }
        !          106218:                break;
        !          106219:        case IFPIPE:
        !          106220:                popen(ip, mode);
        !          106221:                break;
        !          106222:        }
        !          106223: }
        !          106224: 
        !          106225: /*
        !          106226:  * Given an inode, close it.
        !          106227:  */
        !          106228: iclose(ip)
        !          106229: register INODE *ip;
        !          106230: {
        !          106231:        ilock(ip);
        !          106232:        switch (ip->i_mode&IFMT) {
        !          106233:        case IFBLK:
        !          106234:                bflush(ip->i_a.i_rdev);
        !          106235:        case IFCHR:
        !          106236:                iunlock(ip);
        !          106237:                dclose(ip->i_a.i_rdev);
        !          106238:                ilock(ip);
        !          106239:                break;
        !          106240:        case IFPIPE:
        !          106241:                pclose(ip);
        !          106242:                break;
        !          106243:        }
        !          106244:        idetach(ip);
        !          106245: }
        !          106246: 
        !          106247: /*
        !          106248:  * Read from a file described by an inode and an io strucuture.
        !          106249:  */
        !          106250: iread(ip, iop)
        !          106251: register INODE *ip;
        !          106252: register IO *iop;
        !          106253: {
        !          106254:        if (iop->io_ioc == 0)
        !          106255:                return;
        !          106256:        switch (ip->i_mode&IFMT) {
        !          106257:        case IFCHR:
        !          106258:                dread(ip->i_a.i_rdev, iop);
        !          106259:                break;
        !          106260:        case IFBLK:
        !          106261:        case IFREG:
        !          106262:        case IFDIR:
        !          106263:                fread(ip, iop);
        !          106264:                break;
        !          106265:        case IFPIPE:
        !          106266:                pread(ip, iop);
        !          106267:                break;
        !          106268:        default:
        !          106269:                u.u_error = ENXIO;
        !          106270:                break;
        !          106271:        }
        !          106272: }
        !          106273: 
        !          106274: /*
        !          106275:  * Write to a file described by an inode and io structure.
        !          106276:  */
        !          106277: iwrite(ip, iop)
        !          106278: register INODE *ip;
        !          106279: register IO *iop;
        !          106280: {
        !          106281:        imod(ip);       /* write - mtime */
        !          106282:        icrt(ip);       /* write - ctime */
        !          106283:        if (iop->io_ioc == 0)
        !          106284:                return;
        !          106285:        switch (ip->i_mode&IFMT) {
        !          106286:        case IFCHR:
        !          106287:                dwrite(ip->i_a.i_rdev, iop);
        !          106288:                break;
        !          106289:        case IFBLK:
        !          106290:                fwrite(ip, iop);
        !          106291:                break;
        !          106292:        case IFREG:
        !          106293:        case IFDIR:
        !          106294:                if (getment(ip->i_dev, 1) == NULL)
        !          106295:                        return;
        !          106296:                fwrite(ip, iop);
        !          106297:                break;
        !          106298:        case IFPIPE:
        !          106299:                pwrite(ip, iop);
        !          106300:                break;
        !          106301:        default:
        !          106302:                u.u_error = ENXIO;
        !          106303:                break;
        !          106304:        }
        !          106305: }
        !          106306: 
        !          106307: /*
        !          106308:  * Read from a regular or block special file.
        !          106309:  */
        !          106310: fread(ip, iop)
        !          106311: INODE *ip;
        !          106312: register IO *iop;
        !          106313: {
        !          106314: #ifdef TINY
        !          106315:        register unsigned n;
        !          106316:        register fsize_t res;
        !          106317:        register unsigned off;
        !          106318:        register daddr_t lbn;
        !          106319:        register BUF *bp;
        !          106320:        register int blk;
        !          106321: 
        !          106322:        lbn = blockn(iop->io_seek);
        !          106323:        off = blocko(iop->io_seek);
        !          106324:        blk = (ip->i_mode&IFMT) == IFBLK;
        !          106325:        res = ip->i_size - iop->io_seek;
        !          106326:        if (blk!=0 || res>iop->io_ioc)
        !          106327:                res = iop->io_ioc;
        !          106328:        while (res > 0) {
        !          106329:                bp = blk ? bread(ip->i_a.i_rdev, lbn, 1) : vread(ip, lbn);
        !          106330:                if (bp == NULL)
        !          106331:                        return;
        !          106332:                n = BSIZE - off;
        !          106333:                if (n > res)
        !          106334:                        n = res;
        !          106335:                iowrite(iop, FP_OFF(bp->b_faddr)+off, n);
        !          106336:                brelease(bp);
        !          106337:                if (u.u_error)
        !          106338:                        return;
        !          106339:                lbn++;
        !          106340:                off = 0;
        !          106341:                res -= n;
        !          106342:        }
        !          106343: /*
        !          106344:  * Start of daring read ahead code.
        !          106345:  * Altered to not read ahead on block devices
        !          106346:  * due to 20% time penalty incurred for such.
        !          106347:  */
        !          106348: #if 0
        !          106349:        if ( ! blk) {
        !          106350:                lbn = vmap(ip, lbn);
        !          106351:                if (lbn > 0)
        !          106352:                        bread(ip->i_dev, lbn, 0);
        !          106353:        }
        !          106354: #endif
        !          106355: /*
        !          106356:  * End of daring read ahead code.
        !          106357:  */
        !          106358: #else
        !          106359:        register unsigned n;
        !          106360:        register unsigned i;
        !          106361:        register fsize_t res;
        !          106362:        register unsigned off;
        !          106363:        register dev_t dev;
        !          106364:        register daddr_t lbn;
        !          106365:        register daddr_t pbn;
        !          106366:        register daddr_t abn;
        !          106367:        register daddr_t zbn;
        !          106368:        register BUF *bp;
        !          106369:        register int blk;
        !          106370:        daddr_t list[NEXREAD];
        !          106371: 
        !          106372:        if ((ip->i_mode&IFMT) == IFBLK) {
        !          106373:                blk = 1;
        !          106374:                dev = ip->i_a.i_rdev;
        !          106375:        } else {
        !          106376:                blk = 0;
        !          106377:                dev = ip->i_dev;
        !          106378:        }
        !          106379:        abn = 0;
        !          106380:        zbn = 0;
        !          106381:        lbn = blockn(iop->io_seek);
        !          106382:        off = blocko(iop->io_seek);
        !          106383:        res = ip->i_size - iop->io_seek;
        !          106384:        if (blk!=0 || res>iop->io_ioc)
        !          106385:                res = iop->io_ioc;
        !          106386:        if (res <= 0)
        !          106387:                return;
        !          106388:        if (res+off <= BSIZE) {
        !          106389:                bp = blk ? bread(dev, lbn, 1) : vread(ip, lbn);
        !          106390:                if (bp == NULL)
        !          106391:                        return;
        !          106392:                iowrite(iop, FP_OFF(bp->b_faddr)+off, (unsigned)res);
        !          106393:                brelease(bp);
        !          106394:                return;
        !          106395:        }
        !          106396:        while (res > 0) {
        !          106397:                if (lbn >= zbn) {
        !          106398:                        if ((n=blockn(res+BSIZE-1)) > NEXREAD)
        !          106399:                                n = NEXREAD;
        !          106400:                        if (n <= 0)
        !          106401:                                n = 1;
        !          106402:                        abn = lbn;
        !          106403:                        for (i=0, zbn=lbn; i<n; i++, zbn++) {
        !          106404:                                if (blk != 0)
        !          106405:                                        pbn = zbn;
        !          106406:                                else {
        !          106407:                                        if ((pbn=vmap(ip, zbn)) < 0)
        !          106408:                                                return;
        !          106409:                                        if (pbn == 0) {
        !          106410:                                                list[i] = -1;
        !          106411:                                                continue;
        !          106412:                                        }
        !          106413:                                }
        !          106414:                                list[i] = pbn;
        !          106415:                                bread(dev, pbn, 0);
        !          106416:                        }
        !          106417:                }
        !          106418:                if ((pbn=list[lbn-abn]) < 0) {
        !          106419:                        bp = bclaim(NODEV, (daddr_t)0);
        !          106420:                        kclear(FP_OFF(bp->b_faddr), BSIZE);
        !          106421:                } else {
        !          106422:                        if ((bp=bread(dev, pbn, 1)) == NULL)
        !          106423:                                return;
        !          106424:                }
        !          106425:                n = BSIZE - off;
        !          106426:                n = res>n ? n : res;
        !          106427:                iowrite(iop, FP_OFF(bp->b_faddr)+off, n);
        !          106428:                brelease(bp);
        !          106429:                if (u.u_error)
        !          106430:                        return;
        !          106431:                lbn++;
        !          106432:                off = 0;
        !          106433:                res -= n;
        !          106434:        }
        !          106435: #endif
        !          106436: }
        !          106437: 
        !          106438: /*
        !          106439:  * Write to a regular or block special file.
        !          106440:  */
        !          106441: fwrite(ip, iop)
        !          106442: INODE *ip;
        !          106443: register IO *iop;
        !          106444: {
        !          106445:        register unsigned n;
        !          106446:        register unsigned off;
        !          106447:        register daddr_t lbn;
        !          106448:        register BUF *bp;
        !          106449:        register int blk;
        !          106450:        register int com;
        !          106451: 
        !          106452:        lbn = blockn(iop->io_seek);
        !          106453:        off = blocko(iop->io_seek);
        !          106454:        blk = (ip->i_mode&IFMT) == IFBLK;
        !          106455:        while (iop->io_ioc > 0) {
        !          106456:                n = BSIZE - off;
        !          106457:                n = iop->io_ioc>n ? n : iop->io_ioc;
        !          106458:                com = off==0 && n==BSIZE;
        !          106459:                if (blk == 0)
        !          106460:                        bp = aread(ip, lbn, com);
        !          106461:                else {
        !          106462:                        if (com)
        !          106463:                                bp = bclaim(ip->i_a.i_rdev, lbn);
        !          106464:                        else
        !          106465:                                bp = bread(ip->i_a.i_rdev, lbn, 1);
        !          106466:                }
        !          106467:                if (bp == NULL)
        !          106468:                        return;
        !          106469:                ioread(iop, FP_OFF(bp->b_faddr)+off, n);
        !          106470:                bp->b_flag |= BFMOD;
        !          106471:                if (com && ((ip->i_mode&IFMT) != IFPIPE) )
        !          106472:                        bwrite(bp, 0);
        !          106473:                else
        !          106474:                        brelease(bp);
        !          106475:                if (u.u_error)
        !          106476:                        return;
        !          106477:                lbn++;
        !          106478:                off = 0;
        !          106479:                if ((iop->io_seek+=n) > ip->i_size)
        !          106480:                        if (blk == 0)
        !          106481:                                ip->i_size = iop->io_seek;
        !          106482:        }
        !          106483: }
        !          106484: 
        !          106485: /*
        !          106486:  * Given an inode pointer, read the requested virtual block and return
        !          106487:  * a buffer with the data.
        !          106488:  */
        !          106489: BUF *
        !          106490: vread(ip, lb)
        !          106491: register INODE *ip;
        !          106492: daddr_t lb;
        !          106493: {
        !          106494:        register daddr_t pb;
        !          106495:        register BUF *bp;
        !          106496: 
        !          106497:        if ((pb=vmap(ip, lb)) < 0)
        !          106498:                return (NULL);
        !          106499:        if (pb != 0)
        !          106500:                return (bread(ip->i_dev, pb, 1));
        !          106501:        bp = bclaim(NODEV, (daddr_t)0);
        !          106502:        kclear(FP_OFF(bp->b_faddr), BSIZE);
        !          106503:        return (bp);
        !          106504: }
        !          106505: 
        !          106506: /*
        !          106507:  * Convert the given virtual block to a physical block for the given inode.
        !          106508:  * If the block does not map onto a physical block because the file is sparse
        !          106509:  * but it does exist, 0 is returned.  If an error is encountered, -1 is
        !          106510:  * returned.
        !          106511:  */
        !          106512: daddr_t
        !          106513: vmap(ip, lb)
        !          106514: register INODE *ip;
        !          106515: daddr_t lb;
        !          106516: {
        !          106517:        register BUF *bp;
        !          106518:        register int *lp;
        !          106519:        daddr_t * dp;
        !          106520:        daddr_t pb;
        !          106521:        int list[1+NI];
        !          106522: 
        !          106523:        if ((lp=lmap(lb, list)) == NULL)
        !          106524:                return (-1);
        !          106525:        pb = ip->i_a.i_addr[*--lp];
        !          106526:        for (;;) {
        !          106527:                if (pb==0 || lp==list)
        !          106528:                        return (pb);
        !          106529:                if ((bp=bread(ip->i_dev, pb, 1)) == NULL)
        !          106530:                        return (0);
        !          106531:                dp = FP_OFF(bp->b_faddr);
        !          106532:                pb = dp[*--lp];
        !          106533:                brelease(bp);
        !          106534:                candaddr(pb);
        !          106535:        }
        !          106536: }
        !          106537: 
        !          106538: /*
        !          106539:  * Given an inode pointer, read the requested virtual block and return a
        !          106540:  * buffer with the data.  In sparse files, the necessary blocks are allocated.
        !          106541:  * If the flag, `fflag' is set, the final buffer is just claimed rather than
        !          106542:  * read as we are going to change it's contents completely.
        !          106543:  */
        !          106544: BUF *
        !          106545: aread(ip, lb, fflag)
        !          106546: register INODE *ip;
        !          106547: daddr_t lb;
        !          106548: {
        !          106549:        register BUF *bp;
        !          106550:        register int *lp;
        !          106551:        register dev_t dev;
        !          106552:        register int l;
        !          106553:        register int aflag;
        !          106554:        register int lflag;
        !          106555:        daddr_t * dp;
        !          106556:        daddr_t pb;
        !          106557:        int list[1+NI];
        !          106558: 
        !          106559:        if ((lp=lmap(lb, list)) == NULL)
        !          106560:                return (NULL);
        !          106561:        aflag = 0;
        !          106562:        dev = ip->i_dev;
        !          106563:        pb = ip->i_a.i_addr[l=*--lp];
        !          106564:        if (pb == 0) {
        !          106565:                aflag = 1;
        !          106566:                if ((pb=balloc(dev)) == 0)
        !          106567:                        return (NULL);
        !          106568:                ip->i_a.i_addr[l] = pb;
        !          106569:        }
        !          106570:        for (;;) {
        !          106571:                lflag = lp==list;
        !          106572:                if (aflag==0  &&  (fflag==0 || lflag==0)) {
        !          106573:                        if ((bp=bread(dev, pb, 1)) == NULL)
        !          106574:                                return (NULL);
        !          106575:                } else {
        !          106576:                        bp = bclaim(dev, pb);
        !          106577:                        kclear(FP_OFF(bp->b_faddr), BSIZE);
        !          106578:                        bp->b_flag |= BFMOD;
        !          106579:                }
        !          106580:                if (lflag)
        !          106581:                        return (bp);
        !          106582: 
        !          106583:                aflag = 0;
        !          106584:                dp = FP_OFF(bp->b_faddr);
        !          106585:                pb = dp[l=*--lp];
        !          106586:                candaddr(pb);
        !          106587:                if (pb == 0) {
        !          106588:                        aflag = 1;
        !          106589:                        if ((pb=balloc(dev)) == 0) {
        !          106590:                                brelease(bp);
        !          106591:                                return (NULL);
        !          106592:                        }
        !          106593:                        dp[l] = pb;
        !          106594:                        candaddr( dp[l] );
        !          106595:                        bp->b_flag |= BFMOD;
        !          106596:                }
        !          106597:                brelease(bp);
        !          106598:        }
        !          106599: }
        !          106600: 
        !          106601: /*
        !          106602:  * Given a block number, `b', store the offsets for the indirect blocks
        !          106603:  * backwards in the array, `lp', and return a pointer just after the
        !          106604:  * position where the first offset is stored.
        !          106605:  */
        !          106606: int *
        !          106607: lmap(b, lp)
        !          106608: register daddr_t b;
        !          106609: register int *lp;
        !          106610: {
        !          106611:        register int n;
        !          106612: 
        !          106613:        if (b < ND) {
        !          106614:                *lp++ = b;
        !          106615:                return (lp);
        !          106616:        }
        !          106617:        b -= ND;
        !          106618:        n = NI;
        !          106619:        do {
        !          106620:                if (n-- == 0) {
        !          106621:                        u.u_error = EFBIG;
        !          106622:                        return (NULL);
        !          106623:                }
        !          106624:                *lp = nbnrem(b);
        !          106625:                ++lp;
        !          106626:                b = nbndiv(b);
        !          106627:        } while (b--);
        !          106628:        *lp++ = ND+NI-1-n;
        !          106629:        return (lp);
        !          106630: }
        !          106631: 0707070064030103321006440000030000030000011777770507310727500004200000003553/newbits/kernel/USRSRC/coh/main.c/*
        !          106632:  * Coherent.
        !          106633:  *
        !          106634:  * $Log:       main.c,v $
        !          106635:  * Revision 1.4  91/07/24  07:51:15  bin
        !          106636:  * update prov by hal
        !          106637:  * 
        !          106638:  * 
        !          106639:  * Revision 1.2        88/06/29  12:00:29      src
        !          106640:  * Real/Protected mode status now printed during boot sequence.
        !          106641:  * Three part serial numbers now supported, moved to optional fourth line.
        !          106642:  * 
        !          106643:  * Revision 1.1        88/03/24  16:13:58      src
        !          106644:  * Initial revision
        !          106645:  * 
        !          106646:  * 87/04/09    Allan Cornish           /usr/src/sys/coh/main.c
        !          106647:  * Serial numbers changed to support group.
        !          106648:  *
        !          106649:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/main.c
        !          106650:  * Copyright notice revised to include 1987.
        !          106651:  */
        !          106652: #include <sys/coherent.h>
        !          106653: #include <sys/proc.h>
        !          106654: #include <sys/seg.h>
        !          106655: #include <sys/uproc.h>
        !          106656: 
        !          106657: #ifndef VERSION                /* This should be specified at compile time */
        !          106658: #define VERSION        "..."
        !          106659: #endif
        !          106660: 
        !          106661: unsigned long  _entry = 0;             /* really the serial number */
        !          106662: unsigned long  __ = 0;                 /* really the serial number also */
        !          106663: 
        !          106664: /*
        !          106665:  * Initialise various things.  When we return we will return to user mode.
        !          106666:  */
        !          106667: char version[] = VERSION;
        !          106668: char copyright[] = "\
        !          106669: Copyright (c) 1982, 1991 by Mark Williams Company\n\
        !          106670: ";
        !          106671: 
        !          106672: main()
        !          106673: {
        !          106674:        register SEG *sp;
        !          106675:        extern int realmode;    /* real addressing mode - as2.s */
        !          106676: 
        !          106677:        u.u_error = 0;
        !          106678:        bufinit();
        !          106679:        cltinit();
        !          106680:        pcsinit();
        !          106681:        seginit();
        !          106682:        devinit();
        !          106683:        printf("\Mark Williams COHERENT Version %s - %s Mode (mem=%u Kbytes)\n",
        !          106684:                version, (realmode ? "Real" : "Protected"), msize );
        !          106685:        printf(copyright);
        !          106686: 
        !          106687:        if ( _entry ) {
        !          106688:                printf("Serial Number ");
        !          106689:                printf("%U\n", _entry);
        !          106690:        }
        !          106691: 
        !          106692:        /*
        !          106693:         * Verify correct serial number
        !          106694:         */
        !          106695:        if (_entry != __)
        !          106696:                panic("Verification error - call Mark Williams Company at 1-800-MARK-WMS\n");
        !          106697: 
        !          106698:        /*
        !          106699:         * Turn on clock, start off processes, mount root device
        !          106700:         * and return.
        !          106701:         */
        !          106702:        batflag = 1;
        !          106703:        if ((sp=salloc((fsize_t)UPASIZE, SFNCLR|SFNSWP)) == NULL)
        !          106704:                panic("Cannot allocate user area");
        !          106705:        if ((iprocp=process(idle))==NULL || (eprocp=process(NULL))==NULL)
        !          106706:                panic("Cannot create process");
        !          106707:        eveinit(sp);
        !          106708:        fsminit();
        !          106709: }
        !          106710: 0707070064030103311006440000030000030000011777770507310727600004200000004403/newbits/kernel/USRSRC/coh/misc.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/misc.c,v 1.4 91/07/24 07:51:19 bin Exp Locker: bin $ */
        !          106711: /* (lgl-
        !          106712:  *     The information contained herein is a trade secret of Mark Williams
        !          106713:  *     Company, and  is confidential information.  It is provided  under a
        !          106714:  *     license agreement,  and may be  copied or disclosed  only under the
        !          106715:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          106716:  *     material without the express written authorization of Mark Williams
        !          106717:  *     Company or persuant to the license agreement is unlawful.
        !          106718:  *
        !          106719:  *     COHERENT Version 2.3.37
        !          106720:  *     Copyright (c) 1982, 1983, 1984.
        !          106721:  *     An unpublished work by Mark Williams Company, Chicago.
        !          106722:  *     All rights reserved.
        !          106723:  -lgl) */
        !          106724: /*
        !          106725:  * Coherent.
        !          106726:  * Miscellaneous routines.
        !          106727:  *
        !          106728:  * $Log:       misc.c,v $
        !          106729:  * Revision 1.4  91/07/24  07:51:19  bin
        !          106730:  * update prov by hal
        !          106731:  * 
        !          106732:  * 
        !          106733:  * Revision 1.1        88/03/24  16:14:01      src
        !          106734:  * Initial revision
        !          106735:  * 
        !          106736:  * 87/05/08    Allan Cornish           /usr/src/sys/coh/misc.c
        !          106737:  * System code and data segments no longer reported in panic messages.
        !          106738:  *
        !          106739:  * 87/02/17    Allan Cornish           /usr/src/sys/coh/misc.c
        !          106740:  * Panic message now includes system code and data segments.
        !          106741:  */
        !          106742: #include <sys/coherent.h>
        !          106743: #include <acct.h>
        !          106744: #include <errno.h>
        !          106745: #include <sys/ino.h>
        !          106746: #include <sys/stat.h>
        !          106747: #include <sys/uproc.h>
        !          106748: 
        !          106749: /*
        !          106750:  * Copy `n' bytes from `bp1' to `bp2'.
        !          106751:  */
        !          106752: kkcopy(bp1, bp2, n)
        !          106753: register char *bp1;
        !          106754: register char *bp2;
        !          106755: unsigned n;
        !          106756: {
        !          106757:        register unsigned n1;
        !          106758: 
        !          106759:        n1 = n;
        !          106760:        if (n1) {
        !          106761:                do {
        !          106762:                        *bp2++ = *bp1++;
        !          106763:                } while (--n1);
        !          106764:        }
        !          106765:        return (n);
        !          106766: }
        !          106767: 
        !          106768: /*
        !          106769:  * Clear the next `n' bytes starting at `bp'.
        !          106770:  */
        !          106771: kclear(bp, n)
        !          106772: register char *bp;
        !          106773: register unsigned n;
        !          106774: {
        !          106775:        if (n) {
        !          106776:                do {
        !          106777:                        *bp++ = 0;
        !          106778:                } while (--n);
        !          106779:        }
        !          106780: }
        !          106781: 
        !          106782: /*
        !          106783:  * Make sure we are the super user.
        !          106784:  */
        !          106785: super()
        !          106786: {
        !          106787:        if (u.u_uid) {
        !          106788:                u.u_error = EPERM;
        !          106789:                return (0);
        !          106790:        }
        !          106791:        u.u_flag |= ASU;
        !          106792:        return (1);
        !          106793: }
        !          106794: 
        !          106795: /*
        !          106796:  * Make sure we are the gived `uid' or the super user.
        !          106797:  */
        !          106798: owner(uid)
        !          106799: {
        !          106800:        if (u.u_uid == uid)
        !          106801:                return (1);
        !          106802:        if (u.u_uid == 0) {
        !          106803:                u.u_flag |= ASU;
        !          106804:                return (1);
        !          106805:        }
        !          106806:        u.u_error = EPERM;
        !          106807:        return (0);
        !          106808: }
        !          106809: 
        !          106810: /*
        !          106811:  * Panic.
        !          106812:  */
        !          106813: panic(a1)
        !          106814: char *a1;
        !          106815: {
        !          106816:        static panflag;
        !          106817: 
        !          106818:        if (panflag++ == 0) {
        !          106819:                printf("Panic: %r", &a1);
        !          106820:                putchar('\n');
        !          106821:                usync();
        !          106822:        }
        !          106823:        halt();
        !          106824:        --panflag;
        !          106825: }
        !          106826: 
        !          106827: /*
        !          106828:  * Print a message from a device driver.
        !          106829:  */
        !          106830: devmsg(dev, a1)
        !          106831: dev_t dev;
        !          106832: char *a1;
        !          106833: {
        !          106834:        printf("(%d,%d): %r", major(dev), minor(dev), &a1);
        !          106835:        printf("\n");
        !          106836: }
        !          106837: 0707070064030103301006440000030000030000011777770507310727700004200000004536/newbits/kernel/USRSRC/coh/null.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/null.c,v 1.4 91/07/24 07:51:24 bin Exp Locker: bin $ */
        !          106838: /* (lgl-
        !          106839:  *     The information contained herein is a trade secret of Mark Williams
        !          106840:  *     Company, and  is confidential information.  It is provided  under a
        !          106841:  *     license agreement,  and may be  copied or disclosed  only under the
        !          106842:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          106843:  *     material without the express written authorization of Mark Williams
        !          106844:  *     Company or persuant to the license agreement is unlawful.
        !          106845:  *
        !          106846:  *     COHERENT Version 2.3.37
        !          106847:  *     Copyright (c) 1982, 1983, 1984.
        !          106848:  *     An unpublished work by Mark Williams Company, Chicago.
        !          106849:  *     All rights reserved.
        !          106850:  -lgl) */
        !          106851: /*
        !          106852:  * Null and memory driver.
        !          106853:  *  Minor device 0 is /dev/null
        !          106854:  *  Minor device 1 is physical memory
        !          106855:  *  Minor device 2 is kernel data
        !          106856:  *
        !          106857:  * $Log:       null.c,v $
        !          106858:  * Revision 1.4  91/07/24  07:51:24  bin
        !          106859:  * update prov by hal
        !          106860:  * 
        !          106861:  * 
        !          106862:  * Revision 1.1        88/03/24  16:14:04      src
        !          106863:  * Initial revision
        !          106864:  * 
        !          106865:  */
        !          106866: #include <sys/coherent.h>
        !          106867: #include <sys/con.h>
        !          106868: #include <errno.h>
        !          106869: #include <sys/stat.h>
        !          106870: #include <sys/uproc.h>
        !          106871: 
        !          106872: /*
        !          106873:  * Functions for configuration.
        !          106874:  */
        !          106875: int    nlread();
        !          106876: int    nlwrite();
        !          106877: int    nulldev();
        !          106878: int    nonedev();
        !          106879: 
        !          106880: /*
        !          106881:  * Configuration table.
        !          106882:  */
        !          106883: CON nlcon ={
        !          106884:        DFCHR,                          /* Flags */
        !          106885:        0,                              /* Major index */
        !          106886:        nulldev,                        /* Open */
        !          106887:        nulldev,                        /* Close */
        !          106888:        nulldev,                        /* Block */
        !          106889:        nlread,                         /* Read */
        !          106890:        nlwrite,                        /* Write */
        !          106891:        nonedev,                        /* Ioctl */
        !          106892:        nulldev,                        /* Powerfail */
        !          106893:        nulldev,                        /* Timeout */
        !          106894:        nulldev,                        /* Load */
        !          106895:        nulldev                         /* Unload */
        !          106896: };
        !          106897: 
        !          106898: /*
        !          106899:  * Null/memory read routine.
        !          106900:  */
        !          106901: nlread(dev, iop)
        !          106902: dev_t dev;
        !          106903: register IO *iop;
        !          106904: {
        !          106905:        register unsigned n;
        !          106906: 
        !          106907:        switch (minor(dev)) {
        !          106908:        case 0:
        !          106909:                n = 0;
        !          106910:                break;
        !          106911: 
        !          106912:        case 1:
        !          106913:                n = pucopy((long)iop->io_seek, iop->io_base, iop->io_ioc);
        !          106914:                break;
        !          106915: 
        !          106916:        case 2:
        !          106917:                n = kucopy((vaddr_t)iop->io_seek, iop->io_base, iop->io_ioc);
        !          106918:                break;
        !          106919: 
        !          106920:        default:
        !          106921:                u.u_error = ENXIO;
        !          106922:                return;
        !          106923:        }
        !          106924:        iop->io_ioc -= n;
        !          106925:        if (u.u_error == EFAULT)
        !          106926:                u.u_error = 0;
        !          106927: }
        !          106928: 
        !          106929: /*
        !          106930:  * Null/memory write routine.
        !          106931:  */
        !          106932: nlwrite(dev, iop)
        !          106933: dev_t dev;
        !          106934: register IO *iop;
        !          106935: {
        !          106936:        register unsigned n;
        !          106937: 
        !          106938:        switch (minor(dev)) {
        !          106939:        case 0:
        !          106940:                n = iop->io_ioc;
        !          106941:                break;
        !          106942: 
        !          106943:        case 1:
        !          106944:                n = upcopy(iop->io_base, (long)iop->io_seek, iop->io_ioc);
        !          106945:                break;
        !          106946: 
        !          106947:        case 2:
        !          106948:                n = ukcopy(iop->io_base, (vaddr_t)iop->io_seek, iop->io_ioc);
        !          106949:                break;
        !          106950: 
        !          106951:        default:
        !          106952:                u.u_error = ENXIO;
        !          106953:                return;
        !          106954:        }
        !          106955:        iop->io_ioc -= n;
        !          106956:        if (u.u_error == EFAULT)
        !          106957:                u.u_error = 0;
        !          106958: }
        !          106959: 0707070064030103271006440000030000030000011777770507310727700004200000010753/newbits/kernel/USRSRC/coh/pipe.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/pipe.c,v 1.4 91/07/24 07:51:27 bin Exp Locker: bin $ */
        !          106960: /* (lgl-
        !          106961:  *     The information contained herein is a trade secret of Mark Williams
        !          106962:  *     Company, and  is confidential information.  It is provided  under a
        !          106963:  *     license agreement,  and may be  copied or disclosed  only under the
        !          106964:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          106965:  *     material without the express written authorization of Mark Williams
        !          106966:  *     Company or persuant to the license agreement is unlawful.
        !          106967:  *
        !          106968:  *     COHERENT Version 2.3.37
        !          106969:  *     Copyright (c) 1982, 1983, 1984.
        !          106970:  *     An unpublished work by Mark Williams Company, Chicago.
        !          106971:  *     All rights reserved.
        !          106972:  -lgl) */
        !          106973: /*
        !          106974:  * Coherent.
        !          106975:  * Pipes.
        !          106976:  *
        !          106977:  * $Log:       pipe.c,v $
        !          106978:  * Revision 1.4  91/07/24  07:51:27  bin
        !          106979:  * update prov by hal
        !          106980:  * 
        !          106981:  * 
        !          106982:  * Revision 1.1        88/03/24  16:14:07      src
        !          106983:  * Initial revision
        !          106984:  * 
        !          106985:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/pipe.c
        !          106986:  * Added check for non-blocking read and write if (io_flag & IPNDLY) set.
        !          106987:  * Eliminated use of i_a inode field since now included in inode macros.
        !          106988:  */
        !          106989: #include <sys/coherent.h>
        !          106990: #include <errno.h>
        !          106991: #include <sys/filsys.h>
        !          106992: #include <sys/ino.h>
        !          106993: #include <sys/inode.h>
        !          106994: #include <sys/io.h>
        !          106995: #include <sys/proc.h>
        !          106996: #include <sys/sched.h>
        !          106997: #include <signal.h>
        !          106998: #include <sys/uproc.h>
        !          106999: 
        !          107000: /*
        !          107001:  * Create and return a locked pipe inode.  This is called from the
        !          107002:  * pipe system call.
        !          107003:  */
        !          107004: INODE *
        !          107005: pmake(mode)
        !          107006: {
        !          107007:        register INODE *ip;
        !          107008: 
        !          107009:        if ((ip=ialloc(pipedev, IFPIPE|mode)) != NULL) {
        !          107010:                iclear(ip);
        !          107011:                ip->i_pnc = 0;
        !          107012:                ip->i_prx = 0;
        !          107013:                ip->i_pwx = 0;
        !          107014:        }
        !          107015:        return (ip);
        !          107016: }
        !          107017: 
        !          107018: /*
        !          107019:  * Open a pipe given the inode pointer.
        !          107020:  */
        !          107021: popen(ip, mode)
        !          107022: {
        !          107023: }
        !          107024: 
        !          107025: /*
        !          107026:  * Close a pipe inode.
        !          107027:  */
        !          107028: pclose(ip)
        !          107029: register INODE *ip;
        !          107030: {
        !          107031:        if (ip->i_refc == 2) {
        !          107032:                pevent(ip);
        !          107033:                ip->i_flag |= IFEOF;
        !          107034:        }
        !          107035: }
        !          107036: 
        !          107037: /*
        !          107038:  * Only one end of the pipe is going to be left.
        !          107039:  */
        !          107040: pevent(ip)
        !          107041: register INODE *ip;
        !          107042: {
        !          107043:        if ((ip->i_flag&IFWFR) != 0) {
        !          107044:                ip->i_flag &= ~IFWFR;
        !          107045:                wakeup((char *)&ip->i_pwx);
        !          107046:        }
        !          107047:        if ((ip->i_flag&IFWFW) != 0) {
        !          107048:                ip->i_flag &= ~IFWFW;
        !          107049:                wakeup((char *)&ip->i_prx);
        !          107050:        }
        !          107051: }
        !          107052: 
        !          107053: /*
        !          107054:  * Read from a pipe.  The given inode is locked.
        !          107055:  */
        !          107056: pread(ip, iop)
        !          107057: register INODE *ip;
        !          107058: register IO *iop;
        !          107059: {
        !          107060:        register unsigned n;
        !          107061:        register unsigned ioc;
        !          107062: 
        !          107063:        while (ip->i_pnc == 0) {
        !          107064: 
        !          107065:                /*
        !          107066:                 * Logical End of File.
        !          107067:                 */
        !          107068:                if ((ip->i_flag&IFEOF) != 0) {
        !          107069:                        ip->i_flag &= ~IFEOF;
        !          107070:                        break;
        !          107071:                }
        !          107072: 
        !          107073:                /*
        !          107074:                 * Nobody left to write.
        !          107075:                 */
        !          107076:                if (ip->i_nlink==0 && ip->i_refc<2)
        !          107077:                        break;
        !          107078: 
        !          107079:                /*
        !          107080:                 * Non-blocking read.
        !          107081:                 */
        !          107082:                if ( iop->io_flag & IONDLY ) {
        !          107083:                        u.u_error = EAGAIN;
        !          107084:                        return;
        !          107085:                }
        !          107086: 
        !          107087:                /*
        !          107088:                 * Wait for pipe data.
        !          107089:                 */
        !          107090:                ip->i_flag |= IFWFW;
        !          107091:                iunlock(ip);
        !          107092:                sleep((char *)&ip->i_prx, CVPIPE, IVPIPE, SVPIPE);
        !          107093:                ilock(ip);
        !          107094:        }
        !          107095: 
        !          107096:        /*
        !          107097:         * Clear EOF flag.
        !          107098:         */
        !          107099:        if ((ip->i_flag&IFEOF)!=0 && ip->i_pnc==0)
        !          107100:                ip->i_flag &= ~IFEOF;
        !          107101: 
        !          107102:        ioc = iop->io_ioc;
        !          107103:        while (u.u_error==0 && ioc>0 && ip->i_pnc>0) {
        !          107104: 
        !          107105:                /*
        !          107106:                 * Calculate length of data to be read.
        !          107107:                 */
        !          107108:                if ((n=PIPSIZE-ip->i_prx) > ioc)
        !          107109:                        n = ioc;
        !          107110:                if (n > ip->i_pnc)
        !          107111:                        n = ip->i_pnc;
        !          107112: 
        !          107113:                /*
        !          107114:                 * Read data.
        !          107115:                 */
        !          107116:                iop->io_ioc = n;
        !          107117:                iop->io_seek = ip->i_prx;
        !          107118:                fread(ip, iop);
        !          107119:                n -= iop->io_ioc;
        !          107120:                if ((ip->i_prx+=n) == PIPSIZE)
        !          107121:                        ip->i_prx = 0;
        !          107122:                ip->i_pnc -= n;
        !          107123:                ioc -= n;
        !          107124:        }
        !          107125:        iop->io_ioc = ioc;
        !          107126: 
        !          107127:        /*
        !          107128:         * Wake processes waiting to write.
        !          107129:         */
        !          107130:        if ((ip->i_flag&IFWFR)!=0 && ip->i_pnc<PIPSIZE) {
        !          107131:                ip->i_flag &= ~IFWFR;
        !          107132:                wakeup((char *)&ip->i_pwx);
        !          107133:        }
        !          107134: }
        !          107135: 
        !          107136: /*
        !          107137:  * Write to a pipe.  The given inode is locked.
        !          107138:  */
        !          107139: pwrite(ip, iop)
        !          107140: register INODE *ip;
        !          107141: register IO *iop;
        !          107142: {
        !          107143:        register unsigned n;
        !          107144:        register unsigned ioc;
        !          107145: 
        !          107146:        ioc = iop->io_ioc;
        !          107147:        while (u.u_error==0 && ioc>0) {
        !          107148: 
        !          107149:                /*
        !          107150:                 * Nobody left to read.
        !          107151:                 */
        !          107152:                if ( (ip->i_refc < 2) && (ip->i_nlink == 0) ) {
        !          107153:                        u.u_error = EPIPE;
        !          107154:                        sendsig(SIGPIPE, SELF);
        !          107155:                        return;
        !          107156:                }
        !          107157: 
        !          107158:                /*
        !          107159:                 * Calculate free space in pipe.
        !          107160:                 */
        !          107161:                if ( (n=PIPSIZE-ip->i_pwx) > ioc )
        !          107162:                        n = ioc;
        !          107163:                if (n > PIPSIZE-ip->i_pnc)
        !          107164:                        n = PIPSIZE - ip->i_pnc;
        !          107165: 
        !          107166:                /*
        !          107167:                 * Non-blocking write.
        !          107168:                 */
        !          107169:                if ( iop->io_flag & IONDLY ) {
        !          107170:                        if ( (n != ioc) || (ip->i_flag & IFEOF) ) {
        !          107171:                                u.u_error = EAGAIN;
        !          107172:                                return;
        !          107173:                        }
        !          107174:                }
        !          107175: 
        !          107176:                /*
        !          107177:                 * Insufficent space or EOF still pending.
        !          107178:                 */
        !          107179:                if (n==0 || (ip->i_flag&IFEOF)!=0) {
        !          107180:                        ip->i_flag |= IFWFR;
        !          107181:                        iunlock(ip);
        !          107182:                        sleep((char *)&ip->i_pwx, CVPIPE, IVPIPE, SVPIPE);
        !          107183:                        ilock(ip);
        !          107184:                        continue;
        !          107185:                }
        !          107186:                iop->io_ioc = n;
        !          107187:                iop->io_seek = ip->i_pwx;
        !          107188:                fwrite(ip, iop);
        !          107189:                n -= iop->io_ioc;
        !          107190:                if ((ip->i_pwx+=n) == PIPSIZE)
        !          107191:                        ip->i_pwx = 0;
        !          107192:                ip->i_pnc += n;
        !          107193:                ioc -= n;
        !          107194: 
        !          107195:                /*
        !          107196:                 * Wait processes waiting to read.
        !          107197:                 */
        !          107198:                if ((ip->i_flag&IFWFW) && ip->i_pnc>0) {
        !          107199:                        ip->i_flag &= ~IFWFW;
        !          107200:                        wakeup((char *)&ip->i_prx);
        !          107201:                }
        !          107202:        }
        !          107203:        iop->io_ioc = ioc;
        !          107204: }
        !          107205: 0707070064030103261006440000030000030000011777770507310730000004200000010447/newbits/kernel/USRSRC/coh/poll.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/poll.c,v 1.4 91/07/24 07:51:32 bin Exp Locker: bin $ */
        !          107206: /*
        !          107207:  *     The  information  contained herein  is a trade secret  of INETCO
        !          107208:  *     Systems, and is confidential information.   It is provided under
        !          107209:  *     a license agreement,  and may be copied or disclosed  only under
        !          107210:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          107211:  *     this  material  without  the express  written  authorization  of
        !          107212:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          107213:  *
        !          107214:  *     Copyright (c) 1986
        !          107215:  *     An unpublished work by INETCO Systems, Ltd.
        !          107216:  *     All rights reserved.
        !          107217:  */
        !          107218: 
        !          107219: /*
        !          107220:  * [Stream] Polling.
        !          107221:  *
        !          107222:  *     void pollinit( ) -- allocate polling buffers
        !          107223:  *     int pollopen(qp) -- enable polling  by current process  on given queue
        !          107224:  *     int pollwake(qp) -- wake all processes waiting for poll on given queue
        !          107225:  *     int pollexit(  ) -- terminate all polls enabled by current process
        !          107226:  *     event_t * ep;
        !          107227:  *
        !          107228:  * $Log:       poll.c,v $
        !          107229:  * Revision 1.4  91/07/24  07:51:32  bin
        !          107230:  * update prov by hal
        !          107231:  * 
        !          107232:  * 
        !          107233:  * Revision 1.1        88/03/24  16:14:10      src
        !          107234:  * Initial revision
        !          107235:  * 
        !          107236:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/poll.c
        !          107237:  * Ported to Coherent from RTX.
        !          107238:  */
        !          107239: 
        !          107240: #include <sys/coherent.h>
        !          107241: #include <sys/proc.h>
        !          107242: #include <sys/uproc.h>
        !          107243: 
        !          107244: /*
        !          107245:  * Patchable data.
        !          107246:  */
        !          107247: int    NPOLL  = 0;
        !          107248: 
        !          107249: /*
        !          107250:  * Private data.
        !          107251:  */
        !          107252: static event_t * efreep;
        !          107253: 
        !          107254: /**
        !          107255:  *
        !          107256:  * event_t *
        !          107257:  * pollinit()          -- allocate event buffers.
        !          107258:  */
        !          107259: event_t *
        !          107260: pollinit()
        !          107261: {
        !          107262:        register event_t * ep;
        !          107263:        register event_t * ap;
        !          107264:        static int first = 1;
        !          107265: 
        !          107266:        /*
        !          107267:         * If dynamically growing event pool is specified [NPOLL == 0],
        !          107268:         * try to allocate an additional cluster of 32 on each call.
        !          107269:         */
        !          107270:        if ( NPOLL == 0 ) {
        !          107271:                if ( ep = kalloc( 32 * sizeof(event_t) ) )
        !          107272:                        ap = ep + 32;
        !          107273:        }
        !          107274: 
        !          107275:        /*
        !          107276:         * If statically sized event pool is specified [NPOLL != 0],
        !          107277:         * try to allocate the pool on the first call.
        !          107278:         */
        !          107279:        else if ( first ) {
        !          107280:                first = 0;
        !          107281:                if ( ep = kalloc( NPOLL * sizeof(event_t) ) )
        !          107282:                        ap = ep + NPOLL;
        !          107283:        }
        !          107284: 
        !          107285:        /*
        !          107286:         * If event cluster was allocated, insert into free event queue.
        !          107287:         */
        !          107288:        if ( ep ) {
        !          107289:                do {
        !          107290:                        ep->e_pnext = efreep;
        !          107291:                        efreep = ep;
        !          107292:                } while ( ++ep < ap );
        !          107293:        }
        !          107294: 
        !          107295:        return efreep;
        !          107296: }
        !          107297: 
        !          107298: /**
        !          107299:  *
        !          107300:  * int
        !          107301:  * pollopen(qp) -- enable polling by current process on given event queue
        !          107302:  * event_t * qp;
        !          107303:  */
        !          107304: pollopen( qp )
        !          107305: register event_t * qp;
        !          107306: {
        !          107307:        register event_t * ep;
        !          107308: 
        !          107309:        /*
        !          107310:         * Initialize device queue if required.
        !          107311:         */
        !          107312:        if ( qp->e_dnext == 0 )
        !          107313:                qp->e_dnext = qp->e_dlast = qp;
        !          107314: 
        !          107315:        /*
        !          107316:         * Obtain a free event buffer, or return.
        !          107317:         */
        !          107318:        if ( ((ep = efreep) == 0) && ((ep = pollinit()) == 0) ) {
        !          107319:                printf("out of poll buffers\n");
        !          107320:                return;
        !          107321:        }
        !          107322: 
        !          107323:        /*
        !          107324:         * Remove event buffer from free queue.
        !          107325:         */
        !          107326:        efreep = ep->e_pnext;
        !          107327: 
        !          107328:        /*
        !          107329:         * Record process pointer in event buffer.
        !          107330:         */
        !          107331:        ep->e_procp = cprocp;
        !          107332: 
        !          107333:        /*
        !          107334:         * Insert event at head of process event singularly-linked queue.
        !          107335:         */
        !          107336:        ep->e_pnext = cprocp->p_polls;
        !          107337:        cprocp->p_polls = ep;
        !          107338: 
        !          107339:        /*
        !          107340:         * Insert event at tail of circularly-linked device queue.
        !          107341:         * This ensures that processes are first-in first-out.
        !          107342:         */
        !          107343:        ep->e_dnext  = qp;
        !          107344:        (ep->e_dlast = qp->e_dlast)->e_dnext = ep;
        !          107345:        qp->e_dlast  = ep;
        !          107346: 
        !          107347:        /*
        !          107348:         * Record last process to enable polling on device.
        !          107349:         */
        !          107350:        qp->e_procp = cprocp;
        !          107351: }
        !          107352: 
        !          107353: /**
        !          107354:  *
        !          107355:  * int
        !          107356:  * pollwake( qp ) -- wake all processes waiting for poll on given queue
        !          107357:  * event_t * qp;
        !          107358:  */
        !          107359: pollwake( qp )
        !          107360: event_t * qp;
        !          107361: {
        !          107362:        register event_t * ep = qp;
        !          107363:        register PROC    * pp;
        !          107364: 
        !          107365:        /*
        !          107366:         * Clear device process pointer, indicating poll completed.
        !          107367:         * NOTE: interrupt handlers may have already cleared it.
        !          107368:         */
        !          107369:        qp->e_procp = 0;
        !          107370: 
        !          107371:        if ( ep = qp->e_dnext ) {
        !          107372: 
        !          107373:                /*
        !          107374:                 * Service circularly-linked polls on device queue.
        !          107375:                 */
        !          107376:                while ( ep != qp ) {
        !          107377:                        /*
        !          107378:                         * Wake process if it is sleeping.
        !          107379:                         */
        !          107380:                        if ( (pp = ep->e_procp) && (pp->p_state == PSSLEEP) )
        !          107381:                                wakeup( &pp->p_polls );
        !          107382: 
        !          107383:                        ep = ep->e_dnext;
        !          107384:                }
        !          107385:        }
        !          107386: }
        !          107387: 
        !          107388: /**
        !          107389:  *
        !          107390:  * int
        !          107391:  * pollexit() -- terminate all polls opened by current process
        !          107392:  */
        !          107393: int
        !          107394: pollexit()
        !          107395: {
        !          107396:        register PROC    * pp = cprocp;
        !          107397:        register event_t * ep;
        !          107398: 
        !          107399:        /*
        !          107400:         * Service all polling event buffers enabled by current process.
        !          107401:         */
        !          107402:        while ( ep = pp->p_polls ) {
        !          107403: 
        !          107404:                /*
        !          107405:                 * Remove event buffer from circularly-linked device queue.
        !          107406:                 */
        !          107407:                (ep->e_dnext->e_dlast = ep->e_dlast)->e_dnext = ep->e_dnext;
        !          107408: 
        !          107409:                /*
        !          107410:                 * Remove event buffer from singularly-linked process queue.
        !          107411:                 */
        !          107412:                pp->p_polls = ep->e_pnext;
        !          107413: 
        !          107414:                /*
        !          107415:                 * Insert event buffer at head of free event buffer queue.
        !          107416:                 */
        !          107417:                ep->e_pnext = efreep;
        !          107418:                efreep = ep;
        !          107419:        }
        !          107420: }
        !          107421: 0707070064030103251006440000030000030000011777770507310730100004400000005260/newbits/kernel/USRSRC/coh/printf.c/*
        !          107422:  * Coherent.
        !          107423:  * Print formatted.
        !          107424:  *
        !          107425:  * $Log:       printf.c,v $
        !          107426:  * Revision 1.4  91/07/24  07:51:37  bin
        !          107427:  * update prov by hal
        !          107428:  * 
        !          107429:  * 
        !          107430:  * Revision 1.1        88/03/24  16:14:13      src
        !          107431:  * Initial revision
        !          107432:  * 
        !          107433:  * 87/09/20    Allan Cornish           /usr/src/sys/coh/printf.c
        !          107434:  * %U now correctly displays in base 10 rather than base 16.
        !          107435:  *
        !          107436:  * 86/12/16    Allan Cornish           /usr/src/sys/coh/printf.c
        !          107437:  * Added '%D' and '%X options to printf().
        !          107438:  */
        !          107439: #include <sys/coherent.h>
        !          107440: 
        !          107441: /*
        !          107442:  * For indirecting and incrementing argument pointer.
        !          107443:  */
        !          107444: #define ind(p, t)      (*((t *) p))
        !          107445: #define inc(t1, t2)    ((sizeof(t2 *)+sizeof(t1)-1) / sizeof(t1))
        !          107446: 
        !          107447: /*
        !          107448:  * Table for printing out digits.
        !          107449:  */
        !          107450: char digtab[] ={
        !          107451:        '0',    '1',    '2',    '3',    '4',    '5',    '6',    '7',
        !          107452:        '8',    '9',    'A',    'B',    'C',    'D',    'E',    'F'
        !          107453: };
        !          107454: 
        !          107455: /*
        !          107456:  * A simple printf.
        !          107457:  */
        !          107458: printf(fp, a1)
        !          107459: register char *fp;
        !          107460: {
        !          107461:        char * cp;
        !          107462:        register int c;
        !          107463:        register unsigned *ap;
        !          107464:        int lflag;
        !          107465: 
        !          107466:        ap = (char *)&a1;
        !          107467:        for (;;) {
        !          107468:                while ((c=*fp++) != '%') {
        !          107469:                        if (c == '\0')
        !          107470:                                return;
        !          107471:                        putchar(c);
        !          107472:                }
        !          107473: 
        !          107474:                lflag = 0;
        !          107475:                if ( *fp == 'l' ) {
        !          107476:                        lflag = 1;
        !          107477:                        fp++;
        !          107478:                }
        !          107479: 
        !          107480:                switch ( c = *fp++ ) {
        !          107481: 
        !          107482:                case 'c':
        !          107483:                        putchar(*ap++);
        !          107484:                        continue;
        !          107485: 
        !          107486:                case 'd':
        !          107487:                        if ( lflag == 0 ) {
        !          107488:                                if ( ((int)(*ap)) < 0 ) {
        !          107489:                                        putchar('-');
        !          107490:                                        printn( -((long) ((int)(*ap))), 10 );
        !          107491:                                }
        !          107492:                                else
        !          107493:                                        printn( ((long)(*ap)), 10 );
        !          107494:                                ap++;
        !          107495:                                continue;
        !          107496:                        }
        !          107497:                        /* fall through */
        !          107498:                case 'D':
        !          107499:                        if ( *((long *)(ap)) < 0 ) {
        !          107500:                                putchar('-');
        !          107501:                                printn( - *((long *)(ap)), 10 );
        !          107502:                        }
        !          107503:                        else
        !          107504:                                printn(   *((long *)(ap)), 10 );
        !          107505: 
        !          107506:                        ((long *)(ap))++;
        !          107507:                        continue;
        !          107508: 
        !          107509:                case 'o':
        !          107510:                        if ( lflag == 0 ) {
        !          107511:                                printn( ((long)(*ap)), 8);
        !          107512:                                ap++;
        !          107513:                                continue;
        !          107514:                        }
        !          107515:                        /* fall through */
        !          107516:                case 'O':
        !          107517:                        printf( *((long *)(ap)), 8 );
        !          107518:                        ((long *)(ap))++;
        !          107519:                        continue;
        !          107520: 
        !          107521:                case 'r':
        !          107522:                        ap = *((int **) ap);
        !          107523:                        fp = ind(ap, char *);
        !          107524:                        ap += inc(int, char *);
        !          107525:                        continue;
        !          107526: 
        !          107527:                case 's':
        !          107528:                        cp = ind(ap, char *);
        !          107529:                        ap += inc(int, char *);
        !          107530:                        while ((c=*cp++) != '\0')
        !          107531:                                putchar(c);
        !          107532:                        continue;
        !          107533: 
        !          107534:                case 'x':
        !          107535:                        if ( lflag == 0 ) {
        !          107536:                                printn( ((long)(*ap)), 16 );
        !          107537:                                ap++;
        !          107538:                                continue;
        !          107539:                        }
        !          107540:                        /* fall through */
        !          107541:                case 'X':
        !          107542:                        printn( *((long *)(ap)), 16 );
        !          107543:                        ((long *)(ap))++;
        !          107544:                        continue;
        !          107545: 
        !          107546:                case 'u':
        !          107547:                        if ( lflag == 0 ) {
        !          107548:                                printn( ((long)(*ap)), 10);
        !          107549:                                ap++;
        !          107550:                                continue;
        !          107551:                        }
        !          107552:                        /* fall through */
        !          107553:                case 'U':
        !          107554:                        printn( *((long *)(ap)), 10 );
        !          107555:                        ((long *)(ap))++;
        !          107556:                        continue;
        !          107557: 
        !          107558:                case 'p':
        !          107559:                        if (sizeof(char *) > sizeof(int)) {
        !          107560:                                printn( ((long)(*ap)), 16);
        !          107561:                                putchar(':');
        !          107562:                                ap++;
        !          107563:                        }
        !          107564:                        printn( ((long)(*ap)), 16);
        !          107565:                        ap++;
        !          107566:                        continue;
        !          107567: 
        !          107568:                default:
        !          107569:                        putchar(c);
        !          107570:                        continue;
        !          107571:                }
        !          107572:        }
        !          107573: }
        !          107574: 
        !          107575: /*
        !          107576:  * Print out the unsigned long `v' in the base `b'.
        !          107577:  */
        !          107578: printn( v, b )
        !          107579: unsigned long v;
        !          107580: {
        !          107581:        unsigned long n;
        !          107582: 
        !          107583:        if ((n=v/b) != 0)
        !          107584:                printn(n, b);
        !          107585: 
        !          107586:        putchar(digtab[v%b]);
        !          107587: }
        !          107588: 0707070064030103241006440000030000030000011777770507310730200004200000026363/newbits/kernel/USRSRC/coh/proc.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/proc.c,v 1.4 91/07/24 07:51:40 bin Exp Locker: bin $ */
        !          107589: /* (lgl-
        !          107590:  *     The information contained herein is a trade secret of Mark Williams
        !          107591:  *     Company, and  is confidential information.  It is provided  under a
        !          107592:  *     license agreement,  and may be  copied or disclosed  only under the
        !          107593:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          107594:  *     material without the express written authorization of Mark Williams
        !          107595:  *     Company or persuant to the license agreement is unlawful.
        !          107596:  *
        !          107597:  *     COHERENT Version 2.3.37
        !          107598:  *     Copyright (c) 1982, 1983, 1984.
        !          107599:  *     An unpublished work by Mark Williams Company, Chicago.
        !          107600:  *     All rights reserved.
        !          107601:  -lgl) */
        !          107602: /*
        !          107603:  * Coherent.
        !          107604:  * Process handling and scheduling.
        !          107605:  *
        !          107606:  * $Log:       proc.c,v $
        !          107607:  * Revision 1.4  91/07/24  07:51:40  bin
        !          107608:  * update prov by hal
        !          107609:  * 
        !          107610:  * 
        !          107611:  * Revision 1.2        88/08/05  15:30:01      src
        !          107612:  * pfork() made more rigorous, supports loadable driver forks, etc.
        !          107613:  * lock/unlock more efficient, since know wakeup is synchronous.
        !          107614:  * 
        !          107615:  * Revision 1.1        88/03/24  16:14:16      src
        !          107616:  * Initial revision
        !          107617:  * 
        !          107618:  * 88/03/10    Allan Cornish           /usr/src/sys/coh/proc.c
        !          107619:  * Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !          107620:  * These partial fixes will be removed once all CPU's are replaced.
        !          107621:  *
        !          107622:  * 88/01/21    Allan Cornish           /usr/src/sys/coh/proc.c
        !          107623:  * Race condition caused by pexit() calling sfree() on the user-area
        !          107624:  * when the segmentation gate is locked is now prevented.
        !          107625:  * Release of the user area now deferred until relproc() invoked by uwait().
        !          107626:  *
        !          107627:  * 87/11/13    Allan Cornish           /usr/src/sys/coh/proc.c
        !          107628:  * pexit() now sets uasa to 0 before dispatching processor.
        !          107629:  *
        !          107630:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/proc.c
        !          107631:  * New seg struct now used to allow extended addressing.
        !          107632:  *
        !          107633:  * 87/07/08    Allan Cornish           /usr/src/sys/coh/proc.c
        !          107634:  * pexit() now cancels poll/alarm timed functions before terminating.
        !          107635:  *
        !          107636:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/proc.c
        !          107637:  * pexit() now wakes the swapper before terminating.
        !          107638:  */
        !          107639: #include <sys/coherent.h>
        !          107640: #include <acct.h>
        !          107641: #include <errno.h>
        !          107642: #include <sys/inode.h>
        !          107643: #include <sys/proc.h>
        !          107644: #include <sys/ptrace.h>
        !          107645: #include <sys/sched.h>
        !          107646: #include <sys/seg.h>
        !          107647: #include <signal.h>
        !          107648: #include <sys/stat.h>
        !          107649: #include <sys/uproc.h>
        !          107650: 
        !          107651: /*
        !          107652:  * Initialisation.
        !          107653:  * Set up the hash table queues.
        !          107654:  */
        !          107655: pcsinit()
        !          107656: {
        !          107657:        register PROC *pp;
        !          107658:        register PLINK *lp;
        !          107659: 
        !          107660:        pp = &procq;
        !          107661:        SELF = pp;
        !          107662:        procq.p_nforw = pp;
        !          107663:        procq.p_nback = pp;
        !          107664:        procq.p_lforw = pp;
        !          107665:        procq.p_lback = pp;
        !          107666:        for (lp=&linkq[0]; lp<&linkq[NHPLINK]; lp++) {
        !          107667:                lp->p_lforw = lp;
        !          107668:                lp->p_lback = lp;
        !          107669:        }
        !          107670: }
        !          107671: 
        !          107672: /*
        !          107673:  * Initiate a process.  `f' is a kernel function that is associated with
        !          107674:  * the process.
        !          107675:  */
        !          107676: PROC *
        !          107677: process(f)
        !          107678: int (*f)();
        !          107679: {
        !          107680:        register PROC *pp1;
        !          107681:        register PROC *pp;
        !          107682:        register SEG *sp;
        !          107683:        MCON mcon;
        !          107684: 
        !          107685:        if ((pp=kalloc(sizeof(PROC))) == NULL)
        !          107686:                return (NULL);
        !          107687: 
        !          107688:        pp->p_flags = PFCORE;
        !          107689:        pp->p_state = PSRUN;
        !          107690:        pp->p_ttdev = NODEV;
        !          107691: 
        !          107692:        if (f != NULL) {
        !          107693:                pp->p_flags |= PFKERN;
        !          107694:                sp = salloc((fsize_t)UPASIZE, SFSYST|SFHIGH|SFNSWP);
        !          107695:                if (sp == NULL) {
        !          107696:                        kfree(pp);
        !          107697:                        return (NULL);
        !          107698:                }
        !          107699:                pp->p_segp[SIUSERP] = sp;
        !          107700:                msetsys( &mcon, f, FP_SEL(sp->s_faddr) );
        !          107701:                kfcopy( (char *)&mcon,
        !          107702:                        sp->s_faddr + offset(uproc, u_syscon),
        !          107703:                        sizeof(mcon) );
        !          107704:        }
        !          107705:        lock(pnxgate);
        !          107706: next:
        !          107707:        pp->p_pid = cpid++;
        !          107708:        if (cpid >= NPID)
        !          107709:                cpid = 2;
        !          107710:        pp1 = &procq;
        !          107711:        while ((pp1=pp1->p_nforw) != &procq) {
        !          107712:                if (pp1->p_pid < pp->p_pid)
        !          107713:                        break;
        !          107714:                if (pp1->p_pid == pp->p_pid)
        !          107715:                        goto next;
        !          107716:        }
        !          107717:        pp->p_nback = pp1->p_nback;
        !          107718:        pp1->p_nback->p_nforw = pp;
        !          107719:        pp->p_nforw = pp1;
        !          107720:        pp1->p_nback = pp;
        !          107721:        unlock(pnxgate);
        !          107722:        return (pp);
        !          107723: }
        !          107724: 
        !          107725: /*
        !          107726:  * Remove a process from the next queue and release and space.
        !          107727:  */
        !          107728: relproc(pp)
        !          107729: register PROC *pp;
        !          107730: {
        !          107731:        register SEG * sp;
        !          107732: 
        !          107733:        /*
        !          107734:         * Child process still has a user-area.
        !          107735:         */
        !          107736:        if ( (sp = pp->p_segp[SIUSERP]) != NULL ) {
        !          107737: 
        !          107738:                /*
        !          107739:                 * Detach user-area from child process.
        !          107740:                 */
        !          107741:                pp->p_segp[SIUSERP] = NULL;
        !          107742: 
        !          107743:                /*
        !          107744:                 * Child process is swapped out.
        !          107745:                 */
        !          107746:                if ( pp->p_flags & PFSWAP )
        !          107747:                        sp->s_lrefc++;
        !          107748: 
        !          107749:                /*
        !          107750:                 * Release child's user-area.
        !          107751:                 */
        !          107752:                sfree( sp );
        !          107753:        }
        !          107754: 
        !          107755:        /*
        !          107756:         * Remove process from doubly-linked list of all processes.
        !          107757:         * Release space allocated for proc structure.
        !          107758:         */
        !          107759:        lock(pnxgate);
        !          107760:        pp->p_nback->p_nforw = pp->p_nforw;
        !          107761:        pp->p_nforw->p_nback = pp->p_nback;
        !          107762:        unlock(pnxgate);
        !          107763:        kfree(pp);
        !          107764: }
        !          107765: 
        !          107766: /*
        !          107767:  * Create a clone of ourselves.
        !          107768:  *     N.B. - consave(&mcon) returns twice; anything not initialized
        !          107769:  *     in automatic storage before the call to segadup() will not be
        !          107770:  *     initialized when the second return from consave() commences.
        !          107771:  */
        !          107772: pfork()
        !          107773: {
        !          107774:        register PROC *cpp;
        !          107775:        register PROC *pp;
        !          107776:        register int s;
        !          107777:        MCON mcon;
        !          107778: 
        !          107779:        if ((cpp=process(NULL)) == NULL) {
        !          107780:                u.u_error = EAGAIN;
        !          107781:                return;
        !          107782:        }
        !          107783: 
        !          107784:        s = sphi();     /* Make usave a null macro if unnecessary */
        !          107785:        usave();        /* Put the current copy of uarea into its segment */
        !          107786:        spl(s);
        !          107787: 
        !          107788:        if (segadup(cpp) == 0) {
        !          107789:                u.u_error = EAGAIN;
        !          107790:                relproc(cpp);
        !          107791:                return;
        !          107792:        }
        !          107793:        if ( u.u_rdir != NULL )
        !          107794:                u.u_rdir->i_refc++;
        !          107795:        if ( u.u_cdir != NULL )
        !          107796:                u.u_cdir->i_refc++;
        !          107797:        fdadupl();
        !          107798:        pp = SELF;
        !          107799:        cpp->p_uid   = pp->p_uid;
        !          107800:        cpp->p_ruid  = pp->p_ruid;
        !          107801:        cpp->p_rgid  = pp->p_rgid;
        !          107802:        cpp->p_ppid  = pp->p_pid;
        !          107803:        cpp->p_ttdev = pp->p_ttdev;
        !          107804:        cpp->p_group = pp->p_group;
        !          107805:        cpp->p_ssig  = pp->p_ssig;
        !          107806:        cpp->p_isig  = pp->p_isig;
        !          107807:        cpp->p_cval  = CVCHILD;
        !          107808:        cpp->p_ival  = IVCHILD;
        !          107809:        cpp->p_sval  = SVCHILD;
        !          107810:        cpp->p_rval  = RVCHILD;
        !          107811: 
        !          107812:        s = sphi();
        !          107813:        consave(&mcon);
        !          107814:        spl( s );
        !          107815: 
        !          107816:        /*
        !          107817:         * Parent process.
        !          107818:         */
        !          107819:        if ( (pp = SELF) != cpp ) {
        !          107820:                segfinm(cpp->p_segp[SIUSERP]);
        !          107821:                kfcopy( (char *)&mcon,
        !          107822:                        cpp->p_segp[SIUSERP]->s_faddr + offset(uproc,u_syscon),
        !          107823:                        sizeof(mcon) );
        !          107824:                mfixcon(cpp);
        !          107825:                s = sphi();
        !          107826:                setrun(cpp);
        !          107827:                spl(s);
        !          107828:                return( cpp->p_pid );
        !          107829:        }
        !          107830: 
        !          107831:        /*
        !          107832:         * Child process.
        !          107833:         */
        !          107834:        else {
        !          107835:                u.u_btime = timer.t_time;
        !          107836:                u.u_flag = AFORK;
        !          107837:                /* for (i=0; i<NUSEG; i++) done in sproto */
        !          107838:                        /* u.u_segl[i].sr_segp = pp->p_segp[i]; ditto */
        !          107839:                sproto();
        !          107840:                segload();
        !          107841:                return( 0 );
        !          107842:        }
        !          107843: }
        !          107844: 
        !          107845: /*
        !          107846:  * Die.
        !          107847:  */
        !          107848: pexit(s)
        !          107849: {
        !          107850:        register PROC *pp1;
        !          107851:        register PROC *pp;
        !          107852:        register SEG  *sp;
        !          107853:        register int n;
        !          107854: 
        !          107855:        pp = SELF;
        !          107856: 
        !          107857:        /*
        !          107858:         * Cancel alarm and poll timers [if any].
        !          107859:         */
        !          107860:        timeout( &pp->p_alrmtim, 0, NULL, 0 );
        !          107861:        timeout( &pp->p_polltim, 0, NULL, 0 );
        !          107862: 
        !          107863:        /*
        !          107864:         * Write out accounting directory and close all files associated with
        !          107865:         * this process.
        !          107866:         */
        !          107867:        setacct();
        !          107868:        if ( u.u_rdir )
        !          107869:                ldetach(u.u_rdir);
        !          107870:        if ( u.u_cdir )
        !          107871:                ldetach(u.u_cdir);
        !          107872:        fdaclose();
        !          107873: 
        !          107874:        /*
        !          107875:         * Free all segments in reverse order, except for user-area.
        !          107876:         */
        !          107877:        for ( n = NUSEG; --n > 0; ) {
        !          107878:                if ( (sp = pp->p_segp[n]) != NULL ) {
        !          107879:                        pp->p_segp[n] = NULL;
        !          107880:                        sfree( sp );
        !          107881:                }
        !          107882:        }
        !          107883: 
        !          107884:        /*
        !          107885:         * Wakeup our parent.  If we have any children, init will become the
        !          107886:         * new parent.  If there are any children we are tracing who are
        !          107887:         * waiting for us, we wake them up.
        !          107888:         */
        !          107889:        pp1 = &procq;
        !          107890:        while ((pp1=pp1->p_nforw) != &procq) {
        !          107891:                if (pp1->p_pid == pp->p_ppid) {
        !          107892:                        if (pp1->p_state==PSSLEEP && pp1->p_event==(char *)pp1)
        !          107893:                                wakeup((char *)pp1);
        !          107894:                }
        !          107895:                if (pp1->p_ppid == pp->p_pid) {
        !          107896:                        pp1->p_ppid = 1;
        !          107897:                        if (pp1->p_state == PSDEAD)
        !          107898:                                wakeup((char *)eprocp);
        !          107899:                        if ((pp1->p_flags&PFTRAC) != 0)
        !          107900:                                wakeup((char *)&pts.pt_req);
        !          107901:                }
        !          107902:        }
        !          107903: 
        !          107904:        /*
        !          107905:         * Wake up swapper if swap timer is active.
        !          107906:         */
        !          107907:        if ( stimer.t_last != 0 )
        !          107908:                wakeup( (char *) &stimer );
        !          107909: 
        !          107910:        /*
        !          107911:         * And finally mark us as dead and give up the processor forever.
        !          107912:         */
        !          107913:        pp->p_exit = s;
        !          107914:        pp->p_state = PSDEAD;
        !          107915:        uasa = 0;
        !          107916:        dispatch();
        !          107917: }
        !          107918: 
        !          107919: /*
        !          107920:  * Sleep on the event `e'.  This gives up the processor until someone
        !          107921:  * wakes us up.  Since it is possible for many people to sleep on the
        !          107922:  * same event, the caller when awakened should make sure that what he
        !          107923:  * was waiting for has completed and if not, go to sleep again.  `cl'
        !          107924:  * is the cpu value we get to get the cpu as soon as we are woken up.
        !          107925:  * `sl' is the swap value we get to keep us in memory for the duration
        !          107926:  * of the sleep.  `sr' is the swap value that allows us to get swapped
        !          107927:  * in if we have been swapped out.
        !          107928:  */
        !          107929: sleep(e, cl, sl, sr)
        !          107930: char *e;
        !          107931: {
        !          107932:        register PROC *bp;
        !          107933:        register PROC *fp;
        !          107934:        register PROC *pp;
        !          107935:        register int s;
        !          107936: 
        !          107937:        pp = SELF;
        !          107938: 
        !          107939:        /*
        !          107940:         * See if we have a signal awaiting.
        !          107941:         */
        !          107942:        if (cl<CVNOSIG && pp->p_ssig && nondsig()) {
        !          107943:                sphi();
        !          107944:                envrest(&u.u_sigenv);
        !          107945:        }
        !          107946: 
        !          107947:        /*
        !          107948:         * Get ready to go to sleep and do so.
        !          107949:         */
        !          107950:        s = sphi();
        !          107951:        pp->p_state = PSSLEEP;
        !          107952:        pp->p_event = e;
        !          107953:        pp->p_lctim = utimer;
        !          107954:        addu(pp->p_cval, cl);
        !          107955:        pp->p_ival = sl;
        !          107956:        pp->p_rval = sr;
        !          107957:        fp = &linkq[hash(e)];
        !          107958:        bp = fp->p_lback;
        !          107959:        pp->p_lforw = fp;
        !          107960:        fp->p_lback = pp;
        !          107961:        pp->p_lback = bp;
        !          107962:        bp->p_lforw = pp;
        !          107963:        spl(s);
        !          107964:        dispatch();
        !          107965: 
        !          107966:        /*
        !          107967:         * We have just woken up.  Get ready to return.
        !          107968:         */
        !          107969:        subu(pp->p_cval, cl);
        !          107970:        pp->p_ival = 0;
        !          107971:        pp->p_rval = 0;
        !          107972: 
        !          107973:        /*
        !          107974:         * Check for an interrupted system call.
        !          107975:         */
        !          107976:        if (cl<CVNOSIG && pp->p_ssig && nondsig()) {
        !          107977:                sphi();
        !          107978:                envrest(&u.u_sigenv);
        !          107979:        }
        !          107980: }
        !          107981: 
        !          107982: /*
        !          107983:  * Defer function to wake up all processes sleeping on the event `e'.
        !          107984:  */
        !          107985: wakeup(e)
        !          107986: char *e;
        !          107987: {
        !          107988:        extern void dwakeup();
        !          107989: 
        !          107990:        defer( dwakeup, e );
        !          107991: }
        !          107992: 
        !          107993: /*
        !          107994:  * Wake up all processes sleeping on the event `e'.
        !          107995:  */
        !          107996: static void
        !          107997: dwakeup( e )
        !          107998: char *e;
        !          107999: {
        !          108000:        register PROC *pp;
        !          108001:        register PROC *pp1;
        !          108002:        register int s;
        !          108003: 
        !          108004:        /*
        !          108005:         * Identify event queue to check.
        !          108006:         * Disable interrupts.
        !          108007:         */
        !          108008:        pp1 = &linkq[hash(e)];
        !          108009:        pp = pp1;
        !          108010:        s = sphi();
        !          108011: 
        !          108012:        /*
        !          108013:         * Traverse doubly-linked circular event-queue.
        !          108014:         */
        !          108015:        while ( (pp = pp->p_lforw) != pp1 ) {
        !          108016: 
        !          108017:                /*
        !          108018:                 * Process is waiting on event 'e'.
        !          108019:                 */
        !          108020:                if ( pp->p_event == e ) {
        !          108021:                        /*
        !          108022:                         * Remove process from event queue.
        !          108023:                         * Update process priority.
        !          108024:                         * Insert process into run queue.
        !          108025:                         */
        !          108026:                        pp->p_lback->p_lforw = pp->p_lforw;
        !          108027:                        pp->p_lforw->p_lback = pp->p_lback;
        !          108028:                        addu( pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK );
        !          108029:                        setrun( pp );
        !          108030: 
        !          108031:                        /*
        !          108032:                         * Enable interrupts.
        !          108033:                         * Restart search at start of event queue.
        !          108034:                         * Disable interrupts.
        !          108035:                         */
        !          108036:                        spl( s );
        !          108037:                        pp = pp1;
        !          108038:                        s = sphi();
        !          108039:                }
        !          108040:        }
        !          108041:        spl(s);
        !          108042: }
        !          108043: 
        !          108044: /*
        !          108045:  * Reschedule the processor.
        !          108046:  */
        !          108047: dispatch()
        !          108048: {
        !          108049:        register PROC *pp1;
        !          108050:        register PROC *pp2;
        !          108051:        register unsigned v;
        !          108052:        register int s;
        !          108053: 
        !          108054:        s = sphi();
        !          108055:        pp1 = iprocp;
        !          108056:        pp2 = &procq;
        !          108057:        v = 0;
        !          108058:        while ((pp2=pp2->p_lforw) != &procq) {
        !          108059:                v -= pp2->p_cval;
        !          108060:                if ((pp2->p_flags&PFCORE) == 0)
        !          108061:                        continue;
        !          108062:                pp1 = pp2->p_lforw;
        !          108063:                pp1->p_cval += pp2->p_cval;
        !          108064:                pp2->p_cval = v;
        !          108065:                pp1->p_lback = pp2->p_lback;
        !          108066:                pp1->p_lback->p_lforw = pp1;
        !          108067:                pp1 = pp2;
        !          108068:                break;
        !          108069:        }
        !          108070:        spl(s);
        !          108071: 
        !          108072:        quantum = NCRTICK;
        !          108073:        disflag = 0;
        !          108074:        if ( pp1 != SELF ) {
        !          108075:                /*
        !          108076:                 * Consave() returns twice.
        !          108077:                 * 1st time is after our context is saved in u.u_syscon,
        !          108078:                 *      whereupon we should restore other proc's context.
        !          108079:                 * 2nd time is after our context is restored by another proc.
        !          108080:                 * Conrest() forces a context switch to a new process.
        !          108081:                 */
        !          108082:                s = sphi();
        !          108083:                SELF = pp1;
        !          108084:                if (consave(&u.u_syscon) == 0)
        !          108085:                        conrest( FP_SEL(pp1->p_u->s_faddr),
        !          108086:                                 offset(uproc,u_syscon) );
        !          108087:                if ( SELF->p_pid != 0 )
        !          108088:                        segload();
        !          108089:                spl(s);
        !          108090:        }
        !          108091: }
        !          108092: 
        !          108093: /*
        !          108094:  * Add a process to the run queue.
        !          108095:  * This routine must be called at high priority.
        !          108096:  */
        !          108097: setrun(pp1)
        !          108098: register PROC *pp1;
        !          108099: {
        !          108100:        register PROC *pp2;
        !          108101:        register unsigned v;
        !          108102: 
        !          108103:        v = 0;
        !          108104:        pp2 = &procq;
        !          108105:        for (;;) {
        !          108106:                pp2 = pp2->p_lback;
        !          108107:                if ((v+=pp2->p_lforw->p_cval) >= pp1->p_cval)
        !          108108:                        break;
        !          108109:                if (pp2 == &procq)
        !          108110:                        break;
        !          108111:        }
        !          108112:        pp2->p_lforw->p_lback = pp1;
        !          108113:        pp1->p_lforw = pp2->p_lforw;
        !          108114:        pp2->p_lforw = pp1;
        !          108115:        pp1->p_lback = pp2;
        !          108116:        v -= pp1->p_cval;
        !          108117:        pp1->p_cval = v;
        !          108118:        pp1->p_lforw->p_cval -= v;
        !          108119:        pp1->p_state = PSRUN;
        !          108120: }
        !          108121: 
        !          108122: /*
        !          108123:  * Wait for the gate `g' to unlock, and then lock it.
        !          108124:  */
        !          108125: lock(g)
        !          108126: register GATE g;
        !          108127: {
        !          108128:        register int s;
        !          108129: 
        !          108130:        s = sphi();
        !          108131:        while (g[0]) {
        !          108132:                g[1] = 1;
        !          108133:                sleep((char *)g, CVGATE, IVGATE, SVGATE);
        !          108134:        }
        !          108135:        g[0] = 1;
        !          108136:        spl(s);
        !          108137: }
        !          108138: 
        !          108139: /*
        !          108140:  * Unlock the gate `g'.
        !          108141:  */
        !          108142: unlock(g)
        !          108143: register GATE g;
        !          108144: {
        !          108145:        g[0] = 0;
        !          108146:        if (g[1]) {
        !          108147:                g[1] = 0;
        !          108148:                disflag = 1;
        !          108149:                wakeup((char *)g);
        !          108150:        }
        !          108151: }
        !          108152: 0707070064030103231006440000030000030000011777770507310730400004100000041425/newbits/kernel/USRSRC/coh/seg.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/seg.c,v 1.4 91/07/24 07:51:50 bin Exp Locker: bin $ */
        !          108153: /* (lgl-
        !          108154:  *     The information contained herein is a trade secret of Mark Williams
        !          108155:  *     Company, and  is confidential information.  It is provided  under a
        !          108156:  *     license agreement,  and may be  copied or disclosed  only under the
        !          108157:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          108158:  *     material without the express written authorization of Mark Williams
        !          108159:  *     Company or persuant to the license agreement is unlawful.
        !          108160:  *
        !          108161:  *     COHERENT Version 2.3.37
        !          108162:  *     Copyright (c) 1982, 1983, 1984.
        !          108163:  *     An unpublished work by Mark Williams Company, Chicago.
        !          108164:  *     All rights reserved.
        !          108165:  -lgl) */
        !          108166: /*
        !          108167:  * Coherent.
        !          108168:  * Segment manipulation.
        !          108169:  *
        !          108170:  * $Log:       seg.c,v $
        !          108171:  * Revision 1.4  91/07/24  07:51:50  bin
        !          108172:  * update prov by hal
        !          108173:  * 
        !          108174:  * 
        !          108175:  * Revision 1.1        88/03/24  16:14:20      src
        !          108176:  * Initial revision
        !          108177:  * 
        !          108178:  * 88/02/26    Allan Cornish   /usr/src/sys/coh/seg.c
        !          108179:  * swapio() now avoids 64 Kbyte page [dma] straddles.
        !          108180:  *
        !          108181:  * 88/01/22    Allan Cornish   /usr/src/sys/coh/seg.c
        !          108182:  * salloc() now invokes krunch(1000) if initial allocation fails.
        !          108183:  * sfree() now invokes krunch(0).
        !          108184:  *
        !          108185:  * 88/01/21    Allan Cornish   /usr/src/sys/coh/seg.c
        !          108186:  * sfree() modified to eliminate critical race on ref cnts and segment gate.
        !          108187:  * segfinm() now properly maintains segment reference counts.
        !          108188:  *
        !          108189:  * 87/11/13    Allan Cornish   /usr/src/sys/coh/seg.c
        !          108190:  * Support for protected mode segmentation added.
        !          108191:  */
        !          108192: #include <sys/coherent.h>
        !          108193: #include <sys/buf.h>
        !          108194: #include <errno.h>
        !          108195: #include <sys/ino.h>
        !          108196: #include <sys/inode.h>
        !          108197: #include <sys/proc.h>
        !          108198: #include <sys/sched.h>
        !          108199: #include <sys/seg.h>
        !          108200: #include <sys/uproc.h>
        !          108201: 
        !          108202: /*
        !          108203:  * Initialisation code.
        !          108204:  */
        !          108205: seginit()
        !          108206: {
        !          108207:        /*
        !          108208:         * Create empty circular-list of memory segments.
        !          108209:         */
        !          108210:        segmq.s_forw = &segmq;
        !          108211:        segmq.s_back = &segmq;
        !          108212: 
        !          108213:        /*
        !          108214:         * Create empty circular-list of disk segments.
        !          108215:         */
        !          108216:        segdq.s_forw = &segdq;
        !          108217:        segdq.s_back = &segdq;
        !          108218: 
        !          108219:        if ( holebot != holetop ) {
        !          108220:                /*
        !          108221:                 * Define the I/O mem hole between low memory and extended mem.
        !          108222:                 * NOTE: Setting lrefc to urefc+1 stopx segment from moving.
        !          108223:                 */
        !          108224:                segiom.s_paddr = holebot;
        !          108225:                segiom.s_size  = holetop - holebot;
        !          108226:                segiom.s_flags = SFCORE | SFSYST;
        !          108227:                segiom.s_urefc = 1;
        !          108228:                segiom.s_lrefc = 2;
        !          108229: 
        !          108230:                /*
        !          108231:                 * Insert I/O memory segment into memory list.
        !          108232:                 */
        !          108233:                segiom.s_forw = &segmq;
        !          108234:                segiom.s_back = &segmq;
        !          108235:                segmq.s_forw  = &segiom;
        !          108236:                segmq.s_back  = &segiom;
        !          108237:        }
        !          108238: }
        !          108239: 
        !          108240: /*
        !          108241:  * Given an inode, `ip', and flags, `ff', describing a segment associated
        !          108242:  * with the inode, see if the segment already exists and if so, return a
        !          108243:  * copy.  If the segment does not exists, allocate the segment having size
        !          108244:  * `ss', and read the segment using the inode at seek offset `dq' with a
        !          108245:  * size of `ds'.
        !          108246:  */
        !          108247: SEG *
        !          108248: ssalloc(rp, ip, ff, ss, dq, ds)
        !          108249: int *rp;
        !          108250: register INODE *ip;
        !          108251: fsize_t ss;
        !          108252: fsize_t dq;
        !          108253: fsize_t ds;
        !          108254: {
        !          108255:        register SEG *sp;
        !          108256:        register int f;
        !          108257: 
        !          108258:        *rp = -1;
        !          108259:        if (ss == 0) {
        !          108260:                *rp = 1;
        !          108261:                return (NULL);
        !          108262:        }
        !          108263:        lock(seglink);
        !          108264:        f = ff & (SFSHRX|SFTEXT);
        !          108265: 
        !          108266:        /*
        !          108267:         * Look for the segment in the memory queue.
        !          108268:         */
        !          108269:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
        !          108270:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
        !          108271:                        unlock(seglink);
        !          108272:                        if ((sp = segdupl(sp)) != NULL) {
        !          108273:                                segfinm(sp);
        !          108274:                                *rp = 1;
        !          108275:                        }
        !          108276:                        return (sp);
        !          108277:                }
        !          108278:        }
        !          108279: 
        !          108280:        /*
        !          108281:         * Look for the segment on the disk queue.
        !          108282:         */
        !          108283:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
        !          108284:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
        !          108285:                        unlock(seglink);
        !          108286:                        if ((sp = segdupl(sp)) != NULL) {
        !          108287:                                segfinm(sp);
        !          108288:                                *rp = 1;
        !          108289:                        }
        !          108290:                        return (sp);
        !          108291:                }
        !          108292:        }
        !          108293:        unlock(seglink);
        !          108294: 
        !          108295:        /*
        !          108296:         * Allocate and create the segment.
        !          108297:         */
        !          108298:        if ((sp=salloc(ss, ff)) == NULL)
        !          108299:                return (NULL);
        !          108300:        if (exsread(sp, ip, ds, dq, (fsize_t)0) == 0) {
        !          108301:                sfree(sp);
        !          108302:                return (NULL);
        !          108303:        }
        !          108304:        if ((ff&SFSHRX) != 0) {
        !          108305:                sp->s_ip = ip;
        !          108306:                ip->i_refc++;
        !          108307:        }
        !          108308:        *rp = 0;
        !          108309:        return (sp);
        !          108310: }
        !          108311: 
        !          108312: /*
        !          108313:  * Given a pointer to a newly created process, copy all of our segments
        !          108314:  * into the given process.
        !          108315:  */
        !          108316: segadup(cpp)
        !          108317: register PROC *cpp;
        !          108318: {
        !          108319:        register SEG *sp;
        !          108320:        register int n;
        !          108321:        register PROC *pp;
        !          108322: 
        !          108323:        pp = SELF;
        !          108324:        cpp->p_flags |= PFSWIO;
        !          108325:        for (n=0; n<NUSEG; n++) {
        !          108326:                if ((sp=pp->p_segp[n]) == NULL)
        !          108327:                        continue;
        !          108328:                if ((sp=segdupl(sp)) == NULL)
        !          108329:                        break;
        !          108330:                cpp->p_segp[n] = sp;
        !          108331:                if ((sp->s_flags&SFCORE) == 0)
        !          108332:                        cpp->p_flags &= ~PFCORE;
        !          108333:        }
        !          108334:        if (n < NUSEG) {
        !          108335:                while (n > 0) {
        !          108336:                        if ((sp=cpp->p_segp[--n]) != NULL) {
        !          108337:                                cpp->p_segp[n] = NULL;
        !          108338:                                sfree(sp);
        !          108339:                        }
        !          108340:                }
        !          108341:        }
        !          108342:        cpp->p_flags &= ~PFSWIO;
        !          108343:        return (n);
        !          108344: }
        !          108345: 
        !          108346: /*
        !          108347:  * Duplicate a segment.
        !          108348:  */
        !          108349: SEG *
        !          108350: segdupl(sp)
        !          108351: register SEG *sp;
        !          108352: {
        !          108353:        register SEG *sp1;
        !          108354: 
        !          108355:        if ((sp->s_flags&SFSHRX) != 0) {
        !          108356:                sp->s_urefc++;
        !          108357:                sp->s_lrefc++;
        !          108358:                return (sp);
        !          108359:        }
        !          108360:        if ((sp->s_flags&SFCORE) == 0)
        !          108361:                panic("Cannot duplicate non shared swapped segment");
        !          108362:        if ((sp1=salloc(sp->s_size, sp->s_flags|SFNSWP|SFNCLR)) == NULL)
        !          108363:                sp1 = segdupd(sp);
        !          108364:        else {
        !          108365:                sp1->s_flags = sp->s_flags;
        !          108366:                plrcopy( sp->s_paddr, sp1->s_paddr, sp->s_size );
        !          108367:        }
        !          108368:        return (sp1);
        !          108369: }
        !          108370: 
        !          108371: /*
        !          108372:  * Allocate a segment `n' bytes long.  `f' contains some pseudo flags.
        !          108373:  */
        !          108374: SEG *
        !          108375: salloc(n, f)
        !          108376: fsize_t n;
        !          108377: {
        !          108378:        register SEG *sp;
        !          108379:        register int r;
        !          108380: 
        !          108381:        r = (f&(SFSYST|SFHIGH|SFTEXT|SFSHRX|SFDOWN)) | SFCORE;
        !          108382:        n +=  (BSIZE-1);
        !          108383:        n &= ~(BSIZE-1);
        !          108384: 
        !          108385:        lock(seglink);
        !          108386:        sp = sxalloc(n, f);
        !          108387:        unlock(seglink);
        !          108388: 
        !          108389:        if ( sp == NULL ) {
        !          108390:                krunch(1000);
        !          108391:                lock(seglink);
        !          108392:                sp = sxalloc(n, f);
        !          108393:                unlock(seglink);
        !          108394:        }
        !          108395: 
        !          108396:        if (sp != NULL) {
        !          108397:                sp->s_flags = r;
        !          108398:                vremap( sp );
        !          108399:        }
        !          108400:        else {
        !          108401:                if ((f&SFNSWP) != 0)
        !          108402:                        return (NULL);
        !          108403:                if ((sp=kalloc(sizeof(SEG))) == NULL)
        !          108404:                        return (NULL);
        !          108405:                sp->s_forw = sp;
        !          108406:                sp->s_back = sp;
        !          108407:                sp->s_flags = r;
        !          108408:                sp->s_urefc = 1;
        !          108409:                sp->s_lrefc = 1;
        !          108410:                if (segsext(sp, n) == NULL) {
        !          108411:                        kfree(sp);
        !          108412:                        return (NULL);
        !          108413:                }
        !          108414:        }
        !          108415:        if ((f&SFNCLR) == 0)
        !          108416:                pclear( sp->s_paddr, n );
        !          108417:        return (sp);
        !          108418: }
        !          108419: 
        !          108420: /*
        !          108421:  * Free the given segment pointer.
        !          108422:  */
        !          108423: sfree(sp)
        !          108424: register SEG *sp;
        !          108425: {
        !          108426:        register INODE *ip;
        !          108427: 
        !          108428:        if ( sp->s_urefc != 1 ) {
        !          108429:                sp->s_urefc--;
        !          108430:                sp->s_lrefc--;
        !          108431:                return;
        !          108432:        }
        !          108433: 
        !          108434:        lock(seglink);
        !          108435:        --sp->s_lrefc;
        !          108436:        if (--sp->s_urefc != 0) {
        !          108437:                unlock(seglink);
        !          108438:                return;
        !          108439:        }
        !          108440: 
        !          108441:        sp->s_back->s_forw = sp->s_forw;
        !          108442:        sp->s_forw->s_back = sp->s_back;
        !          108443:        unlock(seglink);
        !          108444: 
        !          108445:        if (sp->s_lrefc != 0)
        !          108446:                panic("Bad segment count");
        !          108447:        if ((ip=sp->s_ip) != NULL)
        !          108448:                ldetach(ip);
        !          108449:        vrelse( sp->s_faddr );
        !          108450:        kfree(sp);
        !          108451:        krunch(0);
        !          108452: }
        !          108453: 
        !          108454: /*
        !          108455:  * Grow or shrink the segment `sp' so that it has size `n'.
        !          108456:  */
        !          108457: seggrow(sp, n)
        !          108458: register SEG *sp;
        !          108459: fsize_t n;
        !          108460: {
        !          108461:        register SEG *sp1;
        !          108462:        register fsize_t  d;
        !          108463:        register paddr_t pb;
        !          108464:        register paddr_t nb;
        !          108465:        register int dowflag;
        !          108466: 
        !          108467:        dowflag = sp->s_flags&SFDOWN;
        !          108468: 
        !          108469:        /*
        !          108470:         * Size of new segment is smaller or the same size as the old
        !          108471:         * segment.
        !          108472:         */
        !          108473:        lock(seglink);
        !          108474:        d = n - sp->s_size;
        !          108475:        if (n <= sp->s_size) {
        !          108476:                sp->s_size = n;
        !          108477:                if (dowflag)
        !          108478:                        sp->s_paddr -= d;
        !          108479: 
        !          108480:                vremap( sp );
        !          108481:                unlock(seglink);
        !          108482:                return (1);
        !          108483:        }
        !          108484: 
        !          108485:        if ((sp1=sp->s_back) == &segmq)
        !          108486:                pb = corebot;
        !          108487:        else
        !          108488:                pb = sp1->s_paddr + sp1->s_size;
        !          108489: 
        !          108490:        if ((sp1=sp->s_forw) == &segmq)
        !          108491:                nb = coretop;
        !          108492:        else
        !          108493:                nb = sp1->s_paddr;
        !          108494: 
        !          108495:        /*
        !          108496:         * If the segment does not grow down, see if there is enough
        !          108497:         * space after the segment.
        !          108498:         */
        !          108499:        if (dowflag==0 && nb-sp->s_paddr>=n) {
        !          108500:                pclear(sp->s_paddr+sp->s_size, d);
        !          108501:                sp->s_size = n;
        !          108502:                vremap( sp );
        !          108503:                unlock(seglink);
        !          108504:                return (1);
        !          108505:        }
        !          108506: 
        !          108507:        /*
        !          108508:         * If the segment grows down, see if there is enough space
        !          108509:         * before the segment.
        !          108510:         */
        !          108511:        if (dowflag!=0 && sp->s_paddr+sp->s_size-pb>=n) {
        !          108512:                sp->s_paddr -= d;
        !          108513:                sp->s_size   = n;
        !          108514:                pclear( sp->s_paddr, d );
        !          108515:                vremap( sp );
        !          108516:                unlock(seglink);
        !          108517:                return (1);
        !          108518:        }
        !          108519: 
        !          108520:        /*
        !          108521:         * Is there enough space in total counting the gaps on either
        !          108522:         * side of us?
        !          108523:         */
        !          108524:        if (nb-pb >= n) {
        !          108525:                if (dowflag == 0) {
        !          108526:                        plrcopy(sp->s_paddr, pb, sp->s_size);
        !          108527:                        pclear(pb+sp->s_size, d);
        !          108528:                        sp->s_paddr = pb;
        !          108529:                } else {
        !          108530:                        prlcopy( sp->s_paddr, nb-sp->s_size, sp->s_size );
        !          108531:                        pclear(nb-n, d);
        !          108532:                        sp->s_paddr = nb-n;
        !          108533:                }
        !          108534:                sp->s_size  = n;
        !          108535:                vremap( sp );
        !          108536:                unlock(seglink);
        !          108537:                return (1);
        !          108538:        }
        !          108539: 
        !          108540:        /*
        !          108541:         * Try to allocate a segment somewhere else on the segment queue
        !          108542:         * and copy ourselves there.
        !          108543:         */
        !          108544:        unlock(seglink);
        !          108545:        if ((sp1=salloc((fsize_t)n, sp->s_flags|SFNSWP|SFNCLR)) != NULL) {
        !          108546:                if (dowflag == 0) {
        !          108547:                        plrcopy(sp->s_paddr, sp1->s_paddr, sp->s_size);
        !          108548:                        pclear(sp1->s_paddr+sp->s_size, d);
        !          108549:                } else {
        !          108550:                        plrcopy(sp->s_paddr, sp1->s_paddr+d, sp->s_size);
        !          108551:                        pclear(sp1->s_paddr, d);
        !          108552:                }
        !          108553:                lock(seglink);
        !          108554:                satcopy(sp, sp1);
        !          108555:                unlock(seglink);
        !          108556:                return (1);
        !          108557:        }
        !          108558: 
        !          108559:        /*
        !          108560:         * Last chance.  Extend the segment by swapping it.
        !          108561:         */
        !          108562:        if (segsext(sp, n) != NULL) {
        !          108563:                if (dowflag == 0)
        !          108564:                        pclear(sp->s_paddr+n-d, d);
        !          108565:                else {
        !          108566:                        prlcopy(sp->s_paddr, sp->s_paddr+d, n-d);
        !          108567:                        pclear(sp->s_paddr, d);
        !          108568:                }
        !          108569:                return (1);
        !          108570:        }
        !          108571: 
        !          108572:        /*
        !          108573:         * At least we tried.
        !          108574:         */
        !          108575:        return (0);
        !          108576: }
        !          108577: 
        !          108578: /*
        !          108579:  * Given a segment pointer, `sp' and a segment size, grow the given segment
        !          108580:  * to the given size.
        !          108581:  */
        !          108582: segsize(sp, s2)
        !          108583: register SEG *sp;
        !          108584: vaddr_t s2;
        !          108585: {
        !          108586:        register vaddr_t s1;
        !          108587: 
        !          108588:        s1 = (vaddr_t) sp->s_size;
        !          108589:        if (seggrow(sp, (fsize_t)s2) == 0) {
        !          108590:                u.u_error = ENOMEM;
        !          108591:                return;
        !          108592:        }
        !          108593:        if (sproto() == 0)
        !          108594:                if (seggrow(sp, (fsize_t)s1)==0 || sproto()==0)
        !          108595:                        sendsig(SIGSEGV, SELF);
        !          108596:        segload();
        !          108597: }
        !          108598: 
        !          108599: /*
        !          108600:  * Grow the segment `sp1' to the size `s' in bytes by swapping it out
        !          108601:  * and back in.  The segment may not be locked.
        !          108602:  */
        !          108603: SEG *
        !          108604: segsext(sp1, s)
        !          108605: register SEG *sp1;
        !          108606: register fsize_t s;
        !          108607: {
        !          108608:        register SEG *sp2;
        !          108609: 
        !          108610: #ifndef NOMONITOR
        !          108611:        if (swmflag)
        !          108612:                printf("Segsext(%p, %u)\n", SELF, SELF->p_pid);
        !          108613: #endif
        !          108614:        if (sexflag == 0) {
        !          108615:                u.u_error = ENOMEM;
        !          108616:                return (NULL);
        !          108617:        }
        !          108618:        lock(seglink);
        !          108619:        if ((sp2=sdalloc(s)) == NULL) {
        !          108620:                unlock(seglink);
        !          108621:                return (NULL);
        !          108622:        }
        !          108623:        unlock(seglink);
        !          108624:        sp1->s_lrefc++;
        !          108625:        if (sp1->s_size != 0)
        !          108626:                swapio(1, sp1->s_paddr, sp2->s_daddr, sp1->s_size);
        !          108627:        lock(seglink);
        !          108628:        satcopy(sp1, sp2);
        !          108629:        unlock(seglink);
        !          108630:        sp1->s_flags &= ~SFCORE;
        !          108631:        sp1->s_lrefc--;
        !          108632:        vremap(sp1);
        !          108633:        segfinm(sp1);
        !          108634:        return (sp1);
        !          108635: }
        !          108636: 
        !          108637: /*
        !          108638:  * Force the given segment to be in memory.  One can only force
        !          108639:  * one segment to be in memory at a time.
        !          108640:  */
        !          108641: segfinm(sp)
        !          108642: register SEG *sp;
        !          108643: {
        !          108644:        register PROC *pp;
        !          108645:        register int s;
        !          108646: 
        !          108647:        if ((sp->s_flags&SFCORE) != 0)
        !          108648:                return;
        !          108649:        pp = SELF;
        !          108650:        sp->s_urefc++;
        !          108651:        sp->s_lrefc++;
        !          108652:        pp->p_segp[SIAUXIL] = sp;
        !          108653:        pp->p_flags &= ~PFCORE;
        !          108654: #ifndef QWAKEUP
        !          108655:        s = sphi();
        !          108656: #endif
        !          108657:        setrun(pp);
        !          108658:        dispatch();
        !          108659: #ifndef QWAKEUP
        !          108660:        spl(s);
        !          108661: #endif
        !          108662:        pp->p_segp[SIAUXIL] = NULL;
        !          108663:        sfree(sp);
        !          108664: }
        !          108665: 
        !          108666: /*
        !          108667:  * Make a copy of the segment `sp1' which is in memory by writing
        !          108668:  * it out to disk.
        !          108669:  */
        !          108670: SEG *
        !          108671: segdupd(sp1)
        !          108672: register SEG *sp1;
        !          108673: {
        !          108674:        register SEG *sp2;
        !          108675: 
        !          108676:        if (sexflag == 0)
        !          108677:                return (NULL);
        !          108678:        lock(seglink);
        !          108679:        if ((sp2=sdalloc(sp1->s_size)) == NULL) {
        !          108680:                unlock(seglink);
        !          108681:                return (NULL);
        !          108682:        }
        !          108683:        sp1->s_lrefc++;
        !          108684:        unlock(seglink);
        !          108685:        swapio(1, sp1->s_paddr, sp2->s_daddr, sp1->s_size);
        !          108686:        sp1->s_lrefc--;
        !          108687:        sp2->s_flags = sp1->s_flags & ~SFCORE;
        !          108688:        sp2->s_size  = sp1->s_size;
        !          108689:        vremap( sp2 );
        !          108690:        return (sp2);
        !          108691: }
        !          108692: 
        !          108693: /*
        !          108694:  * Given a flag, a physical core address, a disk address and a count in
        !          108695:  * bytes, perform an I/O operation between core and disk.  If `flag' is
        !          108696:  * set, the transfer is to the disk otherwise it is to memory.  As you may
        !          108697:  * have guessed, this is used by the swapper.
        !          108698:  */
        !          108699: swapio(f, p, d, n)
        !          108700: paddr_t p;
        !          108701: daddr_t d;
        !          108702: fsize_t  n;
        !          108703: {
        !          108704:        register BUF * bp;
        !          108705:        register SEG * sp;
        !          108706:        register int s;
        !          108707:        register int nb;
        !          108708:        static SEG swapseg;     /* NOTE: FP_SEL(swapseg.s_faddr) must stay */
        !          108709: 
        !          108710: #ifndef NOMONITOR
        !          108711:        if (swmflag > 1)
        !          108712:                printf("swapio(%s,%x,%x,%x)\n",f?"out":"in",(int)p,(int)d,n);
        !          108713: #endif
        !          108714:        if (d < swapbot || d+(n/BSIZE) > swaptop
        !          108715:         || p < corebot || p+n > coretop)
        !          108716:                panic("Swapio bad parameter");
        !          108717: 
        !          108718:        bp = &swapbuf;
        !          108719:        sp = &swapseg;
        !          108720:        lock(bp->b_gate);
        !          108721:        SELF->p_flags |= PFSWIO;
        !          108722:        sp->s_flags = SFCORE;
        !          108723:        sp->s_paddr = p;
        !          108724:        sp->s_size  = n;
        !          108725:        vremap( sp );
        !          108726:        bp->b_faddr = sp->s_faddr;
        !          108727: 
        !          108728:        while (n != 0) {
        !          108729:                nb = (n > SCHUNK) ? SCHUNK : n;
        !          108730:                /*
        !          108731:                 * Prevent I/O transfer from crossing 64 Kbyte boundary.
        !          108732:                 */
        !          108733:                if ( (p & 0xFFFF0000L) != ((p+nb) & 0xFFFF0000L) )
        !          108734:                        nb = 0x10000L - (p & 0x0000FFFFL);
        !          108735:                bp->b_flag  = BFNTP;
        !          108736:                bp->b_req   = f ? BWRITE : BREAD;
        !          108737:                bp->b_dev   = swapdev;
        !          108738:                bp->b_bno   = d;
        !          108739:                bp->b_paddr = p;
        !          108740:                bp->b_count = nb;
        !          108741:                s = sphi();
        !          108742:                dblock(swapdev, bp);
        !          108743:                while ((bp->b_flag&BFNTP) != 0)
        !          108744:                        sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          108745:                spl(s);
        !          108746:                if ((bp->b_flag&BFERR) != 0)
        !          108747:                        panic("Swapio error");
        !          108748:                FP_OFF(bp->b_faddr) += nb;
        !          108749:                p += nb;
        !          108750:                d += nb / BSIZE;
        !          108751:                n -= nb;
        !          108752:        }
        !          108753:        sp->s_flags = 0;
        !          108754:        vremap( sp );
        !          108755:        unlock(bp->b_gate);
        !          108756:        SELF->p_flags &= ~PFSWIO;
        !          108757: }
        !          108758: 
        !          108759: /*
        !          108760:  * Make the segment descriptor pointed to by `sp1' have the attributes
        !          108761:  * of `sp2' including it's position in the segment queue and release
        !          108762:  * `sp2'.  `seglink' must be locked when this routine is called.
        !          108763:  */
        !          108764: satcopy(sp1, sp2)
        !          108765: register SEG *sp1;
        !          108766: register SEG *sp2;
        !          108767: {
        !          108768:        if ( FP_SEL(sp2->s_faddr) != 0 )
        !          108769:                vrelse( sp2->s_faddr );
        !          108770: 
        !          108771:        sp1->s_back->s_forw = sp1->s_forw;
        !          108772:        sp1->s_forw->s_back = sp1->s_back;
        !          108773:        sp2->s_back->s_forw = sp1;
        !          108774:        sp1->s_back = sp2->s_back;
        !          108775:        sp2->s_forw->s_back = sp1;
        !          108776:        sp1->s_forw  = sp2->s_forw;
        !          108777:        sp1->s_size  = sp2->s_size;
        !          108778:        sp1->s_paddr = sp2->s_paddr;
        !          108779:        sp1->s_daddr = sp2->s_daddr;
        !          108780:        vremap(sp1);
        !          108781:        kfree(sp2);
        !          108782: }
        !          108783: 
        !          108784: /*
        !          108785:  * Allocate a segment on disk that is `n' bytes long.
        !          108786:  * The `seglink' gate should be locked before this routine is called.
        !          108787:  */
        !          108788: SEG *
        !          108789: sdalloc( s )
        !          108790: fsize_t s;
        !          108791: {
        !          108792:        register SEG *sp1;
        !          108793:        register SEG *sp2;
        !          108794:        register daddr_t d;
        !          108795:        register daddr_t d1;
        !          108796:        register daddr_t d2;
        !          108797: 
        !          108798:        d  = s / BSIZE;
        !          108799:        d1 = swapbot;
        !          108800:        sp1 = &segdq;
        !          108801:        do {
        !          108802:                if (d1 >= swaptop)
        !          108803:                        return (NULL);
        !          108804:                if ((sp1=sp1->s_forw) != &segdq)
        !          108805:                        d2 = sp1->s_daddr;
        !          108806:                else
        !          108807:                        d2 = swaptop;
        !          108808:                if (d2-d1 >= d) {
        !          108809:                        if ((sp2=kalloc(sizeof(SEG))) == NULL)
        !          108810:                                return (NULL);
        !          108811:                        sp1->s_back->s_forw = sp2;
        !          108812:                        sp2->s_back = sp1->s_back;
        !          108813:                        sp1->s_back = sp2;
        !          108814:                        sp2->s_forw = sp1;
        !          108815:                        sp2->s_urefc = 1;
        !          108816:                        sp2->s_lrefc = 1;
        !          108817:                        sp2->s_size  = s;
        !          108818:                        sp2->s_daddr = d1;
        !          108819:                        return (sp2);
        !          108820:                }
        !          108821:                d1 = sp1->s_daddr + (sp1->s_size / BSIZE);
        !          108822:        } while (sp1 != &segdq);
        !          108823:        return (NULL);
        !          108824: }
        !          108825: 
        !          108826: /*
        !          108827:  * Allocate a segment in memory that is `n' bytes long.
        !          108828:  * The `seglink' gate should be locked before this routine is called.
        !          108829:  */
        !          108830: SEG *
        !          108831: smalloc(s)
        !          108832: fsize_t s;
        !          108833: {
        !          108834:        register SEG *sp1;
        !          108835:        register SEG *sp2;
        !          108836:        paddr_t p1;
        !          108837:        paddr_t p2;
        !          108838: 
        !          108839:        p1  = corebot;
        !          108840:        sp1 = &segmq;
        !          108841:        do {
        !          108842:                if ((sp1=sp1->s_forw) != &segmq)
        !          108843:                        p2 = sp1->s_paddr;
        !          108844:                else
        !          108845:                        p2 = coretop;
        !          108846: 
        !          108847:                if (p2-p1 >= s) {
        !          108848:                        if ((sp2=kalloc(sizeof (SEG))) == NULL)
        !          108849:                                return (NULL);
        !          108850:                        sp1->s_back->s_forw = sp2;
        !          108851:                        sp2->s_back = sp1->s_back;
        !          108852:                        sp1->s_back = sp2;
        !          108853:                        sp2->s_forw = sp1;
        !          108854:                        sp2->s_urefc = 1;
        !          108855:                        sp2->s_lrefc = 1;
        !          108856:                        sp2->s_size  = s;
        !          108857:                        sp2->s_paddr = p1;
        !          108858:                        /*   s_faddr = 0; */
        !          108859:                        /*   s_flags = 0; */
        !          108860:                        vremap( sp2 );
        !          108861:                        return (sp2);
        !          108862:                }
        !          108863:                p1 = sp1->s_paddr + sp1->s_size;
        !          108864:        } while (sp1 != &segmq);
        !          108865:        return (NULL);
        !          108866: }
        !          108867: 
        !          108868: /*
        !          108869:  * Allocate a segment from the high end of memory that is `n' bytes long.
        !          108870:  * The `seglink' gate should be locked before this routine is called.
        !          108871:  */
        !          108872: SEG *
        !          108873: shalloc( s )
        !          108874: fsize_t s;
        !          108875: {
        !          108876:        register SEG *sp1;
        !          108877:        register SEG *sp2;
        !          108878:        paddr_t p1;
        !          108879:        paddr_t p2;
        !          108880: 
        !          108881:        sp1 = &segmq;
        !          108882:        p2  = coretop;
        !          108883:        do {
        !          108884:                if ((sp1=sp1->s_back) != &segmq)
        !          108885:                        p1 = sp1->s_paddr + sp1->s_size;
        !          108886:                else
        !          108887:                        p1 = corebot;
        !          108888: 
        !          108889:                if (p2-p1 >= s) {
        !          108890:                        if ((sp2=kalloc(sizeof (SEG))) == NULL)
        !          108891:                                return (NULL);
        !          108892:                        sp1->s_forw->s_back = sp2;
        !          108893:                        sp2->s_forw = sp1->s_forw;
        !          108894:                        sp1->s_forw = sp2;
        !          108895:                        sp2->s_back = sp1;
        !          108896:                        sp2->s_urefc = 1;
        !          108897:                        sp2->s_lrefc = 1;
        !          108898:                        sp2->s_size  = s;
        !          108899:                        sp2->s_paddr = p2-s;
        !          108900:                        /*   s_faddr = 0; */
        !          108901:                        /*   s_flags = 0; */
        !          108902:                        vremap( sp2 );
        !          108903:                        return (sp2);
        !          108904:                }
        !          108905:                p2 = sp1->s_paddr;
        !          108906:        } while (sp1 != &segmq);
        !          108907:        return (NULL);
        !          108908: }
        !          108909: 
        !          108910: /*
        !          108911:  * Set up `SR' structure in user area from segments descriptors in
        !          108912:  * process structure.  Also set up the user segmentation registers.
        !          108913:  */
        !          108914: sproto()
        !          108915: {
        !          108916:        register int n;
        !          108917:        register SEG *sp;
        !          108918: 
        !          108919:        kclear(u.u_segl, sizeof(u.u_segl));
        !          108920:        for (n=0; n<NUSEG; n++) {
        !          108921:                if ((sp=SELF->p_segp[n]) == NULL)
        !          108922:                        continue;
        !          108923:                if (n == SIUSERP)
        !          108924:                        u.u_segl[n].sr_base = &u;
        !          108925:                else
        !          108926:                        u.u_segl[n].sr_flag |= SRFPMAP;
        !          108927:                if (n!=SISTEXT && n!=SISDATA)
        !          108928:                        u.u_segl[n].sr_flag |= SRFDUMP;
        !          108929:                if (n!=SIUSERP && n!=SISTEXT && n!=SIPTEXT)
        !          108930:                        u.u_segl[n].sr_flag |= SRFDATA;
        !          108931:                u.u_segl[n].sr_size = sp->s_size;
        !          108932:                u.u_segl[n].sr_segp = sp;
        !          108933:        }
        !          108934:        return (mproto());
        !          108935: }
        !          108936: 
        !          108937: /*
        !          108938:  * Search for a busy text inode.
        !          108939:  */
        !          108940: sbusy(ip)
        !          108941: register INODE *ip;
        !          108942: {
        !          108943:        register SEG *sp;
        !          108944: 
        !          108945:        lock(seglink);
        !          108946:        /*
        !          108947:         * Look for the segment in the memory queue.
        !          108948:         */
        !          108949:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
        !          108950:                if (sp->s_ip==ip
        !          108951:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
        !          108952:                        unlock(seglink);
        !          108953:                        return (1);
        !          108954:                }
        !          108955:        }
        !          108956: 
        !          108957:        /*
        !          108958:         * Look for the segment on the disk queue.
        !          108959:         */
        !          108960:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
        !          108961:                if (sp->s_ip==ip
        !          108962:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
        !          108963:                        unlock(seglink);
        !          108964:                        return (1);
        !          108965:                }
        !          108966:        }
        !          108967:        unlock(seglink);
        !          108968:        return (0);
        !          108969: }
        !          108970: 
        !          108971: /*
        !          108972:  * Segment consistency checks for the paranoid.
        !          108973: segchk()
        !          108974: {
        !          108975:        register SEG *sp;
        !          108976:        register int nbad;
        !          108977:        fsize_t s;
        !          108978:        daddr_t d;
        !          108979: 
        !          108980:        nbad = 0;
        !          108981:        sp = &segmq;
        !          108982:        s = corebot;
        !          108983:        while ((sp=sp->s_forw) != &segmq) {
        !          108984:                if (sp->s_paddr < s)
        !          108985:                        nbad += badseg("mem", sp->s_paddr, 0);
        !          108986:                s = sp->s_paddr + sp->s_size;
        !          108987:        }
        !          108988:        if (coretop < s)
        !          108989:                nbad += badseg("mem", sp->s_back->s_paddr, sp->s_back->s_size);
        !          108990:        sp = &segdq;
        !          108991:        d = swapbot;
        !          108992:        while ((sp=sp->s_forw) != &segdq) {
        !          108993:                if (sp->s_daddr < d)
        !          108994:                        nbad += badseg("disk", (int)sp->s_daddr, 0);
        !          108995:                d = sp->s_daddr + (sp->s_size / BSIZE);
        !          108996:        }
        !          108997:        if (swaptop < d)
        !          108998:                nbad += badseg("disk", sp->s_back->s_daddr, sp->s_back->s_size);
        !          108999: }
        !          109000: 
        !          109001: badseg(t, b, s)
        !          109002: char *t;
        !          109003: daddr_t b;
        !          109004: fsize_t s;
        !          109005: {
        !          109006:        printf( "Bad %s segment at %X of len %X\n", t, b, s );
        !          109007:        return (1);
        !          109008: }
        !          109009: */
        !          109010: 0707070064030103221006440000030000030000011777770507310731000004100000014435/newbits/kernel/USRSRC/coh/sig.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/sig.c,v 1.4 91/07/24 07:52:13 bin Exp Locker: bin $ */
        !          109011: /* (lgl-
        !          109012:  *     The information contained herein is a trade secret of Mark Williams
        !          109013:  *     Company, and  is confidential information.  It is provided  under a
        !          109014:  *     license agreement,  and may be  copied or disclosed  only under the
        !          109015:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          109016:  *     material without the express written authorization of Mark Williams
        !          109017:  *     Company or persuant to the license agreement is unlawful.
        !          109018:  *
        !          109019:  *     COHERENT Version 2.3.37
        !          109020:  *     Copyright (c) 1982, 1983, 1984.
        !          109021:  *     An unpublished work by Mark Williams Company, Chicago.
        !          109022:  *     All rights reserved.
        !          109023:  -lgl) */
        !          109024: /*
        !          109025:  * Coherent.
        !          109026:  * Signal handling.
        !          109027:  *
        !          109028:  * $Log:       sig.c,v $
        !          109029:  * Revision 1.4  91/07/24  07:52:13  bin
        !          109030:  * update prov by hal
        !          109031:  * 
        !          109032:  * 
        !          109033:  * Revision 1.1        88/03/24  16:14:24      src
        !          109034:  * Initial revision
        !          109035:  * 
        !          109036:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/sig.c
        !          109037:  * New seg struct now used to allow extended addressing.
        !          109038:  *
        !          109039:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/sig.c
        !          109040:  * sigdump() initializes the (new) (IO).io_flag field to 0.
        !          109041:  */
        !          109042: #include <sys/coherent.h>
        !          109043: #include <errno.h>
        !          109044: #include <sys/ino.h>
        !          109045: #include <sys/inode.h>
        !          109046: #include <sys/io.h>
        !          109047: #include <sys/proc.h>
        !          109048: #include <sys/ptrace.h>
        !          109049: #include <sys/sched.h>
        !          109050: #include <sys/seg.h>
        !          109051: #include <signal.h>
        !          109052: #include <sys/uproc.h>
        !          109053: 
        !          109054: /*
        !          109055:  * Send a signal to the process `pp'.
        !          109056:  */
        !          109057: sendsig(sig, pp)
        !          109058: register unsigned sig;
        !          109059: register PROC *pp;
        !          109060: {
        !          109061:        register sig_t f;
        !          109062:        register int s;
        !          109063: 
        !          109064:        f = ((sig_t)1) << (sig-1);
        !          109065:        if ((pp->p_isig&f) != 0)
        !          109066:                return;
        !          109067:        pp->p_ssig |= f;
        !          109068:        if (pp->p_state == PSSLEEP) {
        !          109069:                s = sphi();
        !          109070:                pp->p_lback->p_lforw = pp->p_lforw;
        !          109071:                pp->p_lforw->p_lback = pp->p_lback;
        !          109072:                addu(pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK);
        !          109073:                setrun(pp);
        !          109074:                spl(s);
        !          109075:        }
        !          109076: }
        !          109077: 
        !          109078: /*
        !          109079:  * Return signal number if we have a non ignored signal, else zero.
        !          109080:  */
        !          109081: nondsig()
        !          109082: {
        !          109083:        register PROC *pp;
        !          109084:        register sig_t mask;
        !          109085:        register int signo;
        !          109086: 
        !          109087:        pp = SELF;
        !          109088:        signo = 0;
        !          109089:        pp->p_ssig &= ~pp->p_isig;
        !          109090:        if (pp->p_ssig != 0) {
        !          109091:                mask = (sig_t) 1;
        !          109092:                signo += 1;
        !          109093:                while ((pp->p_ssig&mask) == 0) {
        !          109094:                        mask <<= 1;
        !          109095:                        signo += 1;
        !          109096:                }
        !          109097:        }
        !          109098:        return (signo);
        !          109099: }
        !          109100: 
        !          109101: /*
        !          109102:  * If we have a signal that isn't ignored, activate it.
        !          109103:  */
        !          109104: actvsig()
        !          109105: {
        !          109106:        register int n;
        !          109107:        register PROC *pp;
        !          109108:        register int (*f)();
        !          109109: 
        !          109110: #if EBUG_VM > 0
        !          109111:        printf("actvsig ");     /** DEBUG **/
        !          109112: #endif
        !          109113: 
        !          109114:        if ((n = nondsig()) == 0)
        !          109115:                return;
        !          109116:        pp = SELF;
        !          109117:        --n;
        !          109118:        pp->p_ssig &= ~((sig_t)1<<n);
        !          109119:        f = u.u_sfunc[n];
        !          109120:        u.u_signo = ++n;
        !          109121:        if (f != SIG_DFL) {
        !          109122:                msigint(n, f);
        !          109123:                return;
        !          109124:        }
        !          109125:        msysgen(&u.u_sysgen);
        !          109126:        if ((pp->p_flags&PFTRAC) != 0) {
        !          109127:                pp->p_flags |= PFWAIT;
        !          109128:                n = ptret();
        !          109129:                pp->p_flags &= ~(PFWAIT|PFSTOP);
        !          109130:                if (n == 0)
        !          109131:                        return;
        !          109132:        }
        !          109133:        if (n>SIGKILL || n==SIGQUIT || n==SIGSYS) {
        !          109134:                if (sigdump())
        !          109135:                        n |= 0200;
        !          109136:        }
        !          109137:        pexit(n);
        !          109138: }
        !          109139: 
        !          109140: /*
        !          109141:  * Create a dump of ourselves onto the file `core'.
        !          109142:  */
        !          109143: sigdump()
        !          109144: {
        !          109145:        register INODE *ip;
        !          109146:        register SR *srp;
        !          109147:        register SEG * sp;
        !          109148:        register int n;
        !          109149:        register paddr_t ssize;
        !          109150: 
        !          109151:        if ((SELF->p_flags&PFNDMP) != 0)
        !          109152:                return (0);
        !          109153:        u.u_io.io_seg  = IOSYS;
        !          109154:        u.u_io.io_flag = 0;
        !          109155:        /* Make the core with the real owners */
        !          109156:        schizo();
        !          109157:        if (ftoi("core", 'c') != 0) {
        !          109158:                schizo();
        !          109159:                return (0);
        !          109160:        }
        !          109161:        if ((ip=u.u_cdiri) == NULL) {
        !          109162:                if ((ip=imake(IFREG|0644, 0)) == NULL) {
        !          109163:                        schizo();
        !          109164:                        return (0);
        !          109165:                }
        !          109166:        } else {
        !          109167:                if ((ip->i_mode&IFMT)!=IFREG
        !          109168:                 || iaccess(ip, IPW)==0
        !          109169:                 || getment(ip->i_dev, 1)==NULL) {
        !          109170:                        idetach(ip);
        !          109171:                        schizo();
        !          109172:                        return (0);
        !          109173:                }
        !          109174:                iclear(ip);
        !          109175:        }
        !          109176:        schizo();
        !          109177:        u.u_error = 0;
        !          109178:        u.u_io.io_seek = 0;
        !          109179:        for (srp=u.u_segl; u.u_error==0 && srp<&u.u_segl[NUSEG]; srp++) {
        !          109180:                if ((sp = srp->sr_segp)==NULL || (srp->sr_flag&SRFDUMP)==0)
        !          109181:                        continue;
        !          109182:                u.u_io.io_seg = IOPHY;
        !          109183:                u.u_io.io_phys = sp->s_paddr;
        !          109184:                u.u_io.io_flag = 0;
        !          109185:                ssize = sp->s_size;
        !          109186:                sp->s_lrefc++;
        !          109187:                while (u.u_error == 0 && ssize != 0) {
        !          109188:                        n = ssize > SCHUNK ? SCHUNK : ssize;
        !          109189:                        u.u_io.io_ioc = n;
        !          109190:                        iwrite(ip, &u.u_io);
        !          109191:                        u.u_io.io_phys += (paddr_t)n;
        !          109192:                        ssize -= (paddr_t)n;
        !          109193:                }
        !          109194:                sp->s_lrefc--;
        !          109195:        }
        !          109196:        idetach(ip);
        !          109197:        return (u.u_error==0);
        !          109198: }
        !          109199: 
        !          109200: /*
        !          109201:  * Send a ptrace command to the child.
        !          109202:  */
        !          109203: ptset(req, pid, addr, data)
        !          109204: unsigned req;
        !          109205: int *addr;
        !          109206: {
        !          109207: #ifdef TINY
        !          109208:        sendsig(SELF, SIGSYS);
        !          109209:        return (0);
        !          109210: #else
        !          109211:        register PROC *pp;
        !          109212: 
        !          109213:        lock(pnxgate);
        !          109214:        for (pp=procq.p_nforw; pp!=&procq; pp=pp->p_nforw)
        !          109215:                if (pp->p_pid == pid)
        !          109216:                        break;
        !          109217:        unlock(pnxgate);
        !          109218:        if (pp==&procq || (pp->p_flags&PFSTOP)==0 || pp->p_ppid!=SELF->p_pid) {
        !          109219:                u.u_error = ESRCH;
        !          109220:                return;
        !          109221:        }
        !          109222:        lock(pts.pt_gate);
        !          109223:        pts.pt_req = req;
        !          109224:        pts.pt_pid = pid;
        !          109225:        pts.pt_addr = addr;
        !          109226:        pts.pt_data = data;
        !          109227:        pts.pt_errs = 0;
        !          109228:        pts.pt_rval = 0;
        !          109229:        pts.pt_busy = 1;
        !          109230:        wakeup((char *)&pts.pt_req);
        !          109231:        while (pts.pt_busy != 0)
        !          109232:                sleep((char *)&pts.pt_busy, CVPTSET, IVPTSET, SVPTSET);
        !          109233:        u.u_error = pts.pt_errs;
        !          109234:        unlock(pts.pt_gate);
        !          109235:        return (pts.pt_rval);
        !          109236: #endif
        !          109237: }
        !          109238: 
        !          109239: /*
        !          109240:  * This routine is called when a child that is being traced receives a signal
        !          109241:  * that is not caught or ignored.  It follows up on any requests by the parent
        !          109242:  * and returns when done.
        !          109243:  */
        !          109244: ptret()
        !          109245: {
        !          109246: #ifdef TINY
        !          109247:        return (SIGKILL);
        !          109248: #else
        !          109249:        register PROC *pp;
        !          109250:        register PROC *pp1;
        !          109251:        register int sign;
        !          109252: 
        !          109253:        pp = SELF;
        !          109254: next:
        !          109255:        u.u_error = 0;
        !          109256:        if (pp->p_ppid == 1)
        !          109257:                return (SIGKILL);
        !          109258:        sign = -1;
        !          109259:        lock(pnxgate);
        !          109260:        pp1 = &procq;
        !          109261:        for (;;) {
        !          109262:                if ((pp1=pp1->p_nforw) == &procq) {
        !          109263:                        sign = SIGKILL;
        !          109264:                        break;
        !          109265:                }
        !          109266:                if (pp1->p_pid != pp->p_ppid)
        !          109267:                        continue;
        !          109268:                if (pp1->p_state == PSSLEEP)
        !          109269:                        wakeup((char *)pp1);
        !          109270:                break;
        !          109271:        }
        !          109272:        unlock(pnxgate);
        !          109273:        while (sign < 0) {
        !          109274:                if (pts.pt_busy==0 || pp->p_pid!=pts.pt_pid) {
        !          109275:                        sleep((char *)&pts.pt_req, CVPTRET, IVPTRET, SVPTRET);
        !          109276:                        goto next;
        !          109277:                }
        !          109278:                switch (pts.pt_req) {
        !          109279:                case 1:
        !          109280:                        pts.pt_rval = getuwi(pts.pt_addr);
        !          109281:                        break;
        !          109282:                case 2:
        !          109283:                        pts.pt_rval = getuwd(pts.pt_addr);
        !          109284:                        break;
        !          109285:                case 3:
        !          109286:                        if ((unsigned)pts.pt_addr < UPASIZE)
        !          109287:                                pts.pt_rval = *(int *)((char *)&u+pts.pt_addr);
        !          109288:                        else
        !          109289:                                u.u_error = EINVAL;
        !          109290:                        break;
        !          109291:                case 4:
        !          109292:                        putuwi(pts.pt_addr, pts.pt_data);
        !          109293:                        break;
        !          109294:                case 5:
        !          109295:                        putuwd(pts.pt_addr, pts.pt_data);
        !          109296:                        break;
        !          109297:                case 6:
        !          109298:                        if (msetuof(pts.pt_addr, pts.pt_data) == 0)
        !          109299:                                u.u_error = EINVAL;
        !          109300:                        break;
        !          109301:                case 7:
        !          109302:                        goto sig;
        !          109303:                case 8:
        !          109304:                        sign = SIGKILL;
        !          109305:                        break;
        !          109306:                case 9:
        !          109307:                        msigsin();
        !          109308:                sig:
        !          109309:                        if (pts.pt_data<0 || pts.pt_data>NSIG) {
        !          109310:                                u.u_error = EINVAL;
        !          109311:                                break;
        !          109312:                        }
        !          109313:                        sign = pts.pt_data;
        !          109314:                        if (pts.pt_addr != SIG_IGN)
        !          109315:                                msetppc((vaddr_t)pts.pt_addr);
        !          109316:                        break;
        !          109317:                default:
        !          109318:                        u.u_error = EINVAL;
        !          109319:                }
        !          109320:                if ((pts.pt_errs=u.u_error) == EFAULT)
        !          109321:                        pts.pt_errs = EINVAL;
        !          109322:                pts.pt_busy = 0;
        !          109323:                wakeup((char *)&pts.pt_busy);
        !          109324:        }
        !          109325:        return (sign);
        !          109326: #endif
        !          109327: }
        !          109328: 0707070064030103211006440000030000030000011777770507310731100004200000024362/newbits/kernel/USRSRC/coh/sys1.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/sys1.c,v 1.4 91/07/24 07:52:21 bin Exp Locker: bin $ */
        !          109329: /* (lgl-
        !          109330:  *     The information contained herein is a trade secret of Mark Williams
        !          109331:  *     Company, and  is confidential information.  It is provided  under a
        !          109332:  *     license agreement,  and may be  copied or disclosed  only under the
        !          109333:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          109334:  *     material without the express written authorization of Mark Williams
        !          109335:  *     Company or persuant to the license agreement is unlawful.
        !          109336:  *
        !          109337:  *     COHERENT Version 2.3.37
        !          109338:  *     Copyright (c) 1982, 1983, 1984.
        !          109339:  *     An unpublished work by Mark Williams Company, Chicago.
        !          109340:  *     All rights reserved.
        !          109341:  -lgl) */
        !          109342: /*
        !          109343:  * Coherent.
        !          109344:  * General system calls.
        !          109345:  *
        !          109346:  * $Log:       sys1.c,v $
        !          109347:  * Revision 1.4  91/07/24  07:52:21  bin
        !          109348:  * update prov by hal
        !          109349:  * 
        !          109350:  * 
        !          109351:  * Revision 1.1        88/03/24  16:14:27      src
        !          109352:  * Initial revision
        !          109353:  * 
        !          109354:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          109355:  * New seg struct now used to allow extended addressing.
        !          109356:  *
        !          109357:  * 87/10/21    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          109358:  * ukill() no longer signals kernel processes if pid is -1.
        !          109359:  * usload() changed to new loadable driver format.
        !          109360:  *
        !          109361:  * 87/08/14    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          109362:  * utick() system call added. Returns elapsed clock ticks since system startup.
        !          109363:  *
        !          109364:  * 87/07/23    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          109365:  * ualarm2() now takes the delay interval as a long instead of an unsigned.
        !          109366:  *
        !          109367:  * 87/07/08    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          109368:  * ualarm() modified to use timed functions to send alarm signal.
        !          109369:  * ualarm2() added to allow alarm times in clock ticks rather than seconds.
        !          109370:  *
        !          109371:  * 85/07/25    Allan Cornish
        !          109372:  * ukill() modified to allow a signal of 0 to check process existence.
        !          109373:  *
        !          109374:  * 85/07/9     Allan Cornish
        !          109375:  * ukill() modified to allow signals to be sent to other process groups.
        !          109376:  * usetpgrp() modified to be System V compatible (group set to pid).
        !          109377:  * ugetpgrp() system call added.
        !          109378:  */
        !          109379: #include <sys/coherent.h>
        !          109380: #include <acct.h>
        !          109381: #include <sys/con.h>
        !          109382: #include <errno.h>
        !          109383: #include <sys/proc.h>
        !          109384: #include <sys/sched.h>
        !          109385: #include <sys/seg.h>
        !          109386: #include <signal.h>
        !          109387: #include <sys/timeb.h>
        !          109388: #include <sys/times.h>
        !          109389: #include <sys/uproc.h>
        !          109390: 
        !          109391: /*
        !          109392:  * Send alarm signal to specified process - function timed by ualarm()
        !          109393:  */
        !          109394: static
        !          109395: sigalrm( pp )
        !          109396: register PROC * pp;
        !          109397: {
        !          109398:        sendsig( SIGALRM, pp );
        !          109399: }
        !          109400: 
        !          109401: /*
        !          109402:  * Send a SIGALARM signal in `n' seconds.
        !          109403:  */
        !          109404: ualarm(n)
        !          109405: unsigned n;
        !          109406: {
        !          109407:        register PROC * pp = SELF;
        !          109408:        register unsigned s;
        !          109409: 
        !          109410:        /*
        !          109411:         * Calculate time left before current alarm timeout.
        !          109412:         */
        !          109413:        s = 0;
        !          109414:        if ( pp->p_alrmtim.t_last != NULL )
        !          109415:                s = (pp->p_alrmtim.t_lbolt - lbolt + HZ - 1) / HZ;
        !          109416: 
        !          109417:        /*
        !          109418:         * Cancel previous alarm [if any], start new alarm [if n != 0].
        !          109419:         */
        !          109420:        timeout2( &pp->p_alrmtim, (long) n * HZ, sigalrm, pp );
        !          109421: 
        !          109422:        /*
        !          109423:         * Return time left before previous alarm timeout.
        !          109424:         */
        !          109425:        return( s );
        !          109426: }
        !          109427: 
        !          109428: /*
        !          109429:  * Send a SIGALARM signal in `n' clock ticks.
        !          109430:  */
        !          109431: long
        !          109432: ualarm2(n)
        !          109433: long n;
        !          109434: {
        !          109435:        register PROC * pp = SELF;
        !          109436:        long s;
        !          109437: 
        !          109438:        /*
        !          109439:         * Calculate time left before current alarm timeout.
        !          109440:         */
        !          109441:        s = 0;
        !          109442:        if ( pp->p_alrmtim.t_last != NULL )
        !          109443:                s = pp->p_alrmtim.t_lbolt - lbolt;
        !          109444: 
        !          109445:        /*
        !          109446:         * Cancel previous alarm [if any], start new alarm [if n != 0].
        !          109447:         */
        !          109448:        timeout2( &pp->p_alrmtim, (long) n, sigalrm, pp );
        !          109449: 
        !          109450:        /*
        !          109451:         * Return time left before previous alarm timeout.
        !          109452:         */
        !          109453:        return( s );
        !          109454: }
        !          109455: 
        !          109456: /*
        !          109457:  * Change the size of our data segment.
        !          109458:  */
        !          109459: char *
        !          109460: ubrk(cp)
        !          109461: char *cp;
        !          109462: {
        !          109463:        register SEG *sp;
        !          109464:        register vaddr_t sb;
        !          109465: 
        !          109466:        sp = SELF->p_segp[SIPDATA];
        !          109467:        sb = u.u_segl[SIPDATA].sr_base;
        !          109468:        if (cp != NULL)
        !          109469:                segsize(sp, (vaddr_t)cp-sb);
        !          109470: #ifdef OLD
        !          109471:        return (0);
        !          109472: #else
        !          109473:        sb += sp->s_size;
        !          109474:        return ((char *)sb);
        !          109475: #endif
        !          109476: }
        !          109477: 
        !          109478: /*
        !          109479:  * Execute a l.out.
        !          109480:  */
        !          109481: uexece(np, argp, envp)
        !          109482: char *np;
        !          109483: char *argp[];
        !          109484: char *envp[];
        !          109485: {
        !          109486:        pexece(np, argp, envp);
        !          109487: }
        !          109488: 
        !          109489: /*
        !          109490:  * Exit.
        !          109491:  */
        !          109492: uexit(s)
        !          109493: {
        !          109494:        pexit(s<<8);
        !          109495: }
        !          109496: 
        !          109497: /*
        !          109498:  * Fork.
        !          109499:  */
        !          109500: ufork()
        !          109501: {
        !          109502:        return (pfork());
        !          109503: }
        !          109504: 
        !          109505: /*
        !          109506:  * Return date and time.
        !          109507:  */
        !          109508: uftime(tbp)
        !          109509: struct timeb *tbp;
        !          109510: {
        !          109511:        register int s;
        !          109512:        struct timeb timeb;
        !          109513: 
        !          109514:        timeb.time = timer.t_time;
        !          109515:        /* This should be a machine.h macro to avoid
        !          109516:         * unnecessary long arithmetic and roundoff errors
        !          109517:         */
        !          109518:        timeb.millitm = timer.t_tick*(1000/HZ);
        !          109519:        timeb.timezone = timer.t_zone;
        !          109520:        timeb.dstflag = timer.t_dstf;
        !          109521:        s = sphi();
        !          109522:        kucopy(&timeb, tbp, sizeof(timeb));
        !          109523:        spl(s);
        !          109524: }
        !          109525: 
        !          109526: /*
        !          109527:  * Get effective group id.
        !          109528:  */
        !          109529: ugetegid()
        !          109530: {
        !          109531:        return (u.u_gid);
        !          109532: }
        !          109533: 
        !          109534: /*
        !          109535:  * Get effective user id.
        !          109536:  */
        !          109537: ugeteuid()
        !          109538: {
        !          109539:        return (u.u_uid);
        !          109540: }
        !          109541: 
        !          109542: /*
        !          109543:  * Get group id.
        !          109544:  */
        !          109545: ugetgid()
        !          109546: {
        !          109547:        return (u.u_rgid);
        !          109548: }
        !          109549: 
        !          109550: /*
        !          109551:  * Get process id.
        !          109552:  */
        !          109553: ugetpid()
        !          109554: {
        !          109555:        return (SELF->p_pid);
        !          109556: }
        !          109557: 
        !          109558: /*
        !          109559:  * Get user id.
        !          109560:  */
        !          109561: ugetuid()
        !          109562: {
        !          109563:        return (u.u_ruid);
        !          109564: }
        !          109565: 
        !          109566: /*
        !          109567:  * Get process group.
        !          109568:  */
        !          109569: ugetpgrp()
        !          109570: {
        !          109571:        return (SELF->p_group);
        !          109572: }
        !          109573: 
        !          109574: /*
        !          109575:  * Set the process group.
        !          109576:  * When process group is 0 and a terminal is
        !          109577:  * opened, this process is made the base of
        !          109578:  * processes associated with that terminal.
        !          109579:  */
        !          109580: usetpgrp()
        !          109581: {
        !          109582:        register PROC * pp = SELF;
        !          109583: 
        !          109584:        return (pp->p_group = pp->p_pid);
        !          109585: }
        !          109586: 
        !          109587: /*
        !          109588:  * Send the signal `sig' to the process with id `pid'.
        !          109589:  */
        !          109590: ukill(pid, sig)
        !          109591: int pid;
        !          109592: register unsigned sig;
        !          109593: {
        !          109594:        register PROC *pp;
        !          109595:        register int sigflag;
        !          109596: 
        !          109597:        if ( sig > NSIG ) {
        !          109598:                u.u_error = EINVAL;
        !          109599:                return;
        !          109600:        }
        !          109601:        sigflag = 0;
        !          109602:        lock(pnxgate);
        !          109603:        if (pid > 0) {  /* send to matching process */
        !          109604:                for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) {
        !          109605:                        if (pp->p_state == PSDEAD)
        !          109606:                                continue;
        !          109607:                        if (pp->p_pid == pid) {
        !          109608:                                sigflag = 1;
        !          109609:                                if ( sig ) {
        !          109610:                                        if (sigperm(sig, pp))
        !          109611:                                                sendsig(sig, pp);
        !          109612:                                        else
        !          109613:                                                u.u_error = EPERM;
        !          109614:                                }
        !          109615:                                break;
        !          109616:                        }
        !          109617:                }
        !          109618:        }
        !          109619:        else if (pid < -1) {
        !          109620:                pid = -pid;
        !          109621:                for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) {
        !          109622:                        if (pp->p_state == PSDEAD)
        !          109623:                                continue;
        !          109624:                        if (pp->p_group == pid) {
        !          109625:                                sigflag = 1;
        !          109626:                                if (sig) {
        !          109627:                                        if (sigperm(sig, pp))
        !          109628:                                                sendsig(sig,pp);
        !          109629:                                        else
        !          109630:                                                u.u_error = EPERM;
        !          109631:                                }
        !          109632:                        }
        !          109633:                }
        !          109634:        }
        !          109635:        else if (pid == 0) {
        !          109636:                for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) {
        !          109637:                        if (pp->p_state == PSDEAD)
        !          109638:                                continue;
        !          109639:                        if (pp->p_group == SELF->p_group) {
        !          109640:                                sigflag = 1;
        !          109641:                                if (sig && sigperm(sig, pp))
        !          109642:                                        sendsig(sig, pp);
        !          109643:                        }
        !          109644:                }
        !          109645:        }
        !          109646:        else if (pid == -1) {
        !          109647:                for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) {
        !          109648:                        if (pp->p_state == PSDEAD)
        !          109649:                                continue;
        !          109650:                        if (pp->p_pid == 0)
        !          109651:                                continue;
        !          109652:                        if (pp->p_pid == 1)
        !          109653:                                continue;
        !          109654:                        if ( pp->p_flags & PFKERN )
        !          109655:                                continue;
        !          109656:                        sigflag = 1;
        !          109657:                        if (sig && super())
        !          109658:                                sendsig(sig, pp);
        !          109659:                }
        !          109660:        }
        !          109661:        unlock(pnxgate);
        !          109662:        if (sigflag == 0)
        !          109663:                u.u_error = ESRCH;
        !          109664:        return (0);
        !          109665: }
        !          109666: 
        !          109667: /*
        !          109668:  * See if we have permission to send the signal, `sig' to the process, `pp'.
        !          109669:  */
        !          109670: sigperm(sig, pp)
        !          109671: register PROC *pp;
        !          109672: {
        !          109673:        if (u.u_uid == pp->p_uid)
        !          109674:                return (1);
        !          109675:        if (u.u_ruid == pp->p_ruid) {
        !          109676:                if (sig == SIGHUP
        !          109677:                ||  sig == SIGINT
        !          109678:                ||  sig == SIGQUIT
        !          109679:                ||  sig == SIGTERM)
        !          109680:                        return (1);
        !          109681:        }
        !          109682:        if (u.u_uid == 0) {
        !          109683:                u.u_flag |= ASU;
        !          109684:                return (1);
        !          109685:        }
        !          109686:        return (0);
        !          109687: }
        !          109688: 
        !          109689: /*
        !          109690:  * Lock a process in core.
        !          109691:  */
        !          109692: ulock(f)
        !          109693: {
        !          109694:        if (super() == 0)
        !          109695:                return;
        !          109696:        if (f)
        !          109697:                SELF->p_flags |= PFLOCK;
        !          109698:        else
        !          109699:                SELF->p_flags &= ~PFLOCK;
        !          109700:        return (0);
        !          109701: }
        !          109702: 
        !          109703: /*
        !          109704:  * Change priority by the given increment.
        !          109705:  */
        !          109706: unice(n)
        !          109707: register int n;
        !          109708: {
        !          109709:        n += SELF->p_nice;
        !          109710:        if (n < MINNICE)
        !          109711:                n = MINNICE;
        !          109712:        if (n > MAXNICE)
        !          109713:                n = MAXNICE;
        !          109714:        if (n<SELF->p_nice && super()==0)
        !          109715:                return;
        !          109716:        SELF->p_nice = n;
        !          109717:        return (0);
        !          109718: }
        !          109719: 
        !          109720: /*
        !          109721:  * Non existant system call.
        !          109722:  */
        !          109723: unone()
        !          109724: {
        !          109725:        u.u_error = EFAULT;
        !          109726: }
        !          109727: 
        !          109728: /*
        !          109729:  * Null system call.
        !          109730:  */
        !          109731: unull()
        !          109732: {
        !          109733: }
        !          109734: 
        !          109735: /*
        !          109736:  * Pause.  Go to sleep on a channel that nobody will wakeup so that only
        !          109737:  * signals will wake us up.
        !          109738:  */
        !          109739: upause()
        !          109740: {
        !          109741:        for (;;)
        !          109742:                sleep((char *)&u, CVPAUSE, IVPAUSE, SVPAUSE);
        !          109743: }
        !          109744: 
        !          109745: /*
        !          109746:  * Start profiling.  `bp' is the profile buffer, `n' is the size, `off'
        !          109747:  * is the offset in the users programme and `scale' is the scaling
        !          109748:  * factor.
        !          109749:  */
        !          109750: uprofil(bp, n, off, scale)
        !          109751: register char *bp;
        !          109752: {
        !          109753:        u.u_pbase = bp;
        !          109754:        u.u_pbend = bp + n;
        !          109755:        u.u_pofft = off;
        !          109756:        u.u_pscale = scale;
        !          109757: }
        !          109758: 
        !          109759: /*
        !          109760:  * Process trace.
        !          109761:  */
        !          109762: uptrace(req, pid, add, data)
        !          109763: int *add;
        !          109764: {
        !          109765:        if (req == 0) {
        !          109766:                SELF->p_flags |= PFTRAC;
        !          109767:                return (0);
        !          109768:        }
        !          109769:        return (ptset(req, pid, add, data));
        !          109770: }
        !          109771: 
        !          109772: /*
        !          109773:  * Set group id.
        !          109774:  */
        !          109775: usetgid(gid)
        !          109776: register int gid;
        !          109777: {
        !          109778:        if (u.u_gid!=gid && super()==0)
        !          109779:                return;
        !          109780:        u.u_gid = gid;
        !          109781:        u.u_rgid = gid;
        !          109782:        SELF->p_rgid = gid;
        !          109783:        return (0);
        !          109784: }
        !          109785: 
        !          109786: /*
        !          109787:  * Set user id.
        !          109788:  */
        !          109789: usetuid(uid)
        !          109790: register int uid;
        !          109791: {
        !          109792:        if (uid!=u.u_ruid && super()==0)
        !          109793:                return;
        !          109794:        u.u_uid = uid;
        !          109795:        u.u_ruid = uid;
        !          109796:        SELF->p_uid = uid;
        !          109797:        SELF->p_ruid = uid;
        !          109798:        return (0);
        !          109799: }
        !          109800: 
        !          109801: /*
        !          109802:  * Set up the action to be taken on a signal.
        !          109803:  */
        !          109804: int *
        !          109805: usignal(sig, f)
        !          109806: register int sig;
        !          109807: int (*f)();
        !          109808: {
        !          109809:        register PROC *pp;
        !          109810:        register sig_t s;
        !          109811:        register int (*o)();
        !          109812: 
        !          109813:        pp = SELF;
        !          109814:        if (sig<=0 || sig>NSIG || sig==SIGKILL) {
        !          109815:                u.u_error = EINVAL;
        !          109816:                return;
        !          109817:        }
        !          109818:        s = (sig_t)1 << --sig;
        !          109819:        o = u.u_sfunc[sig];
        !          109820:        /* This order is critical to isig's use */
        !          109821:        if (f == SIG_IGN) {
        !          109822:                pp->p_isig |= s;
        !          109823:                u.u_sfunc[sig] = f;
        !          109824:        } else {
        !          109825:                u.u_sfunc[sig] = f;
        !          109826:                pp->p_isig &= ~s;
        !          109827:        }
        !          109828:        pp->p_ssig &= ~s;
        !          109829:        return (o);
        !          109830: }
        !          109831: 
        !          109832: /*
        !          109833:  * Load a device driver.
        !          109834:  */
        !          109835: usload( np )
        !          109836: char *np;
        !          109837: {
        !          109838:        return( pload( np ) );
        !          109839: }
        !          109840: 
        !          109841: /*
        !          109842:  * Set time and date.
        !          109843:  */
        !          109844: ustime(tp)
        !          109845: register time_t *tp;
        !          109846: {
        !          109847:        register int s;
        !          109848: 
        !          109849:        if (super() == 0)
        !          109850:                return;
        !          109851:        s = sphi();
        !          109852:        ukcopy(tp, &timer.t_time, sizeof(*tp));
        !          109853:        spl(s);
        !          109854:        return (0);
        !          109855: }
        !          109856: 
        !          109857: /*
        !          109858:  * Return elapsed ticks since system startup.
        !          109859:  */
        !          109860: long
        !          109861: utick()
        !          109862: {
        !          109863:        return( lbolt );
        !          109864: }
        !          109865: 
        !          109866: /*
        !          109867:  * Return process times.
        !          109868:  */
        !          109869: utimes(tp)
        !          109870: struct tbuffer *tp;
        !          109871: {
        !          109872:        register PROC *pp;
        !          109873:        struct tbuffer tbuffer;
        !          109874: 
        !          109875:        pp = SELF;
        !          109876:        tbuffer.tb_utime = pp->p_utime;
        !          109877:        tbuffer.tb_stime = pp->p_stime;
        !          109878:        tbuffer.tb_cutime = pp->p_cutime;
        !          109879:        tbuffer.tb_cstime = pp->p_cstime;
        !          109880:        kucopy(&tbuffer, tp, sizeof(tbuffer));
        !          109881:        return (0);
        !          109882: }
        !          109883: 
        !          109884: /*
        !          109885:  * Unload a device driver.
        !          109886:  */
        !          109887: usuload(m)
        !          109888: register int m;
        !          109889: {
        !          109890:        if (super() == 0)
        !          109891:                return;
        !          109892:        puload(m);
        !          109893:        return (0);
        !          109894: }
        !          109895: 
        !          109896: 
        !          109897: /*
        !          109898:  * Wait for a child to terminate.
        !          109899:  */
        !          109900: uwait(stp)
        !          109901: int *stp;
        !          109902: {
        !          109903:        register PROC *pp;
        !          109904:        register PROC *ppp;
        !          109905:        register PROC *cpp;
        !          109906:        register int pid;
        !          109907: 
        !          109908:        ppp = SELF;
        !          109909:        for (;;) {
        !          109910:                lock(pnxgate);
        !          109911:                cpp = NULL;
        !          109912:                pp = &procq;
        !          109913:                while ((pp=pp->p_nforw) != &procq) {
        !          109914:                        if (pp == ppp)
        !          109915:                                continue;
        !          109916:                        if (pp->p_ppid != ppp->p_pid)
        !          109917:                                continue;
        !          109918:                        if ((pp->p_flags&PFSTOP) != 0)
        !          109919:                                continue;
        !          109920:                        if ((pp->p_flags&PFWAIT) != 0) {
        !          109921:                                pp->p_flags &= ~PFWAIT;
        !          109922:                                pp->p_flags |= PFSTOP;
        !          109923:                                unlock(pnxgate);
        !          109924:                                if (stp != NULL)
        !          109925:                                        putuwd(stp, 0177);
        !          109926:                                return (pp->p_pid);
        !          109927:                        }
        !          109928:                        if (pp->p_state == PSDEAD) {
        !          109929:                                ppp->p_cutime += pp->p_utime + pp->p_cutime;
        !          109930:                                ppp->p_cstime += pp->p_stime + pp->p_cstime;
        !          109931:                                if (stp != NULL)
        !          109932:                                        putuwd(stp, pp->p_exit);
        !          109933:                                pid = pp->p_pid;
        !          109934:                                unlock(pnxgate);
        !          109935:                                relproc(pp);
        !          109936:                                return (pid);
        !          109937:                        }
        !          109938:                        cpp = pp;
        !          109939:                }
        !          109940:                unlock(pnxgate);
        !          109941:                if (cpp == NULL) {
        !          109942:                        u.u_error = ECHILD;
        !          109943:                        return;
        !          109944:                }
        !          109945:                sleep((char *)ppp, CVWAIT, IVWAIT, SVWAIT);
        !          109946:        }
        !          109947: }
        !          109948: 0707070064030103201006440000030000030000011777770507310731400004200000026673/newbits/kernel/USRSRC/coh/sys2.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/sys2.c,v 1.5 91/07/24 07:52:31 bin Exp Locker: bin $ */
        !          109949: /* (lgl-
        !          109950:  *     The information contained herein is a trade secret of Mark Williams
        !          109951:  *     Company, and  is confidential information.  It is provided  under a
        !          109952:  *     license agreement,  and may be  copied or disclosed  only under the
        !          109953:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          109954:  *     material without the express written authorization of Mark Williams
        !          109955:  *     Company or persuant to the license agreement is unlawful.
        !          109956:  *
        !          109957:  *     COHERENT Version 2.3.37
        !          109958:  *     Copyright (c) 1982, 1983, 1984.
        !          109959:  *     An unpublished work by Mark Williams Company, Chicago.
        !          109960:  *     All rights reserved.
        !          109961:  -lgl) */
        !          109962: 
        !          109963: /*
        !          109964:  * Coherent.
        !          109965:  * System calls (filesystem related).
        !          109966:  *
        !          109967:  * $Log:       sys2.c,v $
        !          109968:  * Revision 1.5  91/07/24  07:52:31  bin
        !          109969:  * update prov by hal
        !          109970:  * 
        !          109971:  * 
        !          109972:  * Revision 1.1        91/04/30  13:56:54      root
        !          109973:  * Shipped with COH 3.1.0.
        !          109974:  * 
        !          109975:  */
        !          109976: #include <sys/coherent.h>
        !          109977: #include <errno.h>
        !          109978: #include <sys/fcntl.h>
        !          109979: #include <sys/fd.h>
        !          109980: #include <sys/ino.h>
        !          109981: #include <sys/inode.h>
        !          109982: #include <sys/mount.h>
        !          109983: #include <sys/poll.h>
        !          109984: #include <sys/sched.h>
        !          109985: #include <sys/stat.h>
        !          109986: #include <sys/uproc.h>
        !          109987: 
        !          109988: /*
        !          109989:  * Determine accessibility of the given file.
        !          109990:  */
        !          109991: uaccess(np, mode)
        !          109992: char *np;
        !          109993: register int mode;
        !          109994: {
        !          109995:        register INODE *ip;
        !          109996:        register int r;
        !          109997: 
        !          109998:        schizo();
        !          109999:        r = ftoi(np, 'r');
        !          110000:        schizo();
        !          110001:        if (r != 0)
        !          110002:                return;
        !          110003:        ip = u.u_cdiri;
        !          110004:        if ((mode&imode(ip, u.u_ruid, u.u_rgid)) != mode)
        !          110005:                u.u_error = EACCES;
        !          110006:        idetach(ip);
        !          110007:        return (0);
        !          110008: }
        !          110009: 
        !          110010: /*
        !          110011:  * Schizo - swap real and effective id's.
        !          110012:  */
        !          110013: schizo()
        !          110014: {
        !          110015:        register int t;
        !          110016: 
        !          110017:        t = u.u_uid;
        !          110018:        u.u_uid = u.u_ruid;
        !          110019:        u.u_ruid = t;
        !          110020:        t = u.u_gid;
        !          110021:        u.u_gid = u.u_rgid;
        !          110022:        u.u_rgid = t;
        !          110023: }
        !          110024: 
        !          110025: /*
        !          110026:  * Turn accounting on or off.
        !          110027:  */
        !          110028: uacct(np)
        !          110029: register char *np;
        !          110030: {
        !          110031:        register INODE *ip;
        !          110032: 
        !          110033:        if (super() == 0)
        !          110034:                return;
        !          110035:        if (np == NULL) {
        !          110036:                if (acctip == NULL) {
        !          110037:                        u.u_error = EINVAL;
        !          110038:                        return;
        !          110039:                }
        !          110040:                ldetach(acctip);
        !          110041:                acctip = NULL;
        !          110042:        } else {
        !          110043:                if (acctip != NULL) {
        !          110044:                        u.u_error = EINVAL;
        !          110045:                        return;
        !          110046:                }
        !          110047:                if (ftoi(np, 'r') != 0)
        !          110048:                        return;
        !          110049:                ip = u.u_cdiri;
        !          110050:                if ((ip->i_mode&IFMT) != IFREG) {
        !          110051:                        u.u_error = EINVAL;
        !          110052:                        idetach(ip);
        !          110053:                        return;
        !          110054:                }
        !          110055:                iunlock(ip);
        !          110056:                acctip = ip;
        !          110057:        }
        !          110058:        return (0);
        !          110059: }
        !          110060: 
        !          110061: /*
        !          110062:  * Set current directory.
        !          110063:  */
        !          110064: uchdir(np)
        !          110065: char *np;
        !          110066: {
        !          110067:        setcdir(np, &u.u_cdir);
        !          110068:        return (0);
        !          110069: }
        !          110070: 
        !          110071: /*
        !          110072:  * Given a directory name and a pointer to a working directory pointer,
        !          110073:  * Save the inode associated with the directory name in the working
        !          110074:  * directory pointer and release the old one.  This is used to change
        !          110075:  * working and root directories.
        !          110076:  */
        !          110077: setcdir(np, ipp)
        !          110078: char *np;
        !          110079: register INODE **ipp;
        !          110080: {
        !          110081:        register INODE *ip;
        !          110082: 
        !          110083:        if (ftoi(np, 'r') != 0)
        !          110084:                return;
        !          110085:        ip = u.u_cdiri;
        !          110086:        if ((ip->i_mode&IFMT) != IFDIR) {
        !          110087:                u.u_error = ENOTDIR;
        !          110088:                idetach(ip);
        !          110089:                return;
        !          110090:        }
        !          110091:        if (iaccess(ip, IPE) == 0) {
        !          110092:                u.u_error = EACCES;
        !          110093:                idetach(ip);
        !          110094:                return;
        !          110095:        }
        !          110096:        iunlock(ip);
        !          110097:        ldetach(*ipp);
        !          110098:        *ipp = ip;
        !          110099: }
        !          110100: 
        !          110101: /*
        !          110102:  * Change the mode of a file.
        !          110103:  */
        !          110104: uchmod(np, mode)
        !          110105: char *np;
        !          110106: {
        !          110107:        register INODE *ip;
        !          110108: 
        !          110109:        if (ftoi(np, 'r') != 0)
        !          110110:                return;
        !          110111:        ip = u.u_cdiri;
        !          110112:        if (owner(ip->i_uid)) {
        !          110113:                if (u.u_uid != 0)
        !          110114:                        mode &= ~ISVTXT;
        !          110115:                ip->i_mode &= IFMT;
        !          110116:                ip->i_mode |= mode&~IFMT;
        !          110117:                icrt(ip);       /* chmod - ctime */
        !          110118:        }
        !          110119:        idetach(ip);
        !          110120:        return (0);
        !          110121: }
        !          110122: 
        !          110123: /*
        !          110124:  * Change owner and group of a file.
        !          110125:  */
        !          110126: uchown(np, uid, gid)
        !          110127: char *np;
        !          110128: {
        !          110129:        register INODE *ip;
        !          110130: 
        !          110131:        if (ftoi(np, 'r') != 0)
        !          110132:                return;
        !          110133:        ip = u.u_cdiri;
        !          110134:        if (super()) {
        !          110135:                ip->i_mode &= ~(ISUID | ISGID);  /* clear any setuid/setgid */
        !          110136:                ip->i_uid = uid;
        !          110137:                ip->i_gid = gid;
        !          110138:                icrt(ip);       /* chown - ctime */
        !          110139:        }
        !          110140:        idetach(ip);
        !          110141:        return (0);
        !          110142: }
        !          110143: 
        !          110144: /*
        !          110145:  * Set root directory.
        !          110146:  */
        !          110147: uchroot(np)
        !          110148: register char *np;
        !          110149: {
        !          110150:        if (super())
        !          110151:                setcdir(np, &u.u_rdir);
        !          110152:        return (0);
        !          110153: }
        !          110154: 
        !          110155: /*
        !          110156:  * Close the given file descriptor.
        !          110157:  */
        !          110158: uclose(fd)
        !          110159: {
        !          110160:        fdclose(fd);
        !          110161:        return (0);
        !          110162: }
        !          110163: 
        !          110164: /*
        !          110165:  * Create a file with the given mode.
        !          110166:  */
        !          110167: ucreat(np, mode)
        !          110168: char *np;
        !          110169: register int mode;
        !          110170: {
        !          110171:        register INODE *ip;
        !          110172:        register int fd;
        !          110173:        register int cflag;
        !          110174: 
        !          110175:        cflag = 0;
        !          110176:        if (ftoi(np, 'c') != 0)
        !          110177:                return;
        !          110178:        if ((ip=u.u_cdiri) == NULL) {
        !          110179:                if ((ip=imake((mode&~IFMT)|IFREG, 0)) == NULL)
        !          110180:                        return;
        !          110181:        } else {
        !          110182:                if (iaccess(ip, IPW)==0) {
        !          110183:                        idetach(ip);
        !          110184:                        return;
        !          110185:                }
        !          110186:                switch (ip->i_mode&IFMT) {
        !          110187:                case IFBLK:
        !          110188:                case IFCHR:
        !          110189:                        break;
        !          110190:                case IFDIR:
        !          110191:                        u.u_error = EISDIR;
        !          110192:                        idetach(ip);
        !          110193:                        return;
        !          110194:                default:
        !          110195:                        if (getment(ip->i_dev, 1) == NULL) {
        !          110196:                                idetach(ip);
        !          110197:                                return;
        !          110198:                        }
        !          110199:                }
        !          110200:                cflag = 1;
        !          110201:        }
        !          110202:        if ((fd=fdopen(ip, IPW)) < 0) {
        !          110203:                idetach(ip);
        !          110204:                return;
        !          110205:        }
        !          110206:        if (cflag)
        !          110207:                iclear(ip);
        !          110208:        iunlock(ip);
        !          110209:        return (fd);
        !          110210: }
        !          110211: 
        !          110212: /*
        !          110213:  * Duplicate a file descriptor.
        !          110214:  */
        !          110215: udup(ofd, nfd)
        !          110216: {
        !          110217:        return (fddup(ofd, nfd));
        !          110218: }
        !          110219: 
        !          110220: /*
        !          110221:  * Given a file descriptor, return a status structure.
        !          110222:  */
        !          110223: ufstat(fd, stp)
        !          110224: struct stat *stp;
        !          110225: {
        !          110226:        register INODE *ip;
        !          110227:        register FD *fdp;
        !          110228:        struct stat stat;
        !          110229: 
        !          110230:        if ((fdp=fdget(fd)) == NULL)
        !          110231:                return;
        !          110232:        ip = fdp->f_ip;
        !          110233:        istat(ip, &stat);
        !          110234:        kucopy(&stat, stp, sizeof(stat));
        !          110235:        return (0);
        !          110236: }
        !          110237: 
        !          110238: /*
        !          110239:  * File control.
        !          110240:  */
        !          110241: ufcntl( fd, cmd, arg )
        !          110242: int fd, cmd, arg;
        !          110243: {
        !          110244:        register FD * fdp;
        !          110245: 
        !          110246:        /*
        !          110247:         * Validate file descriptor.
        !          110248:         */
        !          110249:        if ( (fd < 0) || (fd >= NUFILE) || ((fdp = u.u_filep[fd]) == 0) ) {
        !          110250:                u.u_error = EBADF;
        !          110251:                return;
        !          110252:        }
        !          110253: 
        !          110254:        switch ( cmd ) {
        !          110255: 
        !          110256:        case F_DUPFD:
        !          110257:                /*
        !          110258:                 * Validate base file descriptor.
        !          110259:                 */
        !          110260:                if ( (arg < 0) || (arg >= NUFILE) ) {
        !          110261:                        u.u_error = EINVAL;
        !          110262:                        return;
        !          110263:                }
        !          110264: 
        !          110265:                /*
        !          110266:                 * Search for next available file descriptor.
        !          110267:                 */
        !          110268:                do {
        !          110269:                        if ( u.u_filep[arg] == 0 ) {
        !          110270:                                u.u_filep[arg] = fdp;
        !          110271:                                fdp->f_refc++;
        !          110272:                                return arg;
        !          110273:                        }
        !          110274:                } while ( ++arg < NUFILE );
        !          110275: 
        !          110276:                u.u_error = EMFILE;
        !          110277:                return;
        !          110278: 
        !          110279:        case F_SETFL:
        !          110280:                fdp->f_flag &= ~IPNDLY;
        !          110281:                if ( arg & O_NDELAY )
        !          110282:                        fdp->f_flag |= IPNDLY;
        !          110283:                if ( arg & O_APPEND )
        !          110284:                        fdp->f_flag |= IPAPPEND;
        !          110285:                /* no break */
        !          110286: 
        !          110287:        case F_GETFL:
        !          110288:                switch ( fdp->f_flag & (IPR+IPW) ) {
        !          110289:                case IPR: arg = O_RDONLY; break;
        !          110290:                case IPW: arg = O_WRONLY; break;
        !          110291:                default:  arg = O_RDWR;   break;
        !          110292:                }
        !          110293:                if ( fdp->f_flag & IPNDLY )
        !          110294:                        arg |= O_NDELAY;
        !          110295:                if ( fdp->f_flag & IPAPPEND )
        !          110296:                        arg |= O_APPEND;
        !          110297:                return arg;
        !          110298: 
        !          110299:        default:
        !          110300:                u.u_error = EINVAL;
        !          110301:        }
        !          110302: }
        !          110303: 
        !          110304: /*
        !          110305:  * Device control information.
        !          110306:  */
        !          110307: uioctl(fd, r, argp)
        !          110308: struct sgttyb *argp;
        !          110309: {
        !          110310:        register FD *fdp;
        !          110311:        register INODE *ip;
        !          110312:        register int mode;
        !          110313: 
        !          110314:        if ((fdp=fdget(fd)) == NULL)
        !          110315:                return;
        !          110316:        ip = fdp->f_ip;
        !          110317:        mode = ip->i_mode&IFMT;
        !          110318:        if (mode!=IFCHR && mode!=IFBLK) {
        !          110319:                u.u_error = ENOTTY;
        !          110320:                return;
        !          110321:        }
        !          110322:        dioctl(ip->i_a.i_rdev, r, argp);
        !          110323:        return (0);
        !          110324: }
        !          110325: 
        !          110326: /*
        !          110327:  * Create a link, `np2' to the already existing file `np1'.
        !          110328:  */
        !          110329: ulink(np1, np2)
        !          110330: char *np1;
        !          110331: char *np2;
        !          110332: {
        !          110333:        register INODE *ip1;
        !          110334: 
        !          110335:        if (ftoi(np1, 'r') != 0)
        !          110336:                return;
        !          110337:        ip1 = u.u_cdiri;
        !          110338:        if ((ip1->i_mode&IFMT)==IFDIR && super()==0) {
        !          110339:                idetach(ip1);
        !          110340:                return;
        !          110341:        }
        !          110342:        iunlock(ip1);
        !          110343:        if (ftoi(np2, 'c') != 0) {
        !          110344:                ldetach(ip1);
        !          110345:                return;
        !          110346:        }
        !          110347:        if (u.u_cdiri != NULL) {
        !          110348:                u.u_error = EEXIST;
        !          110349:                idetach(u.u_cdiri);
        !          110350:                ldetach(ip1);
        !          110351:                return;
        !          110352:        }
        !          110353:        if (ip1->i_dev != u.u_pdiri->i_dev) {
        !          110354:                u.u_error = EXDEV;
        !          110355:                idetach(u.u_pdiri);
        !          110356:                ldetach(ip1);
        !          110357:                return;
        !          110358:        }
        !          110359:        if (iaccess(u.u_pdiri, IPW) == 0) {
        !          110360:                idetach(u.u_pdiri);
        !          110361:                ldetach(ip1);
        !          110362:                return;
        !          110363:        }
        !          110364:        idirent(ip1->i_ino);
        !          110365:        idetach(u.u_pdiri);
        !          110366:        ilock(ip1);
        !          110367:        ip1->i_nlink++;
        !          110368:        icrt(ip1);      /* link - ctime */
        !          110369:        idetach(ip1);
        !          110370:        return (0);
        !          110371: }
        !          110372: 
        !          110373: /*
        !          110374:  * Seek on the given file descriptor.
        !          110375:  */
        !          110376: fsize_t
        !          110377: ulseek(fd, off, w)
        !          110378: register fsize_t off;
        !          110379: {
        !          110380:        register FD *fdp;
        !          110381:        register INODE *ip;
        !          110382: 
        !          110383:        if ((fdp=fdget(fd)) == NULL)
        !          110384:                return;
        !          110385:        ip = fdp->f_ip;
        !          110386:        if ((ip->i_mode&IFMT) == IFPIPE) {
        !          110387:                u.u_error = ESPIPE;
        !          110388:                return;
        !          110389:        }
        !          110390:        switch (w) {
        !          110391:        case 0:
        !          110392:                break;
        !          110393:        case 1:
        !          110394:                off += fdp->f_seek;
        !          110395:                break;
        !          110396:        case 2:
        !          110397:                off += ip->i_size;
        !          110398:                break;
        !          110399:        default:
        !          110400:                u.u_error = EINVAL;
        !          110401:                return;
        !          110402:        }
        !          110403:        if (off < 0) {
        !          110404:                u.u_error = EINVAL;
        !          110405:                return;
        !          110406:        }
        !          110407:        fdp->f_seek = off;
        !          110408:        return (off);
        !          110409: }
        !          110410: 
        !          110411: /*
        !          110412:  * Create a special file.
        !          110413:  */
        !          110414: umknod(np, mode, rdev)
        !          110415: char *np;
        !          110416: dev_t rdev;
        !          110417: {
        !          110418:        register INODE *ip;
        !          110419:        register int type;
        !          110420: 
        !          110421:        type = mode&IFMT;
        !          110422:        if (type!=IFPIPE && super()==0)
        !          110423:                return;
        !          110424:        if (type!=IFBLK && type!=IFCHR)
        !          110425:                rdev = 0;
        !          110426:        if (ftoi(np, 'c') != 0)
        !          110427:                return;
        !          110428:        if ((ip=u.u_cdiri) != NULL) {
        !          110429:                u.u_error = EEXIST;
        !          110430:                idetach(ip);
        !          110431:                return;
        !          110432:        }
        !          110433:        if ((ip=imake(mode, rdev)) != NULL)
        !          110434:                idetach(ip);
        !          110435:        return (0);
        !          110436: }
        !          110437: 
        !          110438: /*
        !          110439:  * Mount the device `sp' on the pathname `np'.  The flag, `f',
        !          110440:  * indicates that the device is to be mounted read only.
        !          110441:  */
        !          110442: umount(sp, np, f)
        !          110443: char *sp;
        !          110444: char *np;
        !          110445: {
        !          110446:        register INODE *ip;
        !          110447:        register MOUNT *mp;
        !          110448:        register dev_t rdev;
        !          110449:        register int mode;
        !          110450: 
        !          110451:        if (ftoi(sp, 'r') != 0)
        !          110452:                return;
        !          110453:        ip = u.u_cdiri;
        !          110454:        if (iaccess(ip, IPR|IPW) == 0)
        !          110455:                goto err;
        !          110456:        mode = ip->i_mode;
        !          110457:        rdev = ip->i_a.i_rdev;
        !          110458:        if ((mode&IFMT) != IFBLK) {
        !          110459:                u.u_error = ENOTBLK;
        !          110460:                goto err;
        !          110461:        }
        !          110462:        idetach(ip);
        !          110463:        if (ftoi(np, 'r') != 0)
        !          110464:                return;
        !          110465:        ip = u.u_cdiri;
        !          110466:        if (iaccess(ip, IPR) == 0)
        !          110467:                goto err;
        !          110468:        if ((ip->i_mode&IFMT) != IFDIR) {
        !          110469:                u.u_error = ENOTDIR;
        !          110470:                goto err;
        !          110471:        }
        !          110472:        /* Check for current directory, open, or mount directory */
        !          110473:        if (ip->i_refc > 1 || ip->i_ino == ROOTIN) {
        !          110474:                u.u_error = EBUSY;
        !          110475:                goto err;
        !          110476:        }
        !          110477:        for (mp=mountp; mp!=NULL; mp=mp->m_next) {
        !          110478:                if (mp->m_dev == rdev) {
        !          110479:                        u.u_error = EBUSY;
        !          110480:                        goto err;
        !          110481:                }
        !          110482:        }
        !          110483:        if ((mp=fsmount(rdev, f)) == NULL)
        !          110484:                goto err;
        !          110485:        mp->m_ip = ip;
        !          110486:        ip->i_flag |= IFMNT;
        !          110487:        ip->i_refc++;
        !          110488: err:
        !          110489:        idetach(ip);
        !          110490:        return (0);
        !          110491: }
        !          110492: 
        !          110493: /*
        !          110494:  * Poll devices for input/output events.
        !          110495:  */
        !          110496: int
        !          110497: upoll( pollfds, npoll, msec )
        !          110498: struct pollfd * pollfds;
        !          110499: unsigned long npoll;
        !          110500: int msec;
        !          110501: {
        !          110502:        register struct pollfd * pollp; /* current poll pointer          */
        !          110503:        register FD *   fdp;            /* current file descriptor ptr   */
        !          110504:        auto     int    fd;             /* current file descriptor       */
        !          110505:        auto     int    rev;            /* last event report received    */
        !          110506:        auto     int    nev;            /* number non-zero event reports */
        !          110507:        auto     int    i;
        !          110508:        extern   char * udl;
        !          110509: 
        !          110510:        /*
        !          110511:         * Validate number of polls.
        !          110512:         */
        !          110513:        if ( (npoll < 0) || (npoll > NUFILE) ) {
        !          110514:                u.u_error = EINVAL;
        !          110515:                return;
        !          110516:        }
        !          110517: 
        !          110518:        /*
        !          110519:         * Validate address of polling information.
        !          110520:         */
        !          110521:        pollp = &pollfds[npoll];
        !          110522:        if ( (pollfds == NULL) || (pollp < pollfds) || (pollp > udl) ) {
        !          110523:                u.u_error = EFAULT;
        !          110524:                return;
        !          110525:        }
        !          110526: 
        !          110527:        do {
        !          110528:                /*
        !          110529:                 * Service each poll in turn.
        !          110530:                 */
        !          110531:                for ( nev=0, i=npoll, pollp = pollfds; i > 0; --i, pollp++ ) {
        !          110532: 
        !          110533:                        /*
        !          110534:                         * Fetch file descriptor.
        !          110535:                         */
        !          110536:                        fd = getuwd( &pollp->fd );
        !          110537: 
        !          110538:                        /*
        !          110539:                         * Ignore negative file descriptors.
        !          110540:                         */
        !          110541:                        if ( fd < 0 ) {
        !          110542:                                rev = 0;
        !          110543:                        }
        !          110544: 
        !          110545:                        /*
        !          110546:                         * Poll message queue.
        !          110547:                         */
        !          110548:                        else if ( fd >= NUFILE ) {
        !          110549: #ifdef MSGPOLL
        !          110550: /*
        !          110551:  * this code only good if msgpoll() is available to the kernel -
        !          110552:  * no good with loadable msg driver
        !          110553:  */
        !          110554:                                rev = msgpoll(  fd,
        !          110555:                                                getuwd( &pollp->events),
        !          110556:                                                msec );
        !          110557: #else
        !          110558:                                rev = POLLNVAL;
        !          110559: #endif
        !          110560:                        }
        !          110561: 
        !          110562:                        /*
        !          110563:                         * Validate file descriptor.
        !          110564:                         */
        !          110565:                        else if ( (fdp = u.u_filep[fd]) == 0 ) {
        !          110566:                                rev = POLLNVAL;
        !          110567:                        }
        !          110568: 
        !          110569:                        /*
        !          110570:                         * Non-character device.
        !          110571:                         */
        !          110572:                        else if ( (fdp->f_ip->i_mode & IFMT) != IFCHR ) {
        !          110573:                                rev = POLLNVAL;
        !          110574:                        }
        !          110575: 
        !          110576:                        /*
        !          110577:                         * Poll character device driver.
        !          110578:                         */
        !          110579:                        else {
        !          110580:                                rev = dpoll( fdp->f_ip->i_a.i_rdev,
        !          110581:                                                getuwd(&pollp->events),
        !          110582:                                                msec );
        !          110583:                        }
        !          110584: 
        !          110585:                        /*
        !          110586:                         * Remember reponses.
        !          110587:                         */
        !          110588:                        putuwd( &pollp->revents, rev );
        !          110589: 
        !          110590:                        /*
        !          110591:                         * Record number of non-zero responses.
        !          110592:                         */
        !          110593:                        if ( rev != 0 ) {
        !          110594:                                msec = 0;
        !          110595:                                nev++;
        !          110596:                        }
        !          110597:                }
        !          110598: 
        !          110599:                /*
        !          110600:                 * Non-blocking poll or poll response received.
        !          110601:                 */
        !          110602:                if ( msec == 0 ) {
        !          110603:                        pollexit();
        !          110604:                        return nev;
        !          110605:                }
        !          110606: 
        !          110607:                /*
        !          110608:                 * Schedule wakeup timer if positive delay interval given.
        !          110609:                 */
        !          110610:                if ( msec > 0 ) {
        !          110611:                        /*
        !          110612:                         * Convert milliseconds to clock ticks.
        !          110613:                         */
        !          110614:                        msec += (1000 / HZ) - 1;
        !          110615:                        msec /= (1000 / HZ);
        !          110616:                        timeout( &cprocp->p_polltim, msec,
        !          110617:                                 wakeup, &cprocp->p_polls );
        !          110618:                }
        !          110619: 
        !          110620:                /*
        !          110621:                 * Wake for polled event, poll timeout, or signal.
        !          110622:                 */
        !          110623:                sleep( &cprocp->p_polls, CVTTOUT, IVTTOUT, SVTTOUT );
        !          110624: 
        !          110625:                /*
        !          110626:                 * Terminate event monitoring.
        !          110627:                 */
        !          110628:                pollexit();
        !          110629: 
        !          110630:                /*
        !          110631:                 * Perform non-blocking poll after first poll timeout.
        !          110632:                 */
        !          110633:                if ( msec > 0 ) {
        !          110634:                        timeout( &cprocp->p_polltim, 0, NULL, NULL );
        !          110635:                        msec = 0;
        !          110636:                }
        !          110637: 
        !          110638:                /*
        !          110639:                 * Signal woke us up.
        !          110640:                 */
        !          110641:                if ( nondsig() ) {
        !          110642:                        u.u_error = EINTR;
        !          110643:                        return -1;
        !          110644:                }
        !          110645: 
        !          110646:        } while ( msec != 0 );
        !          110647: 
        !          110648:        return 0;
        !          110649: }
        !          110650: 0707070064030103171006440000030000030000011777770507310731600004200000017200/newbits/kernel/USRSRC/coh/sys3.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/sys3.c,v 1.4 91/07/24 07:52:41 bin Exp Locker: bin $ */
        !          110651: /* (lgl-
        !          110652:  *     The information contained herein is a trade secret of Mark Williams
        !          110653:  *     Company, and  is confidential information.  It is provided  under a
        !          110654:  *     license agreement,  and may be  copied or disclosed  only under the
        !          110655:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          110656:  *     material without the express written authorization of Mark Williams
        !          110657:  *     Company or persuant to the license agreement is unlawful.
        !          110658:  *
        !          110659:  *     COHERENT Version 2.3.37
        !          110660:  *     Copyright (c) 1982, 1983, 1984.
        !          110661:  *     An unpublished work by Mark Williams Company, Chicago.
        !          110662:  *     All rights reserved.
        !          110663:  -lgl) */
        !          110664: /*
        !          110665:  * Coherent.
        !          110666:  * System calls (more filesystem related calls).
        !          110667:  *
        !          110668:  * $Log:       sys3.c,v $
        !          110669:  * Revision 1.4  91/07/24  07:52:41  bin
        !          110670:  * update prov by hal
        !          110671:  * 
        !          110672:  * 
        !          110673:  * Revision 1.3        89/02/07  18:50:27      src
        !          110674:  * Bug:        Console driver did not validate user addresses before initiating a
        !          110675:  *     transfer.  This resulted in a system trap in protected mode if a write
        !          110676:  *     outside of user data space was attempted.
        !          110677:  * Fix:        Reads and writes now validate user addresses via 'useracc' prior to
        !          110678:  *     calling drivers. (ABC)
        !          110679:  * 
        !          110680:  * Revision 1.2        88/08/02  15:01:04      src
        !          110681:  * O_APPEND flag now supported on open/fcntl system calls.
        !          110682:  * 
        !          110683:  * Revision 1.1        88/03/24  16:14:35      src
        !          110684:  * Initial revision
        !          110685:  * 
        !          110686:  * 88/01/22    Allan Cornish           /usr/src/sys/coh/sys3.c
        !          110687:  * sysio() inode lock extended to cover getting/modifying file seek offset.
        !          110688:  *
        !          110689:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/sys3.c
        !          110690:  * uopen() now checks mode for O_NDELAY and sets IPNDLY bit in fdp->f_flag.
        !          110691:  * sysio() now checks fdp->f_flag for IPNDLY and sets IONDLY bit in io_flag.
        !          110692:  */
        !          110693: #include <sys/coherent.h>
        !          110694: #include <sys/buf.h>
        !          110695: #include <errno.h>
        !          110696: #include <sys/fcntl.h>
        !          110697: #include <sys/fd.h>
        !          110698: #include <sys/filsys.h>
        !          110699: #include <sys/ino.h>
        !          110700: #include <sys/inode.h>
        !          110701: #include <sys/io.h>
        !          110702: #include <sys/mount.h>
        !          110703: #include <sys/stat.h>
        !          110704: #include <sys/uproc.h>
        !          110705: 
        !          110706: /*
        !          110707:  * Open the file `np' with the mode `mode'.
        !          110708:  */
        !          110709: uopen(np, mode)
        !          110710: char *np;
        !          110711: {
        !          110712:        register int f;
        !          110713:        register INODE *ip;
        !          110714:        register int fd;
        !          110715: 
        !          110716:        switch (mode & 3) {
        !          110717:        case O_RDONLY:
        !          110718:                f = IPR;
        !          110719:                break;
        !          110720:        case O_WRONLY:
        !          110721:                f = IPW;
        !          110722:                break;
        !          110723:        case O_RDWR:
        !          110724:                f = IPR|IPW;
        !          110725:                break;
        !          110726:        default:
        !          110727:                u.u_error = EINVAL;
        !          110728:                return;
        !          110729:        }
        !          110730:        if (ftoi(np, 'r') != 0)
        !          110731:                return;
        !          110732:        ip = u.u_cdiri;
        !          110733:        if (iaccess(ip, f) == 0) {
        !          110734:                idetach(ip);
        !          110735:                return;
        !          110736:        }
        !          110737:        if ( mode & O_NDELAY )
        !          110738:                f |= IPNDLY;
        !          110739:        if ( mode & O_APPEND )
        !          110740:                f |= IPAPPEND;
        !          110741:        if ((fd=fdopen(ip, f)) < 0) {
        !          110742:                idetach(ip);
        !          110743:                return;
        !          110744:        }
        !          110745:        iunlock(ip);
        !          110746:        return (fd);
        !          110747: }
        !          110748: 
        !          110749: /*
        !          110750:  * Create a pipe.
        !          110751:  */
        !          110752: upipe(fdp)
        !          110753: int fdp[2];
        !          110754: {
        !          110755:        register INODE *ip;
        !          110756:        register int fd1;
        !          110757:        register int fd2;
        !          110758: 
        !          110759:        if ((ip=pmake(0)) == NULL)
        !          110760:                return;
        !          110761:        if ((fd1=fdopen(ip, IPR)) >= 0) {
        !          110762:                ip->i_refc++;
        !          110763:                if ((fd2=fdopen(ip, IPW)) >= 0) {
        !          110764:                        putuwd(&fdp[0], fd1);
        !          110765:                        putuwd(&fdp[1], fd2);
        !          110766:                        iunlock(ip);
        !          110767:                        return (0);
        !          110768:                }
        !          110769:                --ip->i_refc;
        !          110770:                iunlock(ip);
        !          110771:                fdclose(fd1);
        !          110772:                return (0);
        !          110773:        }
        !          110774:        idetach(ip);
        !          110775:        return (0);
        !          110776: }
        !          110777: 
        !          110778: /*
        !          110779:  * Read `n' bytes into the buffer `bp' from file number `fd'.
        !          110780:  */
        !          110781: uread(fd, bp, n)
        !          110782: char *bp;
        !          110783: unsigned n;
        !          110784: {
        !          110785:        return (sysio(fd, bp, n, 0));
        !          110786: }
        !          110787: 
        !          110788: /*
        !          110789:  * Read or write `n' bytes from the file number `fd' using the buffer
        !          110790:  * `bp'.  If `f' is 0, we read, else write.
        !          110791:  */
        !          110792: sysio(fd, bp, n, f)
        !          110793: char *bp;
        !          110794: unsigned n;
        !          110795: {
        !          110796:        register FD *fdp;
        !          110797:        register INODE *ip;
        !          110798:        register int type;
        !          110799: 
        !          110800:        if ((fdp=fdget(fd)) == NULL)
        !          110801:                return (0);
        !          110802:        if ((fdp->f_flag&(f?IPW:IPR)) == 0) {
        !          110803:                u.u_error = EBADF;
        !          110804:                return (0);
        !          110805:        }
        !          110806:        if ( ! useracc( bp, n ) ) {
        !          110807:                u.u_error = EFAULT;
        !          110808:                return(0);
        !          110809:        }
        !          110810: 
        !          110811:        ip = fdp->f_ip;
        !          110812:        type = ip->i_mode&IFMT;
        !          110813:        if (type != IFCHR)
        !          110814:                ilock(ip);
        !          110815:        if ( fdp->f_flag & IPAPPEND )
        !          110816:                fdp->f_seek = ip->i_size;
        !          110817:        u.u_io.io_seek = fdp->f_seek;
        !          110818:        u.u_io.io_base = bp;
        !          110819:        u.u_io.io_ioc  = n;
        !          110820:        u.u_io.io_flag = (fdp->f_flag & IPNDLY) ? IONDLY : 0;
        !          110821:        if (f == 0) {
        !          110822:                iread(ip, &u.u_io);
        !          110823:                iacc(ip);               /* read - atime */
        !          110824:        } else {
        !          110825:                iwrite(ip, &u.u_io);
        !          110826:        }
        !          110827:        n -= u.u_io.io_ioc;
        !          110828:        fdp->f_seek += n;
        !          110829:        if (type != IFCHR)
        !          110830:                iunlock(ip);
        !          110831:        return (n);
        !          110832: }
        !          110833: 
        !          110834: /*
        !          110835:  * Return a status structure for the given file name.
        !          110836:  */
        !          110837: ustat(np, stp)
        !          110838: char *np;
        !          110839: struct stat *stp;
        !          110840: {
        !          110841:        register INODE *ip;
        !          110842:        struct stat stat;
        !          110843: 
        !          110844:        if (ftoi(np, 'r') != 0)
        !          110845:                return;
        !          110846:        ip = u.u_cdiri;
        !          110847:        istat(ip, &stat);
        !          110848:        idetach(ip);
        !          110849:        kucopy(&stat, stp, sizeof(stat));
        !          110850:        return (0);
        !          110851: }
        !          110852: 
        !          110853: /*
        !          110854:  * Write out all modified buffers, inodes and super blocks to disk.
        !          110855:  */
        !          110856: usync()
        !          110857: {
        !          110858:        register MOUNT *mp;
        !          110859:        static GATE syngate;
        !          110860: 
        !          110861:        lock(syngate);
        !          110862:        for (mp=mountp; mp!=NULL; mp=mp->m_next)
        !          110863:                msync(mp);
        !          110864:        bsync();
        !          110865:        unlock(syngate);
        !          110866:        return (0);
        !          110867: }
        !          110868: 
        !          110869: /*
        !          110870:  * Set the mask for file access.
        !          110871:  */
        !          110872: uumask(mask)
        !          110873: {
        !          110874:        register int omask;
        !          110875: 
        !          110876:        omask = u.u_umask;
        !          110877:        u.u_umask = mask & 0777;
        !          110878:        return (omask);
        !          110879: }
        !          110880: 
        !          110881: /*
        !          110882:  * Unmount the given device.
        !          110883:  */
        !          110884: uumount(sp)
        !          110885: char *sp;
        !          110886: {
        !          110887:        register INODE *ip;
        !          110888:        register MOUNT *mp;
        !          110889:        register MOUNT **mpp;
        !          110890:        register dev_t rdev;
        !          110891:        register int mode;
        !          110892: 
        !          110893:        if (ftoi(sp, 'r') != 0)
        !          110894:                return;
        !          110895:        ip = u.u_cdiri;
        !          110896:        if (iaccess(ip, IPR|IPW) == 0) {
        !          110897:                idetach(ip);
        !          110898:                return;
        !          110899:        }
        !          110900:        rdev = ip->i_a.i_rdev;
        !          110901:        mode = ip->i_mode;
        !          110902:        idetach(ip);
        !          110903:        if ((mode&IFMT) != IFBLK) {
        !          110904:                u.u_error = ENOTBLK;
        !          110905:                return;
        !          110906:        }
        !          110907:        for (mpp=&mountp; (mp=*mpp)!=NULL; mpp=&mp->m_next)
        !          110908:                if (mp->m_dev == rdev)
        !          110909:                        break;
        !          110910:        if (mp == NULL) {
        !          110911:                u.u_error = EINVAL;
        !          110912:                return;
        !          110913:        }
        !          110914:        msync(mp);
        !          110915:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          110916:                if (ip->i_refc>0 && ip->i_dev==rdev) {
        !          110917:                        u.u_error = EBUSY;
        !          110918:                        return;
        !          110919:                }
        !          110920:        }
        !          110921:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          110922:                if (ip->i_dev == rdev)
        !          110923:                        ip->i_ino = 0;
        !          110924:        }
        !          110925:        bflush(rdev);
        !          110926:        dclose(rdev);
        !          110927:        *mpp = mp->m_next;
        !          110928:        mp->m_ip->i_flag &= ~IFMNT;
        !          110929:        ldetach(mp->m_ip);
        !          110930:        kfree(mp);
        !          110931:        return (0);
        !          110932: }
        !          110933: 
        !          110934: /*
        !          110935:  * Return an unique number.
        !          110936:  */
        !          110937: long
        !          110938: uunique()
        !          110939: {
        !          110940:        register MOUNT *mp;
        !          110941:        register struct filsys *fsp;
        !          110942: 
        !          110943:        if ((mp=getment(rootdev, 1)) == NULL)
        !          110944:                return;
        !          110945:        fsp = &mp->m_super;
        !          110946:        fsp->s_fmod = 1;
        !          110947:        return (++fsp->s_unique);
        !          110948: }
        !          110949: 
        !          110950: /*
        !          110951:  * Unlink the given file.
        !          110952:  */
        !          110953: uunlink(np)
        !          110954: char *np;
        !          110955: {
        !          110956:        register INODE *ip;
        !          110957:        register dev_t dev;
        !          110958: 
        !          110959:        if (ftoi(np, 'u') != 0)
        !          110960:                return;
        !          110961:        ip = u.u_pdiri;
        !          110962:        if (iaccess(ip, IPW) == 0) {
        !          110963:                u.u_error = EACCES;
        !          110964:                goto err;
        !          110965:        }
        !          110966:        dev = ip->i_dev;
        !          110967:        if (iucheck(dev, u.u_cdirn) == 0)
        !          110968:                goto err;
        !          110969:        idirent(0);
        !          110970:        idetach(ip);
        !          110971:        if ((ip=iattach(dev, u.u_cdirn)) == NULL)
        !          110972:                return;
        !          110973:        if (ip->i_nlink > 0)
        !          110974:                --ip->i_nlink;
        !          110975:        icrt(ip);       /* unlink - ctime */
        !          110976:        if ((ip->i_mode&IFMT)==IFPIPE && ip->i_nlink==0 && ip->i_refc==2)
        !          110977:                pevent(ip);
        !          110978: err:
        !          110979:        idetach(ip);
        !          110980:        return (0);
        !          110981: }
        !          110982: 
        !          110983: /*
        !          110984:  * Set file times.
        !          110985:  */
        !          110986: uutime(np, utime)
        !          110987: char *np;
        !          110988: time_t utime[2];
        !          110989: {
        !          110990:        register INODE *ip;
        !          110991:        time_t stime[2];
        !          110992: 
        !          110993:        if (ftoi(np, 'r') != 0)
        !          110994:                return;
        !          110995:        ip = u.u_cdiri;
        !          110996:        if (owner(ip->i_uid)) {
        !          110997:                iamc(ip);       /* utime - atime/mtime/ctime */
        !          110998:                if (utime != NULL) {
        !          110999:                        ukcopy(utime, stime, sizeof(time_t[2]));
        !          111000:                        ip->i_atime = stime[0];
        !          111001:                        ip->i_mtime = stime[1];
        !          111002:                }
        !          111003:        }
        !          111004:        idetach(ip);
        !          111005:        return (0);
        !          111006: }
        !          111007: 
        !          111008: /*
        !          111009:  * Write `n' bytes from buffer `bp' on file number `fd'.
        !          111010:  */
        !          111011: uwrite(fd, bp, n)
        !          111012: char *bp;
        !          111013: unsigned n;
        !          111014: {
        !          111015:        return (sysio(fd, bp, n, 1));
        !          111016: }
        !          111017: 
        !          111018: /**
        !          111019:  *
        !          111020:  * int
        !          111021:  * useracc( base, count, mode )        -- determine user accessibility
        !          111022:  * caddr_t base;
        !          111023:  * int count;
        !          111024:  * int mode;
        !          111025:  *
        !          111026:  *     Input:  base  = offset in user data space of the region to be accessed.
        !          111027:  *             count = size of access region in bytes.
        !          111028:  *             mode  = access mode desired [B_READ or B_WRITE].
        !          111029:  *
        !          111030:  *     Action: Verify user has desired access mode into specified region.
        !          111031:  *
        !          111032:  *     Return: 0 = permission denied.
        !          111033:  *             1 = access allowed.
        !          111034:  *
        !          111035:  *     Notes:  Mode is ignored for now, but is required for compatibility
        !          111036:  *             with System V, and future protected mode extensions.
        !          111037:  */
        !          111038: 
        !          111039: int
        !          111040: useracc( base, count, mode )
        !          111041: register char * base;
        !          111042: int count;
        !          111043: int mode;
        !          111044: {
        !          111045:        register char * end;
        !          111046:        extern char * udl;
        !          111047: 
        !          111048:        if ( (count == 0) && (base <= udl) )
        !          111049:                return( 1 );
        !          111050: 
        !          111051:        /*
        !          111052:         * Compute address of last byte to be accessed.
        !          111053:         */
        !          111054:        end = base + count - 1;
        !          111055: 
        !          111056:        /*
        !          111057:         * Address has wrapped, or is past legal limit.
        !          111058:         */
        !          111059:        if ( (end < base) || (end > udl) )
        !          111060:                return( 0 );
        !          111061: 
        !          111062:        return( 1 );
        !          111063: }
        !          111064: 
        !          111065: 
        !          111066: 0707070064030103161006440000030000030000011777770507310732000004500000006442/newbits/kernel/USRSRC/coh/timeout.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/timeout.c,v 1.4 91/07/24 07:52:49 bin Exp Locker: bin $ */
        !          111067: /* (lgl-
        !          111068:  *     The information contained herein is a trade secret of Mark Williams
        !          111069:  *     Company, and  is confidential information.  It is provided  under a
        !          111070:  *     license agreement,  and may be  copied or disclosed  only under the
        !          111071:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          111072:  *     material without the express written authorization of Mark Williams
        !          111073:  *     Company or persuant to the license agreement is unlawful.
        !          111074:  *
        !          111075:  *     COHERENT Version 2.3.37
        !          111076:  *     Copyright (c) 1982, 1983, 1984.
        !          111077:  *     An unpublished work by Mark Williams Company, Chicago.
        !          111078:  *     All rights reserved.
        !          111079:  -lgl) */
        !          111080: /*
        !          111081:  * Coherent.
        !          111082:  * Timeout management.
        !          111083:  *
        !          111084:  * $Log:       timeout.c,v $
        !          111085:  * Revision 1.4  91/07/24  07:52:49  bin
        !          111086:  * update prov by hal
        !          111087:  * 
        !          111088:  * 
        !          111089:  * Revision 1.2        89/08/01  13:56:42      src
        !          111090:  * Bug:        #include <timeout.h> not accurate; timeout.h now in /usr/include/sys.
        !          111091:  * Fix:        #include <sys/timeout.h> now used. (ABC)
        !          111092:  * 
        !          111093:  * Revision 1.1        88/03/24  08:14:38      src
        !          111094:  * Initial revision
        !          111095:  * 
        !          111096:  * 87/07/23    Allan Cornish           /usr/src/sys/coh/timeout.c
        !          111097:  * Timeout2 function now cancels timer if delay value is 0.
        !          111098:  *
        !          111099:  * 87/07/08    Allan Cornish           /usr/src/sys/coh/timeout.c
        !          111100:  * Timeout2 function added to support long timeouts.
        !          111101:  *
        !          111102:  * 87/07/07    Allan Cornish           /usr/src/sys/coh/timeout.c
        !          111103:  * Support for multiple timing queues ported from RTX.
        !          111104:  *
        !          111105:  * 86/11/24    Allan Cornish           /usr/src/sys/coh/timeout.c
        !          111106:  * Added support for new t_last field in tim struct.
        !          111107:  */
        !          111108: #include <sys/coherent.h>
        !          111109: #include <sys/timeout.h>
        !          111110: #include <sys/fun.h>
        !          111111: 
        !          111112: /*
        !          111113:  * Given a pointer to a timeout structure, `tp', call the function `f'
        !          111114:  * with integer argument `a' in `n' ticks of the clock. The list is
        !          111115:  * searched to see if the specified timeout structure is already in a
        !          111116:  * list, and it is removed if already there.
        !          111117:  */
        !          111118: timeout(tp, n, f, a)
        !          111119: register TIM *tp;
        !          111120: unsigned n;
        !          111121: int (*f)();
        !          111122: char *a;
        !          111123: {
        !          111124:        register TIM ** qp;
        !          111125:        int s;
        !          111126: 
        !          111127:        /*
        !          111128:         * Already on a timing queue.
        !          111129:         */
        !          111130:        s = sphi();
        !          111131:        if ( qp = tp->t_last ) {
        !          111132:                tp->t_last = NULL;
        !          111133:                if ( *qp = tp->t_next )
        !          111134:                        tp->t_next->t_last = qp;
        !          111135:        }
        !          111136:        spl( s );
        !          111137: 
        !          111138:        if ( f == NULL )
        !          111139:                return;
        !          111140: 
        !          111141:        /*
        !          111142:         * Calculate clock tick at which timeout is to occur.
        !          111143:         * Record function and argument to be invoked upon timeout.
        !          111144:         */
        !          111145:        tp->t_lbolt = lbolt + n;
        !          111146:        tp->t_func  = f;
        !          111147:        tp->t_farg  = a;
        !          111148: 
        !          111149:        /*
        !          111150:         * Identify timeout queue.
        !          111151:         */
        !          111152:        qp = &timq[ tp->t_lbolt % nel(timq) ];
        !          111153: 
        !          111154:        /*
        !          111155:         * Insert at head of timeout queue.
        !          111156:         */
        !          111157:        s = sphi();
        !          111158:        if ( tp->t_next = *qp )
        !          111159:                tp->t_next->t_last = tp;
        !          111160:        tp->t_last = qp;
        !          111161:        *qp = tp;
        !          111162:        spl(s);
        !          111163: }
        !          111164: 
        !          111165: timeout2(tp, n, f, a)
        !          111166: register TIM *tp;
        !          111167: long n;
        !          111168: int (*f)();
        !          111169: char *a;
        !          111170: {
        !          111171:        register TIM ** qp;
        !          111172:        int s;
        !          111173: 
        !          111174:        /*
        !          111175:         * Already on a timing queue.
        !          111176:         */
        !          111177:        s = sphi();
        !          111178:        if ( qp = tp->t_last ) {
        !          111179:                tp->t_last = NULL;
        !          111180:                if ( *qp = tp->t_next )
        !          111181:                        tp->t_next->t_last = qp;
        !          111182:        }
        !          111183:        spl( s );
        !          111184: 
        !          111185:        /*
        !          111186:         * Do not schedule new timer if no function or delay interval.
        !          111187:         */
        !          111188:        if ( (f == NULL) || (n == 0) )
        !          111189:                return;
        !          111190: 
        !          111191:        /*
        !          111192:         * Calculate clock tick at which timeout is to occur.
        !          111193:         * Record function and argument to be invoked upon timeout.
        !          111194:         */
        !          111195:        tp->t_lbolt = lbolt + n;
        !          111196:        tp->t_func  = f;
        !          111197:        tp->t_farg  = a;
        !          111198: 
        !          111199:        /*
        !          111200:         * Identify timeout queue.
        !          111201:         */
        !          111202:        qp = &timq[ tp->t_lbolt % nel(timq) ];
        !          111203: 
        !          111204:        /*
        !          111205:         * Insert at head of timeout queue.
        !          111206:         */
        !          111207:        s = sphi();
        !          111208:        if ( tp->t_next = *qp )
        !          111209:                tp->t_next->t_last = tp;
        !          111210:        tp->t_last = qp;
        !          111211:        *qp = tp;
        !          111212:        spl(s);
        !          111213: }
        !          111214: 0707070064030103151006440000030000030000011777770507310732100004100000007544/newbits/kernel/USRSRC/coh/var.c/* $Header: /newbits/kernel/USRSRC/coh/RCS/var.c,v 1.4 91/07/24 07:52:52 bin Exp Locker: bin $ */
        !          111215: /* (lgl-
        !          111216:  *     The information contained herein is a trade secret of Mark Williams
        !          111217:  *     Company, and  is confidential information.  It is provided  under a
        !          111218:  *     license agreement,  and may be  copied or disclosed  only under the
        !          111219:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          111220:  *     material without the express written authorization of Mark Williams
        !          111221:  *     Company or persuant to the license agreement is unlawful.
        !          111222:  *
        !          111223:  *     COHERENT Version 2.3.37
        !          111224:  *     Copyright (c) 1982, 1983, 1984.
        !          111225:  *     An unpublished work by Mark Williams Company, Chicago.
        !          111226:  *     All rights reserved.
        !          111227:  -lgl) */
        !          111228: /*
        !          111229:  * Coherent.
        !          111230:  * Variables.
        !          111231:  *
        !          111232:  * $Log:       var.c,v $
        !          111233:  * Revision 1.4  91/07/24  07:52:52  bin
        !          111234:  * update prov by hal
        !          111235:  * 
        !          111236:  * 
        !          111237:  * Revision 1.2        89/08/01  13:57:35      src
        !          111238:  * Bug:        #include <timeout.h> not accurate; timeout.h now in /usr/include/sys.
        !          111239:  * Fix:        #include <sys/timeout.h> now used. (ABC)
        !          111240:  * 
        !          111241:  * Revision 1.1        88/03/24  08:14:41      src
        !          111242:  * Initial revision
        !          111243:  * 
        !          111244:  * 88/01/23    Allan Cornish           /usr/src/sys/coh/var.c
        !          111245:  * Default NSLOT increased from 10 to 64.
        !          111246:  *
        !          111247:  * 87/11/22    Allan Cornish           /usr/src/sys/coh/var.c
        !          111248:  * Holebot/holetop variables added to support extended memory.
        !          111249:  *
        !          111250:  * 87/11/14    Allan Cornish           /usr/src/sys/coh/var.c
        !          111251:  * Init code+data now split into icodep/icodes and idatap/idatas.
        !          111252:  *
        !          111253:  * 87/11/12    Allan Cornish           /usr/src/sys/coh/var.c
        !          111254:  * Corebot/coretop now paddr_t rather than saddr_t to support protected mode.
        !          111255:  *
        !          111256:  * 87/10/05    Allan Cornish           /usrs/rc/sys/coh/var.c
        !          111257:  * NSLOT, slotsz, and slotp variables added - loadable driver specific.
        !          111258:  *
        !          111259:  * 87/07/07    Allan Cornish           /usr/src/sys/coh/var.c
        !          111260:  * Lbolt variable added - clock ticks since startup - incremented by stand().
        !          111261:  * Timl variable replaced with timq variable.
        !          111262:  *
        !          111263:  * 87/02/01    Allan Cornish           /usr/src/sys/coh/var.c
        !          111264:  * ISTSIZE [stack size] changed from a define in /usr/include/sys/const.h to a
        !          111265:  * extern int in /usr/include/sys/param.h, with 4 Kbyte default set in var.c
        !          111266:  */
        !          111267: #include <sys/coherent.h>
        !          111268: #include <sys/buf.h>
        !          111269: #include <sys/con.h>
        !          111270: #include <sys/inode.h>
        !          111271: #include <sys/mount.h>
        !          111272: #include <sys/proc.h>
        !          111273: #include <sys/ptrace.h>
        !          111274: #include <sys/seg.h>
        !          111275: 
        !          111276: int     debflag = 0;                   /* coherent.h */
        !          111277: 
        !          111278: int     batflag;                       /* coherent.h */
        !          111279: int     outflag;                       /* coherent.h */
        !          111280: int     ttyflag;                       /* coherent.h */
        !          111281: unsigned utimer;                       /* coherent.h */
        !          111282: long    lbolt;                         /* coherent.h */
        !          111283: TIM    stimer;                         /* coherent.h */
        !          111284: unsigned msize;                                /* coherent.h */
        !          111285: unsigned asize;                                /* coherent.h */
        !          111286: char    *icodep;                       /* coherent.h */
        !          111287: int     icodes;                        /* coherent.h */
        !          111288: char    *idatap;                       /* coherent.h */
        !          111289: int     idatas;                        /* coherent.h */
        !          111290: paddr_t         corebot;                       /* coherent.h */
        !          111291: paddr_t         coretop;                       /* coherent.h */
        !          111292: paddr_t         holebot;                       /* coherent.h */
        !          111293: paddr_t         holetop;                       /* coherent.h */
        !          111294: paddr_t         blockp;                        /* coherent.h */
        !          111295: paddr_t         clistp;                        /* coherent.h */
        !          111296: struct  all *allkp;                    /* coherent.h */
        !          111297: int    NSLOT   = 64;                   /* coherent.h */
        !          111298: int    slotsz  = 64;                   /* coherent.h */
        !          111299: int *  slotp;                          /* coherent.h */
        !          111300: 
        !          111301: unsigned bufseqn;                      /* buf.h */
        !          111302: int     bufneed;                       /* buf.h */
        !          111303: BUF     swapbuf;                       /* buf.h */
        !          111304: BUF    *bufl;                          /* buf.h */
        !          111305: 
        !          111306: int    cltwant;                        /* clist.h */
        !          111307: cmap_t cltfree;                        /* clist.h */
        !          111308: 
        !          111309: INODE  *inodep;                        /* inode.h */
        !          111310: INODE  *acctip;                        /* inode.h */
        !          111311: 
        !          111312: MOUNT  *mountp;                        /* mount.h */
        !          111313: 
        !          111314: int    ISTSIZE = 4096;                 /* sys/param.h */
        !          111315: 
        !          111316: int    quantum;                        /* proc.h */
        !          111317: int    disflag;                        /* proc.h */
        !          111318: int    intflag;                        /* proc.h */
        !          111319: int    cpid;                           /* proc.h */
        !          111320: #ifdef QWAKEUP
        !          111321: int    ntowake;                        /* proc.h */
        !          111322: #endif
        !          111323: GATE   pnxgate;                        /* proc.h */
        !          111324: PROC   procq;                          /* proc.h */
        !          111325: PROC   *iprocp;                        /* proc.h */
        !          111326: PROC   *eprocp;                        /* proc.h */
        !          111327: PROC   *cprocp;                        /* proc.h */
        !          111328: PLINK  linkq[NHPLINK];                 /* proc.h */
        !          111329: 
        !          111330: struct ptrace pts;                     /* ptrace.h */
        !          111331: 
        !          111332: int    sexflag;                        /* seg.h */
        !          111333: GATE   seglink;                        /* seg.h */
        !          111334: #ifndef NOMONITOR
        !          111335: int    swmflag;                        /* seg.h */
        !          111336: #endif
        !          111337: SEG    segswap;                        /* seg.h */
        !          111338: SEG    segmq;                          /* seg.h */
        !          111339: SEG    segdq;                          /* seg.h */
        !          111340: SEG    segiom;                         /* seg.h */
        !          111341: 
        !          111342: TIM *  timq[256];                      /* timeout.h */
        !          111343: 0707070064030053140407550000030000030000011777770507310732200003700000000000/newbits/kernel/USRSRC/coh/RCS0707070064030053051004440000030000030000011777770507310732200004700000035353/newbits/kernel/USRSRC/coh/RCS/fs1.c,vhead     1.5;
        !          111344: branch   ;
        !          111345: access   ;
        !          111346: symbols  ;
        !          111347: locks    bin:1.5;
        !          111348: comment  @ * @;
        !          111349: 
        !          111350: 
        !          111351: 1.5
        !          111352: date     91.07.24.07.50.40;  author bin;  state Exp;
        !          111353: branches ;
        !          111354: next     1.4;
        !          111355: 
        !          111356: 1.4
        !          111357: date     91.07.15.14.32.16;  author bin;  state Exp;
        !          111358: branches ;
        !          111359: next     1.3;
        !          111360: 
        !          111361: 1.3
        !          111362: date     91.06.20.14.30.01;  author bin;  state Exp;
        !          111363: branches ;
        !          111364: next     1.2;
        !          111365: 
        !          111366: 1.2
        !          111367: date     91.06.10.14.37.05;  author bin;  state Exp;
        !          111368: branches ;
        !          111369: next     1.1;
        !          111370: 
        !          111371: 1.1
        !          111372: date     91.04.12.14.02.18;  author root;  state Exp;
        !          111373: branches ;
        !          111374: next     ;
        !          111375: 
        !          111376: 
        !          111377: desc
        !          111378: @Part of kernel file system.
        !          111379: @
        !          111380: 
        !          111381: 
        !          111382: 1.5
        !          111383: log
        !          111384: @update prov by hal
        !          111385: 
        !          111386: @
        !          111387: text
        !          111388: @/* $Header: /usr/src/sys/coh/RCS/fs1.c,v 1.1 88/03/24 16:13:47 src Exp $ */
        !          111389: /* (lgl-
        !          111390:  *     The information contained herein is a trade secret of Mark Williams
        !          111391:  *     Company, and  is confidential information.  It is provided  under a
        !          111392:  *     license agreement,  and may be  copied or disclosed  only under the
        !          111393:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          111394:  *     material without the express written authorization of Mark Williams
        !          111395:  *     Company or persuant to the license agreement is unlawful.
        !          111396:  *
        !          111397:  *     COHERENT Version 2.3.37
        !          111398:  *     Copyright (c) 1982, 1983, 1984.
        !          111399:  *     An unpublished work by Mark Williams Company, Chicago.
        !          111400:  *     All rights reserved.
        !          111401:  -lgl) */
        !          111402: /*
        !          111403:  * Coherent.
        !          111404:  * Filesystem (mostly handling of in core inodes).
        !          111405:  *
        !          111406:  * $Log:       /usr/src/sys/coh/RCS/fs1.c,v $
        !          111407:  * Revision 1.1        88/03/24  16:13:47      src
        !          111408:  * Initial revision
        !          111409:  * 
        !          111410:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/fs1.c
        !          111411:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          111412:  *
        !          111413:  * 86/12/13    Allan Cornish           /usr/src/sys/coh/fs1.c
        !          111414:  * isync() no longer updates the disk image of a character device inode.
        !          111415:  *
        !          111416:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/fs1.c
        !          111417:  * idirent() initializes the (new) (IO).io_flag field to 0.
        !          111418:  */
        !          111419: #include <sys/coherent.h>
        !          111420: #include <sys/buf.h>
        !          111421: #include <canon.h>
        !          111422: #include <sys/dir.h>
        !          111423: #include <errno.h>
        !          111424: #include <sys/filsys.h>
        !          111425: #include <sys/ino.h>
        !          111426: #include <sys/inode.h>
        !          111427: #include <sys/io.h>
        !          111428: #include <sys/mount.h>>
        !          111429: #include <sys/stat.h>
        !          111430: #include <sys/uproc.h>
        !          111431: 
        !          111432: /*
        !          111433:  * Get character for `ftoi' depending on what space the characters are
        !          111434:  * coming from.
        !          111435:  */
        !          111436: #define ftoic(p)       (u.u_io.io_seg==IOSYS ? *p : getubd(p))
        !          111437: 
        !          111438: /*
        !          111439:  * Map the given filename to an inode.  If an error is encountered,
        !          111440:  * `u.u_error' is set.  `u.u_error' is always returned.  As this routine
        !          111441:  * needs to set several things, depending on the type of access, `t',
        !          111442:  * there are places in the processes' user area reserved for this routine
        !          111443:  * to set.  These are defined in the user process structure.  The seek
        !          111444:  * position is always set to the position of the directory entry of the
        !          111445:  * child if the child exists or the first free position if it doesn't.
        !          111446:  *  'r' =>  Reference.  A pointer to the child's inode is returned locked.
        !          111447:  *  'c' =>  Create.  If the child exists, a pointer to the inode is returned
        !          111448:  *          locked.  Otherwise if the parent directory exists, a pointer to
        !          111449:  *          the parent directory is returned locked.  Otherwise, an error.
        !          111450:  *  'u' =>  Unlink.  The parent directory is returned unlocked.  The child's
        !          111451:  *          inode number is returned.  The seek position is also set.
        !          111452:  */
        !          111453: ftoi(np, t)
        !          111454: char *np;
        !          111455: {
        !          111456:        register INODE *cip;
        !          111457:        register char *cp;
        !          111458:        register int c;
        !          111459:        register struct direct *dp;
        !          111460:        register BUF *bp;
        !          111461:        fsize_t cseek, fseek, s;
        !          111462:        int fflag, mflag;
        !          111463:        dev_t dev;
        !          111464:        ino_t ino;
        !          111465:        daddr_t b;
        !          111466: 
        !          111467:        u.u_cdirn = 0;
        !          111468:        u.u_cdiri = NULL;
        !          111469:        u.u_pdiri = NULL;
        !          111470:        if ((c=ftoic(np++)) != '/')
        !          111471:                cip = u.u_cdir;
        !          111472:        else {
        !          111473:                c = ftoic(np++);
        !          111474:                cip = u.u_rdir;
        !          111475:        }
        !          111476:        while (c == '/')
        !          111477:                c = ftoic(np++);
        !          111478:        ilock(cip);
        !          111479:        cip->i_refc++;
        !          111480:        if (c == '\0') {
        !          111481:                if (t == 'r') {
        !          111482:                        u.u_cdiri = cip;
        !          111483:                        return (u.u_error);
        !          111484:                }
        !          111485:                u.u_error = ENOENT;
        !          111486:                idetach(cip);
        !          111487:                return (u.u_error);
        !          111488:        }
        !          111489:        for (;;) {
        !          111490:                cp = u.u_direct.d_name;
        !          111491:                while (c!='/' && c!='\0') {
        !          111492:                        if (cp < &u.u_direct.d_name[DIRSIZ])
        !          111493:                                *cp++ = c;
        !          111494:                        c = ftoic(np++);
        !          111495:                }
        !          111496:                while (c == '/')
        !          111497:                        c = ftoic(np++);
        !          111498:                while (cp < &u.u_direct.d_name[DIRSIZ])
        !          111499:                        *cp++ = '\0';
        !          111500:                if ((cip->i_mode&IFMT) != IFDIR)
        !          111501:                        u.u_error = ENOTDIR;
        !          111502:                else
        !          111503:                        iaccess(cip, IPE);
        !          111504:                if (u.u_error) {
        !          111505:                        idetach(cip);
        !          111506:                        return (u.u_error);
        !          111507:                }
        !          111508:                cp = u.u_direct.d_name;
        !          111509:                if (cip->i_ino==ROOTIN && cip->i_dev!=rootdev)
        !          111510:                        if (*cp++=='.' && *cp++=='.' && *cp++=='\0')
        !          111511:                                cip = ftoim(cip);
        !          111512:                b = 0;
        !          111513:                fflag = 0;
        !          111514:                mflag = 0;
        !          111515:                cseek = 0;
        !          111516:                s = cip->i_size;
        !          111517:                while (s > 0) {
        !          111518:                        if ((bp=vread(cip, b++)) == NULL) {
        !          111519:                                idetach(cip);
        !          111520:                                return (u.u_error);
        !          111521:                        }
        !          111522:                        dp = FP_OFF(bp->b_faddr);
        !          111523:                        while (dp < FP_OFF(bp->b_faddr)+BSIZE) {
        !          111524:                                if ((s-=sizeof(*dp)) < 0)
        !          111525:                                        break;
        !          111526:                                if ((ino=dp->d_ino) == 0) {
        !          111527:                                        if (fflag == 0) {
        !          111528:                                                fflag++;
        !          111529:                                                fseek = cseek;
        !          111530:                                        }
        !          111531:                                } else {
        !          111532:                                        if (direq(dp)) {
        !          111533:                                                canino(ino);
        !          111534:                                                mflag = 1;
        !          111535:                                                s = 0;
        !          111536:                                                break;
        !          111537:                                        }
        !          111538:                                }
        !          111539:                                cseek += sizeof(*dp);
        !          111540:                                dp++;
        !          111541:                        }
        !          111542:                        brelease(bp);
        !          111543:                }
        !          111544:                dev = cip->i_dev;
        !          111545:                if (fflag == 0)
        !          111546:                        fseek = cseek;
        !          111547:                if (mflag == 0) {
        !          111548:                        if (c=='\0' && t=='c') {
        !          111549:                                u.u_pdiri = cip;
        !          111550:                                u.u_io.io_seek = fseek;
        !          111551:                        } else {
        !          111552:                                u.u_error = ENOENT;
        !          111553:                                idetach(cip);
        !          111554:                        }
        !          111555:                        return (u.u_error);
        !          111556:                }
        !          111557:                if (c == '\0') {
        !          111558:                        if (t == 'u') {
        !          111559:                                u.u_cdirn = ino;
        !          111560:                                u.u_pdiri = cip;
        !          111561:                                u.u_io.io_seek = cseek;
        !          111562:                                return (u.u_error);
        !          111563:                        }
        !          111564:                        idetach(cip);
        !          111565:                        u.u_cdiri = iattach(dev, ino);
        !          111566:                        return (u.u_error);
        !          111567:                }
        !          111568:                idetach(cip);
        !          111569:                if ((cip=iattach(dev, ino)) == NULL)
        !          111570:                        return (u.u_error);
        !          111571:        }
        !          111572: }
        !          111573: 
        !          111574: /*
        !          111575:  * Given an inode which is the root of a file system, return the inode
        !          111576:  * on which the file system was mounted.
        !          111577:  */
        !          111578: INODE *
        !          111579: ftoim(ip)
        !          111580: register INODE *ip;
        !          111581: {
        !          111582:        register MOUNT *mp;
        !          111583: 
        !          111584:        for (mp=mountp; mp!=NULL; mp=mp->m_next) {
        !          111585:                if (mp->m_dev == ip->i_dev) {
        !          111586:                        idetach(ip);
        !          111587:                        ip = mp->m_ip;
        !          111588:                        ilock(ip);
        !          111589:                        ip->i_refc++;
        !          111590:                        break;
        !          111591:                }
        !          111592:        }
        !          111593:        return (ip);
        !          111594: }
        !          111595: 
        !          111596: /*
        !          111597:  * Compare the string in `u.u_direct.d_name' with the name in the
        !          111598:  * given directory pointer.
        !          111599:  */
        !          111600: direq(dp)
        !          111601: struct direct *dp;
        !          111602: {
        !          111603:        register char *cp1, *cp2;
        !          111604:        register unsigned n;
        !          111605: 
        !          111606:        if (dp->d_ino == 0)
        !          111607:                return (0);
        !          111608:        cp1 = dp->d_name;
        !          111609:        cp2 = u.u_direct.d_name;
        !          111610:        n = DIRSIZ;
        !          111611:        do {
        !          111612:                if (*cp1++ != *cp2++)
        !          111613:                        return (0);
        !          111614:        } while (--n);
        !          111615:        return (1);
        !          111616: }
        !          111617: 
        !          111618: /*
        !          111619:  * Make an inode of the given mode and device.  The parent directory,
        !          111620:  * name and such stuff is set by ftoi.
        !          111621:  */
        !          111622: INODE *
        !          111623: imake(mode, rdev)
        !          111624: unsigned mode;
        !          111625: dev_t rdev;
        !          111626: {
        !          111627:        register INODE *ip;
        !          111628: 
        !          111629:        ip = NULL;
        !          111630:        mode &= ~u.u_umask;
        !          111631:        if ((mode&ISVTXT)!=0 && super()==0)
        !          111632:                goto det;
        !          111633:        if (iaccess(u.u_pdiri, IPW) == 0)
        !          111634:                goto det;
        !          111635:        if ((ip=ialloc(u.u_pdiri->i_dev, mode)) == NULL)
        !          111636:                goto det;
        !          111637:        ip->i_nlink = 1;
        !          111638:        ip->i_a.i_rdev = rdev;
        !          111639:        idirent(ip->i_ino);
        !          111640:        iamc(ip);       /* creat/mknod - atime/mtime/ctime */
        !          111641: det:
        !          111642:        idetach(u.u_pdiri);
        !          111643:        return (ip);
        !          111644: }
        !          111645: 
        !          111646: /*
        !          111647:  * Write a directory entry out.  Everything necessary has been conveniently
        !          111648:  * set by `ftoi', except the new inode number of this directory entry.
        !          111649:  */
        !          111650: idirent(ino)
        !          111651: {
        !          111652:        u.u_direct.d_ino = ino;
        !          111653:        canino(u.u_direct.d_ino);
        !          111654:        u.u_io.io_ioc  = sizeof (struct direct);
        !          111655:        u.u_io.io_base = &u.u_direct;
        !          111656:        u.u_io.io_seg  = IOSYS;
        !          111657:        u.u_io.io_flag = 0;
        !          111658:        iwrite(u.u_pdiri, &u.u_io);
        !          111659: }
        !          111660: 
        !          111661: /*
        !          111662:  * Return a pointer to a locked inode in core containing the given
        !          111663:  * inode number and device.
        !          111664:  */
        !          111665: INODE *
        !          111666: iattach(dev, ino)
        !          111667: {
        !          111668:        register INODE *ip;
        !          111669:        register INODE *fip;
        !          111670:        register unsigned lrt;
        !          111671:        register MOUNT *mp;
        !          111672: 
        !          111673:        for (;;) {
        !          111674:                fip = NULL;
        !          111675:                for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          111676:                        if (ip->i_ino==ino && ip->i_dev==dev)
        !          111677:                                break;
        !          111678:                        if (ip->i_refc == 0) {
        !          111679:                                if (fip==NULL || ip->i_lrt<lrt) {
        !          111680:                                        fip = ip;
        !          111681:                                        lrt = ip->i_lrt;
        !          111682:                                }
        !          111683:                        }
        !          111684:                }
        !          111685:                if (ip < inodep) {
        !          111686:                        if ((ip=fip) == NULL) {
        !          111687:                                devmsg(dev, "Inode table overflow");
        !          111688: /*DEBUG*/
        !          111689: { char cmd[11];int i;
        !          111690: for(i=0;i<10&&u.u_comm[i];i++)
        !          111691:     cmd[i]=u.u_comm[i];
        !          111692: cmd[i]='\0';
        !          111693: printf("cmd=%s time=%lu\n",cmd, u.u_btime);
        !          111694: }
        !          111695:                                u.u_error = ENFILE;
        !          111696:                                return (NULL);
        !          111697:                        }
        !          111698:                        ilock(ip);
        !          111699:                        if (ip->i_refc != 0) {
        !          111700:                                iunlock(ip);
        !          111701:                                continue;
        !          111702:                        }
        !          111703:                        ip->i_dev = dev;
        !          111704:                        ip->i_ino = ino;
        !          111705:                        ip->i_refc = 1;
        !          111706:                        ip->i_lrt = timer.t_time;
        !          111707:                        if (icopydm(ip) == 0) {
        !          111708:                                ip->i_ino = 0;
        !          111709:                                ip->i_refc = 0;
        !          111710:                                iunlock(ip);
        !          111711:                                return (NULL);
        !          111712:                        }
        !          111713:                        return (ip);
        !          111714:                }
        !          111715:                if ((ip->i_flag&IFMNT) != 0) {
        !          111716:                        for (mp=mountp; mp!=NULL; mp=mp->m_next) {
        !          111717:                                if (mp->m_ip == ip) {
        !          111718:                                        ino = ROOTIN;
        !          111719:                                        dev = mp->m_dev;
        !          111720:                                        break;
        !          111721:                                }
        !          111722:                        }
        !          111723:                        continue;
        !          111724:                }
        !          111725:                ilock(ip);
        !          111726:                if (ip->i_ino!=ino || ip->i_dev!=dev) {
        !          111727:                        iunlock(ip);
        !          111728:                        continue;
        !          111729:                }
        !          111730:                if (ip->i_refc < 0)
        !          111731:                        panic("ialloc(%p), ip");
        !          111732:                ip->i_refc++;
        !          111733:                ip->i_lrt = timer.t_time;
        !          111734:                return (ip);
        !          111735:        }
        !          111736: }
        !          111737: 
        !          111738: /*
        !          111739:  * Given a locked inode, deaccess it.
        !          111740:  */
        !          111741: idetach(ip)
        !          111742: register INODE *ip;
        !          111743: {
        !          111744:        if (ilocked(ip)==0 || ip->i_refc<=0)
        !          111745:                panic("idetach(%p)", ip);
        !          111746:        if (--ip->i_refc == 0) {
        !          111747:                if ((ip->i_flag&(IFACC|IFMOD|IFCRT)) != 0
        !          111748:                 || ip->i_nlink == 0)
        !          111749:                        icopymd(ip);
        !          111750:        }
        !          111751:        iunlock(ip);
        !          111752: }
        !          111753: 
        !          111754: /*
        !          111755:  * Given a inode which isn't locked, lock it and then deaccess.
        !          111756:  */
        !          111757: ldetach(ip)
        !          111758: register INODE *ip;
        !          111759: {
        !          111760:        ilock(ip);
        !          111761:        idetach(ip);
        !          111762: }
        !          111763: 
        !          111764: /*
        !          111765:  * A specialized routine for finding whether the given inode may be unlinked.
        !          111766:  * Quite simple you say, but we already have an inode locked and could run
        !          111767:  * into gating problems if we were to lock another.  So we look through the
        !          111768:  * cache to see if the inode is there.  If it is, we can easily tell.  If it
        !          111769:  * isn't, `icopydm' is called with a static.  This routine is only used by
        !          111770:  * `uunlink'.
        !          111771:  */
        !          111772: iucheck(dev, ino)
        !          111773: register dev_t dev;
        !          111774: register ino_t ino;
        !          111775: {
        !          111776:        register INODE *ip;
        !          111777:        INODE inode;
        !          111778: 
        !          111779:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          111780:                if (ip->i_ino==ino && ip->i_dev==dev)
        !          111781:                        break;
        !          111782:        }
        !          111783:        if (ip < inodep) {
        !          111784:                ip = &inode;
        !          111785:                ip->i_dev = dev;
        !          111786:                ip->i_ino = ino;
        !          111787:                if (icopydm(ip) == 0)
        !          111788:                        return (0);
        !          111789:        }
        !          111790:        if ((ip->i_mode&IFMT) == IFDIR) {
        !          111791:                if (super() == 0)
        !          111792:                        return (0);
        !          111793:        }
        !          111794:        return (1);
        !          111795: }
        !          111796: 
        !          111797: /*
        !          111798:  * Copy an inode from disk to memory performing canonization.
        !          111799:  */
        !          111800: icopydm(ip)
        !          111801: register INODE *ip;
        !          111802: {
        !          111803:        register struct dinode *dip;
        !          111804:        register BUF *bp;
        !          111805:        register ino_t ino;
        !          111806:        struct dinode dinode;
        !          111807:        vaddr_t v;
        !          111808: 
        !          111809:        ip->i_flag = 0;
        !          111810:        ino = ip->i_ino;
        !          111811: 
        !          111812:        if ((bp=bread(ip->i_dev, (daddr_t)iblockn(ino), 1)) == NULL)
        !          111813:                return (0);
        !          111814: 
        !          111815:        dip = &dinode;
        !          111816:        v = (char *)((struct dinode *)FP_OFF(bp->b_faddr) + iblocko(ino));
        !          111817:        kkcopy( v, dip, sizeof(dinode));
        !          111818:        brelease(bp);
        !          111819:        ip->i_mode = dip->di_mode;
        !          111820:        canshort(ip->i_mode);
        !          111821:        ip->i_nlink = dip->di_nlink;
        !          111822:        canshort(ip->i_nlink);
        !          111823:        ip->i_uid = dip->di_uid;
        !          111824:        canshort(ip->i_uid);
        !          111825:        ip->i_gid = dip->di_gid;
        !          111826:        canshort(ip->i_gid);
        !          111827:        ip->i_size = dip->di_size;
        !          111828:        cansize(ip->i_size);
        !          111829: 
        !          111830:        switch (ip->i_mode&IFMT) {
        !          111831:        case IFBLK:
        !          111832:        case IFCHR:
        !          111833:                ip->i_a.i_rdev = dip->di_a.di_rdev;
        !          111834:                candev(ip->i_a.i_rdev);
        !          111835:                break;
        !          111836:        case IFREG:
        !          111837:        case IFDIR:
        !          111838:                l3tol(ip->i_a.i_addr, dip->di_a.di_addb, NADDR);
        !          111839:                break;
        !          111840:        case IFPIPE:
        !          111841:                l3tol(ip->i_pipe, dip->di_addp, ND);
        !          111842:                ip->i_pnc = dip->di_pnc;
        !          111843:                canint(ip->i_pnc);
        !          111844:                ip->i_prx = dip->di_prx;
        !          111845:                canint(ip->i_prx);
        !          111846:                ip->i_pwx = dip->di_pwx;
        !          111847:                canint(ip->i_pwx);
        !          111848:                break;
        !          111849:        default:
        !          111850:                kclear(&ip->i_a, sizeof(ip->i_a));
        !          111851:                break;
        !          111852:        }
        !          111853: 
        !          111854:        ip->i_atime = dip->di_atime;
        !          111855:        cantime(ip->i_atime);
        !          111856:        ip->i_mtime = dip->di_mtime;
        !          111857:        cantime(ip->i_mtime);
        !          111858:        ip->i_ctime = dip->di_ctime;
        !          111859:        cantime(ip->i_ctime);
        !          111860:        return (1);
        !          111861: }
        !          111862: 
        !          111863: /*
        !          111864:  * Copy an inode from memory back on to disk performing canonization.
        !          111865:  */
        !          111866: icopymd(ip)
        !          111867: register INODE *ip;
        !          111868: {
        !          111869:        register struct dinode *dip;
        !          111870:        register BUF *bp;
        !          111871:        register ino_t ino;
        !          111872:        struct dinode dinode;
        !          111873:        vaddr_t v;
        !          111874: 
        !          111875:        if (getment(ip->i_dev, 0) == NULL)
        !          111876:                return;
        !          111877: 
        !          111878:        ino = ip->i_ino;
        !          111879:        if (ip->i_refc==0 && ip->i_nlink==0 && ino!=BADFIN && ino!=ROOTIN) {
        !          111880:                iclear(ip);
        !          111881:                ip->i_lrt = 0;
        !          111882:                ip->i_mode = 0;
        !          111883:                ifree(ip->i_dev, ino);
        !          111884:        }
        !          111885: 
        !          111886:        dip = &dinode;
        !          111887:        dip->di_mode = ip->i_mode;
        !          111888:        canshort(dip->di_mode);
        !          111889:        dip->di_nlink = ip->i_nlink;
        !          111890:        canshort(dip->di_nlink);
        !          111891:        dip->di_uid = ip->i_uid;
        !          111892:        canshort(dip->di_uid);
        !          111893:        dip->di_gid = ip->i_gid;
        !          111894:        canshort(dip->di_gid);
        !          111895:        dip->di_size = ip->i_size;
        !          111896:        cansize(dip->di_size);
        !          111897: 
        !          111898:        switch (ip->i_mode&IFMT) {
        !          111899:        case IFBLK:
        !          111900:        case IFCHR:
        !          111901:                dip->di_a.di_rdev = ip->i_a.i_rdev;
        !          111902:                candev(dip->di_a.di_rdev);
        !          111903:                break;
        !          111904:        case IFREG:
        !          111905:        case IFDIR:
        !          111906:                ltol3(dip->di_addr, ip->i_a.i_addr, NADDR);
        !          111907:                break;
        !          111908:        case IFPIPE:
        !          111909:                ltol3(dip->di_addp, ip->i_pipe, ND);
        !          111910:                dip->di_pnc = ip->i_pnc;
        !          111911:                canshort(dip->di_pnc);
        !          111912:                dip->di_prx = ip->i_prx;
        !          111913:                canshort(dip->di_prx);
        !          111914:                dip->di_pwx = ip->i_pwx;
        !          111915:                canshort(dip->di_pwx);
        !          111916:                break;
        !          111917:        default:
        !          111918:                kclear(&dip->di_a, sizeof(dip->di_a));
        !          111919:                break;
        !          111920:        }
        !          111921: 
        !          111922:        dip->di_atime = ip->i_atime;
        !          111923:        cantime(dip->di_atime);
        !          111924:        dip->di_mtime = ip->i_mtime;
        !          111925:        cantime(dip->di_mtime);
        !          111926:        dip->di_ctime = ip->i_ctime;
        !          111927:        cantime(dip->di_ctime);
        !          111928: 
        !          111929:        if ((bp=bread(ip->i_dev, (daddr_t)iblockn(ino), 1)) == NULL)
        !          111930:                return;
        !          111931: 
        !          111932:        v = (char *)((struct dinode *)FP_OFF(bp->b_faddr) + iblocko(ino));
        !          111933:        kkcopy(dip, v, sizeof(dinode));
        !          111934:        bp->b_flag |= BFMOD;
        !          111935:        brelease(bp);
        !          111936:        ip->i_flag &= ~(IFACC|IFMOD|IFCRT);
        !          111937: }
        !          111938: 
        !          111939: /*
        !          111940:  * Copy all relevant inodes out on device `dev'.
        !          111941:  */
        !          111942: isync(dev)
        !          111943: register dev_t dev;
        !          111944: {
        !          111945:        register INODE *ip;
        !          111946: 
        !          111947:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          111948:                if (ip->i_refc == 0)
        !          111949:                        continue;
        !          111950:                if (ip->i_dev != dev)
        !          111951:                        continue;
        !          111952:                if ( (ip->i_mode & IFMT) == IFCHR )
        !          111953:                        continue;
        !          111954:                if ((ip->i_flag&(IFACC|IFMOD|IFCRT)) == 0)
        !          111955:                        continue;
        !          111956:                icopymd(ip);
        !          111957:        }
        !          111958: }
        !          111959: 
        !          111960: /*
        !          111961:  * Clear the given inode and all space associated with it.
        !          111962:  */
        !          111963: iclear(ip)
        !          111964: register INODE *ip;
        !          111965: {
        !          111966:        register int n;
        !          111967:        register daddr_t b;
        !          111968: 
        !          111969:        switch (ip->i_mode&IFMT) {
        !          111970:        case IFPIPE:
        !          111971:                ip->i_pnc = 0;
        !          111972:                ip->i_prx = 0;
        !          111973:                ip->i_pwx = 0;
        !          111974:                n = ND;
        !          111975:                break;
        !          111976:        case IFDIR:
        !          111977:        case IFREG:
        !          111978:                n = NADDR;
        !          111979:                break;
        !          111980:        default:
        !          111981:                return;
        !          111982:        }
        !          111983:        while (n > ND) {
        !          111984:                if ((b=ip->i_a.i_addr[--n]) != 0)
        !          111985:                        indfree(ip->i_dev, b, 1+n-ND);
        !          111986:        }
        !          111987:        while (n > 0) {
        !          111988:                if ((b=ip->i_a.i_addr[--n]) != 0)
        !          111989:                        bfree(ip->i_dev, b);
        !          111990:        }
        !          111991:        ip->i_size = 0;
        !          111992:        kclear(ip->i_a.i_addr, sizeof(ip->i_a.i_addr));
        !          111993:        iamc(ip);       /* creat/pipe - atime/mtime/ctime */
        !          111994: }
        !          111995: 
        !          111996: /*
        !          111997:  * Copy the appropriate information from the inode to the stat buffer.
        !          111998:  */
        !          111999: istat(ip, sbp)
        !          112000: register INODE *ip;
        !          112001: register struct stat *sbp;
        !          112002: {
        !          112003:        sbp->st_dev = ip->i_dev;
        !          112004:        sbp->st_ino = ip->i_ino;
        !          112005:        sbp->st_mode = ip->i_mode;
        !          112006:        sbp->st_nlink = ip->i_nlink;
        !          112007:        sbp->st_uid = ip->i_uid;
        !          112008:        sbp->st_gid = ip->i_gid;
        !          112009:        sbp->st_rdev = NODEV;
        !          112010:        sbp->st_size = ip->i_size;
        !          112011:        sbp->st_atime = ip->i_atime;
        !          112012:        sbp->st_mtime = ip->i_mtime;
        !          112013:        sbp->st_ctime = ip->i_ctime;
        !          112014:        switch (ip->i_mode&IFMT) {
        !          112015:        case IFBLK:
        !          112016:        case IFCHR:
        !          112017:                sbp->st_rdev = ip->i_a.i_rdev;
        !          112018:                sbp->st_size = 0;
        !          112019:                break;
        !          112020:        case IFPIPE:
        !          112021:                sbp->st_size = ip->i_pnc;
        !          112022:                break;
        !          112023:        }
        !          112024: }
        !          112025: 
        !          112026: /*
        !          112027:  * See if it is possible to access the given inode with the bits in
        !          112028:  * the given mode.
        !          112029:  * If the mode includes writing, and i_refc is > 1, then check for
        !          112030:  * shared text problems.
        !          112031:  */
        !          112032: iaccess(ip, mode)
        !          112033: register INODE *ip;
        !          112034: register int mode;
        !          112035: {
        !          112036:        if ((imode(ip, u.u_uid, u.u_gid)&mode) != mode) {
        !          112037:                u.u_error = EACCES;
        !          112038:                return (0);
        !          112039:        }
        !          112040:        if ((mode&IPW) != 0 && ip->i_refc > 1 && sbusy(ip)) {
        !          112041:                u.u_error = ETXTBSY;
        !          112042:                return (0);
        !          112043:        }
        !          112044:        return (1);
        !          112045: }
        !          112046: 
        !          112047: /*
        !          112048:  * Get the maximum allowable mode on a file.
        !          112049:  */
        !          112050: imode(ip, uid, gid)
        !          112051: register INODE *ip;
        !          112052: {
        !          112053:        if (uid == 0)
        !          112054:                return (IPR|IPW|IPE);
        !          112055:        if (uid == ip->i_uid)
        !          112056:                return ((ip->i_mode>>6)&07);
        !          112057:        if (gid == ip->i_gid)
        !          112058:                return ((ip->i_mode>>3)&07);
        !          112059:        return (ip->i_mode&07);
        !          112060: }
        !          112061: @
        !          112062: 
        !          112063: 
        !          112064: 1.4
        !          112065: log
        !          112066: @update by hal
        !          112067: @
        !          112068: text
        !          112069: @@
        !          112070: 
        !          112071: 
        !          112072: 1.3
        !          112073: log
        !          112074: @update provided by hal
        !          112075: @
        !          112076: text
        !          112077: @@
        !          112078: 
        !          112079: 
        !          112080: 1.2
        !          112081: log
        !          112082: @initial version prov by hal
        !          112083: @
        !          112084: text
        !          112085: @d32 1
        !          112086: a32 1
        !          112087: #include <coherent.h>
        !          112088: @
        !          112089: 
        !          112090: 
        !          112091: 1.1
        !          112092: log
        !          112093: @used in COH 3.0.0 and 3.1.0
        !          112094: @
        !          112095: text
        !          112096: @d301 7
        !          112097: @
        !          112098: 0707070064030031751004440000030000030000011777770507310732600005000000030344/newbits/kernel/USRSRC/coh/RCS/sys2.c,vhead     1.5;
        !          112099: branch   ;
        !          112100: access   ;
        !          112101: symbols  ;
        !          112102: locks    bin:1.5;
        !          112103: comment  @ * @;
        !          112104: 
        !          112105: 
        !          112106: 1.5
        !          112107: date     91.07.24.07.52.31;  author bin;  state Exp;
        !          112108: branches ;
        !          112109: next     1.4;
        !          112110: 
        !          112111: 1.4
        !          112112: date     91.07.15.14.34.07;  author bin;  state Exp;
        !          112113: branches ;
        !          112114: next     1.3;
        !          112115: 
        !          112116: 1.3
        !          112117: date     91.06.20.14.31.42;  author bin;  state Exp;
        !          112118: branches ;
        !          112119: next     1.2;
        !          112120: 
        !          112121: 1.2
        !          112122: date     91.06.10.14.37.45;  author bin;  state Exp;
        !          112123: branches ;
        !          112124: next     1.1;
        !          112125: 
        !          112126: 1.1
        !          112127: date     91.04.30.13.56.54;  author root;  state Exp;
        !          112128: branches ;
        !          112129: next     ;
        !          112130: 
        !          112131: 
        !          112132: desc
        !          112133: @File system system calls.
        !          112134: @
        !          112135: 
        !          112136: 
        !          112137: 1.5
        !          112138: log
        !          112139: @update prov by hal
        !          112140: 
        !          112141: @
        !          112142: text
        !          112143: @/* $Header: /usr/src/sys/coh/RCS/sys2.c,v 1.1 91/04/30 13:56:54 root Exp $ */
        !          112144: /* (lgl-
        !          112145:  *     The information contained herein is a trade secret of Mark Williams
        !          112146:  *     Company, and  is confidential information.  It is provided  under a
        !          112147:  *     license agreement,  and may be  copied or disclosed  only under the
        !          112148:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          112149:  *     material without the express written authorization of Mark Williams
        !          112150:  *     Company or persuant to the license agreement is unlawful.
        !          112151:  *
        !          112152:  *     COHERENT Version 2.3.37
        !          112153:  *     Copyright (c) 1982, 1983, 1984.
        !          112154:  *     An unpublished work by Mark Williams Company, Chicago.
        !          112155:  *     All rights reserved.
        !          112156:  -lgl) */
        !          112157: 
        !          112158: /*
        !          112159:  * Coherent.
        !          112160:  * System calls (filesystem related).
        !          112161:  *
        !          112162:  * $Log:       /usr/src/sys/coh/RCS/sys2.c,v $
        !          112163:  * Revision 1.1        91/04/30  13:56:54      root
        !          112164:  * Shipped with COH 3.1.0.
        !          112165:  * 
        !          112166:  */
        !          112167: #include <sys/coherent.h>
        !          112168: #include <errno.h>
        !          112169: #include <sys/fcntl.h>
        !          112170: #include <sys/fd.h>
        !          112171: #include <sys/ino.h>
        !          112172: #include <sys/inode.h>
        !          112173: #include <sys/mount.h>
        !          112174: #include <sys/poll.h>
        !          112175: #include <sys/sched.h>
        !          112176: #include <sys/stat.h>
        !          112177: #include <sys/uproc.h>
        !          112178: 
        !          112179: /*
        !          112180:  * Determine accessibility of the given file.
        !          112181:  */
        !          112182: uaccess(np, mode)
        !          112183: char *np;
        !          112184: register int mode;
        !          112185: {
        !          112186:        register INODE *ip;
        !          112187:        register int r;
        !          112188: 
        !          112189:        schizo();
        !          112190:        r = ftoi(np, 'r');
        !          112191:        schizo();
        !          112192:        if (r != 0)
        !          112193:                return;
        !          112194:        ip = u.u_cdiri;
        !          112195:        if ((mode&imode(ip, u.u_ruid, u.u_rgid)) != mode)
        !          112196:                u.u_error = EACCES;
        !          112197:        idetach(ip);
        !          112198:        return (0);
        !          112199: }
        !          112200: 
        !          112201: /*
        !          112202:  * Schizo - swap real and effective id's.
        !          112203:  */
        !          112204: schizo()
        !          112205: {
        !          112206:        register int t;
        !          112207: 
        !          112208:        t = u.u_uid;
        !          112209:        u.u_uid = u.u_ruid;
        !          112210:        u.u_ruid = t;
        !          112211:        t = u.u_gid;
        !          112212:        u.u_gid = u.u_rgid;
        !          112213:        u.u_rgid = t;
        !          112214: }
        !          112215: 
        !          112216: /*
        !          112217:  * Turn accounting on or off.
        !          112218:  */
        !          112219: uacct(np)
        !          112220: register char *np;
        !          112221: {
        !          112222:        register INODE *ip;
        !          112223: 
        !          112224:        if (super() == 0)
        !          112225:                return;
        !          112226:        if (np == NULL) {
        !          112227:                if (acctip == NULL) {
        !          112228:                        u.u_error = EINVAL;
        !          112229:                        return;
        !          112230:                }
        !          112231:                ldetach(acctip);
        !          112232:                acctip = NULL;
        !          112233:        } else {
        !          112234:                if (acctip != NULL) {
        !          112235:                        u.u_error = EINVAL;
        !          112236:                        return;
        !          112237:                }
        !          112238:                if (ftoi(np, 'r') != 0)
        !          112239:                        return;
        !          112240:                ip = u.u_cdiri;
        !          112241:                if ((ip->i_mode&IFMT) != IFREG) {
        !          112242:                        u.u_error = EINVAL;
        !          112243:                        idetach(ip);
        !          112244:                        return;
        !          112245:                }
        !          112246:                iunlock(ip);
        !          112247:                acctip = ip;
        !          112248:        }
        !          112249:        return (0);
        !          112250: }
        !          112251: 
        !          112252: /*
        !          112253:  * Set current directory.
        !          112254:  */
        !          112255: uchdir(np)
        !          112256: char *np;
        !          112257: {
        !          112258:        setcdir(np, &u.u_cdir);
        !          112259:        return (0);
        !          112260: }
        !          112261: 
        !          112262: /*
        !          112263:  * Given a directory name and a pointer to a working directory pointer,
        !          112264:  * Save the inode associated with the directory name in the working
        !          112265:  * directory pointer and release the old one.  This is used to change
        !          112266:  * working and root directories.
        !          112267:  */
        !          112268: setcdir(np, ipp)
        !          112269: char *np;
        !          112270: register INODE **ipp;
        !          112271: {
        !          112272:        register INODE *ip;
        !          112273: 
        !          112274:        if (ftoi(np, 'r') != 0)
        !          112275:                return;
        !          112276:        ip = u.u_cdiri;
        !          112277:        if ((ip->i_mode&IFMT) != IFDIR) {
        !          112278:                u.u_error = ENOTDIR;
        !          112279:                idetach(ip);
        !          112280:                return;
        !          112281:        }
        !          112282:        if (iaccess(ip, IPE) == 0) {
        !          112283:                u.u_error = EACCES;
        !          112284:                idetach(ip);
        !          112285:                return;
        !          112286:        }
        !          112287:        iunlock(ip);
        !          112288:        ldetach(*ipp);
        !          112289:        *ipp = ip;
        !          112290: }
        !          112291: 
        !          112292: /*
        !          112293:  * Change the mode of a file.
        !          112294:  */
        !          112295: uchmod(np, mode)
        !          112296: char *np;
        !          112297: {
        !          112298:        register INODE *ip;
        !          112299: 
        !          112300:        if (ftoi(np, 'r') != 0)
        !          112301:                return;
        !          112302:        ip = u.u_cdiri;
        !          112303:        if (owner(ip->i_uid)) {
        !          112304:                if (u.u_uid != 0)
        !          112305:                        mode &= ~ISVTXT;
        !          112306:                ip->i_mode &= IFMT;
        !          112307:                ip->i_mode |= mode&~IFMT;
        !          112308:                icrt(ip);       /* chmod - ctime */
        !          112309:        }
        !          112310:        idetach(ip);
        !          112311:        return (0);
        !          112312: }
        !          112313: 
        !          112314: /*
        !          112315:  * Change owner and group of a file.
        !          112316:  */
        !          112317: uchown(np, uid, gid)
        !          112318: char *np;
        !          112319: {
        !          112320:        register INODE *ip;
        !          112321: 
        !          112322:        if (ftoi(np, 'r') != 0)
        !          112323:                return;
        !          112324:        ip = u.u_cdiri;
        !          112325:        if (super()) {
        !          112326:                ip->i_mode &= ~(ISUID | ISGID);  /* clear any setuid/setgid */
        !          112327:                ip->i_uid = uid;
        !          112328:                ip->i_gid = gid;
        !          112329:                icrt(ip);       /* chown - ctime */
        !          112330:        }
        !          112331:        idetach(ip);
        !          112332:        return (0);
        !          112333: }
        !          112334: 
        !          112335: /*
        !          112336:  * Set root directory.
        !          112337:  */
        !          112338: uchroot(np)
        !          112339: register char *np;
        !          112340: {
        !          112341:        if (super())
        !          112342:                setcdir(np, &u.u_rdir);
        !          112343:        return (0);
        !          112344: }
        !          112345: 
        !          112346: /*
        !          112347:  * Close the given file descriptor.
        !          112348:  */
        !          112349: uclose(fd)
        !          112350: {
        !          112351:        fdclose(fd);
        !          112352:        return (0);
        !          112353: }
        !          112354: 
        !          112355: /*
        !          112356:  * Create a file with the given mode.
        !          112357:  */
        !          112358: ucreat(np, mode)
        !          112359: char *np;
        !          112360: register int mode;
        !          112361: {
        !          112362:        register INODE *ip;
        !          112363:        register int fd;
        !          112364:        register int cflag;
        !          112365: 
        !          112366:        cflag = 0;
        !          112367:        if (ftoi(np, 'c') != 0)
        !          112368:                return;
        !          112369:        if ((ip=u.u_cdiri) == NULL) {
        !          112370:                if ((ip=imake((mode&~IFMT)|IFREG, 0)) == NULL)
        !          112371:                        return;
        !          112372:        } else {
        !          112373:                if (iaccess(ip, IPW)==0) {
        !          112374:                        idetach(ip);
        !          112375:                        return;
        !          112376:                }
        !          112377:                switch (ip->i_mode&IFMT) {
        !          112378:                case IFBLK:
        !          112379:                case IFCHR:
        !          112380:                        break;
        !          112381:                case IFDIR:
        !          112382:                        u.u_error = EISDIR;
        !          112383:                        idetach(ip);
        !          112384:                        return;
        !          112385:                default:
        !          112386:                        if (getment(ip->i_dev, 1) == NULL) {
        !          112387:                                idetach(ip);
        !          112388:                                return;
        !          112389:                        }
        !          112390:                }
        !          112391:                cflag = 1;
        !          112392:        }
        !          112393:        if ((fd=fdopen(ip, IPW)) < 0) {
        !          112394:                idetach(ip);
        !          112395:                return;
        !          112396:        }
        !          112397:        if (cflag)
        !          112398:                iclear(ip);
        !          112399:        iunlock(ip);
        !          112400:        return (fd);
        !          112401: }
        !          112402: 
        !          112403: /*
        !          112404:  * Duplicate a file descriptor.
        !          112405:  */
        !          112406: udup(ofd, nfd)
        !          112407: {
        !          112408:        return (fddup(ofd, nfd));
        !          112409: }
        !          112410: 
        !          112411: /*
        !          112412:  * Given a file descriptor, return a status structure.
        !          112413:  */
        !          112414: ufstat(fd, stp)
        !          112415: struct stat *stp;
        !          112416: {
        !          112417:        register INODE *ip;
        !          112418:        register FD *fdp;
        !          112419:        struct stat stat;
        !          112420: 
        !          112421:        if ((fdp=fdget(fd)) == NULL)
        !          112422:                return;
        !          112423:        ip = fdp->f_ip;
        !          112424:        istat(ip, &stat);
        !          112425:        kucopy(&stat, stp, sizeof(stat));
        !          112426:        return (0);
        !          112427: }
        !          112428: 
        !          112429: /*
        !          112430:  * File control.
        !          112431:  */
        !          112432: ufcntl( fd, cmd, arg )
        !          112433: int fd, cmd, arg;
        !          112434: {
        !          112435:        register FD * fdp;
        !          112436: 
        !          112437:        /*
        !          112438:         * Validate file descriptor.
        !          112439:         */
        !          112440:        if ( (fd < 0) || (fd >= NUFILE) || ((fdp = u.u_filep[fd]) == 0) ) {
        !          112441:                u.u_error = EBADF;
        !          112442:                return;
        !          112443:        }
        !          112444: 
        !          112445:        switch ( cmd ) {
        !          112446: 
        !          112447:        case F_DUPFD:
        !          112448:                /*
        !          112449:                 * Validate base file descriptor.
        !          112450:                 */
        !          112451:                if ( (arg < 0) || (arg >= NUFILE) ) {
        !          112452:                        u.u_error = EINVAL;
        !          112453:                        return;
        !          112454:                }
        !          112455: 
        !          112456:                /*
        !          112457:                 * Search for next available file descriptor.
        !          112458:                 */
        !          112459:                do {
        !          112460:                        if ( u.u_filep[arg] == 0 ) {
        !          112461:                                u.u_filep[arg] = fdp;
        !          112462:                                fdp->f_refc++;
        !          112463:                                return arg;
        !          112464:                        }
        !          112465:                } while ( ++arg < NUFILE );
        !          112466: 
        !          112467:                u.u_error = EMFILE;
        !          112468:                return;
        !          112469: 
        !          112470:        case F_SETFL:
        !          112471:                fdp->f_flag &= ~IPNDLY;
        !          112472:                if ( arg & O_NDELAY )
        !          112473:                        fdp->f_flag |= IPNDLY;
        !          112474:                if ( arg & O_APPEND )
        !          112475:                        fdp->f_flag |= IPAPPEND;
        !          112476:                /* no break */
        !          112477: 
        !          112478:        case F_GETFL:
        !          112479:                switch ( fdp->f_flag & (IPR+IPW) ) {
        !          112480:                case IPR: arg = O_RDONLY; break;
        !          112481:                case IPW: arg = O_WRONLY; break;
        !          112482:                default:  arg = O_RDWR;   break;
        !          112483:                }
        !          112484:                if ( fdp->f_flag & IPNDLY )
        !          112485:                        arg |= O_NDELAY;
        !          112486:                if ( fdp->f_flag & IPAPPEND )
        !          112487:                        arg |= O_APPEND;
        !          112488:                return arg;
        !          112489: 
        !          112490:        default:
        !          112491:                u.u_error = EINVAL;
        !          112492:        }
        !          112493: }
        !          112494: 
        !          112495: /*
        !          112496:  * Device control information.
        !          112497:  */
        !          112498: uioctl(fd, r, argp)
        !          112499: struct sgttyb *argp;
        !          112500: {
        !          112501:        register FD *fdp;
        !          112502:        register INODE *ip;
        !          112503:        register int mode;
        !          112504: 
        !          112505:        if ((fdp=fdget(fd)) == NULL)
        !          112506:                return;
        !          112507:        ip = fdp->f_ip;
        !          112508:        mode = ip->i_mode&IFMT;
        !          112509:        if (mode!=IFCHR && mode!=IFBLK) {
        !          112510:                u.u_error = ENOTTY;
        !          112511:                return;
        !          112512:        }
        !          112513:        dioctl(ip->i_a.i_rdev, r, argp);
        !          112514:        return (0);
        !          112515: }
        !          112516: 
        !          112517: /*
        !          112518:  * Create a link, `np2' to the already existing file `np1'.
        !          112519:  */
        !          112520: ulink(np1, np2)
        !          112521: char *np1;
        !          112522: char *np2;
        !          112523: {
        !          112524:        register INODE *ip1;
        !          112525: 
        !          112526:        if (ftoi(np1, 'r') != 0)
        !          112527:                return;
        !          112528:        ip1 = u.u_cdiri;
        !          112529:        if ((ip1->i_mode&IFMT)==IFDIR && super()==0) {
        !          112530:                idetach(ip1);
        !          112531:                return;
        !          112532:        }
        !          112533:        iunlock(ip1);
        !          112534:        if (ftoi(np2, 'c') != 0) {
        !          112535:                ldetach(ip1);
        !          112536:                return;
        !          112537:        }
        !          112538:        if (u.u_cdiri != NULL) {
        !          112539:                u.u_error = EEXIST;
        !          112540:                idetach(u.u_cdiri);
        !          112541:                ldetach(ip1);
        !          112542:                return;
        !          112543:        }
        !          112544:        if (ip1->i_dev != u.u_pdiri->i_dev) {
        !          112545:                u.u_error = EXDEV;
        !          112546:                idetach(u.u_pdiri);
        !          112547:                ldetach(ip1);
        !          112548:                return;
        !          112549:        }
        !          112550:        if (iaccess(u.u_pdiri, IPW) == 0) {
        !          112551:                idetach(u.u_pdiri);
        !          112552:                ldetach(ip1);
        !          112553:                return;
        !          112554:        }
        !          112555:        idirent(ip1->i_ino);
        !          112556:        idetach(u.u_pdiri);
        !          112557:        ilock(ip1);
        !          112558:        ip1->i_nlink++;
        !          112559:        icrt(ip1);      /* link - ctime */
        !          112560:        idetach(ip1);
        !          112561:        return (0);
        !          112562: }
        !          112563: 
        !          112564: /*
        !          112565:  * Seek on the given file descriptor.
        !          112566:  */
        !          112567: fsize_t
        !          112568: ulseek(fd, off, w)
        !          112569: register fsize_t off;
        !          112570: {
        !          112571:        register FD *fdp;
        !          112572:        register INODE *ip;
        !          112573: 
        !          112574:        if ((fdp=fdget(fd)) == NULL)
        !          112575:                return;
        !          112576:        ip = fdp->f_ip;
        !          112577:        if ((ip->i_mode&IFMT) == IFPIPE) {
        !          112578:                u.u_error = ESPIPE;
        !          112579:                return;
        !          112580:        }
        !          112581:        switch (w) {
        !          112582:        case 0:
        !          112583:                break;
        !          112584:        case 1:
        !          112585:                off += fdp->f_seek;
        !          112586:                break;
        !          112587:        case 2:
        !          112588:                off += ip->i_size;
        !          112589:                break;
        !          112590:        default:
        !          112591:                u.u_error = EINVAL;
        !          112592:                return;
        !          112593:        }
        !          112594:        if (off < 0) {
        !          112595:                u.u_error = EINVAL;
        !          112596:                return;
        !          112597:        }
        !          112598:        fdp->f_seek = off;
        !          112599:        return (off);
        !          112600: }
        !          112601: 
        !          112602: /*
        !          112603:  * Create a special file.
        !          112604:  */
        !          112605: umknod(np, mode, rdev)
        !          112606: char *np;
        !          112607: dev_t rdev;
        !          112608: {
        !          112609:        register INODE *ip;
        !          112610:        register int type;
        !          112611: 
        !          112612:        type = mode&IFMT;
        !          112613:        if (type!=IFPIPE && super()==0)
        !          112614:                return;
        !          112615:        if (type!=IFBLK && type!=IFCHR)
        !          112616:                rdev = 0;
        !          112617:        if (ftoi(np, 'c') != 0)
        !          112618:                return;
        !          112619:        if ((ip=u.u_cdiri) != NULL) {
        !          112620:                u.u_error = EEXIST;
        !          112621:                idetach(ip);
        !          112622:                return;
        !          112623:        }
        !          112624:        if ((ip=imake(mode, rdev)) != NULL)
        !          112625:                idetach(ip);
        !          112626:        return (0);
        !          112627: }
        !          112628: 
        !          112629: /*
        !          112630:  * Mount the device `sp' on the pathname `np'.  The flag, `f',
        !          112631:  * indicates that the device is to be mounted read only.
        !          112632:  */
        !          112633: umount(sp, np, f)
        !          112634: char *sp;
        !          112635: char *np;
        !          112636: {
        !          112637:        register INODE *ip;
        !          112638:        register MOUNT *mp;
        !          112639:        register dev_t rdev;
        !          112640:        register int mode;
        !          112641: 
        !          112642:        if (ftoi(sp, 'r') != 0)
        !          112643:                return;
        !          112644:        ip = u.u_cdiri;
        !          112645:        if (iaccess(ip, IPR|IPW) == 0)
        !          112646:                goto err;
        !          112647:        mode = ip->i_mode;
        !          112648:        rdev = ip->i_a.i_rdev;
        !          112649:        if ((mode&IFMT) != IFBLK) {
        !          112650:                u.u_error = ENOTBLK;
        !          112651:                goto err;
        !          112652:        }
        !          112653:        idetach(ip);
        !          112654:        if (ftoi(np, 'r') != 0)
        !          112655:                return;
        !          112656:        ip = u.u_cdiri;
        !          112657:        if (iaccess(ip, IPR) == 0)
        !          112658:                goto err;
        !          112659:        if ((ip->i_mode&IFMT) != IFDIR) {
        !          112660:                u.u_error = ENOTDIR;
        !          112661:                goto err;
        !          112662:        }
        !          112663:        /* Check for current directory, open, or mount directory */
        !          112664:        if (ip->i_refc > 1 || ip->i_ino == ROOTIN) {
        !          112665:                u.u_error = EBUSY;
        !          112666:                goto err;
        !          112667:        }
        !          112668:        for (mp=mountp; mp!=NULL; mp=mp->m_next) {
        !          112669:                if (mp->m_dev == rdev) {
        !          112670:                        u.u_error = EBUSY;
        !          112671:                        goto err;
        !          112672:                }
        !          112673:        }
        !          112674:        if ((mp=fsmount(rdev, f)) == NULL)
        !          112675:                goto err;
        !          112676:        mp->m_ip = ip;
        !          112677:        ip->i_flag |= IFMNT;
        !          112678:        ip->i_refc++;
        !          112679: err:
        !          112680:        idetach(ip);
        !          112681:        return (0);
        !          112682: }
        !          112683: 
        !          112684: /*
        !          112685:  * Poll devices for input/output events.
        !          112686:  */
        !          112687: int
        !          112688: upoll( pollfds, npoll, msec )
        !          112689: struct pollfd * pollfds;
        !          112690: unsigned long npoll;
        !          112691: int msec;
        !          112692: {
        !          112693:        register struct pollfd * pollp; /* current poll pointer          */
        !          112694:        register FD *   fdp;            /* current file descriptor ptr   */
        !          112695:        auto     int    fd;             /* current file descriptor       */
        !          112696:        auto     int    rev;            /* last event report received    */
        !          112697:        auto     int    nev;            /* number non-zero event reports */
        !          112698:        auto     int    i;
        !          112699:        extern   char * udl;
        !          112700: 
        !          112701:        /*
        !          112702:         * Validate number of polls.
        !          112703:         */
        !          112704:        if ( (npoll < 0) || (npoll > NUFILE) ) {
        !          112705:                u.u_error = EINVAL;
        !          112706:                return;
        !          112707:        }
        !          112708: 
        !          112709:        /*
        !          112710:         * Validate address of polling information.
        !          112711:         */
        !          112712:        pollp = &pollfds[npoll];
        !          112713:        if ( (pollfds == NULL) || (pollp < pollfds) || (pollp > udl) ) {
        !          112714:                u.u_error = EFAULT;
        !          112715:                return;
        !          112716:        }
        !          112717: 
        !          112718:        do {
        !          112719:                /*
        !          112720:                 * Service each poll in turn.
        !          112721:                 */
        !          112722:                for ( nev=0, i=npoll, pollp = pollfds; i > 0; --i, pollp++ ) {
        !          112723: 
        !          112724:                        /*
        !          112725:                         * Fetch file descriptor.
        !          112726:                         */
        !          112727:                        fd = getuwd( &pollp->fd );
        !          112728: 
        !          112729:                        /*
        !          112730:                         * Ignore negative file descriptors.
        !          112731:                         */
        !          112732:                        if ( fd < 0 ) {
        !          112733:                                rev = 0;
        !          112734:                        }
        !          112735: 
        !          112736:                        /*
        !          112737:                         * Poll message queue.
        !          112738:                         */
        !          112739:                        else if ( fd >= NUFILE ) {
        !          112740: #ifdef MSGPOLL
        !          112741: /*
        !          112742:  * this code only good if msgpoll() is available to the kernel -
        !          112743:  * no good with loadable msg driver
        !          112744:  */
        !          112745:                                rev = msgpoll(  fd,
        !          112746:                                                getuwd( &pollp->events),
        !          112747:                                                msec );
        !          112748: #else
        !          112749:                                rev = POLLNVAL;
        !          112750: #endif
        !          112751:                        }
        !          112752: 
        !          112753:                        /*
        !          112754:                         * Validate file descriptor.
        !          112755:                         */
        !          112756:                        else if ( (fdp = u.u_filep[fd]) == 0 ) {
        !          112757:                                rev = POLLNVAL;
        !          112758:                        }
        !          112759: 
        !          112760:                        /*
        !          112761:                         * Non-character device.
        !          112762:                         */
        !          112763:                        else if ( (fdp->f_ip->i_mode & IFMT) != IFCHR ) {
        !          112764:                                rev = POLLNVAL;
        !          112765:                        }
        !          112766: 
        !          112767:                        /*
        !          112768:                         * Poll character device driver.
        !          112769:                         */
        !          112770:                        else {
        !          112771:                                rev = dpoll( fdp->f_ip->i_a.i_rdev,
        !          112772:                                                getuwd(&pollp->events),
        !          112773:                                                msec );
        !          112774:                        }
        !          112775: 
        !          112776:                        /*
        !          112777:                         * Remember reponses.
        !          112778:                         */
        !          112779:                        putuwd( &pollp->revents, rev );
        !          112780: 
        !          112781:                        /*
        !          112782:                         * Record number of non-zero responses.
        !          112783:                         */
        !          112784:                        if ( rev != 0 ) {
        !          112785:                                msec = 0;
        !          112786:                                nev++;
        !          112787:                        }
        !          112788:                }
        !          112789: 
        !          112790:                /*
        !          112791:                 * Non-blocking poll or poll response received.
        !          112792:                 */
        !          112793:                if ( msec == 0 ) {
        !          112794:                        pollexit();
        !          112795:                        return nev;
        !          112796:                }
        !          112797: 
        !          112798:                /*
        !          112799:                 * Schedule wakeup timer if positive delay interval given.
        !          112800:                 */
        !          112801:                if ( msec > 0 ) {
        !          112802:                        /*
        !          112803:                         * Convert milliseconds to clock ticks.
        !          112804:                         */
        !          112805:                        msec += (1000 / HZ) - 1;
        !          112806:                        msec /= (1000 / HZ);
        !          112807:                        timeout( &cprocp->p_polltim, msec,
        !          112808:                                 wakeup, &cprocp->p_polls );
        !          112809:                }
        !          112810: 
        !          112811:                /*
        !          112812:                 * Wake for polled event, poll timeout, or signal.
        !          112813:                 */
        !          112814:                sleep( &cprocp->p_polls, CVTTOUT, IVTTOUT, SVTTOUT );
        !          112815: 
        !          112816:                /*
        !          112817:                 * Terminate event monitoring.
        !          112818:                 */
        !          112819:                pollexit();
        !          112820: 
        !          112821:                /*
        !          112822:                 * Perform non-blocking poll after first poll timeout.
        !          112823:                 */
        !          112824:                if ( msec > 0 ) {
        !          112825:                        timeout( &cprocp->p_polltim, 0, NULL, NULL );
        !          112826:                        msec = 0;
        !          112827:                }
        !          112828: 
        !          112829:                /*
        !          112830:                 * Signal woke us up.
        !          112831:                 */
        !          112832:                if ( nondsig() ) {
        !          112833:                        u.u_error = EINTR;
        !          112834:                        return -1;
        !          112835:                }
        !          112836: 
        !          112837:        } while ( msec != 0 );
        !          112838: 
        !          112839:        return 0;
        !          112840: }
        !          112841: @
        !          112842: 
        !          112843: 
        !          112844: 1.4
        !          112845: log
        !          112846: @update by hal
        !          112847: @
        !          112848: text
        !          112849: @@
        !          112850: 
        !          112851: 
        !          112852: 1.3
        !          112853: log
        !          112854: @update provided by hal
        !          112855: @
        !          112856: text
        !          112857: @@
        !          112858: 
        !          112859: 
        !          112860: 1.2
        !          112861: log
        !          112862: @
        !          112863: @
        !          112864: text
        !          112865: @d25 1
        !          112866: a25 1
        !          112867: #include <coherent.h>
        !          112868: @
        !          112869: 
        !          112870: 
        !          112871: 1.1
        !          112872: log
        !          112873: @Shipped with COH 3.1.0.
        !          112874: @
        !          112875: text
        !          112876: @d1 1
        !          112877: a1 1
        !          112878: /* $Header: /usr/src/sys/coh/RCS/sys2.c,v 1.2 88/08/02 15:00:22 src Exp $ */
        !          112879: d20 4
        !          112880: a23 1
        !          112881:  * $Log$
        !          112882: d32 1
        !          112883: d598 5
        !          112884: d606 3
        !          112885: @
        !          112886: 0707070064030053111005550000030000030000011777770507310733200004500000000441/newbits/kernel/USRSRC/coh/RCS/RCS,vhead     1.1;
        !          112887: access   ;
        !          112888: symbols  ;
        !          112889: locks    bin:1.1;
        !          112890: comment  @@;
        !          112891: 
        !          112892: 
        !          112893: 1.1
        !          112894: date     91.06.10.14.36.00;  author bin;  state Exp;
        !          112895: branches ;
        !          112896: next   ;
        !          112897: 
        !          112898: 
        !          112899: desc
        !          112900: @@
        !          112901: 
        !          112902: 
        !          112903: 
        !          112904: 1.1
        !          112905: log
        !          112906: @Initial revision
        !          112907: @
        !          112908: text
        !          112909: @.3..fs1.c,vsys2.c,v#,RCS,',RCSnew00380a@
        !          112910: 0707070064030076111004440000030000030000011777770507310733200005100000005612/newbits/kernel/USRSRC/coh/RCS/alloc.c,vhead     1.4;
        !          112911: branch   ;
        !          112912: access   ;
        !          112913: symbols  ;
        !          112914: locks    bin:1.4;
        !          112915: comment  @ * @;
        !          112916: 
        !          112917: 
        !          112918: 1.4
        !          112919: date     91.07.24.07.48.16;  author bin;  state Exp;
        !          112920: branches ;
        !          112921: next     1.3;
        !          112922: 
        !          112923: 1.3
        !          112924: date     91.07.15.14.31.20;  author bin;  state Exp;
        !          112925: branches ;
        !          112926: next     1.2;
        !          112927: 
        !          112928: 1.2
        !          112929: date     91.06.20.14.29.04;  author bin;  state Exp;
        !          112930: branches ;
        !          112931: next     1.1;
        !          112932: 
        !          112933: 1.1
        !          112934: date     91.06.10.14.36.03;  author bin;  state Exp;
        !          112935: branches ;
        !          112936: next     ;
        !          112937: 
        !          112938: 
        !          112939: desc
        !          112940: @initial version prov by hal
        !          112941: @
        !          112942: 
        !          112943: 
        !          112944: 1.4
        !          112945: log
        !          112946: @initial version prov by hal
        !          112947: @
        !          112948: text
        !          112949: @/* $Header: /usr/src/sys/coh/RCS/alloc.c,v 1.1 88/03/24 16:13:25 src Exp $ */
        !          112950: /* (lgl-
        !          112951:  *     The information contained herein is a trade secret of Mark Williams
        !          112952:  *     Company, and  is confidential information.  It is provided  under a
        !          112953:  *     license agreement,  and may be  copied or disclosed  only under the
        !          112954:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          112955:  *     material without the express written authorization of Mark Williams
        !          112956:  *     Company or persuant to the license agreement is unlawful.
        !          112957:  *
        !          112958:  *     COHERENT Version 2.3.37
        !          112959:  *     Copyright (c) 1982, 1983, 1984.
        !          112960:  *     An unpublished work by Mark Williams Company, Chicago.
        !          112961:  *     All rights reserved.
        !          112962:  -lgl) */
        !          112963: /*
        !          112964:  * Coherent.
        !          112965:  * Storage allocator.
        !          112966:  *
        !          112967:  * $Log:       /usr/src/sys/coh/RCS/alloc.c,v $
        !          112968:  * Revision 1.1        88/03/24  16:13:25      src
        !          112969:  * Initial revision
        !          112970:  * 
        !          112971:  */
        !          112972: #include <sys/coherent.h>
        !          112973: #include <sys/alloc.h>
        !          112974: #include <errno.h>
        !          112975: #include <sys/proc.h>
        !          112976: #include <sys/uproc.h>
        !          112977: 
        !          112978: /*
        !          112979:  * Create an arena.
        !          112980:  */
        !          112981: ALL *
        !          112982: setarena(cp, n)
        !          112983: register char *cp;
        !          112984: {
        !          112985:        register ALL *ap1;
        !          112986:        register ALL *ap2;
        !          112987: 
        !          112988:        if ((char *)(ap1=align(cp)) < (char *)cp)
        !          112989:                ap1++;
        !          112990:        if ((ap2=align(&cp[n])-1) < ap1)
        !          112991:                panic("Arena %o too small", (int) cp);
        !          112992:        ap1->a_link = (char *)ap2;
        !          112993:        ap2->a_link = (char *)ap1;
        !          112994:        setused(ap2);
        !          112995:        return (ap1);
        !          112996: }
        !          112997: 
        !          112998: /*
        !          112999:  * Allocate `l' bytes of memory.
        !          113000:  */
        !          113001: char *
        !          113002: alloc(apq, l)
        !          113003: ALL *apq;
        !          113004: unsigned l;
        !          113005: {
        !          113006:        register ALL *ap;
        !          113007:        register ALL *ap1;
        !          113008:        register ALL *ap2;
        !          113009:        register unsigned i;
        !          113010:        register unsigned n;
        !          113011:        register unsigned s;
        !          113012: 
        !          113013:        n = 1 + (l + sizeof(ALL) - 1) / sizeof(ALL);
        !          113014:        for (i=0; i<2; i++) {
        !          113015:                for (ap1=apq; link(ap1)!=apq; ap1=link(ap1)) {
        !          113016:                        if (ap1 == NULL)
        !          113017:                                panic("Corrupt arena");
        !          113018:                        if (tstfree(ap1)) {
        !          113019:                               for (ap2=link(ap1); tstfree(ap2); ap2=link(ap2))
        !          113020:                                        if (ap2 == apq)
        !          113021:                                                break;
        !          113022:                                ap1->a_link = (char *)ap2;
        !          113023:                                if ((s=ap2-ap1) >= n) {
        !          113024:                                        if (s > n) {
        !          113025:                                                if (i == 0)
        !          113026:                                                        continue;
        !          113027:                                                ap = &ap1[n];
        !          113028:                                                ap->a_link = (char *)ap2;
        !          113029:                                                ap1->a_link = (char *)ap;
        !          113030:                                        }
        !          113031:                                        setused(ap1);
        !          113032:                                        kclear((char *)ap1->a_data, l);
        !          113033:                                        return (ap1->a_data);
        !          113034:                                }
        !          113035:                        }
        !          113036:                }
        !          113037:        }
        !          113038:        u.u_error = EKSPACE;
        !          113039:        return (NULL);
        !          113040: }
        !          113041: 
        !          113042: /*
        !          113043:  * Free memory.
        !          113044:  */
        !          113045: free(cp)
        !          113046: char *cp;
        !          113047: {
        !          113048:        register ALL *ap;
        !          113049:        extern char end;
        !          113050: 
        !          113051:        ap = ((ALL *)cp) - 1;
        !          113052:        if (ap<(ALL *)&end || tstfree(ap))
        !          113053:                panic("Bad free %o\n", (unsigned)cp);
        !          113054:        setfree(ap);
        !          113055: }
        !          113056: @
        !          113057: 
        !          113058: 
        !          113059: 1.3
        !          113060: log
        !          113061: @update by hal
        !          113062: @
        !          113063: text
        !          113064: @@
        !          113065: 
        !          113066: 
        !          113067: 1.2
        !          113068: log
        !          113069: @update provided by hal
        !          113070: @
        !          113071: text
        !          113072: @@
        !          113073: 
        !          113074: 
        !          113075: 1.1
        !          113076: log
        !          113077: @Initial revision
        !          113078: @
        !          113079: text
        !          113080: @d24 2
        !          113081: a25 2
        !          113082: #include <coherent.h>
        !          113083: #include <alloc.h>
        !          113084: @
        !          113085: 0707070064030113641004440000030000030000011777770507310733300004700000033005/newbits/kernel/USRSRC/coh/RCS/bio.c,vhead     1.4;
        !          113086: branch   ;
        !          113087: access   ;
        !          113088: symbols  ;
        !          113089: locks    bin:1.4;
        !          113090: comment  @ * @;
        !          113091: 
        !          113092: 
        !          113093: 1.4
        !          113094: date     91.07.24.07.49.45;  author bin;  state Exp;
        !          113095: branches ;
        !          113096: next     1.3;
        !          113097: 
        !          113098: 1.3
        !          113099: date     91.07.15.14.31.29;  author bin;  state Exp;
        !          113100: branches ;
        !          113101: next     1.2;
        !          113102: 
        !          113103: 1.2
        !          113104: date     91.06.20.14.29.21;  author bin;  state Exp;
        !          113105: branches ;
        !          113106: next     1.1;
        !          113107: 
        !          113108: 1.1
        !          113109: date     91.06.10.14.36.13;  author bin;  state Exp;
        !          113110: branches ;
        !          113111: next     ;
        !          113112: 
        !          113113: 
        !          113114: desc
        !          113115: @initial version prov by hal
        !          113116: @
        !          113117: 
        !          113118: 
        !          113119: 1.4
        !          113120: log
        !          113121: @update prov by hal
        !          113122: 
        !          113123: @
        !          113124: text
        !          113125: @/* $Header: /usr/src/sys/coh/RCS/bio.c,v 1.1 88/03/24 16:13:29 src Exp $ */
        !          113126: /* (lgl-
        !          113127:  *     The information contained herein is a trade secret of Mark Williams
        !          113128:  *     Company, and  is confidential information.  It is provided  under a
        !          113129:  *     license agreement,  and may be  copied or disclosed  only under the
        !          113130:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          113131:  *     material without the express written authorization of Mark Williams
        !          113132:  *     Company or persuant to the license agreement is unlawful.
        !          113133:  *
        !          113134:  *     COHERENT Version 2.3.37
        !          113135:  *     Copyright (c) 1982, 1983, 1984.
        !          113136:  *     An unpublished work by Mark Williams Company, Chicago.
        !          113137:  *     All rights reserved.
        !          113138:  -lgl) */
        !          113139: /*
        !          113140:  * Coherent.
        !          113141:  * Buffered I/O.
        !          113142:  *
        !          113143:  * $Log:       /usr/src/sys/coh/RCS/bio.c,v $
        !          113144:  * Revision 1.1        88/03/24  16:13:29      src
        !          113145:  * Initial revision
        !          113146:  * 
        !          113147:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/bio.c
        !          113148:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          113149:  *
        !          113150:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/bio.c
        !          113151:  * New seg struct now used to allow extended addressing.
        !          113152:  *
        !          113153:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/bio.c
        !          113154:  * ioreq() now only wakes &stimer if the swap timer is active.
        !          113155:  *
        !          113156:  * 86/12/12    Allan Cornish           /usr/src/sys/coh/bio.c
        !          113157:  * Added 3rd arg to dpoll() to specify blocking poll if non-zero.
        !          113158:  *
        !          113159:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/bio.c
        !          113160:  * Added dpoll() routine to perform device polls [System V.3 compatible].
        !          113161:  *
        !          113162:  * 86/07/24    Allan Cornish           /usr/src/sys/coh/bio.c
        !          113163:  * Added check in devinit() for null dp->d_conp->c_load function pointer.
        !          113164:  */
        !          113165: #include <sys/coherent.h>
        !          113166: #include <sys/buf.h>
        !          113167: #include <sys/con.h>
        !          113168: #include <errno.h>
        !          113169: #include <sys/io.h>
        !          113170: #include <sys/proc.h>
        !          113171: #include <sys/sched.h>
        !          113172: #include <sys/seg.h>
        !          113173: #include <sys/stat.h>
        !          113174: #include <sys/uproc.h>
        !          113175: 
        !          113176: /*
        !          113177:  * Initialise buffer headers.
        !          113178:  */
        !          113179: bufinit()
        !          113180: {
        !          113181:        register BUF *bp;
        !          113182:        faddr_t f;
        !          113183:        paddr_t p;
        !          113184: 
        !          113185:        FP_SEL(f) = sds;
        !          113186:        FP_OFF(f) = 0;
        !          113187:        p = blockp;
        !          113188:        FP_OFF(f) = blockp - vtop(f);
        !          113189: 
        !          113190:        bufl = kalloc(NBUF * sizeof(BUF));
        !          113191:        if (bufl == NULL)
        !          113192:                panic("bufinit: no space for BUF's");
        !          113193: 
        !          113194:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          113195:                bp->b_dev = NODEV;
        !          113196:                bp->b_faddr = f;
        !          113197:                bp->b_paddr = p;
        !          113198:                FP_OFF(f) += BSIZE;
        !          113199:                p += BSIZE;
        !          113200:        }
        !          113201: }
        !          113202: 
        !          113203: /*
        !          113204:  * Synchronise the buffer cache.
        !          113205:  */
        !          113206: bsync()
        !          113207: {
        !          113208:        register BUF *bp;
        !          113209: 
        !          113210:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          113211:                if ((bp->b_flag&BFMOD) == 0)
        !          113212:                        continue;
        !          113213:                lock(bp->b_gate);
        !          113214:                if ((bp->b_flag&BFMOD) != 0)
        !          113215:                        bwrite(bp, 1);
        !          113216:                unlock(bp->b_gate);
        !          113217:        }
        !          113218: }
        !          113219: 
        !          113220: /*
        !          113221:  * Synchronise all block for a particular device in the buffer cache
        !          113222:  * and invalidate all references.
        !          113223:  */
        !          113224: bflush(dev)
        !          113225: register dev_t dev;
        !          113226: {
        !          113227:        register BUF *bp;
        !          113228: 
        !          113229:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          113230:                if (bp->b_dev != dev)
        !          113231:                        continue;
        !          113232:                lock(bp->b_gate);
        !          113233:                if (bp->b_dev == dev) {
        !          113234:                        if ((bp->b_flag&BFMOD) != 0)
        !          113235:                                bwrite(bp, 1);
        !          113236:                        bp->b_dev = NODEV;
        !          113237:                }
        !          113238:                unlock(bp->b_gate);
        !          113239:        }
        !          113240: }
        !          113241: 
        !          113242: /*
        !          113243:  * Return a buffer containing the given block from the given device.
        !          113244:  * If `f' is not set, the read is asynchronous and no buffer is returned.
        !          113245:  */
        !          113246: BUF *
        !          113247: bread(dev, bno, f)
        !          113248: dev_t dev;
        !          113249: daddr_t bno;
        !          113250: register int f;
        !          113251: {
        !          113252:        register BUF *bp;
        !          113253:        register int s;
        !          113254: 
        !          113255:        bp = bclaim(dev, bno);
        !          113256:        if ((bp->b_flag&BFNTP) != 0) {
        !          113257:                if (f != 0)
        !          113258:                        bp->b_flag &= ~BFASY;
        !          113259:                else {
        !          113260:                        bp->b_flag |= BFASY;
        !          113261:                        bumap(bp);
        !          113262:                }
        !          113263:                bp->b_req = BREAD;
        !          113264:                bp->b_count = BSIZE;
        !          113265:                s = sphi();
        !          113266:                dblock(dev, bp);
        !          113267:                if (f == 0) {
        !          113268:                        spl(s);
        !          113269:                        return (NULL);
        !          113270:                }
        !          113271:                while ((bp->b_flag&BFNTP) != 0)
        !          113272:                        sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          113273:                spl(s);
        !          113274:                if ((bp->b_flag&BFERR) != 0) {
        !          113275:                        u.u_error = bp->b_err ? bp->b_err : EIO;
        !          113276:                        brelease(bp);
        !          113277:                        return (NULL);
        !          113278:                }
        !          113279:                if (bp->b_resid == BSIZE) {
        !          113280:                        brelease(bp);
        !          113281:                        return (NULL);
        !          113282:                }
        !          113283:        }
        !          113284:        if (f == 0) {
        !          113285:                brelease(bp);
        !          113286:                return (NULL);
        !          113287:        }
        !          113288:        u.u_block++;
        !          113289:        return (bp);
        !          113290: }
        !          113291: 
        !          113292: /*
        !          113293:  * If the requested buffer is in the buffer cache, return a pointer to
        !          113294:  * it.  If not, pick an empty buffer, set it up and return it.
        !          113295:  */
        !          113296: BUF *
        !          113297: bclaim(dev, bno)
        !          113298: dev_t dev;
        !          113299: daddr_t bno;
        !          113300: {
        !          113301:        register BUF *bp;
        !          113302:        register BUF *bp1;
        !          113303:        register unsigned seqn;
        !          113304:        register int s;
        !          113305: 
        !          113306: again:
        !          113307:        bp1 = NULL;
        !          113308:        seqn = 0;
        !          113309:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          113310:                if (bp->b_bno == bno  &&  bp->b_dev == dev) {
        !          113311:                        lock(bp->b_gate);
        !          113312:                        if (bp->b_bno != bno  ||  bp->b_dev != dev) {
        !          113313:                                unlock(bp->b_gate);
        !          113314:                                goto again;
        !          113315:                        }
        !          113316:                        if ((bp->b_flag&BFERR) != 0)
        !          113317:                                bp->b_flag |= BFNTP;
        !          113318:                        bsmap(bp);
        !          113319:                        return (bp);
        !          113320:                }
        !          113321:                if (locked(bp->b_gate) == 0) {
        !          113322:                        if (bufseqn-bp->b_seqn >= seqn) {
        !          113323:                                bp1 = bp;
        !          113324:                                seqn = bufseqn - bp->b_seqn;
        !          113325:                        }
        !          113326:                }
        !          113327:        }
        !          113328:        if (bp1 == NULL) {
        !          113329:                s = sphi();
        !          113330:                for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
        !          113331:                        if (locked(bp->b_gate) == 0) {
        !          113332:                                if (bufseqn-bp->b_seqn >= seqn) {
        !          113333:                                        bp1 = bp;
        !          113334:                                        seqn = bufseqn - bp->b_seqn;
        !          113335:                                }
        !          113336:                        }
        !          113337:                }
        !          113338:                if (bp1 == NULL) {
        !          113339:                        bufneed = 1;
        !          113340:                        sleep((char *)&bufneed, CVBLKIO, IVBLKIO, SVBLKIO);
        !          113341:                        spl(s);
        !          113342:                        goto again;
        !          113343:                }
        !          113344:                spl(s);
        !          113345:        }
        !          113346:        bp = bp1;
        !          113347:        lock(bp->b_gate);
        !          113348:        if ((bp->b_flag&BFMOD) != 0) {
        !          113349:                bwrite(bp, 0);
        !          113350:                goto again;
        !          113351:        }
        !          113352:        bp->b_flag = BFNTP;
        !          113353:        bp->b_dev = dev;
        !          113354:        bp->b_bno = bno;
        !          113355:        bsmap(bp);
        !          113356:        return (bp);
        !          113357: }
        !          113358: 
        !          113359: /*
        !          113360:  * Write the given buffer out.  If `f' is set, the write is synchronous,
        !          113361:  * otherwise asynchronous.  This routine must be called with the buffer
        !          113362:  * gate locked.
        !          113363:  */
        !          113364: bwrite(bp, f)
        !          113365: register BUF *bp;
        !          113366: {
        !          113367:        register int s;
        !          113368: 
        !          113369:        if (f != 0)
        !          113370:                bp->b_flag &= ~BFASY;
        !          113371:        else {
        !          113372:                bp->b_flag |= BFASY;
        !          113373:                bumap(bp);
        !          113374:        }
        !          113375:        bp->b_flag |= BFNTP;
        !          113376:        bp->b_req = BWRITE;
        !          113377:        bp->b_count = BSIZE;
        !          113378:        s = sphi();
        !          113379:        dblock(bp->b_dev, bp);
        !          113380:        if (f == 0) {
        !          113381:                spl(s);
        !          113382:                return;
        !          113383:        }
        !          113384:        while ((bp->b_flag&BFNTP) != 0)
        !          113385:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          113386:        spl(s);
        !          113387: }
        !          113388: 
        !          113389: /*
        !          113390:  * This is called by the driver when I/O has completed on a buffer.
        !          113391:  */
        !          113392: bdone(bp)
        !          113393: register BUF *bp;
        !          113394: {
        !          113395:        if (bp->b_req == BWRITE)
        !          113396:                bp->b_flag &= ~BFMOD;
        !          113397:        if (bp->b_req == BREAD) {
        !          113398:                if ((bp->b_flag&BFERR) != 0)
        !          113399:                        bp->b_dev = NODEV;
        !          113400:        }
        !          113401:        if ((bp->b_flag&BFASY) != 0) {
        !          113402:                bp->b_flag &= ~BFASY;
        !          113403:                brelease(bp);
        !          113404:        }
        !          113405:        bp->b_flag &= ~BFNTP;
        !          113406:        wakeup((char *)bp);
        !          113407: }
        !          113408: 
        !          113409: /*
        !          113410:  * Release the given buffer.
        !          113411:  */
        !          113412: brelease(bp)
        !          113413: register BUF *bp;
        !          113414: {
        !          113415:        if ((bp->b_flag&BFERR) == 0)
        !          113416:                bp->b_seqn = bufseqn++;
        !          113417:        else {
        !          113418:                bp->b_flag &= ~BFERR;
        !          113419:                bp->b_dev = NODEV;
        !          113420:        }
        !          113421:        bp->b_flag &= ~BFNTP;
        !          113422:        bumap(bp);
        !          113423:        unlock(bp->b_gate);
        !          113424:        if (bufneed != 0) {
        !          113425:                bufneed = 0;
        !          113426:                wakeup((char *)&bufneed);
        !          113427:        }
        !          113428: }
        !          113429: 
        !          113430: /*
        !          113431:  * Map the given buffer.
        !          113432:  */
        !          113433: bsmap(bp)
        !          113434: register BUF *bp;
        !          113435: {
        !          113436:        bsave(bp->b_map);
        !          113437:        bp->b_flag |= BFMAP;
        !          113438:        bmapv(bconv(bp->b_paddr));
        !          113439: }
        !          113440: 
        !          113441: /*
        !          113442:  * Unmap the given buffer.
        !          113443:  */
        !          113444: bumap(bp)
        !          113445: register BUF *bp;
        !          113446: {
        !          113447:        if ((bp->b_flag&BFMAP) == 0)
        !          113448:                return;
        !          113449:        bp->b_flag &= ~BFMAP;
        !          113450:        brest(bp->b_map);
        !          113451: }
        !          113452: 
        !          113453: /*
        !          113454:  * Read data from the I/O segment into kernel space.
        !          113455:  */
        !          113456: ioread(iop, v, n)
        !          113457: register IO *iop;
        !          113458: register char *v;
        !          113459: register unsigned n;
        !          113460: {
        !          113461:        switch (iop->io_seg) {
        !          113462:        case IOSYS:
        !          113463:                iop->io_base += kkcopy(iop->io_base, v, n);
        !          113464:                break;
        !          113465:        case IOUSR:
        !          113466:                iop->io_base += ukcopy(iop->io_base, v, n);
        !          113467:                break;
        !          113468:        case IOPHY:
        !          113469:                iop->io_phys += pkcopy(iop->io_phys, v, n);
        !          113470:                break;
        !          113471:        }
        !          113472:        iop->io_ioc -= n;
        !          113473: }
        !          113474: 
        !          113475: /*
        !          113476:  * Write data from kernel space to the I/O segment.
        !          113477:  */
        !          113478: iowrite(iop, v, n)
        !          113479: register IO *iop;
        !          113480: register char *v;
        !          113481: register unsigned n;
        !          113482: {
        !          113483:        switch (iop->io_seg) {
        !          113484:        case IOSYS:
        !          113485:                iop->io_base += kkcopy(v, iop->io_base, n);
        !          113486:                break;
        !          113487:        case IOUSR:
        !          113488:                iop->io_base += kucopy(v, iop->io_base, n);
        !          113489:                break;
        !          113490:        case IOPHY:
        !          113491:                iop->io_phys += kpcopy(v, iop->io_phys, n);
        !          113492:                break;
        !          113493:        }
        !          113494:        iop->io_ioc -= n;
        !          113495: }
        !          113496: 
        !          113497: /*
        !          113498:  * Get a character from the I/O segment.
        !          113499:  */
        !          113500: iogetc(iop)
        !          113501: register IO *iop;
        !          113502: {
        !          113503:        register int c;
        !          113504: 
        !          113505:        if (iop->io_ioc == 0)
        !          113506:                return (-1);
        !          113507:        --iop->io_ioc;
        !          113508:        if (iop->io_seg == IOSYS)
        !          113509:                c = *iop->io_base++ & 0377;
        !          113510:        else {
        !          113511:                c = getubd(iop->io_base++);
        !          113512:                if (u.u_error)
        !          113513:                        return (-1);
        !          113514:        }
        !          113515:        return (c);
        !          113516: }
        !          113517: 
        !          113518: /*
        !          113519:  * Put a character using the I/O segment.
        !          113520:  */
        !          113521: ioputc(c, iop)
        !          113522: register IO *iop;
        !          113523: {
        !          113524:        if (iop->io_ioc == 0)
        !          113525:                return (-1);
        !          113526:        --iop->io_ioc;
        !          113527:        if (iop->io_seg == IOSYS)
        !          113528:                *iop->io_base++ = c;
        !          113529:        else {
        !          113530:                putubd(iop->io_base++, c);
        !          113531:                if (u.u_error)
        !          113532:                        return (-1);
        !          113533:        }
        !          113534:        return (c);
        !          113535: }
        !          113536: 
        !          113537: /*
        !          113538:  * Given a buffer pointer, an I/O structure, a device, request type, and
        !          113539:  * a flags word, check the I/O structure and perform the I/O request.
        !          113540:  */
        !          113541: ioreq(bp, iop, dev, req, f)
        !          113542: register BUF *bp;
        !          113543: register IO *iop;
        !          113544: dev_t dev;
        !          113545: {
        !          113546:        register SEG *sp;
        !          113547:        register int n;
        !          113548:        register int s;
        !          113549:        register CON *cp;
        !          113550:        dold_t dold;
        !          113551: 
        !          113552:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113553:                return;
        !          113554:        lock(bp->b_gate);
        !          113555:        n = cp->c_flag; /* n should do something with that flag */
        !          113556:        drest(dold);
        !          113557:        sp = NULL;
        !          113558:        if (iop != NULL) {
        !          113559:                if ((f&BFBLK) != 0) {
        !          113560:                        if (blocko(iop->io_seek) != 0) {
        !          113561:                                u.u_error = EIO;
        !          113562:                                goto out;
        !          113563:                        }
        !          113564:                }
        !          113565:                if ((f&BFIOC) != 0) {
        !          113566:                        if ((sp=iomapvp(iop, bp)) == NULL) {
        !          113567:                                u.u_error = EIO;
        !          113568:                                goto out;
        !          113569:                        }
        !          113570:                }
        !          113571:        }
        !          113572:        bp->b_flag = f|BFNTP;
        !          113573:        bp->b_req = req;
        !          113574:        bp->b_dev = dev;
        !          113575:        if (iop != NULL) {
        !          113576:                bp->b_bno = blockn(iop->io_seek);
        !          113577:                bp->b_count = iop->io_ioc;
        !          113578:        }
        !          113579:        if (sp != NULL) {
        !          113580:                bp->b_faddr = ptov( bp->b_paddr, (fsize_t) bp->b_count );
        !          113581:                sp->s_lrefc++;
        !          113582:        }
        !          113583:        s = sphi();
        !          113584:        dblock(dev, bp);
        !          113585:        while ((bp->b_flag&BFNTP) != 0)
        !          113586:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          113587:        spl(s);
        !          113588:        if (sp != NULL) {
        !          113589:                vrelse( bp->b_faddr );
        !          113590:                sp->s_lrefc--;
        !          113591:        }
        !          113592:        if (stimer.t_last != 0)
        !          113593:                wakeup((char *)&stimer);
        !          113594:        if ((bp->b_flag&BFERR) != 0) {
        !          113595:                u.u_error = bp->b_err ? bp->b_err : EIO;
        !          113596:                goto out;
        !          113597:        }
        !          113598:        if (iop != NULL) {
        !          113599:                n = iop->io_ioc - bp->b_resid;
        !          113600:                iop->io_seek += n;
        !          113601:                iop->io_ioc -= n;
        !          113602:        }
        !          113603: out:
        !          113604:        unlock(bp->b_gate);
        !          113605: }
        !          113606: 
        !          113607: /*
        !          113608:  * Given an I/O structure and a buffer header, see if the addresses
        !          113609:  * in the I/O structure are valid and set up the buffer header.
        !          113610:  */
        !          113611: SEG *
        !          113612: iomapvp(iop, bp)
        !          113613: register IO *iop;
        !          113614: register BUF *bp;
        !          113615: {
        !          113616:        register SR *srp;
        !          113617:        register SEG *sp;
        !          113618:        register vaddr_t b;
        !          113619: 
        !          113620:        if (iop->io_seg != IOUSR)
        !          113621:                panic("Raw I/O from non user");
        !          113622:        for (srp=u.u_segl; srp<&u.u_segl[NUSEG]; srp++) {
        !          113623:                if ((sp=srp->sr_segp) == NULL)
        !          113624:                        continue;
        !          113625:                if ((srp->sr_flag&SRFDATA) == 0)
        !          113626:                        continue;
        !          113627: /* Yet another bug in the 8000 C compiler
        !          113628:                if ((long)(b=iop->io_base) < (long)srp->sr_base)
        !          113629: */
        !          113630:                if ((b=iop->io_base) < srp->sr_base)
        !          113631:                        continue;
        !          113632:                if ((long)b+iop->io_ioc > (long)srp->sr_base + sp->s_size)
        !          113633:                        continue;
        !          113634:                bp->b_paddr = sp->s_paddr + (vaddr_t) (b - srp->sr_base);
        !          113635:                return (sp);
        !          113636:        }
        !          113637:        return (NULL);
        !          113638: }
        !          113639: 
        !          113640: /*
        !          113641:  * Initialise devices.
        !          113642:  */
        !          113643: devinit()
        !          113644: {
        !          113645:        register DRV *dp;
        !          113646:        register int mind;
        !          113647: 
        !          113648:        for ( dp = drvl, mind = 0; mind < drvn; mind++, dp++ ) {
        !          113649:                if ((dp->d_conp != NULL) && (dp->d_conp->c_load != NULL)) {
        !          113650:                        (*dp->d_conp->c_load)();
        !          113651:                }
        !          113652:        }
        !          113653: }
        !          113654: 
        !          113655: /*
        !          113656:  * Open a device.
        !          113657:  */
        !          113658: dopen(dev, m, f)
        !          113659: register dev_t dev;
        !          113660: {
        !          113661:        register CON *cp;
        !          113662:        dold_t dold;
        !          113663: 
        !          113664:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113665:                return;
        !          113666:        if ((cp->c_flag&f) == 0) {
        !          113667:                u.u_error = ENXIO;
        !          113668:                return;
        !          113669:        }
        !          113670:        (*cp->c_open)(dev, m);
        !          113671:        drest(dold);
        !          113672: }
        !          113673: 
        !          113674: /*
        !          113675:  * Close a device.
        !          113676:  */
        !          113677: dclose(dev)
        !          113678: register dev_t dev;
        !          113679: {
        !          113680:        register CON *cp;
        !          113681:        dold_t dold;
        !          113682: 
        !          113683:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113684:                return;
        !          113685:        (*cp->c_close)(dev);
        !          113686:        drest(dold);
        !          113687: }
        !          113688: 
        !          113689: /*
        !          113690:  * Call the block entry point of a device.
        !          113691:  */
        !          113692: dblock(dev, bp)
        !          113693: dev_t dev;
        !          113694: BUF *bp;
        !          113695: {
        !          113696:        register CON *cp;
        !          113697:        dold_t dold;
        !          113698: 
        !          113699:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113700:                return;
        !          113701:        (*cp->c_block)(bp);
        !          113702:        drest(dold);
        !          113703: }
        !          113704: 
        !          113705: /*
        !          113706:  * Read from a device.
        !          113707:  */
        !          113708: dread(dev, iop)
        !          113709: register dev_t dev;
        !          113710: register IO *iop;
        !          113711: {
        !          113712:        register CON *cp;
        !          113713:        dold_t dold;
        !          113714: 
        !          113715:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113716:                return;
        !          113717:        (*cp->c_read)(dev, iop);
        !          113718:        drest(dold);
        !          113719: }
        !          113720: 
        !          113721: /*
        !          113722:  * Write to a device.
        !          113723:  */
        !          113724: dwrite(dev, iop)
        !          113725: register dev_t dev;
        !          113726: register IO *iop;
        !          113727: {
        !          113728:        register CON *cp;
        !          113729:        dold_t dold;
        !          113730: 
        !          113731:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113732:                return;
        !          113733:        (*cp->c_write)(dev, iop);
        !          113734:        drest(dold);
        !          113735: }
        !          113736: 
        !          113737: /*
        !          113738:  * Call the ioctl function for a device.
        !          113739:  */
        !          113740: dioctl(dev, com, vec)
        !          113741: register dev_t dev;
        !          113742: union ioctl *vec;
        !          113743: {
        !          113744:        register CON *cp;
        !          113745:        dold_t dold;
        !          113746: 
        !          113747:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113748:                return;
        !          113749:        (*cp->c_ioctl)(dev, com, vec);
        !          113750:        drest(dold);
        !          113751: }
        !          113752: 
        !          113753: /*
        !          113754:  * Call the powerfail entry point of a device.
        !          113755:  */
        !          113756: dpower(dev)
        !          113757: register dev_t dev;
        !          113758: {
        !          113759:        register CON *cp;
        !          113760:        dold_t dold;
        !          113761: 
        !          113762:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113763:                return;
        !          113764:        (*cp->c_power)(dev);
        !          113765:        drest(dold);
        !          113766: }
        !          113767: 
        !          113768: /*
        !          113769:  * Call the timeout entry point of a device.
        !          113770:  */
        !          113771: dtime(dev)
        !          113772: register dev_t dev;
        !          113773: {
        !          113774:        register CON *cp;
        !          113775:        dold_t dold;
        !          113776: 
        !          113777:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113778:                return;
        !          113779:        (*cp->c_timer)(dev);
        !          113780:        drest(dold);
        !          113781: }
        !          113782: 
        !          113783: /*
        !          113784:  * Poll a device.
        !          113785:  */
        !          113786: dpoll(dev, ev, msec)
        !          113787: register dev_t dev;
        !          113788: int ev;
        !          113789: int msec;
        !          113790: {
        !          113791:        register CON *cp;
        !          113792:        dold_t dold;
        !          113793: 
        !          113794:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113795:                return POLLNVAL;
        !          113796: 
        !          113797:        if ( cp->c_flag & DFPOL )
        !          113798:                ev = (*cp->c_poll)(dev, ev, msec);
        !          113799:        else
        !          113800:                ev = POLLNVAL;
        !          113801: 
        !          113802:        drest(dold);
        !          113803:        return ev;
        !          113804: }
        !          113805: 
        !          113806: /*
        !          113807:  * Given a device, return the flags word.
        !          113808:  */
        !          113809: dflag(dev)
        !          113810: dev_t dev;
        !          113811: {
        !          113812:        register CON *cp;
        !          113813:        register int f;
        !          113814:        dold_t dold;
        !          113815: 
        !          113816:        if ((cp=drvmap(dev, &dold)) == NULL)
        !          113817:                return (DFERR);
        !          113818:        f = cp->c_flag;
        !          113819:        drest(dold);
        !          113820:        return (f);
        !          113821: }
        !          113822: 
        !          113823: /*
        !          113824:  * Given a device, and a pointer to a driver map save area, save the
        !          113825:  * current map in the driver map save area and map in the new device,
        !          113826:  * returning a pointer to the configuration entry for that device.
        !          113827:  */
        !          113828: CON *
        !          113829: drvmap(dev, doldp)
        !          113830: dev_t dev;
        !          113831: dold_t *doldp;
        !          113832: {
        !          113833:        register DRV *dp;
        !          113834:        register unsigned m;
        !          113835: 
        !          113836:        if ((m=major(dev)) >= drvn) {
        !          113837:                u.u_error = ENXIO;
        !          113838:                return (NULL);
        !          113839:        }
        !          113840:        dp = &drvl[m];
        !          113841:        if (locked(dp->d_gate)) {
        !          113842:                u.u_error = ENXIO;
        !          113843:                return (NULL);
        !          113844:        }
        !          113845:        if (dp->d_conp == NULL) {
        !          113846:                u.u_error = ENXIO;
        !          113847:                return (NULL);
        !          113848:        }
        !          113849:        dsave(*doldp);
        !          113850:        if (dp->d_map != 0)
        !          113851:                dmapv(dp->d_map);
        !          113852:        return (dp->d_conp);
        !          113853: }
        !          113854: 
        !          113855: /*
        !          113856:  * Non existant device.
        !          113857:  */
        !          113858: nonedev()
        !          113859: {
        !          113860:        u.u_error = ENXIO;
        !          113861: }
        !          113862: 
        !          113863: /*
        !          113864:  * Null device.
        !          113865:  */
        !          113866: nulldev()
        !          113867: {
        !          113868: }
        !          113869: @
        !          113870: 
        !          113871: 
        !          113872: 1.3
        !          113873: log
        !          113874: @update by hal
        !          113875: @
        !          113876: text
        !          113877: @@
        !          113878: 
        !          113879: 
        !          113880: 1.2
        !          113881: log
        !          113882: @update provided by hal
        !          113883: @
        !          113884: text
        !          113885: @@
        !          113886: 
        !          113887: 
        !          113888: 1.1
        !          113889: log
        !          113890: @Initial revision
        !          113891: @
        !          113892: text
        !          113893: @d41 1
        !          113894: a41 1
        !          113895: #include <coherent.h>
        !          113896: d47 1
        !          113897: a47 1
        !          113898: #include <sched.h>
        !          113899: @
        !          113900: 0707070064030000521004440000030000030000011777770507310733600005100000006714/newbits/kernel/USRSRC/coh/RCS/clist.c,vhead     1.4;
        !          113901: branch   ;
        !          113902: access   ;
        !          113903: symbols  ;
        !          113904: locks    bin:1.4;
        !          113905: comment  @ * @;
        !          113906: 
        !          113907: 
        !          113908: 1.4
        !          113909: date     91.07.24.07.50.03;  author bin;  state Exp;
        !          113910: branches ;
        !          113911: next     1.3;
        !          113912: 
        !          113913: 1.3
        !          113914: date     91.07.15.14.31.43;  author bin;  state Exp;
        !          113915: branches ;
        !          113916: next     1.2;
        !          113917: 
        !          113918: 1.2
        !          113919: date     91.06.20.14.29.34;  author bin;  state Exp;
        !          113920: branches ;
        !          113921: next     1.1;
        !          113922: 
        !          113923: 1.1
        !          113924: date     91.06.10.14.36.53;  author bin;  state Exp;
        !          113925: branches ;
        !          113926: next     ;
        !          113927: 
        !          113928: 
        !          113929: desc
        !          113930: @initial version prov by hal
        !          113931: @
        !          113932: 
        !          113933: 
        !          113934: 1.4
        !          113935: log
        !          113936: @update prov by hal
        !          113937: 
        !          113938: @
        !          113939: text
        !          113940: @/* $Header: /usr/src/sys/coh/RCS/clist.c,v 1.1 88/03/24 16:13:33 src Exp $ */
        !          113941: /* (lgl-
        !          113942:  *     The information contained herein is a trade secret of Mark Williams
        !          113943:  *     Company, and  is confidential information.  It is provided  under a
        !          113944:  *     license agreement,  and may be  copied or disclosed  only under the
        !          113945:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          113946:  *     material without the express written authorization of Mark Williams
        !          113947:  *     Company or persuant to the license agreement is unlawful.
        !          113948:  *
        !          113949:  *     COHERENT Version 2.3.37
        !          113950:  *     Copyright (c) 1982, 1983, 1984.
        !          113951:  *     An unpublished work by Mark Williams Company, Chicago.
        !          113952:  *     All rights reserved.
        !          113953:  -lgl) */
        !          113954: /*
        !          113955:  * Coherent.
        !          113956:  * Character list management.
        !          113957:  *
        !          113958:  * $Log:       /usr/src/sys/coh/RCS/clist.c,v $
        !          113959:  * Revision 1.1        88/03/24  16:13:33      src
        !          113960:  * Initial revision
        !          113961:  * 
        !          113962:  */
        !          113963: #include <sys/coherent.h>
        !          113964: #include <clist.h>
        !          113965: #include <sched.h>
        !          113966: 
        !          113967: /*
        !          113968:  * Initialise character list queues.
        !          113969:  */
        !          113970: cltinit()
        !          113971: {
        !          113972:        register cmap_t cm;
        !          113973:        register cmap_t lm;
        !          113974:        register paddr_t p;
        !          113975:        register int s;
        !          113976:        cold_t om;
        !          113977: 
        !          113978:        s = sphi();
        !          113979:        csave(om);
        !          113980:        lm = 0;
        !          113981:        for (p = clistp+NCLIST*sizeof(CLIST); (p-=sizeof(CLIST)) >= clistp; ) {
        !          113982:                cm = cconv(p);
        !          113983:                cmapv(cm);
        !          113984:                cvirt(cm)->cl_fp = lm;
        !          113985:                lm = cm;
        !          113986:        }
        !          113987:        cltfree = lm;
        !          113988:        crest(om);
        !          113989:        spl(s);
        !          113990: }
        !          113991: 
        !          113992: /*
        !          113993:  * Get a character from the given queue.
        !          113994:  */
        !          113995: getq(cqp)
        !          113996: register CQUEUE *cqp;
        !          113997: {
        !          113998:        register cmap_t op;
        !          113999:        register cmap_t np;
        !          114000:        register int ox;
        !          114001:        register int c;
        !          114002:        register int s;
        !          114003:        cold_t om;
        !          114004: 
        !          114005:        if (cqp->cq_cc == 0)
        !          114006:                return (-1);
        !          114007:        s = sphi();
        !          114008:        op = cqp->cq_op;
        !          114009:        ox = cqp->cq_ox;
        !          114010:        csave(om);
        !          114011:        cmapv(op);
        !          114012:        c = cvirt(op)->cl_ch[ox]&0377;
        !          114013:        crest(om);
        !          114014:        if (--cqp->cq_cc==0 || ++cqp->cq_ox==NCPCL) {
        !          114015:                cqp->cq_ox = 0;
        !          114016:                cmapv(op);
        !          114017:                np = cvirt(op)->cl_fp;
        !          114018:                cvirt(op)->cl_fp = cltfree;
        !          114019:                crest(om);
        !          114020:                cqp->cq_op = np;
        !          114021:                cltfree = op;
        !          114022:                if (np == 0) {
        !          114023:                        cqp->cq_ip = 0;
        !          114024:                        cqp->cq_ix = 0;
        !          114025:                }
        !          114026:                if (cltwant) {
        !          114027:                        cltwant = 0;
        !          114028:                        wakeup((char *)&cltwant);
        !          114029:                }
        !          114030:        }
        !          114031:        spl(s);
        !          114032:        return (c);
        !          114033: }
        !          114034: 
        !          114035: /*
        !          114036:  * Put a character on the given queue.
        !          114037:  */
        !          114038: putq(cqp, c)
        !          114039: register CQUEUE *cqp;
        !          114040: {
        !          114041:        register cmap_t ip;
        !          114042:        register int ix;
        !          114043:        register int s;
        !          114044:        register cmap_t np;
        !          114045:        cold_t om;
        !          114046: 
        !          114047:        s = sphi();
        !          114048:        ip = cqp->cq_ip;
        !          114049:        csave(om);
        !          114050:        if ((ix=cqp->cq_ix) == 0) {
        !          114051:                if ((ip=cltfree) == 0) {
        !          114052:                        spl(s);
        !          114053:                        return (-1);
        !          114054:                }
        !          114055:                cmapv(ip);
        !          114056:                cltfree = cvirt(ip)->cl_fp;
        !          114057:                cvirt(ip)->cl_fp = 0;
        !          114058:                crest(om);
        !          114059:                if ((np=cqp->cq_ip) == 0)
        !          114060:                        cqp->cq_op = ip;
        !          114061:                else {
        !          114062:                        cmapv(np);
        !          114063:                        cvirt(np)->cl_fp = ip;
        !          114064:                        crest(om);
        !          114065:                }
        !          114066:                cqp->cq_ip = ip;
        !          114067:        }
        !          114068:        cmapv(ip);
        !          114069:        cvirt(ip)->cl_ch[ix] = c;
        !          114070:        crest(om);
        !          114071:        if (++cqp->cq_ix == NCPCL)
        !          114072:                cqp->cq_ix = 0;
        !          114073:        cqp->cq_cc++;
        !          114074:        spl(s);
        !          114075:        return (c);
        !          114076: }
        !          114077: 
        !          114078: /*
        !          114079:  * Clear a character queue.
        !          114080:  */
        !          114081: clrq(cqp)
        !          114082: register CQUEUE *cqp;
        !          114083: {
        !          114084:        register int s;
        !          114085: 
        !          114086:        s = sphi();
        !          114087:        while (getq(cqp) >= 0)
        !          114088:                ;
        !          114089:        spl(s);
        !          114090: }
        !          114091: 
        !          114092: /*
        !          114093:  * Wait for more character queues to become available.
        !          114094:  */
        !          114095: waitq()
        !          114096: {
        !          114097:        while (cltfree == 0) {
        !          114098:                cltwant = 1;
        !          114099:                sleep((char *)&cltwant, CVCLIST, IVCLIST, SVCLIST);
        !          114100:        }
        !          114101: }
        !          114102: @
        !          114103: 
        !          114104: 
        !          114105: 1.3
        !          114106: log
        !          114107: @update by hal
        !          114108: @
        !          114109: text
        !          114110: @@
        !          114111: 
        !          114112: 
        !          114113: 1.2
        !          114114: log
        !          114115: @update provided by hal
        !          114116: @
        !          114117: text
        !          114118: @@
        !          114119: 
        !          114120: 
        !          114121: 1.1
        !          114122: log
        !          114123: @Initial revision
        !          114124: @
        !          114125: text
        !          114126: @d24 1
        !          114127: a24 1
        !          114128: #include <coherent.h>
        !          114129: @
        !          114130: 0707070064030053061004440000030000030000011777770507310733700005100000015375/newbits/kernel/USRSRC/coh/RCS/clock.c,vhead     1.2;
        !          114131: branch   ;
        !          114132: access   ;
        !          114133: symbols  ;
        !          114134: locks    bin:1.2;
        !          114135: comment  @ * @;
        !          114136: 
        !          114137: 
        !          114138: 1.2
        !          114139: date     91.06.20.14.29.38;  author bin;  state Exp;
        !          114140: branches ;
        !          114141: next     1.1;
        !          114142: 
        !          114143: 1.1
        !          114144: date     91.06.10.14.36.56;  author bin;  state Exp;
        !          114145: branches ;
        !          114146: next     ;
        !          114147: 
        !          114148: 
        !          114149: desc
        !          114150: @initial version prov by hal
        !          114151: @
        !          114152: 
        !          114153: 
        !          114154: 1.2
        !          114155: log
        !          114156: @update provided by hal
        !          114157: @
        !          114158: text
        !          114159: @/* $Header: /x/usr/src/sys/coh/RCS/clock.c,v 1.2 91/06/20 14:12:44 hal Exp $ */
        !          114160: /* (lgl-
        !          114161:  *     The information contained herein is a trade secret of Mark Williams
        !          114162:  *     Company, and  is confidential information.  It is provided  under a
        !          114163:  *     license agreement,  and may be  copied or disclosed  only under the
        !          114164:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          114165:  *     material without the express written authorization of Mark Williams
        !          114166:  *     Company or persuant to the license agreement is unlawful.
        !          114167:  *
        !          114168:  *     COHERENT Version 2.3.37
        !          114169:  *     Copyright (c) 1982, 1983, 1984.
        !          114170:  *     An unpublished work by Mark Williams Company, Chicago.
        !          114171:  *     All rights reserved.
        !          114172:  -lgl) */
        !          114173: /*
        !          114174:  * Coherent.
        !          114175:  * Clock.
        !          114176:  * The clock comes in two parts.  There is the routine `clock' which
        !          114177:  * gets called every tick at high priority.  It does the minimum it
        !          114178:  * can and returns as soon as possible.  The second routine, `stand',
        !          114179:  * gets called whenever we are about to return from an interrupt to
        !          114180:  * user mode a low priority.  It can look at flags that the clock set
        !          114181:  * and do the things the clock really wanted to do but didn't have time.
        !          114182:  * Stand is truly the kernel of the system.
        !          114183:  *
        !          114184:  * 90/08/13    Hal Snyder              /usr/src/sys/coh/clock.c
        !          114185:  * Add external altclk to allow polled device drivers.
        !          114186:  * (extern'ed in coherent.h)
        !          114187:  * 
        !          114188:  * 87/10/26    Allan cornish           /usr/src/sys/coh/clock.c
        !          114189:  * Timed functions are now invoked with TIM * tp as second argument.
        !          114190:  * This facilitates the use of timed functions within loadable drivers.
        !          114191:  *
        !          114192:  * 87/07/07    Allan Cornish           /usr/src/sys/coh/clock.c
        !          114193:  * Clocks static variable added - incremented by clock, decremented by stand().
        !          114194:  * Lbolt variable added - clock ticks since startup - incremented by stand().
        !          114195:  * Support for multiple timing queues ported from RTX.
        !          114196:  *
        !          114197:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/clock.c
        !          114198:  * stand() now only wakes &stimer if swap timer is active.
        !          114199:  *
        !          114200:  * 86/11/24    Allan Cornish           /usr/src/sys/coh/clock.c
        !          114201:  * Added support for new t_last field in tim struct.
        !          114202:  *
        !          114203:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/clock.c
        !          114204:  * Stand() calls defend() to execute functions deferred from interrupt level.
        !          114205:  */
        !          114206: #include <sys/coherent.h>
        !          114207: #include <sys/con.h>
        !          114208: #include <sys/proc.h>
        !          114209: #include <sys/sched.h>
        !          114210: #include <sys/stat.h>
        !          114211: #include <sys/timeout.h>
        !          114212: #include <sys/uproc.h>
        !          114213: #include <sys/mdata.h>
        !          114214: 
        !          114215: int (*altclk)();       /* pointer to higher-speed clock function */
        !          114216: int altsel;    /* if nonzero, CS for LOADABLE driver owning altclk() */
        !          114217: 
        !          114218: static int clocks;
        !          114219: 
        !          114220: /*
        !          114221:  * This routine is called once every tick (1/HZ seconds).
        !          114222:  * It gets called with the programme counter that was interrupted
        !          114223:  * a flag telling whether we were in user or kernel mode and the
        !          114224:  * previous priority we were in.
        !          114225:  */
        !          114226: clock(pc, umode)
        !          114227: vaddr_t pc;
        !          114228: {
        !          114229:        register PROC *pp;
        !          114230:        /*
        !          114231:         * Ignore clock interrupts till we are ready.
        !          114232:         */
        !          114233:        if (batflag == 0)
        !          114234:                return;
        !          114235: 
        !          114236:        /*
        !          114237:         * Hook for alternate clock interrupt;
        !          114238:         * Call polling function ("altclk") if there is one.
        !          114239:         *
        !          114240:         * For near function, "altsel" is 0 and "altclk" is offset.
        !          114241:         * For far function, "altsel" is the CS selector and "altclk"
        !          114242:         * is the offset.
        !          114243:         *
        !          114244:         * Since the polling function ends with a near rather than
        !          114245:         * far return, far invocation is via ld_call() (ldas.s) which uses
        !          114246:         * the despatch routine at CS:4 (ld.s) in any loadable driver.
        !          114247:         */
        !          114248:        if (altclk) {
        !          114249:                if (altsel) {   /* will do far call to altclk fn */
        !          114250:                        if (ld_call(altsel, altclk))
        !          114251:                                return;
        !          114252:                } else
        !          114253:                        if ((*altclk)())
        !          114254:                                return;
        !          114255:        }
        !          114256: 
        !          114257:        /*
        !          114258:         * Update timers.  Decrement time slice.
        !          114259:         */
        !          114260:        utimer += 1;
        !          114261:        clocks += 1;
        !          114262:        timer.t_tick += 1;
        !          114263:        quantum -= 1;
        !          114264: 
        !          114265:        /*
        !          114266:         * Give processes their schedule values per tick.
        !          114267:         */
        !          114268:        if (procq.p_lforw->p_cval > CVCLOCK) {
        !          114269:                procq.p_lforw->p_cval -= CVCLOCK;
        !          114270:                procq.p_cval += CVCLOCK;
        !          114271:        }
        !          114272: 
        !          114273:        /*
        !          114274:         * Tax current process and update his times.
        !          114275:         */
        !          114276:        pp = SELF;
        !          114277:        pp->p_cval >>= 1;
        !          114278:        if (umode == 0)
        !          114279:                pp->p_stime++;
        !          114280:        else {
        !          114281:                pp->p_utime++;
        !          114282:                u.u_ppc = pc;
        !          114283:        }
        !          114284: }
        !          114285: 
        !          114286: /*
        !          114287:  * Do everything the clock wanted to do but couldn't as it would have
        !          114288:  * taken too long.
        !          114289:  * Also perform any system bookkeeping required at regular intervals.
        !          114290:  */
        !          114291: stand()
        !          114292: {
        !          114293:        int s;
        !          114294: 
        !          114295:        u.u_error = 0;
        !          114296: 
        !          114297:        /*
        !          114298:         * Update the clock.
        !          114299:         */
        !          114300:        while (timer.t_tick >= HZ) {
        !          114301:                timer.t_time++;
        !          114302:                timer.t_tick -= HZ;
        !          114303:                outflag = 1;
        !          114304:        }
        !          114305: 
        !          114306:        /*
        !          114307:         * Check expiration of quantum.
        !          114308:         */
        !          114309:        if (quantum <= 0) {
        !          114310:                quantum = 0;
        !          114311:                disflag = 1;
        !          114312:        }
        !          114313: 
        !          114314:        /*
        !          114315:         * Check the timed function queue if necessary.
        !          114316:         */
        !          114317:        if ( clocks > 0 )
        !          114318:        do {
        !          114319:                register TIM * np;
        !          114320:                register TIM * tp;
        !          114321: 
        !          114322:                /*
        !          114323:                 * Update [serviced] clock ticks since startup.
        !          114324:                 */
        !          114325:                lbolt++;
        !          114326: 
        !          114327:                /*
        !          114328:                 * Remove timing list from queue, creating new temporary queue.
        !          114329:                 */
        !          114330:                tp = (TIM *) &timq[ lbolt % nel(timq) ];
        !          114331:                s  = sphi();
        !          114332: 
        !          114333:                /*
        !          114334:                 * Scan timing list.
        !          114335:                 */
        !          114336:                for ( np = tp->t_next; tp = np; ) {
        !          114337: 
        !          114338:                        /*
        !          114339:                         * Remember next function in timing list.
        !          114340:                         * NOTE: Must be done before function is invoked,
        !          114341:                         *       since it may start a new timer.
        !          114342:                         */
        !          114343:                        np = tp->t_next;
        !          114344: 
        !          114345:                        /*
        !          114346:                         * Function has not timed out: leave it on timing list.
        !          114347:                         */
        !          114348:                        if ( tp->t_lbolt != lbolt )
        !          114349:                                continue;
        !          114350: 
        !          114351:                        /*
        !          114352:                         * Remove function from timing list.
        !          114353:                         */
        !          114354:                        if ( tp->t_last->t_next = tp->t_next )
        !          114355:                                tp->t_next->t_last = tp->t_last;
        !          114356:                        tp->t_last = NULL;
        !          114357: 
        !          114358:                        /*
        !          114359:                         * Invoke function.
        !          114360:                         */
        !          114361:                        spl(s);
        !          114362:                        (*tp->t_func)( tp->t_farg, tp );
        !          114363:                        sphi();
        !          114364:                }
        !          114365: 
        !          114366:                spl( s );
        !          114367: 
        !          114368:        } while ( --clocks > 0 );
        !          114369: 
        !          114370:        /*
        !          114371:         * Timeout any devices.
        !          114372:         */
        !          114373:        if (outflag) {
        !          114374:                register int n;
        !          114375: 
        !          114376:                outflag = 0;
        !          114377:                for (n=0; n<drvn; n++) {
        !          114378:                        if (drvl[n].d_time == 0)
        !          114379:                                continue;
        !          114380:                        s = sphi();
        !          114381:                        dtime((dev_t)makedev(n, 0));
        !          114382:                        spl(s);
        !          114383:                }
        !          114384:        }
        !          114385: 
        !          114386:        /*
        !          114387:         * Do profiling.
        !          114388:         */
        !          114389:        if (u.u_pscale != 0) {
        !          114390:                register unsigned p;
        !          114391:                register vaddr_t a;
        !          114392: 
        !          114393:                p = u.u_pscale;
        !          114394:                a = (int *)u.u_pbase +
        !          114395:                    pscale(u.u_ppc-u.u_pofft, p/sizeof (int));
        !          114396:                if (a < u.u_pbend)
        !          114397:                        putuwd(a, getuwd(a)+1);
        !          114398:        }
        !          114399: 
        !          114400:        /*
        !          114401:         * Check for signals and execute them.
        !          114402:         */
        !          114403:        if (SELF->p_ssig)
        !          114404:                actvsig();
        !          114405: 
        !          114406:        /*
        !          114407:         * Execute deferred functions.
        !          114408:         */
        !          114409:        defend();
        !          114410: 
        !          114411:        /*
        !          114412:         * Should we dispatch?
        !          114413:         */
        !          114414:        if ((SELF->p_flags&PFDISP) != 0) {
        !          114415:                SELF->p_flags &= ~PFDISP;
        !          114416:                disflag = 1;
        !          114417:                if ( stimer.t_last != 0 )
        !          114418:                        wakeup((char *)&stimer);
        !          114419:        }
        !          114420: 
        !          114421: #ifdef QWAKEUP
        !          114422:        /*
        !          114423:         * Dispatch pending wakeups.
        !          114424:         */
        !          114425:        while (ntowake)
        !          114426:                wakeup2();
        !          114427: 
        !          114428: #endif
        !          114429:        /*
        !          114430:         * Redispatch.
        !          114431:         * This used to be a function call in tsave,
        !          114432:         * expanded in line here.
        !          114433:         */
        !          114434:        if (disflag) {
        !          114435:                register PROC *pp;
        !          114436: 
        !          114437: #ifndef QWAKEUP
        !          114438:                s=sphi();
        !          114439: #endif
        !          114440:                if ((pp=SELF)!=iprocp)
        !          114441:                        setrun(pp);
        !          114442:                dispatch();
        !          114443: #ifndef QWAKEUP
        !          114444:                spl(s);
        !          114445: #endif
        !          114446:        }
        !          114447: }
        !          114448: @
        !          114449: 
        !          114450: 
        !          114451: 1.1
        !          114452: log
        !          114453: @Initial revision
        !          114454: @
        !          114455: text
        !          114456: @d1 1
        !          114457: a1 1
        !          114458: /* $Header: /usr/src/sys/coh/RCS/clock.c,v 1.1 88/03/24 16:13:36 src Exp $ */
        !          114459: d28 1
        !          114460: a28 1
        !          114461:  * (extern'ed in /usr/src/sys/sys/coherent.h)
        !          114462: @
        !          114463: 0707070064030031551004440000030000030000011777770507310734100005000000032525/newbits/kernel/USRSRC/coh/RCS/exec.c,vhead     1.4;
        !          114464: branch   ;
        !          114465: access   ;
        !          114466: symbols  ;
        !          114467: locks    bin:1.4;
        !          114468: comment  @ * @;
        !          114469: 
        !          114470: 
        !          114471: 1.4
        !          114472: date     91.07.24.07.50.20;  author bin;  state Exp;
        !          114473: branches ;
        !          114474: next     1.3;
        !          114475: 
        !          114476: 1.3
        !          114477: date     91.07.15.14.31.51;  author bin;  state Exp;
        !          114478: branches ;
        !          114479: next     1.2;
        !          114480: 
        !          114481: 1.2
        !          114482: date     91.06.20.14.29.45;  author bin;  state Exp;
        !          114483: branches ;
        !          114484: next     1.1;
        !          114485: 
        !          114486: 1.1
        !          114487: date     91.06.10.14.36.59;  author bin;  state Exp;
        !          114488: branches ;
        !          114489: next     ;
        !          114490: 
        !          114491: 
        !          114492: desc
        !          114493: @initial version prov by hal
        !          114494: @
        !          114495: 
        !          114496: 
        !          114497: 1.4
        !          114498: log
        !          114499: @update prov by hal
        !          114500: 
        !          114501: @
        !          114502: text
        !          114503: @/* $Header: /usr/src/sys/coh/RCS/exec.c,v 1.1 88/03/24 16:13:39 src Exp $ */
        !          114504: /* (lgl-
        !          114505:  *     The information contained herein is a trade secret of Mark Williams
        !          114506:  *     Company, and  is confidential information.  It is provided  under a
        !          114507:  *     license agreement,  and may be  copied or disclosed  only under the
        !          114508:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          114509:  *     material without the express written authorization of Mark Williams
        !          114510:  *     Company or persuant to the license agreement is unlawful.
        !          114511:  *
        !          114512:  *     COHERENT Version 2.3.37
        !          114513:  *     Copyright (c) 1982, 1983, 1984.
        !          114514:  *     An unpublished work by Mark Williams Company, Chicago.
        !          114515:  *     All rights reserved.
        !          114516:  -lgl) */
        !          114517: /*
        !          114518:  * Coherent.
        !          114519:  * Exec and driver load code.
        !          114520:  *
        !          114521:  * $Log:       /usr/src/sys/coh/RCS/exec.c,v $
        !          114522:  * Revision 1.1        88/03/24  16:13:39      src
        !          114523:  * Initial revision
        !          114524:  * 
        !          114525:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/exec.c
        !          114526:  * Exsread() initializes the (new) (IO).io_flag field to 0.
        !          114527:  */
        !          114528: #include <sys/coherent.h>
        !          114529: #include <acct.h>
        !          114530: #include <sys/buf.h>
        !          114531: #include <canon.h>
        !          114532: #include <sys/con.h>
        !          114533: #include <errno.h>
        !          114534: #include <sys/filsys.h>
        !          114535: #include <sys/ino.h>
        !          114536: #include <sys/inode.h>
        !          114537: #include <l.out.h>
        !          114538: #include <sys/proc.h>
        !          114539: #include <sys/seg.h>
        !          114540: #include <signal.h>
        !          114541: #include <sys/uproc.h>
        !          114542: 
        !          114543: /*
        !          114544:  * Sizes.
        !          114545:  */
        !          114546: #define        sh      ((fsize_t)sizeof(struct ldheader))
        !          114547: #define si     lssize[L_SHRI]
        !          114548: #define pi     lssize[L_PRVI]
        !          114549: #define bi     lssize[L_BSSI]
        !          114550: #define sd     lssize[L_SHRD]
        !          114551: #define pd     lssize[L_PRVD]
        !          114552: #define bd     lssize[L_BSSD]
        !          114553: 
        !          114554: /*
        !          114555:  * Segments.
        !          114556:  */
        !          114557: #define upsp   pp->p_segp[SIUSERP]
        !          114558: #define sssp   pp->p_segp[SISTACK]
        !          114559: #define        sisp    pp->p_segp[SISTEXT]
        !          114560: #define pisp   pp->p_segp[SIPTEXT]
        !          114561: #define sdsp   pp->p_segp[SISDATA]
        !          114562: #define pdsp   pp->p_segp[SIPDATA]
        !          114563: 
        !          114564: /*
        !          114565:  * Set up the first process, a small programme which will exec
        !          114566:  * the init programme.
        !          114567:  */
        !          114568: eveinit(sp)
        !          114569: SEG *sp;
        !          114570: {
        !          114571:        register PROC *pp;
        !          114572: 
        !          114573:        SELF = pp = eprocp;
        !          114574:        pp->p_segp[SIUSERP] = sp;
        !          114575:        if ((sp=salloc((fsize_t)icodes, 0)) == NULL)
        !          114576:                panic("eveinit()");
        !          114577:        pp->p_segp[SIPDATA] = sp;
        !          114578:        kscopy(icodep, sp, 0, icodes);
        !          114579:        if ((sp=salloc((fsize_t)UPASIZE, SFDOWN)) == NULL)
        !          114580:                panic("eveinit()");
        !          114581:        pp->p_segp[SISTACK] = sp;
        !          114582:        u.u_argp = 0;
        !          114583:        if (sproto() == 0)
        !          114584:                panic("eveinit()");
        !          114585:        segload();
        !          114586: }
        !          114587: 
        !          114588: /*
        !          114589:  * Given a major number, a file containing a device driver and a configuration
        !          114590:  * pointer, load the driver on the major number.
        !          114591:  */
        !          114592: pload(m, np, cp)
        !          114593: char *np;
        !          114594: CON *cp;
        !          114595: {
        !          114596:        register INODE *ip;
        !          114597:        register SEG *sp;
        !          114598:        register DRV *dp;
        !          114599:        register fsize_t ss;
        !          114600:        dold_t dold;
        !          114601:        int lflag;
        !          114602:        int r;
        !          114603:        vaddr_t pc;
        !          114604:        fsize_t lssize[NUSEG];
        !          114605: 
        !          114606:        if (m >= drvn) {
        !          114607:                u.u_error = ENXIO;
        !          114608:                return;
        !          114609:        }
        !          114610:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
        !          114611:                return;
        !          114612:        ss = pi+si+pd+sd;
        !          114613:        sp = ssalloc(&r, ip, SFSHRX, ss+bi+bd, sh, ss);
        !          114614:        idetach(ip);
        !          114615:        if (r < 0)
        !          114616:                return;
        !          114617:        dp = &drvl[m];
        !          114618:        lock(dp->d_gate);
        !          114619:        if (dp->d_conp != NULL) {
        !          114620:                unlock(dp->d_gate);
        !          114621:                sfree(sp);
        !          114622:                u.u_error = EDBUSY;
        !          114623:                return;
        !          114624:        }
        !          114625:        dp->d_time = 0;
        !          114626:        dp->d_conp = cp;
        !          114627:        dp->d_segp = sp;
        !          114628:        dp->d_map = sp->s_mbase;
        !          114629:        dsave(dold);
        !          114630:        dmapv(dp->d_map);
        !          114631:        (*cp->c_load)();
        !          114632:        drest(dold);
        !          114633:        unlock(dp->d_gate);
        !          114634: }
        !          114635: 
        !          114636: /*
        !          114637:  * Given a major number, undo the previous function.
        !          114638:  */
        !          114639: puload(m)
        !          114640: int m;
        !          114641: {
        !          114642:        register CON *cp;
        !          114643:        register DRV *dp;
        !          114644:        dold_t dold;
        !          114645: 
        !          114646:        dp = &drvl[m];
        !          114647:        lock(dp->d_gate);
        !          114648:        if (m>=drvn || dp->d_segp==NULL || (cp=dp->d_conp)==NULL) {
        !          114649:                u.u_error = ENXIO;
        !          114650:                goto ret;
        !          114651:        }
        !          114652:        dsave(dold);
        !          114653:        dmapv(dp->d_map);
        !          114654:        (*cp->c_uload)();
        !          114655:        drest(dold);
        !          114656:        if (u.u_error)
        !          114657:                goto ret;
        !          114658:        sfree(dp->d_segp);
        !          114659:        dp->d_conp = NULL;
        !          114660:        dp->d_segp = NULL;
        !          114661:        dp->d_map = 0;
        !          114662: ret:
        !          114663:        unlock(dp->d_gate);
        !          114664:        return (0);
        !          114665: }
        !          114666: 
        !          114667: /*
        !          114668:  * Given the name of an executable l.out, a null terminated argument
        !          114669:  * list and a null terminated environment list, execute the l.out with the
        !          114670:  * given arguments and environments.
        !          114671:  */
        !          114672: pexece(np, argp, envp)
        !          114673: char   *np;
        !          114674: char   *argp[];
        !          114675: char   *envp[];
        !          114676: {
        !          114677:        register INODE  *ip;                    /* Load file INODE */
        !          114678:        register PROC   *pp;                    /* A cheap copy of SELF */
        !          114679:        register SEG    *ssp;                   /* New stack segment */
        !          114680:        register fsize_t        ss;                     /* Segment size temp. */
        !          114681:        register int    kprocflag;              /* Set if kernal process */
        !          114682:        register int    i;                      /* For looping over segments */
        !          114683:        int             r;                      /* Flag for "exload" */
        !          114684:        int             lflag;                  /* l_flags from l.out */
        !          114685:        vaddr_t         pc;                     /* l_entry from l.out */
        !          114686:        vaddr_t         sp;                     /* Initial stack pointer */
        !          114687:        fsize_t         lssize[NUSEG];          /* Segment sizes */
        !          114688: 
        !          114689:        pp = SELF;
        !          114690:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
        !          114691:                return;
        !          114692:        if ((lflag&LF_KER) != 0) {
        !          114693:                pp->p_flags |= PFKERN;
        !          114694:                kprocflag = 1;
        !          114695:                ssp = NULL;
        !          114696:                if (super() == 0) {
        !          114697:                        idetach(ip);
        !          114698:                        return;
        !          114699:                }
        !          114700:        } else {
        !          114701:                kprocflag = 0;
        !          114702:                if ((ssp=exstack(&sp, argp, envp)) == NULL) {
        !          114703:                        idetach(ip);
        !          114704:                        return;
        !          114705:                }
        !          114706:        }
        !          114707:        /*
        !          114708:         * At this point the file has been
        !          114709:         * validated as an object module, and the
        !          114710:         * argument list has been build. Release all of
        !          114711:         * the original segments. At this point we have
        !          114712:         * committed to the new image. A "sys exec" that
        !          114713:         * gets an I/O error is doomed.
        !          114714:         */
        !          114715:        for (i=1; i<NUSEG; ++i) {
        !          114716:                if (pp->p_segp[i] != NULL) {
        !          114717:                        sfree(pp->p_segp[i]);
        !          114718:                        pp->p_segp[i] = NULL;
        !          114719:                }
        !          114720:        }
        !          114721:        sssp = ssp;
        !          114722:        /*
        !          114723:         * Read in load module.
        !          114724:         */
        !          114725:        switch (lflag&(LF_SHR|LF_SEP)) {
        !          114726:        case 0:
        !          114727:                ss = si+pi+sd+pd;
        !          114728:                pdsp = ssalloc(&r, ip, kprocflag?SFHIGH:0, ss+bi+bd, sh, ss);
        !          114729:                if (r < 0)
        !          114730:                        goto out;
        !          114731:                break;
        !          114732: 
        !          114733:        case LF_SHR:
        !          114734:                sdsp = ssalloc(&r, ip, SFSHRX, si+sd, sh, si);
        !          114735:                if (r < 0)
        !          114736:                        goto out;
        !          114737:                if (r == 0) {
        !          114738:                        if (exsread(sdsp, ip, sd, sh+si+pi, si) == 0)
        !          114739:                                goto out;
        !          114740:                }
        !          114741:                pdsp = ssalloc(&r, ip, 0, pi+pd+bi+bd, sh+si, pi);
        !          114742:                if (r < 0)
        !          114743:                        goto out;
        !          114744:                if (r == 0) {
        !          114745:                        if (exsread(pdsp, ip, pd, sh+si+pi+sd, pi) == 0)
        !          114746:                                goto out;
        !          114747:                }
        !          114748:                break;
        !          114749: 
        !          114750:        case LF_SEP:
        !          114751:                pisp = ssalloc(&r, ip, SFTEXT, si+pi+bi, sh, si+pi);
        !          114752:                if (r < 0)
        !          114753:                        goto out;
        !          114754:                pdsp = ssalloc(&r, ip, 0, sd+pd+bd, sh+si+bi, sd+pd);
        !          114755:                if (r < 0)
        !          114756:                        goto out;
        !          114757:                break;
        !          114758: 
        !          114759:        case LF_SHR|LF_SEP:
        !          114760:                sisp = ssalloc(&r, ip, SFSHRX|SFTEXT, si, sh, si);
        !          114761:                if (r < 0)
        !          114762:                        goto out;
        !          114763:                pisp = ssalloc(&r, ip, SFTEXT, pi+bi, sh+si, pi);
        !          114764:                if (r < 0)
        !          114765:                        goto out;
        !          114766:                sdsp = ssalloc(&r, ip, SFSHRX, sd, sh+si+pi, sd);
        !          114767:                if (r < 0)
        !          114768:                        goto out;
        !          114769:                pdsp = ssalloc(&r, ip, 0, pd+bd, sh+si+pi+pd, pd);
        !          114770:                if (r < 0)
        !          114771:                        goto out;
        !          114772:        }
        !          114773:        if (sproto() == 0)
        !          114774:                goto out;
        !          114775:        /*
        !          114776:         * The new image is read in
        !          114777:         * and mapped. Perform the final grunge
        !          114778:         * (set-uid stuff, accounting, loading up
        !          114779:         * registers, etc).
        !          114780:         */
        !          114781:        u.u_flag &= ~AFORK;
        !          114782:        kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm));
        !          114783:        if (iaccess(ip, IPR) == 0)
        !          114784:                pp->p_flags |= PFNDMP;
        !          114785:        if ((ip->i_mode&ISUID) != 0)
        !          114786:                pp->p_uid = u.u_uid = ip->i_uid;
        !          114787:        if ((ip->i_mode&ISGID) != 0)
        !          114788:                u.u_gid = ip->i_gid;
        !          114789:        for (i=0; i<NSIG; ++i) {
        !          114790:                if (u.u_sfunc[i] != SIG_IGN)
        !          114791:                        u.u_sfunc[i] = SIG_DFL;
        !          114792:        }
        !          114793:        if ((pp->p_flags&PFTRAC) != 0)
        !          114794:                sendsig(SIGTRAP, pp);
        !          114795:        idetach(ip);
        !          114796:        msetusr(pc, sp);
        !          114797:        segload();
        !          114798:        return (0);
        !          114799: 
        !          114800:        /*
        !          114801:         * We did not make it.
        !          114802:         * Release the INODE for the load
        !          114803:         * file, and return through the "sys exit"
        !          114804:         * code. A better exit status should be
        !          114805:         * chosen!
        !          114806:         */
        !          114807: out:
        !          114808:        idetach(ip);
        !          114809:        pexit(0);
        !          114810: }
        !          114811: 
        !          114812: /*
        !          114813:  * Open an l.out, make sure it is an l.out and executable and return the
        !          114814:  * appropriate information.
        !          114815:  */
        !          114816: INODE *
        !          114817: exlopen(np, ssizep, flagp, pcp)
        !          114818: char *np;
        !          114819: fsize_t *ssizep;
        !          114820: int *flagp;
        !          114821: vaddr_t *pcp;
        !          114822: {
        !          114823:        register INODE *ip;
        !          114824:        register struct ldheader *ldp;
        !          114825:        register int n;
        !          114826:        register BUF *bp;
        !          114827:        int m;
        !          114828: 
        !          114829:        /*
        !          114830:         * Make sure the file is really an executable l.out and read the
        !          114831:         * header in.
        !          114832:         */
        !          114833:        if (ftoi(np, 'r') != 0)
        !          114834:                return (NULL);
        !          114835:        ip = u.u_cdiri;
        !          114836:        if (iaccess(ip, IPE) == 0) {
        !          114837:                idetach(ip);
        !          114838:                return (NULL);
        !          114839:        }
        !          114840:        if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) {
        !          114841:                u.u_error = EACCES;
        !          114842:                idetach(ip);
        !          114843:                return (NULL);
        !          114844:        }
        !          114845:        if ((bp=vread(ip, (daddr_t)0)) == NULL) {
        !          114846:                u.u_error = EBADFMT;
        !          114847:                idetach(ip);
        !          114848:                return (NULL);
        !          114849:        }
        !          114850: 
        !          114851:        /*
        !          114852:         * Copy everything we need from the l.out header and check magic
        !          114853:         * number and machine type.
        !          114854:         */
        !          114855:        ldp = bp->b_vaddr;
        !          114856:        m = ldp->l_magic;
        !          114857:        canint(m);
        !          114858:        if (m != L_MAGIC) {
        !          114859:                u.u_error = ENOEXEC;
        !          114860:                brelease(bp);
        !          114861:                idetach(ip);
        !          114862:                return (NULL);
        !          114863:        }
        !          114864:        m = ldp->l_machine;
        !          114865:        canint(m);
        !          114866:        if (m != mactype) {
        !          114867:                u.u_error = EBADFMT;
        !          114868:                brelease(bp);
        !          114869:                idetach(ip);
        !          114870:                return (NULL);
        !          114871:        }
        !          114872:        kkcopy(ldp->l_ssize, ssizep, NXSEG*sizeof(fsize_t));
        !          114873:        for (n=0; n<NXSEG; n++)
        !          114874:                cansize(ssizep[n]);
        !          114875:        *flagp = ldp->l_flag;
        !          114876:        canint(*flagp);
        !          114877:        *pcp = ldp->l_entry;
        !          114878:        canvaddr(*pcp);
        !          114879:        brelease(bp);
        !          114880:        return (ip);
        !          114881: }
        !          114882: 
        !          114883: /*
        !          114884:  * Given a segment `sp', read `ss' bytes from the inode `ip' starting
        !          114885:  * at seek address `sa' into offset `so' in the segment.
        !          114886:  */
        !          114887: SEG *
        !          114888: exsread(sp, ip, ss, sa, so)
        !          114889: register SEG *sp;
        !          114890: INODE *ip;
        !          114891: fsize_t sa;
        !          114892: fsize_t ss;
        !          114893: fsize_t so;
        !          114894: {
        !          114895:        u.u_io.io_seg = IOPHY;
        !          114896:        u.u_io.io_ioc = ss;
        !          114897:        u.u_io.io_seek = sa;
        !          114898:        u.u_io.io_phys = ctob((paddr_t)sp->s_mbase) + so;
        !          114899:        u.u_io.io_flag = 0;
        !          114900:        iread(ip, &u.u_io);
        !          114901:        return (u.u_error==0);
        !          114902: }
        !          114903: 
        !          114904: /*
        !          114905:  * Given a pointer to a list of arguments and a pointer to a list of
        !          114906:  * environments, return a stack with the arguments and environments on it.
        !          114907:  */
        !          114908: SEG *
        !          114909: exstack(iusp, argp, envp)
        !          114910: char **iusp;           /* Back patch sp value */
        !          114911: char *argp[];          /* Arguments for new process */
        !          114912: char *envp[];          /* Environments for new process */
        !          114913: {
        !          114914:        SEG *sp;                /* Stack segment pointer */
        !          114915:        struct adata {          /* Storage for arg and env data */
        !          114916:                char    **up;           /* User vector pointer */
        !          114917:                int     np;             /* Number of pointers in vector */
        !          114918:                int     nc;             /* Number of characters in strings */
        !          114919:        } arg, env;
        !          114920:        struct sdata {          /* To keep segment pointers */
        !          114921:                vaddr_t base;           /* Top of segment virtual */
        !          114922:                vaddr_t ap;             /* Argc, argv, envp pointer */
        !          114923:                vaddr_t vp;             /* Argv[i], envp[i] pointer */
        !          114924:                vaddr_t cp;             /* Argv[i][j], envp[i][j] pointer */
        !          114925:        } aux, stk;
        !          114926:        aold_t aold;                    /* Auxiliary map storage */
        !          114927:        register char **usrvp;          /* Vector pointer into user seg */
        !          114928:        register char *usrcp;           /* Character pointer into user seg */
        !          114929:        register int c;                 /* Character fetched from user */
        !          114930:        register int chrsz;             /* Size of strings */
        !          114931:        register struct adata *adp;     /* Arg and env scanner */
        !          114932:        register int vecsz;             /* Size of vectors */
        !          114933:        register int stksz;             /* Size of stack argument region */
        !          114934: 
        !          114935:        /* Validate and evaluate size of args and envs */
        !          114936:        arg.up = argp;
        !          114937:        env.up = envp;
        !          114938:        chrsz = 0;
        !          114939:        vecsz = 0;
        !          114940:        for (adp = &arg; ; adp = &env) {
        !          114941:                adp->np = 0;
        !          114942:                adp->nc = 0;
        !          114943:                if (excount(adp->up, &adp->np, &adp->nc) == 0)
        !          114944:                        return (NULL);
        !          114945:                chrsz += adp->nc * sizeof(char);
        !          114946:                vecsz += adp->np * sizeof(char *);
        !          114947:                if (adp == &env)
        !          114948:                        break;
        !          114949:        }
        !          114950: 
        !          114951:        /* Calculate stack size and allocate it */
        !          114952:        chrsz = roundu(chrsz, sizeof(int));
        !          114953:        stksz = sizeof(int)             /* argc */
        !          114954:                + sizeof(char **)       /* argv */
        !          114955:                + sizeof(char **)       /* envp */
        !          114956:                + vecsz                 /* argv[i] and envp[i] */
        !          114957:                + chrsz                 /* *argv[i] and *envp[i] */
        !          114958:                + sizeof(int)           /* Mystery zero word */
        !          114959:                + sizeof(char *)        /* Splimit for z8000 */
        !          114960:                + sizeof(int);          /* errno */
        !          114961:        stksz += ISTSIZE;
        !          114962:        if (stksz > MADSIZE) {
        !          114963:                u.u_error = E2BIG;
        !          114964:                return (NULL);
        !          114965:        }
        !          114966:        if ((sp=salloc((fsize_t)stksz, SFDOWN)) == NULL)
        !          114967:                return (NULL);
        !          114968:        stksz -= ISTSIZE;
        !          114969: 
        !          114970:        /*
        !          114971:         * Initialize segment data.
        !          114972:         */
        !          114973:        asave(aold);
        !          114974: 
        !          114975:        aux.base = abase(sp->s_mbase) + ctob(sp->s_size);
        !          114976:        aux.ap = aux.base - stksz;
        !          114977:        aux.vp = aux.ap + sizeof(int) + 2*sizeof(char **);
        !          114978:        aux.cp = aux.vp + vecsz;
        !          114979: 
        !          114980:        stk.base = ISTVIRT;
        !          114981:        stk.ap = stk.base - stksz;
        !          114982:        stk.vp = stk.ap + sizeof(int) + 2*sizeof(char **);
        !          114983:        stk.cp = stk.vp + vecsz;
        !          114984: 
        !          114985:        /*
        !          114986:         * Write argc.
        !          114987:         */
        !          114988:        aputi((int *)aux.ap, arg.np-1);
        !          114989:        aux.ap += sizeof(int);
        !          114990: 
        !          114991:        /*
        !          114992:         * Arguments and environments.
        !          114993:         */
        !          114994:        for (adp = &arg; ; adp = &env) {
        !          114995: 
        !          114996:                /* Write argv or envp */
        !          114997:                aputp((char ***)aux.ap, (char **)stk.vp);
        !          114998:                aux.ap += sizeof(char **);
        !          114999:                if ((usrvp = adp->up) != NULL) {
        !          115000: 
        !          115001:                        /* Write argv[i] or envp[i] */
        !          115002:                        while ((usrcp = getupd(usrvp++)) != NULL) {
        !          115003:                                aputp((char **)aux.vp, (char *)stk.cp);
        !          115004:                                aux.vp += sizeof(char *);
        !          115005:                                stk.vp += sizeof(char *);
        !          115006: 
        !          115007:                                /* Write argv[i][j] or envp[i][j] */
        !          115008:                                do {
        !          115009:                                        c = getubd(usrcp++);
        !          115010:                                        aputc((char *)aux.cp, c);
        !          115011:                                        aux.cp += sizeof(char);
        !          115012:                                        stk.cp += sizeof(char);
        !          115013:                                } while (c != '\0');
        !          115014:                        }
        !          115015:                }
        !          115016: 
        !          115017:                /* Write argv[argc] or envp[envc] */
        !          115018:                aputp((char **)aux.vp, NULL);
        !          115019:                aux.vp += sizeof(char *);
        !          115020:                stk.vp += sizeof(char *);
        !          115021:                if (adp == &env)
        !          115022:                        break;
        !          115023:        }
        !          115024: 
        !          115025:        /*
        !          115026:         * Clear out the slop.
        !          115027:         */
        !          115028:        aux.base -= sizeof(int);
        !          115029:        aputi((int *) aux.base, 0);             /* errno */
        !          115030:        aux.base -= sizeof(char *);
        !          115031:        aputp((char **) aux.base, (char *)stk.base-ctob(sp->s_size)+SOVSIZE);
        !          115032:        aux.base -= sizeof(int);
        !          115033:        aputi((int *) aux.base, 0);             /* mystery word */
        !          115034: 
        !          115035:        arest(aold);
        !          115036: 
        !          115037:        /*
        !          115038:         * Patch some values and return.
        !          115039:         */
        !          115040:        *iusp = stk.ap;         /* Patch initial usp */
        !          115041:        u.u_argc = arg.np-1;
        !          115042:        u.u_argp = stk.vp;      /* Points after NULL of envs */
        !          115043:        return (sp);
        !          115044: }
        !          115045: 
        !          115046: /*
        !          115047:  * Given a pointer to a list of arguments, a pointer to an argument count
        !          115048:  * and a pointer to a byte count, update incrementally the argument count
        !          115049:  * and the byte count.
        !          115050:  */
        !          115051: excount(usrvp, nap, nbp)
        !          115052: register char **usrvp;
        !          115053: int *nap;
        !          115054: int *nbp;
        !          115055: {
        !          115056:        register char *usrcp;
        !          115057:        register int c;
        !          115058:        register unsigned nb;
        !          115059:        register unsigned na;
        !          115060: 
        !          115061:        na = 1;
        !          115062:        nb = 0;
        !          115063:        if (usrvp != NULL) {
        !          115064:                for (;;) {
        !          115065:                        usrcp = getupd(usrvp++);
        !          115066:                        if (u.u_error)
        !          115067:                                return (0);
        !          115068:                        if (usrcp == NULL)
        !          115069:                                break;
        !          115070:                        na++;
        !          115071:                        for (;;) {
        !          115072:                                c = getubd(usrcp++);
        !          115073:                                if (u.u_error)
        !          115074:                                        return (0);
        !          115075:                                nb++;
        !          115076:                                if (c == '\0')
        !          115077:                                        break;
        !          115078:                        }
        !          115079:                }
        !          115080:        }
        !          115081:        *nap += na;
        !          115082:        *nbp += nb;
        !          115083:        return (1);
        !          115084: }
        !          115085: @
        !          115086: 
        !          115087: 
        !          115088: 1.3
        !          115089: log
        !          115090: @update by hal
        !          115091: @
        !          115092: text
        !          115093: @@
        !          115094: 
        !          115095: 
        !          115096: 1.2
        !          115097: log
        !          115098: @update provided by hal
        !          115099: @
        !          115100: text
        !          115101: @@
        !          115102: 
        !          115103: 
        !          115104: 1.1
        !          115105: log
        !          115106: @Initial revision
        !          115107: @
        !          115108: text
        !          115109: @d26 1
        !          115110: a26 1
        !          115111: #include <coherent.h>
        !          115112: @
        !          115113: 0707070064030053071004440000030000030000011777770507310734400004600000007516/newbits/kernel/USRSRC/coh/RCS/fd.c,vhead     1.4;
        !          115114: branch   ;
        !          115115: access   ;
        !          115116: symbols  ;
        !          115117: locks    bin:1.4;
        !          115118: comment  @ * @;
        !          115119: 
        !          115120: 
        !          115121: 1.4
        !          115122: date     91.07.24.07.50.35;  author bin;  state Exp;
        !          115123: branches ;
        !          115124: next     1.3;
        !          115125: 
        !          115126: 1.3
        !          115127: date     91.07.15.14.32.09;  author bin;  state Exp;
        !          115128: branches ;
        !          115129: next     1.2;
        !          115130: 
        !          115131: 1.2
        !          115132: date     91.06.20.14.29.57;  author bin;  state Exp;
        !          115133: branches ;
        !          115134: next     1.1;
        !          115135: 
        !          115136: 1.1
        !          115137: date     91.06.10.14.37.04;  author bin;  state Exp;
        !          115138: branches ;
        !          115139: next     ;
        !          115140: 
        !          115141: 
        !          115142: desc
        !          115143: @initial version prov by hal
        !          115144: @
        !          115145: 
        !          115146: 
        !          115147: 1.4
        !          115148: log
        !          115149: @update prov by hal
        !          115150: 
        !          115151: @
        !          115152: text
        !          115153: @/* $Header: /usr/src/sys/coh/RCS/fd.c,v 1.1 88/03/24 16:13:43 src Exp $ */
        !          115154: /* (lgl-
        !          115155:  *     The information contained herein is a trade secret of Mark Williams
        !          115156:  *     Company, and  is confidential information.  It is provided  under a
        !          115157:  *     license agreement,  and may be  copied or disclosed  only under the
        !          115158:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          115159:  *     material without the express written authorization of Mark Williams
        !          115160:  *     Company or persuant to the license agreement is unlawful.
        !          115161:  *
        !          115162:  *     COHERENT Version 2.3.37
        !          115163:  *     Copyright (c) 1982, 1983, 1984.
        !          115164:  *     An unpublished work by Mark Williams Company, Chicago.
        !          115165:  *     All rights reserved.
        !          115166:  -lgl) */
        !          115167: /*
        !          115168:  * Coherent.
        !          115169:  * File descriptor routines.
        !          115170:  *
        !          115171:  * $Log:       /usr/src/sys/coh/RCS/fd.c,v $
        !          115172:  * Revision 1.1        88/03/24  16:13:43      src
        !          115173:  * Initial revision
        !          115174:  * 
        !          115175:  */
        !          115176: #include <sys/coherent.h>
        !          115177: #include <errno.h>
        !          115178: #include <sys/fd.h>
        !          115179: #include <sys/inode.h>
        !          115180: #include <sys/uproc.h>
        !          115181: 
        !          115182: /*
        !          115183:  * Given a file number, return the file descriptor.
        !          115184:  */
        !          115185: FD *
        !          115186: fdget(fd)
        !          115187: register unsigned fd;
        !          115188: {
        !          115189:        register FD *fdp;
        !          115190: 
        !          115191:        if (fd>=NUFILE || (fdp=u.u_filep[fd])==NULL) {
        !          115192:                u.u_error = EBADF;
        !          115193:                return (NULL);
        !          115194:        }
        !          115195:        return (fdp);
        !          115196: }
        !          115197: 
        !          115198: /*
        !          115199:  * Duplicate a file descriptor number.  This has the same calling
        !          115200:  * sequence as the dup2 system call and even uses the silly DUP2 bit.
        !          115201:  */
        !          115202: fddup(ofd, nfd)
        !          115203: register unsigned ofd;
        !          115204: register unsigned nfd;
        !          115205: {
        !          115206:        register FD *fdp;
        !          115207: 
        !          115208:        if ((fdp=fdget(ofd&~DUP2)) == NULL)
        !          115209:                return (-1);
        !          115210:        if ((ofd&DUP2) != 0) {
        !          115211:                if (nfd >= NUFILE) {
        !          115212:                        u.u_error = EBADF;
        !          115213:                        return (-1);
        !          115214:                }
        !          115215:                ofd &= ~DUP2;
        !          115216:                if (ofd == nfd)
        !          115217:                        return (nfd);
        !          115218:                if (u.u_filep[nfd] != NULL) {
        !          115219:                        fdclose(nfd);
        !          115220:                        if (u.u_error)
        !          115221:                                return (-1);
        !          115222:                }
        !          115223:        } else {
        !          115224:                for (nfd=0; nfd<NUFILE; nfd++)
        !          115225:                        if (u.u_filep[nfd] == NULL)
        !          115226:                                break;
        !          115227:                if (nfd == NUFILE) {
        !          115228:                        u.u_error = EMFILE;
        !          115229:                        return (-1);
        !          115230:                }
        !          115231:        }
        !          115232:        u.u_filep[nfd] = fdp;
        !          115233:        fdp->f_refc++;
        !          115234:        return (nfd);
        !          115235: }
        !          115236: 
        !          115237: /*
        !          115238:  * Given an inode, and a mode containing permission flags, open the
        !          115239:  * inode with the appropriate permissions and return a file descriptor
        !          115240:  * containing it.
        !          115241:  */
        !          115242: fdopen(ip, mode)
        !          115243: register INODE *ip;
        !          115244: {
        !          115245:        register FD **fdpp;
        !          115246:        register FD *fdp;
        !          115247: 
        !          115248:        for (fdpp=u.u_filep; fdpp<&u.u_filep[NUFILE]; fdpp++) {
        !          115249:                if (*fdpp != NULL)
        !          115250:                        continue;
        !          115251:                if ((fdp=kalloc(sizeof(FD))) == NULL)
        !          115252:                        return (-1);
        !          115253:                iopen(ip, mode);
        !          115254:                if (u.u_error) {
        !          115255:                        kfree(fdp);
        !          115256:                        return (-1);
        !          115257:                }
        !          115258:                fdp->f_flag = mode;
        !          115259:                fdp->f_refc = 1;
        !          115260:                fdp->f_seek = 0;
        !          115261:                fdp->f_ip = ip;
        !          115262:                *fdpp = fdp;
        !          115263:                return (fdpp-u.u_filep);
        !          115264:        }
        !          115265:        u.u_error = EMFILE;
        !          115266:        return (-1);
        !          115267: }
        !          115268: 
        !          115269: /*
        !          115270:  * Close the given file number.
        !          115271:  */
        !          115272: fdclose(fd)
        !          115273: register unsigned fd;
        !          115274: {
        !          115275:        register FD *fdp;
        !          115276: 
        !          115277:        if (fd>=NUFILE || (fdp=u.u_filep[fd])==NULL) {
        !          115278:                u.u_error = EBADF;
        !          115279:                return;
        !          115280:        }
        !          115281:        u.u_filep[fd] = NULL;
        !          115282:        if (fdp->f_refc == 0)
        !          115283:                panic("fdclose()");
        !          115284:        if (--fdp->f_refc == 0) {
        !          115285:                iclose(fdp->f_ip);
        !          115286:                kfree(fdp);
        !          115287:        }
        !          115288: }
        !          115289: 
        !          115290: /*
        !          115291:  * Assuming we have made a copy of the user area, increment the reference
        !          115292:  * of all open files.  (used in fork).
        !          115293:  */
        !          115294: fdadupl()
        !          115295: {
        !          115296:        register FD **fdpp;
        !          115297:        register FD *fdp;
        !          115298: 
        !          115299:        for (fdpp=u.u_filep; fdpp<&u.u_filep[NUFILE]; fdpp++) {
        !          115300:                if ((fdp=*fdpp) == NULL)
        !          115301:                        continue;
        !          115302:                fdp->f_refc++;
        !          115303:        }
        !          115304: }
        !          115305: 
        !          115306: /*
        !          115307:  * Close all open files in the current process.
        !          115308:  */
        !          115309: fdaclose()
        !          115310: {
        !          115311:        register int fd;
        !          115312: 
        !          115313:        for (fd=0; fd<NUFILE; fd++) {
        !          115314:                if (u.u_filep[fd] == NULL)
        !          115315:                        continue;
        !          115316:                fdclose(fd);
        !          115317:        }
        !          115318: }
        !          115319: @
        !          115320: 
        !          115321: 
        !          115322: 1.3
        !          115323: log
        !          115324: @update by hal
        !          115325: @
        !          115326: text
        !          115327: @@
        !          115328: 
        !          115329: 
        !          115330: 1.2
        !          115331: log
        !          115332: @update provided by hal
        !          115333: @
        !          115334: text
        !          115335: @@
        !          115336: 
        !          115337: 
        !          115338: 1.1
        !          115339: log
        !          115340: @Initial revision
        !          115341: @
        !          115342: text
        !          115343: @d24 1
        !          115344: a24 1
        !          115345: #include <coherent.h>
        !          115346: @
        !          115347: 0707070064030053041004440000030000030000011777770507310734500004700000025257/newbits/kernel/USRSRC/coh/RCS/fs2.c,vhead     1.4;
        !          115348: branch   ;
        !          115349: access   ;
        !          115350: symbols  ;
        !          115351: locks    bin:1.4;
        !          115352: comment  @ * @;
        !          115353: 
        !          115354: 
        !          115355: 1.4
        !          115356: date     91.07.24.07.50.55;  author bin;  state Exp;
        !          115357: branches ;
        !          115358: next     1.3;
        !          115359: 
        !          115360: 1.3
        !          115361: date     91.07.15.14.32.31;  author bin;  state Exp;
        !          115362: branches ;
        !          115363: next     1.2;
        !          115364: 
        !          115365: 1.2
        !          115366: date     91.06.20.14.30.16;  author bin;  state Exp;
        !          115367: branches ;
        !          115368: next     1.1;
        !          115369: 
        !          115370: 1.1
        !          115371: date     91.06.10.14.37.16;  author bin;  state Exp;
        !          115372: branches ;
        !          115373: next     ;
        !          115374: 
        !          115375: 
        !          115376: desc
        !          115377: @initial version prov by hal
        !          115378: @
        !          115379: 
        !          115380: 
        !          115381: 1.4
        !          115382: log
        !          115383: @update prov by hal
        !          115384: 
        !          115385: @
        !          115386: text
        !          115387: @/* $Header: /usr/src/sys/coh/RCS/fs2.c,v 1.1 88/03/24 16:13:51 src Exp $ */
        !          115388: /* (lgl-
        !          115389:  *     The information contained herein is a trade secret of Mark Williams
        !          115390:  *     Company, and  is confidential information.  It is provided  under a
        !          115391:  *     license agreement,  and may be  copied or disclosed  only under the
        !          115392:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          115393:  *     material without the express written authorization of Mark Williams
        !          115394:  *     Company or persuant to the license agreement is unlawful.
        !          115395:  *
        !          115396:  *     COHERENT Version 2.3.37
        !          115397:  *     Copyright (c) 1982, 1983, 1984.
        !          115398:  *     An unpublished work by Mark Williams Company, Chicago.
        !          115399:  *     All rights reserved.
        !          115400:  -lgl) */
        !          115401: /*
        !          115402:  * Coherent.
        !          115403:  * Filesystem (disk inodes).
        !          115404:  *
        !          115405:  * $Log:       /usr/src/sys/coh/RCS/fs2.c,v $
        !          115406:  * Revision 1.1        88/03/24  16:13:51      src
        !          115407:  * Initial revision
        !          115408:  * 
        !          115409:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/fs2.c
        !          115410:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          115411:  *
        !          115412:  * 87/04/29    Allan Cornish           /usr/src/sys/coh/fs2.c
        !          115413:  * Fsminit panic messages now specify the root major and minor device.
        !          115414:  *
        !          115415:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/fs2.c
        !          115416:  * setacct() initializes the (new) (IO).io_flag field to 0.
        !          115417:  *
        !          115418:  * 85/08/08    Allan Cornish
        !          115419:  * ialloc() erroneously did a brelease(NULL) if bclaim() returned NULL.
        !          115420:  * also, sbp->s_fmod was set BEFORE the in-core inode table was updated.
        !          115421:  * This created a critical race with msync() (called by sync system call).
        !          115422:  *
        !          115423:  * 85/04/17    Allan Cornish
        !          115424:  * eliminated test for rootdev in msync()
        !          115425:  */
        !          115426: #include <sys/coherent.h>
        !          115427: #include <acct.h>
        !          115428: #include <sys/buf.h>
        !          115429: #include <canon.h>
        !          115430: #include <sys/con.h>
        !          115431: #include <errno.h>
        !          115432: #include <sys/filsys.h>
        !          115433: #include <sys/ino.h>
        !          115434: #include <sys/inode.h>
        !          115435: #include <sys/io.h>
        !          115436: #include <sys/mount.h>
        !          115437: #include <sys/proc.h>
        !          115438: #include <sys/stat.h>
        !          115439: #include <sys/uproc.h>
        !          115440: 
        !          115441: /*
        !          115442:  * Initialise filesystem.
        !          115443:  */
        !          115444: fsminit()
        !          115445: {
        !          115446:        register MOUNT *mp;
        !          115447: 
        !          115448:        /*
        !          115449:         * Mount the root file system.
        !          115450:         */
        !          115451:        if ( (mp = fsmount(rootdev, ronflag)) == NULL )
        !          115452:                panic(  "fsminit: no rootdev(%d,%d)",
        !          115453:                        major(rootdev), minor(rootdev) );
        !          115454: 
        !          115455:        /*
        !          115456:         * Set system time from the super block.
        !          115457:         */
        !          115458:        timer.t_time = mp->m_super.s_time;
        !          115459: 
        !          115460:        /*
        !          115461:         * Access the root directory.
        !          115462:         */
        !          115463:        if ( (u.u_rdir = iattach(rootdev, ROOTIN)) == NULL )
        !          115464:                panic(  "fsminit: no / on rootdev(%d,%d)",
        !          115465:                        major(rootdev), minor(rootdev) );
        !          115466: 
        !          115467:        /*
        !          115468:         * Record current directory.
        !          115469:         */
        !          115470:        u.u_cdir = u.u_rdir;
        !          115471:        u.u_cdir->i_refc++;
        !          115472:        iunlock(u.u_rdir);
        !          115473: }
        !          115474: 
        !          115475: /*
        !          115476:  * Mount the given device.
        !          115477:  */
        !          115478: MOUNT *
        !          115479: fsmount(dev, f)
        !          115480: register dev_t dev;
        !          115481: {
        !          115482:        register MOUNT *mp;
        !          115483:        register BUF *bp;
        !          115484: 
        !          115485:        if ((mp=kalloc(sizeof(MOUNT))) == NULL)
        !          115486:                return (NULL);
        !          115487:        dopen(dev, (f?IPR:IPR|IPW), DFBLK);
        !          115488:        if (u.u_error != 0) {
        !          115489:                kfree(mp);
        !          115490:                return (NULL);
        !          115491:        }
        !          115492:        if ((bp=bread(dev, (daddr_t)SUPERI, 1)) == NULL) {
        !          115493:                dclose(dev);
        !          115494:                kfree(mp);
        !          115495:                return (NULL);
        !          115496:        }
        !          115497:        kkcopy(FP_OFF(bp->b_faddr), &mp->m_super, sizeof(struct filsys));
        !          115498:        brelease(bp);
        !          115499:        cansuper(&mp->m_super);
        !          115500:        mp->m_ip = NULL;
        !          115501:        mp->m_dev = dev;
        !          115502:        mp->m_flag = f;
        !          115503:        mp->m_super.s_fmod = 0;
        !          115504:        mp->m_next = mountp;
        !          115505:        mountp = mp;
        !          115506:        return (mp);
        !          115507: }
        !          115508: 
        !          115509: /*
        !          115510:  * Canonize a super block.
        !          115511:  */
        !          115512: cansuper(fsp)
        !          115513: register struct filsys *fsp;
        !          115514: {
        !          115515:        register int i;
        !          115516: 
        !          115517:        canint(fsp->s_isize);
        !          115518:        candaddr(fsp->s_fsize);
        !          115519:        canshort(fsp->s_nfree);
        !          115520:        for (i=0; i<NICFREE; i++)
        !          115521:                candaddr(fsp->s_free[i]);
        !          115522:        canshort(fsp->s_ninode);
        !          115523:        for (i=0; i<NICINOD; i++)
        !          115524:                canino(fsp->s_inode[i]);
        !          115525:        cantime(fsp->s_time);
        !          115526:        candaddr(fsp->s_tfree);
        !          115527:        canino(fsp->s_tinode);
        !          115528:        canshort(fsp->s_m);
        !          115529:        canshort(fsp->s_n);
        !          115530:        canlong(fsp->s_unique);
        !          115531: }
        !          115532: 
        !          115533: /*
        !          115534:  * Given a pointer to a mount entry, write out all inodes on that device.
        !          115535:  */
        !          115536: msync(mp)
        !          115537: register MOUNT *mp;
        !          115538: {
        !          115539:        register struct filsys *sbp;
        !          115540:        register BUF *bp;
        !          115541: 
        !          115542:        if ((mp->m_flag&MFRON) != 0)
        !          115543:                return;
        !          115544:        isync(mp->m_dev);
        !          115545:        sbp = &mp->m_super;
        !          115546:        if (sbp->s_fmod==0)
        !          115547:                return;
        !          115548:        bp = bclaim(mp->m_dev, (daddr_t)SUPERI);
        !          115549:        sbp->s_time = timer.t_time;
        !          115550:        sbp->s_fmod = 0;
        !          115551:        kkcopy(sbp, FP_OFF(bp->b_faddr), sizeof(*sbp));
        !          115552:        cansuper(FP_OFF(bp->b_faddr));
        !          115553:        bwrite(bp, 1);
        !          115554:        brelease(bp);
        !          115555: }
        !          115556: 
        !          115557: /*
        !          115558:  * Return the mount entry for the given device.  If `f' is not set
        !          115559:  * and the device is read only, don't set the error status.
        !          115560:  */
        !          115561: MOUNT *
        !          115562: getment(dev, f)
        !          115563: register dev_t dev;
        !          115564: {
        !          115565:        register MOUNT *mp;
        !          115566: 
        !          115567:        for (mp=mountp; mp!=NULL; mp=mp->m_next) {
        !          115568:                if (mp->m_dev != dev)
        !          115569:                        continue;
        !          115570:                if ((mp->m_flag&MFRON) != 0) {
        !          115571:                        if (f != 0)
        !          115572:                                u.u_error = EROFS;
        !          115573:                        return (NULL);
        !          115574:                }
        !          115575:                return (mp);
        !          115576:        }
        !          115577:        panic("getment: dev=0x%x", dev);
        !          115578: }
        !          115579: 
        !          115580: /*
        !          115581:  * Allocate a new inode with the given mode.  The returned inode is locked.
        !          115582:  */
        !          115583: INODE *
        !          115584: ialloc(dev, mode)
        !          115585: dev_t dev;
        !          115586: unsigned mode;
        !          115587: {
        !          115588:        register struct dinode *dip;
        !          115589:        register struct filsys *sbp;
        !          115590:        register ino_t *inop;
        !          115591:        register ino_t ino;
        !          115592:        register BUF *bp;
        !          115593:        register daddr_t b;
        !          115594:        register struct dinode *dipe;
        !          115595:        register ino_t *inope;
        !          115596:        register MOUNT *mp;
        !          115597:        register INODE *ip;
        !          115598: 
        !          115599:        if ((mp=getment(dev, 1)) == NULL)
        !          115600:                return (NULL);
        !          115601:        sbp = &mp->m_super;
        !          115602:        for (;;) {
        !          115603:                lock(mp->m_ilock);
        !          115604:                if (sbp->s_ninode == 0) {
        !          115605:                        ino = 1;
        !          115606:                        inop = sbp->s_inode;
        !          115607:                        inope = &sbp->s_inode[NICINOD];
        !          115608:                        for (b=INODEI; b<sbp->s_isize; b++) {
        !          115609:                                if (bad(dev, b)) {
        !          115610:                                        ino += INOPB;
        !          115611:                                        continue;
        !          115612:                                }
        !          115613:                                if ((bp=bread(dev, b, 1)) == NULL) {
        !          115614:                                        ino += INOPB;
        !          115615:                                        continue;
        !          115616:                                }
        !          115617:                                dip = FP_OFF(bp->b_faddr);
        !          115618:                                dipe = &dip[INOPB];
        !          115619:                                for (; dip<dipe; dip++, ino++) {
        !          115620:                                        if (dip->di_mode != 0)
        !          115621:                                                continue;
        !          115622:                                        if (inop >= inope)
        !          115623:                                                break;
        !          115624:                                        *inop++ = ino;
        !          115625:                                }
        !          115626:                                brelease(bp);
        !          115627:                                if (inop >= inope)
        !          115628:                                        break;
        !          115629:                        }
        !          115630:                        sbp->s_ninode = inop - sbp->s_inode;
        !          115631:                        if (sbp->s_ninode == 0) {
        !          115632:                                sbp->s_tinode = 0;
        !          115633:                                unlock(mp->m_ilock);
        !          115634:                                devmsg(dev, "Out of inodes");
        !          115635:                                u.u_error = ENOSPC;
        !          115636:                                return (NULL);
        !          115637:                        }
        !          115638:                }
        !          115639:                ino = sbp->s_inode[--sbp->s_ninode];
        !          115640:                --sbp->s_tinode;
        !          115641:                sbp->s_fmod = 1;
        !          115642:                unlock(mp->m_ilock);
        !          115643:                if ((ip=iattach(dev, ino)) != NULL) {
        !          115644:                        if (ip->i_mode != 0) {
        !          115645:                                devmsg(dev, "Inode %u busy", ino);
        !          115646:                                idetach(ip);
        !          115647:                                continue;
        !          115648:                        }
        !          115649:                        ip->i_flag = 0;
        !          115650:                        ip->i_mode = mode;
        !          115651:                        ip->i_nlink = 0;
        !          115652:                        ip->i_uid = u.u_uid;
        !          115653:                        ip->i_gid = u.u_gid;
        !          115654:                }
        !          115655:                return (ip);
        !          115656:        }
        !          115657: }
        !          115658: 
        !          115659: /*
        !          115660:  * Free the inode `ino' on device `dev'.
        !          115661:  */
        !          115662: ifree(dev, ino)
        !          115663: dev_t dev;
        !          115664: ino_t ino;
        !          115665: {
        !          115666:        register struct filsys *sbp;
        !          115667:        register MOUNT *mp;
        !          115668: 
        !          115669:        if ((mp=getment(dev, 1)) == NULL)
        !          115670:                return;
        !          115671:        lock(mp->m_ilock);
        !          115672:        sbp = &mp->m_super;
        !          115673:        sbp->s_fmod = 1;
        !          115674:        if (sbp->s_ninode < NICINOD)
        !          115675:                sbp->s_inode[sbp->s_ninode++] = ino;
        !          115676:        sbp->s_tinode++;
        !          115677:        unlock(mp->m_ilock);
        !          115678: }
        !          115679: 
        !          115680: /*
        !          115681:  * Free all blocks in the indirect block `b' on the device `dev'.
        !          115682:  * `l' is the level of indirection.
        !          115683:  */
        !          115684: indfree(dev, b, l)
        !          115685: dev_t dev;
        !          115686: daddr_t b;
        !          115687: register unsigned l;
        !          115688: {
        !          115689:        register int i;
        !          115690:        register BUF *bp;
        !          115691:        daddr_t * dp;
        !          115692:        daddr_t b1;
        !          115693: 
        !          115694:        if (b == 0)
        !          115695:                return;
        !          115696:        if (l-->0 && (bp=bread(dev, b, 1))!=NULL) {
        !          115697:                i = NBN;
        !          115698:                while (i-- > 0) {
        !          115699:                        dp = FP_OFF(bp->b_faddr);
        !          115700: 
        !          115701:                        if ((b1 = dp[i]) == 0)
        !          115702:                                continue;
        !          115703:                        candaddr(b1);
        !          115704:                        if (l == 0)
        !          115705:                                bfree(dev, b1);
        !          115706:                        else
        !          115707:                                indfree(dev, b1, l);
        !          115708:                }
        !          115709:                brelease(bp);
        !          115710:        }
        !          115711:        bfree(dev, b);
        !          115712: }
        !          115713: 
        !          115714: /*
        !          115715:  * Allocate a block from the filesystem mounted of device `dev'.
        !          115716:  */
        !          115717: daddr_t
        !          115718: balloc(dev)
        !          115719: dev_t dev;
        !          115720: {
        !          115721:        register struct filsys *sbp;
        !          115722:        register struct fblk *fbp;
        !          115723:        register daddr_t b;
        !          115724:        register BUF *bp;
        !          115725:        register MOUNT *mp;
        !          115726: 
        !          115727:        if ((mp=getment(dev, 1)) == NULL)
        !          115728:                return (0);
        !          115729:        lock(mp->m_flock);
        !          115730:        sbp = &mp->m_super;
        !          115731:        if (sbp->s_nfree == 0) {
        !          115732: enospc:
        !          115733:                sbp->s_nfree = 0;
        !          115734:                devmsg(dev, "Out of space");
        !          115735:                u.u_error = ENOSPC;
        !          115736:                b = 0;
        !          115737:        } else {
        !          115738:                sbp->s_fmod = 1;
        !          115739:                if ((b=sbp->s_free[--sbp->s_nfree]) == 0)
        !          115740:                        goto enospc;
        !          115741:                if (sbp->s_nfree == 0) {
        !          115742:                        if (b >= sbp->s_fsize
        !          115743:                         || b < sbp->s_isize
        !          115744:                         || (bp = bread(dev, b, 1)) == NULL) {
        !          115745: ebadflist:
        !          115746:                                devmsg(dev, "Bad free list");
        !          115747:                                goto enospc;
        !          115748:                        }
        !          115749:                        fbp = FP_OFF(bp->b_faddr);
        !          115750:                        sbp->s_nfree = fbp->df_nfree;
        !          115751:                        canshort(sbp->s_nfree);
        !          115752:                        if ((unsigned)sbp->s_nfree > NICFREE)
        !          115753:                                goto ebadflist;
        !          115754:                        kkcopy(fbp->df_free, sbp->s_free, sizeof(sbp->s_free));
        !          115755:                        canndaddr(sbp->s_free, sbp->s_nfree);
        !          115756:                        brelease(bp);
        !          115757:                }
        !          115758:                --sbp->s_tfree;
        !          115759:                if (b >= sbp->s_fsize || b < sbp->s_isize)
        !          115760:                        goto ebadflist;
        !          115761:        }
        !          115762:        unlock(mp->m_flock);
        !          115763:        return (b);
        !          115764: }
        !          115765: 
        !          115766: /*
        !          115767:  * Free the block `b' on the device `dev'.
        !          115768:  */
        !          115769: bfree(dev, b)
        !          115770: dev_t dev;
        !          115771: daddr_t b;
        !          115772: {
        !          115773:        register struct filsys *sbp;
        !          115774:        register struct fblk *fbp;
        !          115775:        register BUF *bp;
        !          115776:        register MOUNT *mp;
        !          115777: 
        !          115778:        if ((mp=getment(dev, 1)) == NULL)
        !          115779:                return;
        !          115780:        sbp = &mp->m_super;
        !          115781:        if (b>=sbp->s_fsize || b<sbp->s_isize) {
        !          115782:                devmsg(dev, "Bad block %u (free)", (unsigned)b);
        !          115783:                return;
        !          115784:        }
        !          115785:        lock(mp->m_flock);
        !          115786:        if (sbp->s_nfree == 0 || sbp->s_nfree == NICFREE) {
        !          115787:                bp = bclaim(dev, b);
        !          115788:                fbp = FP_OFF(bp->b_faddr);
        !          115789:                kclear(fbp, BSIZE);
        !          115790:                fbp->df_nfree = sbp->s_nfree;
        !          115791:                canshort(fbp->df_nfree);
        !          115792:                kkcopy(sbp->s_free, fbp->df_free, sizeof(fbp->df_free));
        !          115793:                canndaddr(fbp->df_free, sbp->s_nfree);
        !          115794:                bp->b_flag |= BFMOD;
        !          115795:                brelease(bp);
        !          115796:                sbp->s_nfree = 0;
        !          115797:        }
        !          115798:        sbp->s_free[sbp->s_nfree++] = b;
        !          115799:        sbp->s_tfree++;
        !          115800:        sbp->s_fmod = 1;
        !          115801:        unlock(mp->m_flock);
        !          115802: }
        !          115803: 
        !          115804: /*
        !          115805:  * Determine if the given block is bad.
        !          115806:  */
        !          115807: bad(dev, b)
        !          115808: dev_t dev;
        !          115809: daddr_t b;
        !          115810: {
        !          115811:        register INODE *ip;
        !          115812:        register BUF *bp;
        !          115813:        register int i;
        !          115814:        register int m;
        !          115815:        register int n;
        !          115816:        daddr_t l;
        !          115817: 
        !          115818:        if ((ip=iattach(dev, 1)) == NULL)
        !          115819:                panic("bad()");
        !          115820:        n = blockn(ip->i_size);
        !          115821:        if ((m=n) > ND)
        !          115822:                m = ND;
        !          115823:        for (i=0; i<m; i++) {
        !          115824:                --n;
        !          115825:                if (b == ip->i_a.i_addr[i]) {
        !          115826:                        idetach(ip);
        !          115827:                        return (1);
        !          115828:                }
        !          115829:        }
        !          115830:        l = ip->i_a.i_addr[ND];
        !          115831:        idetach(ip);
        !          115832:        if (n == 0)
        !          115833:                return (0);
        !          115834:        if ((bp=bread(dev, l, 1)) == NULL)
        !          115835:                return (0);
        !          115836:        if ((m=n) > NBN)
        !          115837:                m = NBN;
        !          115838:        for (i=0; i<m; i++) {
        !          115839:                l = ((daddr_t *)bp)[i];
        !          115840:                candaddr(l);
        !          115841:                if (b == l) {
        !          115842:                        brelease(bp);
        !          115843:                        return (1);
        !          115844:                }
        !          115845:        }
        !          115846:        brelease(bp);
        !          115847:        return (0);
        !          115848: }
        !          115849: 
        !          115850: /*
        !          115851:  * Canonize `n' disk addresses.
        !          115852:  */
        !          115853: canndaddr(dp, n)
        !          115854: register daddr_t *dp;
        !          115855: register int n;
        !          115856: {
        !          115857:        while (n--) {
        !          115858:                candaddr(*dp);
        !          115859:                dp++;
        !          115860:        }
        !          115861: }
        !          115862: 
        !          115863: /*
        !          115864:  * Write out an accounting record.
        !          115865:  */
        !          115866: setacct()
        !          115867: {
        !          115868:        register PROC *pp;
        !          115869:        struct acct acct;
        !          115870:        IO acctio;
        !          115871: 
        !          115872:        if (acctip == NULL)
        !          115873:                return;
        !          115874:        pp = SELF;
        !          115875:        kkcopy(u.u_comm, acct.ac_comm, 10);
        !          115876:        acct.ac_utime = ltoc(pp->p_utime);
        !          115877:        acct.ac_stime = ltoc(pp->p_stime);
        !          115878:        acct.ac_etime = ltoc(timer.t_time - u.u_btime);
        !          115879:        acct.ac_btime = u.u_btime;
        !          115880:        acct.ac_uid = u.u_uid;
        !          115881:        acct.ac_gid = u.u_gid;
        !          115882:        acct.ac_mem = 0;
        !          115883:        acct.ac_io = ltoc(u.u_block);
        !          115884:        acct.ac_tty = pp->p_ttdev;
        !          115885:        acct.ac_flag = u.u_flag;
        !          115886:        ilock(acctip);
        !          115887:        acctio.io_seek = acctip->i_size;
        !          115888:        acctio.io_ioc  = sizeof (acct);
        !          115889:        acctio.io_base = &acct;
        !          115890:        acctio.io_seg  = IOSYS;
        !          115891:        acctio.io_flag = 0;
        !          115892:        iwrite(acctip, &acctio);
        !          115893:        iunlock(acctip);
        !          115894:        u.u_error = 0;
        !          115895: }
        !          115896: @
        !          115897: 
        !          115898: 
        !          115899: 1.3
        !          115900: log
        !          115901: @update by hal
        !          115902: @
        !          115903: text
        !          115904: @@
        !          115905: 
        !          115906: 
        !          115907: 1.2
        !          115908: log
        !          115909: @update provided by hal
        !          115910: @
        !          115911: text
        !          115912: @@
        !          115913: 
        !          115914: 
        !          115915: 1.1
        !          115916: log
        !          115917: @Initial revision
        !          115918: @
        !          115919: text
        !          115920: @d40 1
        !          115921: a40 1
        !          115922: #include <coherent.h>
        !          115923: @
        !          115924: 0707070064030053031004440000030000030000011777770507310735000004700000023157/newbits/kernel/USRSRC/coh/RCS/fs3.c,vhead     1.4;
        !          115925: branch   ;
        !          115926: access   ;
        !          115927: symbols  ;
        !          115928: locks    bin:1.4;
        !          115929: comment  @ * @;
        !          115930: 
        !          115931: 
        !          115932: 1.4
        !          115933: date     91.07.24.07.51.06;  author bin;  state Exp;
        !          115934: branches ;
        !          115935: next     1.3;
        !          115936: 
        !          115937: 1.3
        !          115938: date     91.07.15.14.32.42;  author bin;  state Exp;
        !          115939: branches ;
        !          115940: next     1.2;
        !          115941: 
        !          115942: 1.2
        !          115943: date     91.06.20.14.30.26;  author bin;  state Exp;
        !          115944: branches ;
        !          115945: next     1.1;
        !          115946: 
        !          115947: 1.1
        !          115948: date     91.06.10.14.37.19;  author bin;  state Exp;
        !          115949: branches ;
        !          115950: next     ;
        !          115951: 
        !          115952: 
        !          115953: desc
        !          115954: @initial version prov by hal
        !          115955: @
        !          115956: 
        !          115957: 
        !          115958: 1.4
        !          115959: log
        !          115960: @update prov by hal
        !          115961: 
        !          115962: @
        !          115963: text
        !          115964: @/* $Header: /usr/src/sys/coh/RCS/fs3.c,v 1.1 88/03/24 16:13:54 src Exp $ */
        !          115965: /* (lgl-
        !          115966:  *     The information contained herein is a trade secret of Mark Williams
        !          115967:  *     Company, and  is confidential information.  It is provided  under a
        !          115968:  *     license agreement,  and may be  copied or disclosed  only under the
        !          115969:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          115970:  *     material without the express written authorization of Mark Williams
        !          115971:  *     Company or persuant to the license agreement is unlawful.
        !          115972:  *
        !          115973:  *     COHERENT Version 2.3.37
        !          115974:  *     Copyright (c) 1982, 1983, 1984.
        !          115975:  *     An unpublished work by Mark Williams Company, Chicago.
        !          115976:  *     All rights reserved.
        !          115977:  -lgl) */
        !          115978: /*
        !          115979:  * Coherent.
        !          115980:  * Filesystem (I/O).
        !          115981:  *
        !          115982:  * $Log:       /usr/src/sys/coh/RCS/fs3.c,v $
        !          115983:  * Revision 1.1        88/03/24  16:13:54      src
        !          115984:  * Initial revision
        !          115985:  * 
        !          115986:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/fs3.c
        !          115987:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !          115988:  *
        !          115989:  * 86/02/01    Allan Cornish
        !          115990:  * Added code to fwrite() to avoid needless writing of pipe blocks.
        !          115991:  * Throughput on 6 Mhz AT rose from 30 Kbytes/sec to 79 Kbytes/sec.
        !          115992:  */
        !          115993: #include <sys/coherent.h>
        !          115994: #include <sys/buf.h>
        !          115995: #include <canon.h>
        !          115996: #include <sys/con.h>
        !          115997: #include <errno.h>
        !          115998: #include <sys/filsys.h>
        !          115999: #include <sys/mount.h>
        !          116000: #include <sys/io.h>
        !          116001: #include <sys/ino.h>
        !          116002: #include <sys/inode.h>
        !          116003: #include <sys/uproc.h>
        !          116004: #include <sys/stat.h>
        !          116005: 
        !          116006: /*
        !          116007:  * Given an inode, open it.
        !          116008:  */
        !          116009: iopen(ip, mode)
        !          116010: register INODE *ip;
        !          116011: {
        !          116012:        register int type;
        !          116013: 
        !          116014:        type = ip->i_mode & IFMT;
        !          116015:        switch (type) {
        !          116016:        case IFCHR:
        !          116017:        case IFBLK:
        !          116018:                iunlock(ip);
        !          116019:                dopen(ip->i_a.i_rdev, mode, type==IFCHR ? DFCHR : DFBLK);
        !          116020:                ilock(ip);
        !          116021:                break;
        !          116022:        case IFDIR:
        !          116023:                if ((mode&IPW) != 0) {
        !          116024:                        if (super() == 0)
        !          116025:                                return;
        !          116026:                        if (mode == IPW) {
        !          116027:                                u.u_error = EISDIR;
        !          116028:                                return;
        !          116029:                        }
        !          116030:                }
        !          116031:                break;
        !          116032:        case IFPIPE:
        !          116033:                popen(ip, mode);
        !          116034:                break;
        !          116035:        }
        !          116036: }
        !          116037: 
        !          116038: /*
        !          116039:  * Given an inode, close it.
        !          116040:  */
        !          116041: iclose(ip)
        !          116042: register INODE *ip;
        !          116043: {
        !          116044:        ilock(ip);
        !          116045:        switch (ip->i_mode&IFMT) {
        !          116046:        case IFBLK:
        !          116047:                bflush(ip->i_a.i_rdev);
        !          116048:        case IFCHR:
        !          116049:                iunlock(ip);
        !          116050:                dclose(ip->i_a.i_rdev);
        !          116051:                ilock(ip);
        !          116052:                break;
        !          116053:        case IFPIPE:
        !          116054:                pclose(ip);
        !          116055:                break;
        !          116056:        }
        !          116057:        idetach(ip);
        !          116058: }
        !          116059: 
        !          116060: /*
        !          116061:  * Read from a file described by an inode and an io strucuture.
        !          116062:  */
        !          116063: iread(ip, iop)
        !          116064: register INODE *ip;
        !          116065: register IO *iop;
        !          116066: {
        !          116067:        if (iop->io_ioc == 0)
        !          116068:                return;
        !          116069:        switch (ip->i_mode&IFMT) {
        !          116070:        case IFCHR:
        !          116071:                dread(ip->i_a.i_rdev, iop);
        !          116072:                break;
        !          116073:        case IFBLK:
        !          116074:        case IFREG:
        !          116075:        case IFDIR:
        !          116076:                fread(ip, iop);
        !          116077:                break;
        !          116078:        case IFPIPE:
        !          116079:                pread(ip, iop);
        !          116080:                break;
        !          116081:        default:
        !          116082:                u.u_error = ENXIO;
        !          116083:                break;
        !          116084:        }
        !          116085: }
        !          116086: 
        !          116087: /*
        !          116088:  * Write to a file described by an inode and io structure.
        !          116089:  */
        !          116090: iwrite(ip, iop)
        !          116091: register INODE *ip;
        !          116092: register IO *iop;
        !          116093: {
        !          116094:        imod(ip);       /* write - mtime */
        !          116095:        icrt(ip);       /* write - ctime */
        !          116096:        if (iop->io_ioc == 0)
        !          116097:                return;
        !          116098:        switch (ip->i_mode&IFMT) {
        !          116099:        case IFCHR:
        !          116100:                dwrite(ip->i_a.i_rdev, iop);
        !          116101:                break;
        !          116102:        case IFBLK:
        !          116103:                fwrite(ip, iop);
        !          116104:                break;
        !          116105:        case IFREG:
        !          116106:        case IFDIR:
        !          116107:                if (getment(ip->i_dev, 1) == NULL)
        !          116108:                        return;
        !          116109:                fwrite(ip, iop);
        !          116110:                break;
        !          116111:        case IFPIPE:
        !          116112:                pwrite(ip, iop);
        !          116113:                break;
        !          116114:        default:
        !          116115:                u.u_error = ENXIO;
        !          116116:                break;
        !          116117:        }
        !          116118: }
        !          116119: 
        !          116120: /*
        !          116121:  * Read from a regular or block special file.
        !          116122:  */
        !          116123: fread(ip, iop)
        !          116124: INODE *ip;
        !          116125: register IO *iop;
        !          116126: {
        !          116127: #ifdef TINY
        !          116128:        register unsigned n;
        !          116129:        register fsize_t res;
        !          116130:        register unsigned off;
        !          116131:        register daddr_t lbn;
        !          116132:        register BUF *bp;
        !          116133:        register int blk;
        !          116134: 
        !          116135:        lbn = blockn(iop->io_seek);
        !          116136:        off = blocko(iop->io_seek);
        !          116137:        blk = (ip->i_mode&IFMT) == IFBLK;
        !          116138:        res = ip->i_size - iop->io_seek;
        !          116139:        if (blk!=0 || res>iop->io_ioc)
        !          116140:                res = iop->io_ioc;
        !          116141:        while (res > 0) {
        !          116142:                bp = blk ? bread(ip->i_a.i_rdev, lbn, 1) : vread(ip, lbn);
        !          116143:                if (bp == NULL)
        !          116144:                        return;
        !          116145:                n = BSIZE - off;
        !          116146:                if (n > res)
        !          116147:                        n = res;
        !          116148:                iowrite(iop, FP_OFF(bp->b_faddr)+off, n);
        !          116149:                brelease(bp);
        !          116150:                if (u.u_error)
        !          116151:                        return;
        !          116152:                lbn++;
        !          116153:                off = 0;
        !          116154:                res -= n;
        !          116155:        }
        !          116156: /*
        !          116157:  * Start of daring read ahead code.
        !          116158:  * Altered to not read ahead on block devices
        !          116159:  * due to 20% time penalty incurred for such.
        !          116160:  */
        !          116161: #if 0
        !          116162:        if ( ! blk) {
        !          116163:                lbn = vmap(ip, lbn);
        !          116164:                if (lbn > 0)
        !          116165:                        bread(ip->i_dev, lbn, 0);
        !          116166:        }
        !          116167: #endif
        !          116168: /*
        !          116169:  * End of daring read ahead code.
        !          116170:  */
        !          116171: #else
        !          116172:        register unsigned n;
        !          116173:        register unsigned i;
        !          116174:        register fsize_t res;
        !          116175:        register unsigned off;
        !          116176:        register dev_t dev;
        !          116177:        register daddr_t lbn;
        !          116178:        register daddr_t pbn;
        !          116179:        register daddr_t abn;
        !          116180:        register daddr_t zbn;
        !          116181:        register BUF *bp;
        !          116182:        register int blk;
        !          116183:        daddr_t list[NEXREAD];
        !          116184: 
        !          116185:        if ((ip->i_mode&IFMT) == IFBLK) {
        !          116186:                blk = 1;
        !          116187:                dev = ip->i_a.i_rdev;
        !          116188:        } else {
        !          116189:                blk = 0;
        !          116190:                dev = ip->i_dev;
        !          116191:        }
        !          116192:        abn = 0;
        !          116193:        zbn = 0;
        !          116194:        lbn = blockn(iop->io_seek);
        !          116195:        off = blocko(iop->io_seek);
        !          116196:        res = ip->i_size - iop->io_seek;
        !          116197:        if (blk!=0 || res>iop->io_ioc)
        !          116198:                res = iop->io_ioc;
        !          116199:        if (res <= 0)
        !          116200:                return;
        !          116201:        if (res+off <= BSIZE) {
        !          116202:                bp = blk ? bread(dev, lbn, 1) : vread(ip, lbn);
        !          116203:                if (bp == NULL)
        !          116204:                        return;
        !          116205:                iowrite(iop, FP_OFF(bp->b_faddr)+off, (unsigned)res);
        !          116206:                brelease(bp);
        !          116207:                return;
        !          116208:        }
        !          116209:        while (res > 0) {
        !          116210:                if (lbn >= zbn) {
        !          116211:                        if ((n=blockn(res+BSIZE-1)) > NEXREAD)
        !          116212:                                n = NEXREAD;
        !          116213:                        if (n <= 0)
        !          116214:                                n = 1;
        !          116215:                        abn = lbn;
        !          116216:                        for (i=0, zbn=lbn; i<n; i++, zbn++) {
        !          116217:                                if (blk != 0)
        !          116218:                                        pbn = zbn;
        !          116219:                                else {
        !          116220:                                        if ((pbn=vmap(ip, zbn)) < 0)
        !          116221:                                                return;
        !          116222:                                        if (pbn == 0) {
        !          116223:                                                list[i] = -1;
        !          116224:                                                continue;
        !          116225:                                        }
        !          116226:                                }
        !          116227:                                list[i] = pbn;
        !          116228:                                bread(dev, pbn, 0);
        !          116229:                        }
        !          116230:                }
        !          116231:                if ((pbn=list[lbn-abn]) < 0) {
        !          116232:                        bp = bclaim(NODEV, (daddr_t)0);
        !          116233:                        kclear(FP_OFF(bp->b_faddr), BSIZE);
        !          116234:                } else {
        !          116235:                        if ((bp=bread(dev, pbn, 1)) == NULL)
        !          116236:                                return;
        !          116237:                }
        !          116238:                n = BSIZE - off;
        !          116239:                n = res>n ? n : res;
        !          116240:                iowrite(iop, FP_OFF(bp->b_faddr)+off, n);
        !          116241:                brelease(bp);
        !          116242:                if (u.u_error)
        !          116243:                        return;
        !          116244:                lbn++;
        !          116245:                off = 0;
        !          116246:                res -= n;
        !          116247:        }
        !          116248: #endif
        !          116249: }
        !          116250: 
        !          116251: /*
        !          116252:  * Write to a regular or block special file.
        !          116253:  */
        !          116254: fwrite(ip, iop)
        !          116255: INODE *ip;
        !          116256: register IO *iop;
        !          116257: {
        !          116258:        register unsigned n;
        !          116259:        register unsigned off;
        !          116260:        register daddr_t lbn;
        !          116261:        register BUF *bp;
        !          116262:        register int blk;
        !          116263:        register int com;
        !          116264: 
        !          116265:        lbn = blockn(iop->io_seek);
        !          116266:        off = blocko(iop->io_seek);
        !          116267:        blk = (ip->i_mode&IFMT) == IFBLK;
        !          116268:        while (iop->io_ioc > 0) {
        !          116269:                n = BSIZE - off;
        !          116270:                n = iop->io_ioc>n ? n : iop->io_ioc;
        !          116271:                com = off==0 && n==BSIZE;
        !          116272:                if (blk == 0)
        !          116273:                        bp = aread(ip, lbn, com);
        !          116274:                else {
        !          116275:                        if (com)
        !          116276:                                bp = bclaim(ip->i_a.i_rdev, lbn);
        !          116277:                        else
        !          116278:                                bp = bread(ip->i_a.i_rdev, lbn, 1);
        !          116279:                }
        !          116280:                if (bp == NULL)
        !          116281:                        return;
        !          116282:                ioread(iop, FP_OFF(bp->b_faddr)+off, n);
        !          116283:                bp->b_flag |= BFMOD;
        !          116284:                if (com && ((ip->i_mode&IFMT) != IFPIPE) )
        !          116285:                        bwrite(bp, 0);
        !          116286:                else
        !          116287:                        brelease(bp);
        !          116288:                if (u.u_error)
        !          116289:                        return;
        !          116290:                lbn++;
        !          116291:                off = 0;
        !          116292:                if ((iop->io_seek+=n) > ip->i_size)
        !          116293:                        if (blk == 0)
        !          116294:                                ip->i_size = iop->io_seek;
        !          116295:        }
        !          116296: }
        !          116297: 
        !          116298: /*
        !          116299:  * Given an inode pointer, read the requested virtual block and return
        !          116300:  * a buffer with the data.
        !          116301:  */
        !          116302: BUF *
        !          116303: vread(ip, lb)
        !          116304: register INODE *ip;
        !          116305: daddr_t lb;
        !          116306: {
        !          116307:        register daddr_t pb;
        !          116308:        register BUF *bp;
        !          116309: 
        !          116310:        if ((pb=vmap(ip, lb)) < 0)
        !          116311:                return (NULL);
        !          116312:        if (pb != 0)
        !          116313:                return (bread(ip->i_dev, pb, 1));
        !          116314:        bp = bclaim(NODEV, (daddr_t)0);
        !          116315:        kclear(FP_OFF(bp->b_faddr), BSIZE);
        !          116316:        return (bp);
        !          116317: }
        !          116318: 
        !          116319: /*
        !          116320:  * Convert the given virtual block to a physical block for the given inode.
        !          116321:  * If the block does not map onto a physical block because the file is sparse
        !          116322:  * but it does exist, 0 is returned.  If an error is encountered, -1 is
        !          116323:  * returned.
        !          116324:  */
        !          116325: daddr_t
        !          116326: vmap(ip, lb)
        !          116327: register INODE *ip;
        !          116328: daddr_t lb;
        !          116329: {
        !          116330:        register BUF *bp;
        !          116331:        register int *lp;
        !          116332:        daddr_t * dp;
        !          116333:        daddr_t pb;
        !          116334:        int list[1+NI];
        !          116335: 
        !          116336:        if ((lp=lmap(lb, list)) == NULL)
        !          116337:                return (-1);
        !          116338:        pb = ip->i_a.i_addr[*--lp];
        !          116339:        for (;;) {
        !          116340:                if (pb==0 || lp==list)
        !          116341:                        return (pb);
        !          116342:                if ((bp=bread(ip->i_dev, pb, 1)) == NULL)
        !          116343:                        return (0);
        !          116344:                dp = FP_OFF(bp->b_faddr);
        !          116345:                pb = dp[*--lp];
        !          116346:                brelease(bp);
        !          116347:                candaddr(pb);
        !          116348:        }
        !          116349: }
        !          116350: 
        !          116351: /*
        !          116352:  * Given an inode pointer, read the requested virtual block and return a
        !          116353:  * buffer with the data.  In sparse files, the necessary blocks are allocated.
        !          116354:  * If the flag, `fflag' is set, the final buffer is just claimed rather than
        !          116355:  * read as we are going to change it's contents completely.
        !          116356:  */
        !          116357: BUF *
        !          116358: aread(ip, lb, fflag)
        !          116359: register INODE *ip;
        !          116360: daddr_t lb;
        !          116361: {
        !          116362:        register BUF *bp;
        !          116363:        register int *lp;
        !          116364:        register dev_t dev;
        !          116365:        register int l;
        !          116366:        register int aflag;
        !          116367:        register int lflag;
        !          116368:        daddr_t * dp;
        !          116369:        daddr_t pb;
        !          116370:        int list[1+NI];
        !          116371: 
        !          116372:        if ((lp=lmap(lb, list)) == NULL)
        !          116373:                return (NULL);
        !          116374:        aflag = 0;
        !          116375:        dev = ip->i_dev;
        !          116376:        pb = ip->i_a.i_addr[l=*--lp];
        !          116377:        if (pb == 0) {
        !          116378:                aflag = 1;
        !          116379:                if ((pb=balloc(dev)) == 0)
        !          116380:                        return (NULL);
        !          116381:                ip->i_a.i_addr[l] = pb;
        !          116382:        }
        !          116383:        for (;;) {
        !          116384:                lflag = lp==list;
        !          116385:                if (aflag==0  &&  (fflag==0 || lflag==0)) {
        !          116386:                        if ((bp=bread(dev, pb, 1)) == NULL)
        !          116387:                                return (NULL);
        !          116388:                } else {
        !          116389:                        bp = bclaim(dev, pb);
        !          116390:                        kclear(FP_OFF(bp->b_faddr), BSIZE);
        !          116391:                        bp->b_flag |= BFMOD;
        !          116392:                }
        !          116393:                if (lflag)
        !          116394:                        return (bp);
        !          116395: 
        !          116396:                aflag = 0;
        !          116397:                dp = FP_OFF(bp->b_faddr);
        !          116398:                pb = dp[l=*--lp];
        !          116399:                candaddr(pb);
        !          116400:                if (pb == 0) {
        !          116401:                        aflag = 1;
        !          116402:                        if ((pb=balloc(dev)) == 0) {
        !          116403:                                brelease(bp);
        !          116404:                                return (NULL);
        !          116405:                        }
        !          116406:                        dp[l] = pb;
        !          116407:                        candaddr( dp[l] );
        !          116408:                        bp->b_flag |= BFMOD;
        !          116409:                }
        !          116410:                brelease(bp);
        !          116411:        }
        !          116412: }
        !          116413: 
        !          116414: /*
        !          116415:  * Given a block number, `b', store the offsets for the indirect blocks
        !          116416:  * backwards in the array, `lp', and return a pointer just after the
        !          116417:  * position where the first offset is stored.
        !          116418:  */
        !          116419: int *
        !          116420: lmap(b, lp)
        !          116421: register daddr_t b;
        !          116422: register int *lp;
        !          116423: {
        !          116424:        register int n;
        !          116425: 
        !          116426:        if (b < ND) {
        !          116427:                *lp++ = b;
        !          116428:                return (lp);
        !          116429:        }
        !          116430:        b -= ND;
        !          116431:        n = NI;
        !          116432:        do {
        !          116433:                if (n-- == 0) {
        !          116434:                        u.u_error = EFBIG;
        !          116435:                        return (NULL);
        !          116436:                }
        !          116437:                *lp = nbnrem(b);
        !          116438:                ++lp;
        !          116439:                b = nbndiv(b);
        !          116440:        } while (b--);
        !          116441:        *lp++ = ND+NI-1-n;
        !          116442:        return (lp);
        !          116443: }
        !          116444: @
        !          116445: 
        !          116446: 
        !          116447: 1.3
        !          116448: log
        !          116449: @update by hal
        !          116450: @
        !          116451: text
        !          116452: @@
        !          116453: 
        !          116454: 
        !          116455: 1.2
        !          116456: log
        !          116457: @update provided by hal
        !          116458: @
        !          116459: text
        !          116460: @@
        !          116461: 
        !          116462: 
        !          116463: 1.1
        !          116464: log
        !          116465: @Initial revision
        !          116466: @
        !          116467: text
        !          116468: @d30 1
        !          116469: a30 1
        !          116470: #include <coherent.h>
        !          116471: @
        !          116472: 0707070064030053151004440000030000030000011777770507310735200005000000004672/newbits/kernel/USRSRC/coh/RCS/main.c,vhead     1.4;
        !          116473: branch   ;
        !          116474: access   ;
        !          116475: symbols  ;
        !          116476: locks    bin:1.4;
        !          116477: comment  @ * @;
        !          116478: 
        !          116479: 
        !          116480: 1.4
        !          116481: date     91.07.24.07.51.15;  author bin;  state Exp;
        !          116482: branches ;
        !          116483: next     1.3;
        !          116484: 
        !          116485: 1.3
        !          116486: date     91.07.15.14.32.53;  author bin;  state Exp;
        !          116487: branches ;
        !          116488: next     1.2;
        !          116489: 
        !          116490: 1.2
        !          116491: date     91.06.20.14.30.36;  author bin;  state Exp;
        !          116492: branches ;
        !          116493: next     1.1;
        !          116494: 
        !          116495: 1.1
        !          116496: date     91.06.10.14.37.22;  author bin;  state Exp;
        !          116497: branches ;
        !          116498: next     ;
        !          116499: 
        !          116500: 
        !          116501: desc
        !          116502: @initial version prov by hal
        !          116503: @
        !          116504: 
        !          116505: 
        !          116506: 1.4
        !          116507: log
        !          116508: @update prov by hal
        !          116509: 
        !          116510: @
        !          116511: text
        !          116512: @/*
        !          116513:  * Coherent.
        !          116514:  *
        !          116515:  * $Log:       /usr/src/sys/coh/RCS/main.c,v $
        !          116516:  * Revision 1.2        88/06/29  12:00:29      src
        !          116517:  * Real/Protected mode status now printed during boot sequence.
        !          116518:  * Three part serial numbers now supported, moved to optional fourth line.
        !          116519:  * 
        !          116520:  * Revision 1.1        88/03/24  16:13:58      src
        !          116521:  * Initial revision
        !          116522:  * 
        !          116523:  * 87/04/09    Allan Cornish           /usr/src/sys/coh/main.c
        !          116524:  * Serial numbers changed to support group.
        !          116525:  *
        !          116526:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/main.c
        !          116527:  * Copyright notice revised to include 1987.
        !          116528:  */
        !          116529: #include <sys/coherent.h>
        !          116530: #include <sys/proc.h>
        !          116531: #include <sys/seg.h>
        !          116532: #include <sys/uproc.h>
        !          116533: 
        !          116534: #ifndef VERSION                /* This should be specified at compile time */
        !          116535: #define VERSION        "..."
        !          116536: #endif
        !          116537: 
        !          116538: unsigned long  _entry = 0;             /* really the serial number */
        !          116539: unsigned long  __ = 0;                 /* really the serial number also */
        !          116540: 
        !          116541: /*
        !          116542:  * Initialise various things.  When we return we will return to user mode.
        !          116543:  */
        !          116544: char version[] = VERSION;
        !          116545: char copyright[] = "\
        !          116546: Copyright (c) 1982, 1991 by Mark Williams Company\n\
        !          116547: ";
        !          116548: 
        !          116549: main()
        !          116550: {
        !          116551:        register SEG *sp;
        !          116552:        extern int realmode;    /* real addressing mode - as2.s */
        !          116553: 
        !          116554:        u.u_error = 0;
        !          116555:        bufinit();
        !          116556:        cltinit();
        !          116557:        pcsinit();
        !          116558:        seginit();
        !          116559:        devinit();
        !          116560:        printf("\Mark Williams COHERENT Version %s - %s Mode (mem=%u Kbytes)\n",
        !          116561:                version, (realmode ? "Real" : "Protected"), msize );
        !          116562:        printf(copyright);
        !          116563: 
        !          116564:        if ( _entry ) {
        !          116565:                printf("Serial Number ");
        !          116566:                printf("%U\n", _entry);
        !          116567:        }
        !          116568: 
        !          116569:        /*
        !          116570:         * Verify correct serial number
        !          116571:         */
        !          116572:        if (_entry != __)
        !          116573:                panic("Verification error - call Mark Williams Company at 1-800-MARK-WMS\n");
        !          116574: 
        !          116575:        /*
        !          116576:         * Turn on clock, start off processes, mount root device
        !          116577:         * and return.
        !          116578:         */
        !          116579:        batflag = 1;
        !          116580:        if ((sp=salloc((fsize_t)UPASIZE, SFNCLR|SFNSWP)) == NULL)
        !          116581:                panic("Cannot allocate user area");
        !          116582:        if ((iprocp=process(idle))==NULL || (eprocp=process(NULL))==NULL)
        !          116583:                panic("Cannot create process");
        !          116584:        eveinit(sp);
        !          116585:        fsminit();
        !          116586: }
        !          116587: @
        !          116588: 
        !          116589: 
        !          116590: 1.3
        !          116591: log
        !          116592: @update by hal
        !          116593: @
        !          116594: text
        !          116595: @@
        !          116596: 
        !          116597: 
        !          116598: 1.2
        !          116599: log
        !          116600: @update provided by hal
        !          116601: @
        !          116602: text
        !          116603: @@
        !          116604: 
        !          116605: 
        !          116606: 1.1
        !          116607: log
        !          116608: @Initial revision
        !          116609: @
        !          116610: text
        !          116611: @d18 1
        !          116612: a18 1
        !          116613: #include <coherent.h>
        !          116614: @
        !          116615: 0707070064030053021004440000030000030000011777770507310735300005000000005474/newbits/kernel/USRSRC/coh/RCS/misc.c,vhead     1.4;
        !          116616: branch   ;
        !          116617: access   ;
        !          116618: symbols  ;
        !          116619: locks    bin:1.4;
        !          116620: comment  @ * @;
        !          116621: 
        !          116622: 
        !          116623: 1.4
        !          116624: date     91.07.24.07.51.19;  author bin;  state Exp;
        !          116625: branches ;
        !          116626: next     1.3;
        !          116627: 
        !          116628: 1.3
        !          116629: date     91.07.15.14.32.56;  author bin;  state Exp;
        !          116630: branches ;
        !          116631: next     1.2;
        !          116632: 
        !          116633: 1.2
        !          116634: date     91.06.20.14.30.39;  author bin;  state Exp;
        !          116635: branches ;
        !          116636: next     1.1;
        !          116637: 
        !          116638: 1.1
        !          116639: date     91.06.10.14.37.23;  author bin;  state Exp;
        !          116640: branches ;
        !          116641: next     ;
        !          116642: 
        !          116643: 
        !          116644: desc
        !          116645: @initial version prov by hal
        !          116646: @
        !          116647: 
        !          116648: 
        !          116649: 1.4
        !          116650: log
        !          116651: @update prov by hal
        !          116652: 
        !          116653: @
        !          116654: text
        !          116655: @/* $Header: /usr/src/sys/coh/RCS/misc.c,v 1.1 88/03/24 16:14:01 src Exp $ */
        !          116656: /* (lgl-
        !          116657:  *     The information contained herein is a trade secret of Mark Williams
        !          116658:  *     Company, and  is confidential information.  It is provided  under a
        !          116659:  *     license agreement,  and may be  copied or disclosed  only under the
        !          116660:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          116661:  *     material without the express written authorization of Mark Williams
        !          116662:  *     Company or persuant to the license agreement is unlawful.
        !          116663:  *
        !          116664:  *     COHERENT Version 2.3.37
        !          116665:  *     Copyright (c) 1982, 1983, 1984.
        !          116666:  *     An unpublished work by Mark Williams Company, Chicago.
        !          116667:  *     All rights reserved.
        !          116668:  -lgl) */
        !          116669: /*
        !          116670:  * Coherent.
        !          116671:  * Miscellaneous routines.
        !          116672:  *
        !          116673:  * $Log:       /usr/src/sys/coh/RCS/misc.c,v $
        !          116674:  * Revision 1.1        88/03/24  16:14:01      src
        !          116675:  * Initial revision
        !          116676:  * 
        !          116677:  * 87/05/08    Allan Cornish           /usr/src/sys/coh/misc.c
        !          116678:  * System code and data segments no longer reported in panic messages.
        !          116679:  *
        !          116680:  * 87/02/17    Allan Cornish           /usr/src/sys/coh/misc.c
        !          116681:  * Panic message now includes system code and data segments.
        !          116682:  */
        !          116683: #include <sys/coherent.h>
        !          116684: #include <acct.h>
        !          116685: #include <errno.h>
        !          116686: #include <sys/ino.h>
        !          116687: #include <sys/stat.h>
        !          116688: #include <sys/uproc.h>
        !          116689: 
        !          116690: /*
        !          116691:  * Copy `n' bytes from `bp1' to `bp2'.
        !          116692:  */
        !          116693: kkcopy(bp1, bp2, n)
        !          116694: register char *bp1;
        !          116695: register char *bp2;
        !          116696: unsigned n;
        !          116697: {
        !          116698:        register unsigned n1;
        !          116699: 
        !          116700:        n1 = n;
        !          116701:        if (n1) {
        !          116702:                do {
        !          116703:                        *bp2++ = *bp1++;
        !          116704:                } while (--n1);
        !          116705:        }
        !          116706:        return (n);
        !          116707: }
        !          116708: 
        !          116709: /*
        !          116710:  * Clear the next `n' bytes starting at `bp'.
        !          116711:  */
        !          116712: kclear(bp, n)
        !          116713: register char *bp;
        !          116714: register unsigned n;
        !          116715: {
        !          116716:        if (n) {
        !          116717:                do {
        !          116718:                        *bp++ = 0;
        !          116719:                } while (--n);
        !          116720:        }
        !          116721: }
        !          116722: 
        !          116723: /*
        !          116724:  * Make sure we are the super user.
        !          116725:  */
        !          116726: super()
        !          116727: {
        !          116728:        if (u.u_uid) {
        !          116729:                u.u_error = EPERM;
        !          116730:                return (0);
        !          116731:        }
        !          116732:        u.u_flag |= ASU;
        !          116733:        return (1);
        !          116734: }
        !          116735: 
        !          116736: /*
        !          116737:  * Make sure we are the gived `uid' or the super user.
        !          116738:  */
        !          116739: owner(uid)
        !          116740: {
        !          116741:        if (u.u_uid == uid)
        !          116742:                return (1);
        !          116743:        if (u.u_uid == 0) {
        !          116744:                u.u_flag |= ASU;
        !          116745:                return (1);
        !          116746:        }
        !          116747:        u.u_error = EPERM;
        !          116748:        return (0);
        !          116749: }
        !          116750: 
        !          116751: /*
        !          116752:  * Panic.
        !          116753:  */
        !          116754: panic(a1)
        !          116755: char *a1;
        !          116756: {
        !          116757:        static panflag;
        !          116758: 
        !          116759:        if (panflag++ == 0) {
        !          116760:                printf("Panic: %r", &a1);
        !          116761:                putchar('\n');
        !          116762:                usync();
        !          116763:        }
        !          116764:        halt();
        !          116765:        --panflag;
        !          116766: }
        !          116767: 
        !          116768: /*
        !          116769:  * Print a message from a device driver.
        !          116770:  */
        !          116771: devmsg(dev, a1)
        !          116772: dev_t dev;
        !          116773: char *a1;
        !          116774: {
        !          116775:        printf("(%d,%d): %r", major(dev), minor(dev), &a1);
        !          116776:        printf("\n");
        !          116777: }
        !          116778: @
        !          116779: 
        !          116780: 
        !          116781: 1.3
        !          116782: log
        !          116783: @update by hal
        !          116784: @
        !          116785: text
        !          116786: @@
        !          116787: 
        !          116788: 
        !          116789: 1.2
        !          116790: log
        !          116791: @update provided by hal
        !          116792: @
        !          116793: text
        !          116794: @@
        !          116795: 
        !          116796: 
        !          116797: 1.1
        !          116798: log
        !          116799: @Initial revision
        !          116800: @
        !          116801: text
        !          116802: @d29 1
        !          116803: a29 1
        !          116804: #include <coherent.h>
        !          116805: @
        !          116806: 0707070064030053011004440000030000030000011777770507310735300005000000005627/newbits/kernel/USRSRC/coh/RCS/null.c,vhead     1.4;
        !          116807: branch   ;
        !          116808: access   ;
        !          116809: symbols  ;
        !          116810: locks    bin:1.4;
        !          116811: comment  @ * @;
        !          116812: 
        !          116813: 
        !          116814: 1.4
        !          116815: date     91.07.24.07.51.24;  author bin;  state Exp;
        !          116816: branches ;
        !          116817: next     1.3;
        !          116818: 
        !          116819: 1.3
        !          116820: date     91.07.15.14.33.00;  author bin;  state Exp;
        !          116821: branches ;
        !          116822: next     1.2;
        !          116823: 
        !          116824: 1.2
        !          116825: date     91.06.20.14.30.43;  author bin;  state Exp;
        !          116826: branches ;
        !          116827: next     1.1;
        !          116828: 
        !          116829: 1.1
        !          116830: date     91.06.10.14.37.25;  author bin;  state Exp;
        !          116831: branches ;
        !          116832: next     ;
        !          116833: 
        !          116834: 
        !          116835: desc
        !          116836: @initial version prov by hal
        !          116837: @
        !          116838: 
        !          116839: 
        !          116840: 1.4
        !          116841: log
        !          116842: @update prov by hal
        !          116843: 
        !          116844: @
        !          116845: text
        !          116846: @/* $Header: /usr/src/sys/coh/RCS/null.c,v 1.1 88/03/24 16:14:04 src Exp $ */
        !          116847: /* (lgl-
        !          116848:  *     The information contained herein is a trade secret of Mark Williams
        !          116849:  *     Company, and  is confidential information.  It is provided  under a
        !          116850:  *     license agreement,  and may be  copied or disclosed  only under the
        !          116851:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          116852:  *     material without the express written authorization of Mark Williams
        !          116853:  *     Company or persuant to the license agreement is unlawful.
        !          116854:  *
        !          116855:  *     COHERENT Version 2.3.37
        !          116856:  *     Copyright (c) 1982, 1983, 1984.
        !          116857:  *     An unpublished work by Mark Williams Company, Chicago.
        !          116858:  *     All rights reserved.
        !          116859:  -lgl) */
        !          116860: /*
        !          116861:  * Null and memory driver.
        !          116862:  *  Minor device 0 is /dev/null
        !          116863:  *  Minor device 1 is physical memory
        !          116864:  *  Minor device 2 is kernel data
        !          116865:  *
        !          116866:  * $Log:       /usr/src/sys/coh/RCS/null.c,v $
        !          116867:  * Revision 1.1        88/03/24  16:14:04      src
        !          116868:  * Initial revision
        !          116869:  * 
        !          116870:  */
        !          116871: #include <sys/coherent.h>
        !          116872: #include <sys/con.h>
        !          116873: #include <errno.h>
        !          116874: #include <sys/stat.h>
        !          116875: #include <sys/uproc.h>
        !          116876: 
        !          116877: /*
        !          116878:  * Functions for configuration.
        !          116879:  */
        !          116880: int    nlread();
        !          116881: int    nlwrite();
        !          116882: int    nulldev();
        !          116883: int    nonedev();
        !          116884: 
        !          116885: /*
        !          116886:  * Configuration table.
        !          116887:  */
        !          116888: CON nlcon ={
        !          116889:        DFCHR,                          /* Flags */
        !          116890:        0,                              /* Major index */
        !          116891:        nulldev,                        /* Open */
        !          116892:        nulldev,                        /* Close */
        !          116893:        nulldev,                        /* Block */
        !          116894:        nlread,                         /* Read */
        !          116895:        nlwrite,                        /* Write */
        !          116896:        nonedev,                        /* Ioctl */
        !          116897:        nulldev,                        /* Powerfail */
        !          116898:        nulldev,                        /* Timeout */
        !          116899:        nulldev,                        /* Load */
        !          116900:        nulldev                         /* Unload */
        !          116901: };
        !          116902: 
        !          116903: /*
        !          116904:  * Null/memory read routine.
        !          116905:  */
        !          116906: nlread(dev, iop)
        !          116907: dev_t dev;
        !          116908: register IO *iop;
        !          116909: {
        !          116910:        register unsigned n;
        !          116911: 
        !          116912:        switch (minor(dev)) {
        !          116913:        case 0:
        !          116914:                n = 0;
        !          116915:                break;
        !          116916: 
        !          116917:        case 1:
        !          116918:                n = pucopy((long)iop->io_seek, iop->io_base, iop->io_ioc);
        !          116919:                break;
        !          116920: 
        !          116921:        case 2:
        !          116922:                n = kucopy((vaddr_t)iop->io_seek, iop->io_base, iop->io_ioc);
        !          116923:                break;
        !          116924: 
        !          116925:        default:
        !          116926:                u.u_error = ENXIO;
        !          116927:                return;
        !          116928:        }
        !          116929:        iop->io_ioc -= n;
        !          116930:        if (u.u_error == EFAULT)
        !          116931:                u.u_error = 0;
        !          116932: }
        !          116933: 
        !          116934: /*
        !          116935:  * Null/memory write routine.
        !          116936:  */
        !          116937: nlwrite(dev, iop)
        !          116938: dev_t dev;
        !          116939: register IO *iop;
        !          116940: {
        !          116941:        register unsigned n;
        !          116942: 
        !          116943:        switch (minor(dev)) {
        !          116944:        case 0:
        !          116945:                n = iop->io_ioc;
        !          116946:                break;
        !          116947: 
        !          116948:        case 1:
        !          116949:                n = upcopy(iop->io_base, (long)iop->io_seek, iop->io_ioc);
        !          116950:                break;
        !          116951: 
        !          116952:        case 2:
        !          116953:                n = ukcopy(iop->io_base, (vaddr_t)iop->io_seek, iop->io_ioc);
        !          116954:                break;
        !          116955: 
        !          116956:        default:
        !          116957:                u.u_error = ENXIO;
        !          116958:                return;
        !          116959:        }
        !          116960:        iop->io_ioc -= n;
        !          116961:        if (u.u_error == EFAULT)
        !          116962:                u.u_error = 0;
        !          116963: }
        !          116964: @
        !          116965: 
        !          116966: 
        !          116967: 1.3
        !          116968: log
        !          116969: @update by hal
        !          116970: @
        !          116971: text
        !          116972: @@
        !          116973: 
        !          116974: 
        !          116975: 1.2
        !          116976: log
        !          116977: @update provided by hal
        !          116978: @
        !          116979: text
        !          116980: @@
        !          116981: 
        !          116982: 
        !          116983: 1.1
        !          116984: log
        !          116985: @Initial revision
        !          116986: @
        !          116987: text
        !          116988: @d26 1
        !          116989: a26 1
        !          116990: #include <coherent.h>
        !          116991: @
        !          116992: 0707070064030053001004440000030000030000011777770507310735400005000000012103/newbits/kernel/USRSRC/coh/RCS/pipe.c,vhead     1.4;
        !          116993: branch   ;
        !          116994: access   ;
        !          116995: symbols  ;
        !          116996: locks    bin:1.4;
        !          116997: comment  @ * @;
        !          116998: 
        !          116999: 
        !          117000: 1.4
        !          117001: date     91.07.24.07.51.27;  author bin;  state Exp;
        !          117002: branches ;
        !          117003: next     1.3;
        !          117004: 
        !          117005: 1.3
        !          117006: date     91.07.15.14.33.03;  author bin;  state Exp;
        !          117007: branches ;
        !          117008: next     1.2;
        !          117009: 
        !          117010: 1.2
        !          117011: date     91.06.20.14.30.46;  author bin;  state Exp;
        !          117012: branches ;
        !          117013: next     1.1;
        !          117014: 
        !          117015: 1.1
        !          117016: date     91.06.10.14.37.26;  author bin;  state Exp;
        !          117017: branches ;
        !          117018: next     ;
        !          117019: 
        !          117020: 
        !          117021: desc
        !          117022: @initial version prov by hal
        !          117023: @
        !          117024: 
        !          117025: 
        !          117026: 1.4
        !          117027: log
        !          117028: @update prov by hal
        !          117029: 
        !          117030: @
        !          117031: text
        !          117032: @/* $Header: /usr/src/sys/coh/RCS/pipe.c,v 1.1 88/03/24 16:14:07 src Exp $ */
        !          117033: /* (lgl-
        !          117034:  *     The information contained herein is a trade secret of Mark Williams
        !          117035:  *     Company, and  is confidential information.  It is provided  under a
        !          117036:  *     license agreement,  and may be  copied or disclosed  only under the
        !          117037:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          117038:  *     material without the express written authorization of Mark Williams
        !          117039:  *     Company or persuant to the license agreement is unlawful.
        !          117040:  *
        !          117041:  *     COHERENT Version 2.3.37
        !          117042:  *     Copyright (c) 1982, 1983, 1984.
        !          117043:  *     An unpublished work by Mark Williams Company, Chicago.
        !          117044:  *     All rights reserved.
        !          117045:  -lgl) */
        !          117046: /*
        !          117047:  * Coherent.
        !          117048:  * Pipes.
        !          117049:  *
        !          117050:  * $Log:       /usr/src/sys/coh/RCS/pipe.c,v $
        !          117051:  * Revision 1.1        88/03/24  16:14:07      src
        !          117052:  * Initial revision
        !          117053:  * 
        !          117054:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/pipe.c
        !          117055:  * Added check for non-blocking read and write if (io_flag & IPNDLY) set.
        !          117056:  * Eliminated use of i_a inode field since now included in inode macros.
        !          117057:  */
        !          117058: #include <sys/coherent.h>
        !          117059: #include <errno.h>
        !          117060: #include <sys/filsys.h>
        !          117061: #include <sys/ino.h>
        !          117062: #include <sys/inode.h>
        !          117063: #include <sys/io.h>
        !          117064: #include <sys/proc.h>
        !          117065: #include <sys/sched.h>
        !          117066: #include <signal.h>
        !          117067: #include <sys/uproc.h>
        !          117068: 
        !          117069: /*
        !          117070:  * Create and return a locked pipe inode.  This is called from the
        !          117071:  * pipe system call.
        !          117072:  */
        !          117073: INODE *
        !          117074: pmake(mode)
        !          117075: {
        !          117076:        register INODE *ip;
        !          117077: 
        !          117078:        if ((ip=ialloc(pipedev, IFPIPE|mode)) != NULL) {
        !          117079:                iclear(ip);
        !          117080:                ip->i_pnc = 0;
        !          117081:                ip->i_prx = 0;
        !          117082:                ip->i_pwx = 0;
        !          117083:        }
        !          117084:        return (ip);
        !          117085: }
        !          117086: 
        !          117087: /*
        !          117088:  * Open a pipe given the inode pointer.
        !          117089:  */
        !          117090: popen(ip, mode)
        !          117091: {
        !          117092: }
        !          117093: 
        !          117094: /*
        !          117095:  * Close a pipe inode.
        !          117096:  */
        !          117097: pclose(ip)
        !          117098: register INODE *ip;
        !          117099: {
        !          117100:        if (ip->i_refc == 2) {
        !          117101:                pevent(ip);
        !          117102:                ip->i_flag |= IFEOF;
        !          117103:        }
        !          117104: }
        !          117105: 
        !          117106: /*
        !          117107:  * Only one end of the pipe is going to be left.
        !          117108:  */
        !          117109: pevent(ip)
        !          117110: register INODE *ip;
        !          117111: {
        !          117112:        if ((ip->i_flag&IFWFR) != 0) {
        !          117113:                ip->i_flag &= ~IFWFR;
        !          117114:                wakeup((char *)&ip->i_pwx);
        !          117115:        }
        !          117116:        if ((ip->i_flag&IFWFW) != 0) {
        !          117117:                ip->i_flag &= ~IFWFW;
        !          117118:                wakeup((char *)&ip->i_prx);
        !          117119:        }
        !          117120: }
        !          117121: 
        !          117122: /*
        !          117123:  * Read from a pipe.  The given inode is locked.
        !          117124:  */
        !          117125: pread(ip, iop)
        !          117126: register INODE *ip;
        !          117127: register IO *iop;
        !          117128: {
        !          117129:        register unsigned n;
        !          117130:        register unsigned ioc;
        !          117131: 
        !          117132:        while (ip->i_pnc == 0) {
        !          117133: 
        !          117134:                /*
        !          117135:                 * Logical End of File.
        !          117136:                 */
        !          117137:                if ((ip->i_flag&IFEOF) != 0) {
        !          117138:                        ip->i_flag &= ~IFEOF;
        !          117139:                        break;
        !          117140:                }
        !          117141: 
        !          117142:                /*
        !          117143:                 * Nobody left to write.
        !          117144:                 */
        !          117145:                if (ip->i_nlink==0 && ip->i_refc<2)
        !          117146:                        break;
        !          117147: 
        !          117148:                /*
        !          117149:                 * Non-blocking read.
        !          117150:                 */
        !          117151:                if ( iop->io_flag & IONDLY ) {
        !          117152:                        u.u_error = EAGAIN;
        !          117153:                        return;
        !          117154:                }
        !          117155: 
        !          117156:                /*
        !          117157:                 * Wait for pipe data.
        !          117158:                 */
        !          117159:                ip->i_flag |= IFWFW;
        !          117160:                iunlock(ip);
        !          117161:                sleep((char *)&ip->i_prx, CVPIPE, IVPIPE, SVPIPE);
        !          117162:                ilock(ip);
        !          117163:        }
        !          117164: 
        !          117165:        /*
        !          117166:         * Clear EOF flag.
        !          117167:         */
        !          117168:        if ((ip->i_flag&IFEOF)!=0 && ip->i_pnc==0)
        !          117169:                ip->i_flag &= ~IFEOF;
        !          117170: 
        !          117171:        ioc = iop->io_ioc;
        !          117172:        while (u.u_error==0 && ioc>0 && ip->i_pnc>0) {
        !          117173: 
        !          117174:                /*
        !          117175:                 * Calculate length of data to be read.
        !          117176:                 */
        !          117177:                if ((n=PIPSIZE-ip->i_prx) > ioc)
        !          117178:                        n = ioc;
        !          117179:                if (n > ip->i_pnc)
        !          117180:                        n = ip->i_pnc;
        !          117181: 
        !          117182:                /*
        !          117183:                 * Read data.
        !          117184:                 */
        !          117185:                iop->io_ioc = n;
        !          117186:                iop->io_seek = ip->i_prx;
        !          117187:                fread(ip, iop);
        !          117188:                n -= iop->io_ioc;
        !          117189:                if ((ip->i_prx+=n) == PIPSIZE)
        !          117190:                        ip->i_prx = 0;
        !          117191:                ip->i_pnc -= n;
        !          117192:                ioc -= n;
        !          117193:        }
        !          117194:        iop->io_ioc = ioc;
        !          117195: 
        !          117196:        /*
        !          117197:         * Wake processes waiting to write.
        !          117198:         */
        !          117199:        if ((ip->i_flag&IFWFR)!=0 && ip->i_pnc<PIPSIZE) {
        !          117200:                ip->i_flag &= ~IFWFR;
        !          117201:                wakeup((char *)&ip->i_pwx);
        !          117202:        }
        !          117203: }
        !          117204: 
        !          117205: /*
        !          117206:  * Write to a pipe.  The given inode is locked.
        !          117207:  */
        !          117208: pwrite(ip, iop)
        !          117209: register INODE *ip;
        !          117210: register IO *iop;
        !          117211: {
        !          117212:        register unsigned n;
        !          117213:        register unsigned ioc;
        !          117214: 
        !          117215:        ioc = iop->io_ioc;
        !          117216:        while (u.u_error==0 && ioc>0) {
        !          117217: 
        !          117218:                /*
        !          117219:                 * Nobody left to read.
        !          117220:                 */
        !          117221:                if ( (ip->i_refc < 2) && (ip->i_nlink == 0) ) {
        !          117222:                        u.u_error = EPIPE;
        !          117223:                        sendsig(SIGPIPE, SELF);
        !          117224:                        return;
        !          117225:                }
        !          117226: 
        !          117227:                /*
        !          117228:                 * Calculate free space in pipe.
        !          117229:                 */
        !          117230:                if ( (n=PIPSIZE-ip->i_pwx) > ioc )
        !          117231:                        n = ioc;
        !          117232:                if (n > PIPSIZE-ip->i_pnc)
        !          117233:                        n = PIPSIZE - ip->i_pnc;
        !          117234: 
        !          117235:                /*
        !          117236:                 * Non-blocking write.
        !          117237:                 */
        !          117238:                if ( iop->io_flag & IONDLY ) {
        !          117239:                        if ( (n != ioc) || (ip->i_flag & IFEOF) ) {
        !          117240:                                u.u_error = EAGAIN;
        !          117241:                                return;
        !          117242:                        }
        !          117243:                }
        !          117244: 
        !          117245:                /*
        !          117246:                 * Insufficent space or EOF still pending.
        !          117247:                 */
        !          117248:                if (n==0 || (ip->i_flag&IFEOF)!=0) {
        !          117249:                        ip->i_flag |= IFWFR;
        !          117250:                        iunlock(ip);
        !          117251:                        sleep((char *)&ip->i_pwx, CVPIPE, IVPIPE, SVPIPE);
        !          117252:                        ilock(ip);
        !          117253:                        continue;
        !          117254:                }
        !          117255:                iop->io_ioc = n;
        !          117256:                iop->io_seek = ip->i_pwx;
        !          117257:                fwrite(ip, iop);
        !          117258:                n -= iop->io_ioc;
        !          117259:                if ((ip->i_pwx+=n) == PIPSIZE)
        !          117260:                        ip->i_pwx = 0;
        !          117261:                ip->i_pnc += n;
        !          117262:                ioc -= n;
        !          117263: 
        !          117264:                /*
        !          117265:                 * Wait processes waiting to read.
        !          117266:                 */
        !          117267:                if ((ip->i_flag&IFWFW) && ip->i_pnc>0) {
        !          117268:                        ip->i_flag &= ~IFWFW;
        !          117269:                        wakeup((char *)&ip->i_prx);
        !          117270:                }
        !          117271:        }
        !          117272:        iop->io_ioc = ioc;
        !          117273: }
        !          117274: @
        !          117275: 
        !          117276: 
        !          117277: 1.3
        !          117278: log
        !          117279: @update by hal
        !          117280: @
        !          117281: text
        !          117282: @@
        !          117283: 
        !          117284: 
        !          117285: 1.2
        !          117286: log
        !          117287: @update provided by hal
        !          117288: @
        !          117289: text
        !          117290: @@
        !          117291: 
        !          117292: 
        !          117293: 1.1
        !          117294: log
        !          117295: @Initial revision
        !          117296: @
        !          117297: text
        !          117298: @d27 1
        !          117299: a27 1
        !          117300: #include <coherent.h>
        !          117301: d34 1
        !          117302: a34 1
        !          117303: #include <sched.h>
        !          117304: @
        !          117305: 0707070064030052771004440000030000030000011777770507310735500005000000011540/newbits/kernel/USRSRC/coh/RCS/poll.c,vhead     1.4;
        !          117306: branch   ;
        !          117307: access   ;
        !          117308: symbols  ;
        !          117309: locks    bin:1.4;
        !          117310: comment  @ * @;
        !          117311: 
        !          117312: 
        !          117313: 1.4
        !          117314: date     91.07.24.07.51.32;  author bin;  state Exp;
        !          117315: branches ;
        !          117316: next     1.3;
        !          117317: 
        !          117318: 1.3
        !          117319: date     91.07.15.14.33.09;  author bin;  state Exp;
        !          117320: branches ;
        !          117321: next     1.2;
        !          117322: 
        !          117323: 1.2
        !          117324: date     91.06.20.14.30.50;  author bin;  state Exp;
        !          117325: branches ;
        !          117326: next     1.1;
        !          117327: 
        !          117328: 1.1
        !          117329: date     91.06.10.14.37.27;  author bin;  state Exp;
        !          117330: branches ;
        !          117331: next     ;
        !          117332: 
        !          117333: 
        !          117334: desc
        !          117335: @initial version prov by hal
        !          117336: @
        !          117337: 
        !          117338: 
        !          117339: 1.4
        !          117340: log
        !          117341: @update prov by hal
        !          117342: 
        !          117343: @
        !          117344: text
        !          117345: @/* $Header: /usr/src/sys/coh/RCS/poll.c,v 1.1 88/03/24 16:14:10 src Exp $ */
        !          117346: /*
        !          117347:  *     The  information  contained herein  is a trade secret  of INETCO
        !          117348:  *     Systems, and is confidential information.   It is provided under
        !          117349:  *     a license agreement,  and may be copied or disclosed  only under
        !          117350:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          117351:  *     this  material  without  the express  written  authorization  of
        !          117352:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          117353:  *
        !          117354:  *     Copyright (c) 1986
        !          117355:  *     An unpublished work by INETCO Systems, Ltd.
        !          117356:  *     All rights reserved.
        !          117357:  */
        !          117358: 
        !          117359: /*
        !          117360:  * [Stream] Polling.
        !          117361:  *
        !          117362:  *     void pollinit( ) -- allocate polling buffers
        !          117363:  *     int pollopen(qp) -- enable polling  by current process  on given queue
        !          117364:  *     int pollwake(qp) -- wake all processes waiting for poll on given queue
        !          117365:  *     int pollexit(  ) -- terminate all polls enabled by current process
        !          117366:  *     event_t * ep;
        !          117367:  *
        !          117368:  * $Log:       /usr/src/sys/coh/RCS/poll.c,v $
        !          117369:  * Revision 1.1        88/03/24  16:14:10      src
        !          117370:  * Initial revision
        !          117371:  * 
        !          117372:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/poll.c
        !          117373:  * Ported to Coherent from RTX.
        !          117374:  */
        !          117375: 
        !          117376: #include <sys/coherent.h>
        !          117377: #include <sys/proc.h>
        !          117378: #include <sys/uproc.h>
        !          117379: 
        !          117380: /*
        !          117381:  * Patchable data.
        !          117382:  */
        !          117383: int    NPOLL  = 0;
        !          117384: 
        !          117385: /*
        !          117386:  * Private data.
        !          117387:  */
        !          117388: static event_t * efreep;
        !          117389: 
        !          117390: /**
        !          117391:  *
        !          117392:  * event_t *
        !          117393:  * pollinit()          -- allocate event buffers.
        !          117394:  */
        !          117395: event_t *
        !          117396: pollinit()
        !          117397: {
        !          117398:        register event_t * ep;
        !          117399:        register event_t * ap;
        !          117400:        static int first = 1;
        !          117401: 
        !          117402:        /*
        !          117403:         * If dynamically growing event pool is specified [NPOLL == 0],
        !          117404:         * try to allocate an additional cluster of 32 on each call.
        !          117405:         */
        !          117406:        if ( NPOLL == 0 ) {
        !          117407:                if ( ep = kalloc( 32 * sizeof(event_t) ) )
        !          117408:                        ap = ep + 32;
        !          117409:        }
        !          117410: 
        !          117411:        /*
        !          117412:         * If statically sized event pool is specified [NPOLL != 0],
        !          117413:         * try to allocate the pool on the first call.
        !          117414:         */
        !          117415:        else if ( first ) {
        !          117416:                first = 0;
        !          117417:                if ( ep = kalloc( NPOLL * sizeof(event_t) ) )
        !          117418:                        ap = ep + NPOLL;
        !          117419:        }
        !          117420: 
        !          117421:        /*
        !          117422:         * If event cluster was allocated, insert into free event queue.
        !          117423:         */
        !          117424:        if ( ep ) {
        !          117425:                do {
        !          117426:                        ep->e_pnext = efreep;
        !          117427:                        efreep = ep;
        !          117428:                } while ( ++ep < ap );
        !          117429:        }
        !          117430: 
        !          117431:        return efreep;
        !          117432: }
        !          117433: 
        !          117434: /**
        !          117435:  *
        !          117436:  * int
        !          117437:  * pollopen(qp) -- enable polling by current process on given event queue
        !          117438:  * event_t * qp;
        !          117439:  */
        !          117440: pollopen( qp )
        !          117441: register event_t * qp;
        !          117442: {
        !          117443:        register event_t * ep;
        !          117444: 
        !          117445:        /*
        !          117446:         * Initialize device queue if required.
        !          117447:         */
        !          117448:        if ( qp->e_dnext == 0 )
        !          117449:                qp->e_dnext = qp->e_dlast = qp;
        !          117450: 
        !          117451:        /*
        !          117452:         * Obtain a free event buffer, or return.
        !          117453:         */
        !          117454:        if ( ((ep = efreep) == 0) && ((ep = pollinit()) == 0) ) {
        !          117455:                printf("out of poll buffers\n");
        !          117456:                return;
        !          117457:        }
        !          117458: 
        !          117459:        /*
        !          117460:         * Remove event buffer from free queue.
        !          117461:         */
        !          117462:        efreep = ep->e_pnext;
        !          117463: 
        !          117464:        /*
        !          117465:         * Record process pointer in event buffer.
        !          117466:         */
        !          117467:        ep->e_procp = cprocp;
        !          117468: 
        !          117469:        /*
        !          117470:         * Insert event at head of process event singularly-linked queue.
        !          117471:         */
        !          117472:        ep->e_pnext = cprocp->p_polls;
        !          117473:        cprocp->p_polls = ep;
        !          117474: 
        !          117475:        /*
        !          117476:         * Insert event at tail of circularly-linked device queue.
        !          117477:         * This ensures that processes are first-in first-out.
        !          117478:         */
        !          117479:        ep->e_dnext  = qp;
        !          117480:        (ep->e_dlast = qp->e_dlast)->e_dnext = ep;
        !          117481:        qp->e_dlast  = ep;
        !          117482: 
        !          117483:        /*
        !          117484:         * Record last process to enable polling on device.
        !          117485:         */
        !          117486:        qp->e_procp = cprocp;
        !          117487: }
        !          117488: 
        !          117489: /**
        !          117490:  *
        !          117491:  * int
        !          117492:  * pollwake( qp ) -- wake all processes waiting for poll on given queue
        !          117493:  * event_t * qp;
        !          117494:  */
        !          117495: pollwake( qp )
        !          117496: event_t * qp;
        !          117497: {
        !          117498:        register event_t * ep = qp;
        !          117499:        register PROC    * pp;
        !          117500: 
        !          117501:        /*
        !          117502:         * Clear device process pointer, indicating poll completed.
        !          117503:         * NOTE: interrupt handlers may have already cleared it.
        !          117504:         */
        !          117505:        qp->e_procp = 0;
        !          117506: 
        !          117507:        if ( ep = qp->e_dnext ) {
        !          117508: 
        !          117509:                /*
        !          117510:                 * Service circularly-linked polls on device queue.
        !          117511:                 */
        !          117512:                while ( ep != qp ) {
        !          117513:                        /*
        !          117514:                         * Wake process if it is sleeping.
        !          117515:                         */
        !          117516:                        if ( (pp = ep->e_procp) && (pp->p_state == PSSLEEP) )
        !          117517:                                wakeup( &pp->p_polls );
        !          117518: 
        !          117519:                        ep = ep->e_dnext;
        !          117520:                }
        !          117521:        }
        !          117522: }
        !          117523: 
        !          117524: /**
        !          117525:  *
        !          117526:  * int
        !          117527:  * pollexit() -- terminate all polls opened by current process
        !          117528:  */
        !          117529: int
        !          117530: pollexit()
        !          117531: {
        !          117532:        register PROC    * pp = cprocp;
        !          117533:        register event_t * ep;
        !          117534: 
        !          117535:        /*
        !          117536:         * Service all polling event buffers enabled by current process.
        !          117537:         */
        !          117538:        while ( ep = pp->p_polls ) {
        !          117539: 
        !          117540:                /*
        !          117541:                 * Remove event buffer from circularly-linked device queue.
        !          117542:                 */
        !          117543:                (ep->e_dnext->e_dlast = ep->e_dlast)->e_dnext = ep->e_dnext;
        !          117544: 
        !          117545:                /*
        !          117546:                 * Remove event buffer from singularly-linked process queue.
        !          117547:                 */
        !          117548:                pp->p_polls = ep->e_pnext;
        !          117549: 
        !          117550:                /*
        !          117551:                 * Insert event buffer at head of free event buffer queue.
        !          117552:                 */
        !          117553:                ep->e_pnext = efreep;
        !          117554:                efreep = ep;
        !          117555:        }
        !          117556: }
        !          117557: @
        !          117558: 
        !          117559: 
        !          117560: 1.3
        !          117561: log
        !          117562: @update by hal
        !          117563: @
        !          117564: text
        !          117565: @@
        !          117566: 
        !          117567: 
        !          117568: 1.2
        !          117569: log
        !          117570: @update provided by hal
        !          117571: @
        !          117572: text
        !          117573: @@
        !          117574: 
        !          117575: 
        !          117576: 1.1
        !          117577: log
        !          117578: @Initial revision
        !          117579: @
        !          117580: text
        !          117581: @d32 1
        !          117582: a32 1
        !          117583: #include <coherent.h>
        !          117584: @
        !          117585: 0707070064030052761004440000030000030000011777770507310735600005200000006377/newbits/kernel/USRSRC/coh/RCS/printf.c,vhead     1.4;
        !          117586: branch   ;
        !          117587: access   ;
        !          117588: symbols  ;
        !          117589: locks    bin:1.4;
        !          117590: comment  @ * @;
        !          117591: 
        !          117592: 
        !          117593: 1.4
        !          117594: date     91.07.24.07.51.37;  author bin;  state Exp;
        !          117595: branches ;
        !          117596: next     1.3;
        !          117597: 
        !          117598: 1.3
        !          117599: date     91.07.15.14.33.14;  author bin;  state Exp;
        !          117600: branches ;
        !          117601: next     1.2;
        !          117602: 
        !          117603: 1.2
        !          117604: date     91.06.20.14.30.54;  author bin;  state Exp;
        !          117605: branches ;
        !          117606: next     1.1;
        !          117607: 
        !          117608: 1.1
        !          117609: date     91.06.10.14.37.29;  author bin;  state Exp;
        !          117610: branches ;
        !          117611: next     ;
        !          117612: 
        !          117613: 
        !          117614: desc
        !          117615: @initial version prov by hal
        !          117616: @
        !          117617: 
        !          117618: 
        !          117619: 1.4
        !          117620: log
        !          117621: @update prov by hal
        !          117622: 
        !          117623: @
        !          117624: text
        !          117625: @/*
        !          117626:  * Coherent.
        !          117627:  * Print formatted.
        !          117628:  *
        !          117629:  * $Log:       /usr/src/sys/coh/RCS/printf.c,v $
        !          117630:  * Revision 1.1        88/03/24  16:14:13      src
        !          117631:  * Initial revision
        !          117632:  * 
        !          117633:  * 87/09/20    Allan Cornish           /usr/src/sys/coh/printf.c
        !          117634:  * %U now correctly displays in base 10 rather than base 16.
        !          117635:  *
        !          117636:  * 86/12/16    Allan Cornish           /usr/src/sys/coh/printf.c
        !          117637:  * Added '%D' and '%X options to printf().
        !          117638:  */
        !          117639: #include <sys/coherent.h>
        !          117640: 
        !          117641: /*
        !          117642:  * For indirecting and incrementing argument pointer.
        !          117643:  */
        !          117644: #define ind(p, t)      (*((t *) p))
        !          117645: #define inc(t1, t2)    ((sizeof(t2 *)+sizeof(t1)-1) / sizeof(t1))
        !          117646: 
        !          117647: /*
        !          117648:  * Table for printing out digits.
        !          117649:  */
        !          117650: char digtab[] ={
        !          117651:        '0',    '1',    '2',    '3',    '4',    '5',    '6',    '7',
        !          117652:        '8',    '9',    'A',    'B',    'C',    'D',    'E',    'F'
        !          117653: };
        !          117654: 
        !          117655: /*
        !          117656:  * A simple printf.
        !          117657:  */
        !          117658: printf(fp, a1)
        !          117659: register char *fp;
        !          117660: {
        !          117661:        char * cp;
        !          117662:        register int c;
        !          117663:        register unsigned *ap;
        !          117664:        int lflag;
        !          117665: 
        !          117666:        ap = (char *)&a1;
        !          117667:        for (;;) {
        !          117668:                while ((c=*fp++) != '%') {
        !          117669:                        if (c == '\0')
        !          117670:                                return;
        !          117671:                        putchar(c);
        !          117672:                }
        !          117673: 
        !          117674:                lflag = 0;
        !          117675:                if ( *fp == 'l' ) {
        !          117676:                        lflag = 1;
        !          117677:                        fp++;
        !          117678:                }
        !          117679: 
        !          117680:                switch ( c = *fp++ ) {
        !          117681: 
        !          117682:                case 'c':
        !          117683:                        putchar(*ap++);
        !          117684:                        continue;
        !          117685: 
        !          117686:                case 'd':
        !          117687:                        if ( lflag == 0 ) {
        !          117688:                                if ( ((int)(*ap)) < 0 ) {
        !          117689:                                        putchar('-');
        !          117690:                                        printn( -((long) ((int)(*ap))), 10 );
        !          117691:                                }
        !          117692:                                else
        !          117693:                                        printn( ((long)(*ap)), 10 );
        !          117694:                                ap++;
        !          117695:                                continue;
        !          117696:                        }
        !          117697:                        /* fall through */
        !          117698:                case 'D':
        !          117699:                        if ( *((long *)(ap)) < 0 ) {
        !          117700:                                putchar('-');
        !          117701:                                printn( - *((long *)(ap)), 10 );
        !          117702:                        }
        !          117703:                        else
        !          117704:                                printn(   *((long *)(ap)), 10 );
        !          117705: 
        !          117706:                        ((long *)(ap))++;
        !          117707:                        continue;
        !          117708: 
        !          117709:                case 'o':
        !          117710:                        if ( lflag == 0 ) {
        !          117711:                                printn( ((long)(*ap)), 8);
        !          117712:                                ap++;
        !          117713:                                continue;
        !          117714:                        }
        !          117715:                        /* fall through */
        !          117716:                case 'O':
        !          117717:                        printf( *((long *)(ap)), 8 );
        !          117718:                        ((long *)(ap))++;
        !          117719:                        continue;
        !          117720: 
        !          117721:                case 'r':
        !          117722:                        ap = *((int **) ap);
        !          117723:                        fp = ind(ap, char *);
        !          117724:                        ap += inc(int, char *);
        !          117725:                        continue;
        !          117726: 
        !          117727:                case 's':
        !          117728:                        cp = ind(ap, char *);
        !          117729:                        ap += inc(int, char *);
        !          117730:                        while ((c=*cp++) != '\0')
        !          117731:                                putchar(c);
        !          117732:                        continue;
        !          117733: 
        !          117734:                case 'x':
        !          117735:                        if ( lflag == 0 ) {
        !          117736:                                printn( ((long)(*ap)), 16 );
        !          117737:                                ap++;
        !          117738:                                continue;
        !          117739:                        }
        !          117740:                        /* fall through */
        !          117741:                case 'X':
        !          117742:                        printn( *((long *)(ap)), 16 );
        !          117743:                        ((long *)(ap))++;
        !          117744:                        continue;
        !          117745: 
        !          117746:                case 'u':
        !          117747:                        if ( lflag == 0 ) {
        !          117748:                                printn( ((long)(*ap)), 10);
        !          117749:                                ap++;
        !          117750:                                continue;
        !          117751:                        }
        !          117752:                        /* fall through */
        !          117753:                case 'U':
        !          117754:                        printn( *((long *)(ap)), 10 );
        !          117755:                        ((long *)(ap))++;
        !          117756:                        continue;
        !          117757: 
        !          117758:                case 'p':
        !          117759:                        if (sizeof(char *) > sizeof(int)) {
        !          117760:                                printn( ((long)(*ap)), 16);
        !          117761:                                putchar(':');
        !          117762:                                ap++;
        !          117763:                        }
        !          117764:                        printn( ((long)(*ap)), 16);
        !          117765:                        ap++;
        !          117766:                        continue;
        !          117767: 
        !          117768:                default:
        !          117769:                        putchar(c);
        !          117770:                        continue;
        !          117771:                }
        !          117772:        }
        !          117773: }
        !          117774: 
        !          117775: /*
        !          117776:  * Print out the unsigned long `v' in the base `b'.
        !          117777:  */
        !          117778: printn( v, b )
        !          117779: unsigned long v;
        !          117780: {
        !          117781:        unsigned long n;
        !          117782: 
        !          117783:        if ((n=v/b) != 0)
        !          117784:                printn(n, b);
        !          117785: 
        !          117786:        putchar(digtab[v%b]);
        !          117787: }
        !          117788: @
        !          117789: 
        !          117790: 
        !          117791: 1.3
        !          117792: log
        !          117793: @update by hal
        !          117794: @
        !          117795: text
        !          117796: @@
        !          117797: 
        !          117798: 
        !          117799: 1.2
        !          117800: log
        !          117801: @update provided by hal
        !          117802: @
        !          117803: text
        !          117804: @@
        !          117805: 
        !          117806: 
        !          117807: 1.1
        !          117808: log
        !          117809: @Initial revision
        !          117810: @
        !          117811: text
        !          117812: @d15 1
        !          117813: a15 1
        !          117814: #include <coherent.h>
        !          117815: @
        !          117816: 0707070064030050701004440000030000030000011777770507310735700005000000027537/newbits/kernel/USRSRC/coh/RCS/proc.c,vhead     1.4;
        !          117817: branch   ;
        !          117818: access   ;
        !          117819: symbols  ;
        !          117820: locks    bin:1.4;
        !          117821: comment  @ * @;
        !          117822: 
        !          117823: 
        !          117824: 1.4
        !          117825: date     91.07.24.07.51.40;  author bin;  state Exp;
        !          117826: branches ;
        !          117827: next     1.3;
        !          117828: 
        !          117829: 1.3
        !          117830: date     91.07.15.14.33.19;  author bin;  state Exp;
        !          117831: branches ;
        !          117832: next     1.2;
        !          117833: 
        !          117834: 1.2
        !          117835: date     91.06.20.14.30.58;  author bin;  state Exp;
        !          117836: branches ;
        !          117837: next     1.1;
        !          117838: 
        !          117839: 1.1
        !          117840: date     91.06.10.14.37.30;  author bin;  state Exp;
        !          117841: branches ;
        !          117842: next     ;
        !          117843: 
        !          117844: 
        !          117845: desc
        !          117846: @initial version prov by hal
        !          117847: @
        !          117848: 
        !          117849: 
        !          117850: 1.4
        !          117851: log
        !          117852: @update prov by hal
        !          117853: 
        !          117854: @
        !          117855: text
        !          117856: @/* $Header: /usr/src/sys/coh/RCS/proc.c,v 1.2 88/08/05 15:30:01 src Exp $ */
        !          117857: /* (lgl-
        !          117858:  *     The information contained herein is a trade secret of Mark Williams
        !          117859:  *     Company, and  is confidential information.  It is provided  under a
        !          117860:  *     license agreement,  and may be  copied or disclosed  only under the
        !          117861:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          117862:  *     material without the express written authorization of Mark Williams
        !          117863:  *     Company or persuant to the license agreement is unlawful.
        !          117864:  *
        !          117865:  *     COHERENT Version 2.3.37
        !          117866:  *     Copyright (c) 1982, 1983, 1984.
        !          117867:  *     An unpublished work by Mark Williams Company, Chicago.
        !          117868:  *     All rights reserved.
        !          117869:  -lgl) */
        !          117870: /*
        !          117871:  * Coherent.
        !          117872:  * Process handling and scheduling.
        !          117873:  *
        !          117874:  * $Log:       /usr/src/sys/coh/RCS/proc.c,v $
        !          117875:  * Revision 1.2        88/08/05  15:30:01      src
        !          117876:  * pfork() made more rigorous, supports loadable driver forks, etc.
        !          117877:  * lock/unlock more efficient, since know wakeup is synchronous.
        !          117878:  * 
        !          117879:  * Revision 1.1        88/03/24  16:14:16      src
        !          117880:  * Initial revision
        !          117881:  * 
        !          117882:  * 88/03/10    Allan Cornish           /usr/src/sys/coh/proc.c
        !          117883:  * Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !          117884:  * These partial fixes will be removed once all CPU's are replaced.
        !          117885:  *
        !          117886:  * 88/01/21    Allan Cornish           /usr/src/sys/coh/proc.c
        !          117887:  * Race condition caused by pexit() calling sfree() on the user-area
        !          117888:  * when the segmentation gate is locked is now prevented.
        !          117889:  * Release of the user area now deferred until relproc() invoked by uwait().
        !          117890:  *
        !          117891:  * 87/11/13    Allan Cornish           /usr/src/sys/coh/proc.c
        !          117892:  * pexit() now sets uasa to 0 before dispatching processor.
        !          117893:  *
        !          117894:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/proc.c
        !          117895:  * New seg struct now used to allow extended addressing.
        !          117896:  *
        !          117897:  * 87/07/08    Allan Cornish           /usr/src/sys/coh/proc.c
        !          117898:  * pexit() now cancels poll/alarm timed functions before terminating.
        !          117899:  *
        !          117900:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/proc.c
        !          117901:  * pexit() now wakes the swapper before terminating.
        !          117902:  */
        !          117903: #include <sys/coherent.h>
        !          117904: #include <acct.h>
        !          117905: #include <errno.h>
        !          117906: #include <sys/inode.h>
        !          117907: #include <sys/proc.h>
        !          117908: #include <sys/ptrace.h>
        !          117909: #include <sys/sched.h>
        !          117910: #include <sys/seg.h>
        !          117911: #include <signal.h>
        !          117912: #include <sys/stat.h>
        !          117913: #include <sys/uproc.h>
        !          117914: 
        !          117915: /*
        !          117916:  * Initialisation.
        !          117917:  * Set up the hash table queues.
        !          117918:  */
        !          117919: pcsinit()
        !          117920: {
        !          117921:        register PROC *pp;
        !          117922:        register PLINK *lp;
        !          117923: 
        !          117924:        pp = &procq;
        !          117925:        SELF = pp;
        !          117926:        procq.p_nforw = pp;
        !          117927:        procq.p_nback = pp;
        !          117928:        procq.p_lforw = pp;
        !          117929:        procq.p_lback = pp;
        !          117930:        for (lp=&linkq[0]; lp<&linkq[NHPLINK]; lp++) {
        !          117931:                lp->p_lforw = lp;
        !          117932:                lp->p_lback = lp;
        !          117933:        }
        !          117934: }
        !          117935: 
        !          117936: /*
        !          117937:  * Initiate a process.  `f' is a kernel function that is associated with
        !          117938:  * the process.
        !          117939:  */
        !          117940: PROC *
        !          117941: process(f)
        !          117942: int (*f)();
        !          117943: {
        !          117944:        register PROC *pp1;
        !          117945:        register PROC *pp;
        !          117946:        register SEG *sp;
        !          117947:        MCON mcon;
        !          117948: 
        !          117949:        if ((pp=kalloc(sizeof(PROC))) == NULL)
        !          117950:                return (NULL);
        !          117951: 
        !          117952:        pp->p_flags = PFCORE;
        !          117953:        pp->p_state = PSRUN;
        !          117954:        pp->p_ttdev = NODEV;
        !          117955: 
        !          117956:        if (f != NULL) {
        !          117957:                pp->p_flags |= PFKERN;
        !          117958:                sp = salloc((fsize_t)UPASIZE, SFSYST|SFHIGH|SFNSWP);
        !          117959:                if (sp == NULL) {
        !          117960:                        kfree(pp);
        !          117961:                        return (NULL);
        !          117962:                }
        !          117963:                pp->p_segp[SIUSERP] = sp;
        !          117964:                msetsys( &mcon, f, FP_SEL(sp->s_faddr) );
        !          117965:                kfcopy( (char *)&mcon,
        !          117966:                        sp->s_faddr + offset(uproc, u_syscon),
        !          117967:                        sizeof(mcon) );
        !          117968:        }
        !          117969:        lock(pnxgate);
        !          117970: next:
        !          117971:        pp->p_pid = cpid++;
        !          117972:        if (cpid >= NPID)
        !          117973:                cpid = 2;
        !          117974:        pp1 = &procq;
        !          117975:        while ((pp1=pp1->p_nforw) != &procq) {
        !          117976:                if (pp1->p_pid < pp->p_pid)
        !          117977:                        break;
        !          117978:                if (pp1->p_pid == pp->p_pid)
        !          117979:                        goto next;
        !          117980:        }
        !          117981:        pp->p_nback = pp1->p_nback;
        !          117982:        pp1->p_nback->p_nforw = pp;
        !          117983:        pp->p_nforw = pp1;
        !          117984:        pp1->p_nback = pp;
        !          117985:        unlock(pnxgate);
        !          117986:        return (pp);
        !          117987: }
        !          117988: 
        !          117989: /*
        !          117990:  * Remove a process from the next queue and release and space.
        !          117991:  */
        !          117992: relproc(pp)
        !          117993: register PROC *pp;
        !          117994: {
        !          117995:        register SEG * sp;
        !          117996: 
        !          117997:        /*
        !          117998:         * Child process still has a user-area.
        !          117999:         */
        !          118000:        if ( (sp = pp->p_segp[SIUSERP]) != NULL ) {
        !          118001: 
        !          118002:                /*
        !          118003:                 * Detach user-area from child process.
        !          118004:                 */
        !          118005:                pp->p_segp[SIUSERP] = NULL;
        !          118006: 
        !          118007:                /*
        !          118008:                 * Child process is swapped out.
        !          118009:                 */
        !          118010:                if ( pp->p_flags & PFSWAP )
        !          118011:                        sp->s_lrefc++;
        !          118012: 
        !          118013:                /*
        !          118014:                 * Release child's user-area.
        !          118015:                 */
        !          118016:                sfree( sp );
        !          118017:        }
        !          118018: 
        !          118019:        /*
        !          118020:         * Remove process from doubly-linked list of all processes.
        !          118021:         * Release space allocated for proc structure.
        !          118022:         */
        !          118023:        lock(pnxgate);
        !          118024:        pp->p_nback->p_nforw = pp->p_nforw;
        !          118025:        pp->p_nforw->p_nback = pp->p_nback;
        !          118026:        unlock(pnxgate);
        !          118027:        kfree(pp);
        !          118028: }
        !          118029: 
        !          118030: /*
        !          118031:  * Create a clone of ourselves.
        !          118032:  *     N.B. - consave(&mcon) returns twice; anything not initialized
        !          118033:  *     in automatic storage before the call to segadup() will not be
        !          118034:  *     initialized when the second return from consave() commences.
        !          118035:  */
        !          118036: pfork()
        !          118037: {
        !          118038:        register PROC *cpp;
        !          118039:        register PROC *pp;
        !          118040:        register int s;
        !          118041:        MCON mcon;
        !          118042: 
        !          118043:        if ((cpp=process(NULL)) == NULL) {
        !          118044:                u.u_error = EAGAIN;
        !          118045:                return;
        !          118046:        }
        !          118047: 
        !          118048:        s = sphi();     /* Make usave a null macro if unnecessary */
        !          118049:        usave();        /* Put the current copy of uarea into its segment */
        !          118050:        spl(s);
        !          118051: 
        !          118052:        if (segadup(cpp) == 0) {
        !          118053:                u.u_error = EAGAIN;
        !          118054:                relproc(cpp);
        !          118055:                return;
        !          118056:        }
        !          118057:        if ( u.u_rdir != NULL )
        !          118058:                u.u_rdir->i_refc++;
        !          118059:        if ( u.u_cdir != NULL )
        !          118060:                u.u_cdir->i_refc++;
        !          118061:        fdadupl();
        !          118062:        pp = SELF;
        !          118063:        cpp->p_uid   = pp->p_uid;
        !          118064:        cpp->p_ruid  = pp->p_ruid;
        !          118065:        cpp->p_rgid  = pp->p_rgid;
        !          118066:        cpp->p_ppid  = pp->p_pid;
        !          118067:        cpp->p_ttdev = pp->p_ttdev;
        !          118068:        cpp->p_group = pp->p_group;
        !          118069:        cpp->p_ssig  = pp->p_ssig;
        !          118070:        cpp->p_isig  = pp->p_isig;
        !          118071:        cpp->p_cval  = CVCHILD;
        !          118072:        cpp->p_ival  = IVCHILD;
        !          118073:        cpp->p_sval  = SVCHILD;
        !          118074:        cpp->p_rval  = RVCHILD;
        !          118075: 
        !          118076:        s = sphi();
        !          118077:        consave(&mcon);
        !          118078:        spl( s );
        !          118079: 
        !          118080:        /*
        !          118081:         * Parent process.
        !          118082:         */
        !          118083:        if ( (pp = SELF) != cpp ) {
        !          118084:                segfinm(cpp->p_segp[SIUSERP]);
        !          118085:                kfcopy( (char *)&mcon,
        !          118086:                        cpp->p_segp[SIUSERP]->s_faddr + offset(uproc,u_syscon),
        !          118087:                        sizeof(mcon) );
        !          118088:                mfixcon(cpp);
        !          118089:                s = sphi();
        !          118090:                setrun(cpp);
        !          118091:                spl(s);
        !          118092:                return( cpp->p_pid );
        !          118093:        }
        !          118094: 
        !          118095:        /*
        !          118096:         * Child process.
        !          118097:         */
        !          118098:        else {
        !          118099:                u.u_btime = timer.t_time;
        !          118100:                u.u_flag = AFORK;
        !          118101:                /* for (i=0; i<NUSEG; i++) done in sproto */
        !          118102:                        /* u.u_segl[i].sr_segp = pp->p_segp[i]; ditto */
        !          118103:                sproto();
        !          118104:                segload();
        !          118105:                return( 0 );
        !          118106:        }
        !          118107: }
        !          118108: 
        !          118109: /*
        !          118110:  * Die.
        !          118111:  */
        !          118112: pexit(s)
        !          118113: {
        !          118114:        register PROC *pp1;
        !          118115:        register PROC *pp;
        !          118116:        register SEG  *sp;
        !          118117:        register int n;
        !          118118: 
        !          118119:        pp = SELF;
        !          118120: 
        !          118121:        /*
        !          118122:         * Cancel alarm and poll timers [if any].
        !          118123:         */
        !          118124:        timeout( &pp->p_alrmtim, 0, NULL, 0 );
        !          118125:        timeout( &pp->p_polltim, 0, NULL, 0 );
        !          118126: 
        !          118127:        /*
        !          118128:         * Write out accounting directory and close all files associated with
        !          118129:         * this process.
        !          118130:         */
        !          118131:        setacct();
        !          118132:        if ( u.u_rdir )
        !          118133:                ldetach(u.u_rdir);
        !          118134:        if ( u.u_cdir )
        !          118135:                ldetach(u.u_cdir);
        !          118136:        fdaclose();
        !          118137: 
        !          118138:        /*
        !          118139:         * Free all segments in reverse order, except for user-area.
        !          118140:         */
        !          118141:        for ( n = NUSEG; --n > 0; ) {
        !          118142:                if ( (sp = pp->p_segp[n]) != NULL ) {
        !          118143:                        pp->p_segp[n] = NULL;
        !          118144:                        sfree( sp );
        !          118145:                }
        !          118146:        }
        !          118147: 
        !          118148:        /*
        !          118149:         * Wakeup our parent.  If we have any children, init will become the
        !          118150:         * new parent.  If there are any children we are tracing who are
        !          118151:         * waiting for us, we wake them up.
        !          118152:         */
        !          118153:        pp1 = &procq;
        !          118154:        while ((pp1=pp1->p_nforw) != &procq) {
        !          118155:                if (pp1->p_pid == pp->p_ppid) {
        !          118156:                        if (pp1->p_state==PSSLEEP && pp1->p_event==(char *)pp1)
        !          118157:                                wakeup((char *)pp1);
        !          118158:                }
        !          118159:                if (pp1->p_ppid == pp->p_pid) {
        !          118160:                        pp1->p_ppid = 1;
        !          118161:                        if (pp1->p_state == PSDEAD)
        !          118162:                                wakeup((char *)eprocp);
        !          118163:                        if ((pp1->p_flags&PFTRAC) != 0)
        !          118164:                                wakeup((char *)&pts.pt_req);
        !          118165:                }
        !          118166:        }
        !          118167: 
        !          118168:        /*
        !          118169:         * Wake up swapper if swap timer is active.
        !          118170:         */
        !          118171:        if ( stimer.t_last != 0 )
        !          118172:                wakeup( (char *) &stimer );
        !          118173: 
        !          118174:        /*
        !          118175:         * And finally mark us as dead and give up the processor forever.
        !          118176:         */
        !          118177:        pp->p_exit = s;
        !          118178:        pp->p_state = PSDEAD;
        !          118179:        uasa = 0;
        !          118180:        dispatch();
        !          118181: }
        !          118182: 
        !          118183: /*
        !          118184:  * Sleep on the event `e'.  This gives up the processor until someone
        !          118185:  * wakes us up.  Since it is possible for many people to sleep on the
        !          118186:  * same event, the caller when awakened should make sure that what he
        !          118187:  * was waiting for has completed and if not, go to sleep again.  `cl'
        !          118188:  * is the cpu value we get to get the cpu as soon as we are woken up.
        !          118189:  * `sl' is the swap value we get to keep us in memory for the duration
        !          118190:  * of the sleep.  `sr' is the swap value that allows us to get swapped
        !          118191:  * in if we have been swapped out.
        !          118192:  */
        !          118193: sleep(e, cl, sl, sr)
        !          118194: char *e;
        !          118195: {
        !          118196:        register PROC *bp;
        !          118197:        register PROC *fp;
        !          118198:        register PROC *pp;
        !          118199:        register int s;
        !          118200: 
        !          118201:        pp = SELF;
        !          118202: 
        !          118203:        /*
        !          118204:         * See if we have a signal awaiting.
        !          118205:         */
        !          118206:        if (cl<CVNOSIG && pp->p_ssig && nondsig()) {
        !          118207:                sphi();
        !          118208:                envrest(&u.u_sigenv);
        !          118209:        }
        !          118210: 
        !          118211:        /*
        !          118212:         * Get ready to go to sleep and do so.
        !          118213:         */
        !          118214:        s = sphi();
        !          118215:        pp->p_state = PSSLEEP;
        !          118216:        pp->p_event = e;
        !          118217:        pp->p_lctim = utimer;
        !          118218:        addu(pp->p_cval, cl);
        !          118219:        pp->p_ival = sl;
        !          118220:        pp->p_rval = sr;
        !          118221:        fp = &linkq[hash(e)];
        !          118222:        bp = fp->p_lback;
        !          118223:        pp->p_lforw = fp;
        !          118224:        fp->p_lback = pp;
        !          118225:        pp->p_lback = bp;
        !          118226:        bp->p_lforw = pp;
        !          118227:        spl(s);
        !          118228:        dispatch();
        !          118229: 
        !          118230:        /*
        !          118231:         * We have just woken up.  Get ready to return.
        !          118232:         */
        !          118233:        subu(pp->p_cval, cl);
        !          118234:        pp->p_ival = 0;
        !          118235:        pp->p_rval = 0;
        !          118236: 
        !          118237:        /*
        !          118238:         * Check for an interrupted system call.
        !          118239:         */
        !          118240:        if (cl<CVNOSIG && pp->p_ssig && nondsig()) {
        !          118241:                sphi();
        !          118242:                envrest(&u.u_sigenv);
        !          118243:        }
        !          118244: }
        !          118245: 
        !          118246: /*
        !          118247:  * Defer function to wake up all processes sleeping on the event `e'.
        !          118248:  */
        !          118249: wakeup(e)
        !          118250: char *e;
        !          118251: {
        !          118252:        extern void dwakeup();
        !          118253: 
        !          118254:        defer( dwakeup, e );
        !          118255: }
        !          118256: 
        !          118257: /*
        !          118258:  * Wake up all processes sleeping on the event `e'.
        !          118259:  */
        !          118260: static void
        !          118261: dwakeup( e )
        !          118262: char *e;
        !          118263: {
        !          118264:        register PROC *pp;
        !          118265:        register PROC *pp1;
        !          118266:        register int s;
        !          118267: 
        !          118268:        /*
        !          118269:         * Identify event queue to check.
        !          118270:         * Disable interrupts.
        !          118271:         */
        !          118272:        pp1 = &linkq[hash(e)];
        !          118273:        pp = pp1;
        !          118274:        s = sphi();
        !          118275: 
        !          118276:        /*
        !          118277:         * Traverse doubly-linked circular event-queue.
        !          118278:         */
        !          118279:        while ( (pp = pp->p_lforw) != pp1 ) {
        !          118280: 
        !          118281:                /*
        !          118282:                 * Process is waiting on event 'e'.
        !          118283:                 */
        !          118284:                if ( pp->p_event == e ) {
        !          118285:                        /*
        !          118286:                         * Remove process from event queue.
        !          118287:                         * Update process priority.
        !          118288:                         * Insert process into run queue.
        !          118289:                         */
        !          118290:                        pp->p_lback->p_lforw = pp->p_lforw;
        !          118291:                        pp->p_lforw->p_lback = pp->p_lback;
        !          118292:                        addu( pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK );
        !          118293:                        setrun( pp );
        !          118294: 
        !          118295:                        /*
        !          118296:                         * Enable interrupts.
        !          118297:                         * Restart search at start of event queue.
        !          118298:                         * Disable interrupts.
        !          118299:                         */
        !          118300:                        spl( s );
        !          118301:                        pp = pp1;
        !          118302:                        s = sphi();
        !          118303:                }
        !          118304:        }
        !          118305:        spl(s);
        !          118306: }
        !          118307: 
        !          118308: /*
        !          118309:  * Reschedule the processor.
        !          118310:  */
        !          118311: dispatch()
        !          118312: {
        !          118313:        register PROC *pp1;
        !          118314:        register PROC *pp2;
        !          118315:        register unsigned v;
        !          118316:        register int s;
        !          118317: 
        !          118318:        s = sphi();
        !          118319:        pp1 = iprocp;
        !          118320:        pp2 = &procq;
        !          118321:        v = 0;
        !          118322:        while ((pp2=pp2->p_lforw) != &procq) {
        !          118323:                v -= pp2->p_cval;
        !          118324:                if ((pp2->p_flags&PFCORE) == 0)
        !          118325:                        continue;
        !          118326:                pp1 = pp2->p_lforw;
        !          118327:                pp1->p_cval += pp2->p_cval;
        !          118328:                pp2->p_cval = v;
        !          118329:                pp1->p_lback = pp2->p_lback;
        !          118330:                pp1->p_lback->p_lforw = pp1;
        !          118331:                pp1 = pp2;
        !          118332:                break;
        !          118333:        }
        !          118334:        spl(s);
        !          118335: 
        !          118336:        quantum = NCRTICK;
        !          118337:        disflag = 0;
        !          118338:        if ( pp1 != SELF ) {
        !          118339:                /*
        !          118340:                 * Consave() returns twice.
        !          118341:                 * 1st time is after our context is saved in u.u_syscon,
        !          118342:                 *      whereupon we should restore other proc's context.
        !          118343:                 * 2nd time is after our context is restored by another proc.
        !          118344:                 * Conrest() forces a context switch to a new process.
        !          118345:                 */
        !          118346:                s = sphi();
        !          118347:                SELF = pp1;
        !          118348:                if (consave(&u.u_syscon) == 0)
        !          118349:                        conrest( FP_SEL(pp1->p_u->s_faddr),
        !          118350:                                 offset(uproc,u_syscon) );
        !          118351:                if ( SELF->p_pid != 0 )
        !          118352:                        segload();
        !          118353:                spl(s);
        !          118354:        }
        !          118355: }
        !          118356: 
        !          118357: /*
        !          118358:  * Add a process to the run queue.
        !          118359:  * This routine must be called at high priority.
        !          118360:  */
        !          118361: setrun(pp1)
        !          118362: register PROC *pp1;
        !          118363: {
        !          118364:        register PROC *pp2;
        !          118365:        register unsigned v;
        !          118366: 
        !          118367:        v = 0;
        !          118368:        pp2 = &procq;
        !          118369:        for (;;) {
        !          118370:                pp2 = pp2->p_lback;
        !          118371:                if ((v+=pp2->p_lforw->p_cval) >= pp1->p_cval)
        !          118372:                        break;
        !          118373:                if (pp2 == &procq)
        !          118374:                        break;
        !          118375:        }
        !          118376:        pp2->p_lforw->p_lback = pp1;
        !          118377:        pp1->p_lforw = pp2->p_lforw;
        !          118378:        pp2->p_lforw = pp1;
        !          118379:        pp1->p_lback = pp2;
        !          118380:        v -= pp1->p_cval;
        !          118381:        pp1->p_cval = v;
        !          118382:        pp1->p_lforw->p_cval -= v;
        !          118383:        pp1->p_state = PSRUN;
        !          118384: }
        !          118385: 
        !          118386: /*
        !          118387:  * Wait for the gate `g' to unlock, and then lock it.
        !          118388:  */
        !          118389: lock(g)
        !          118390: register GATE g;
        !          118391: {
        !          118392:        register int s;
        !          118393: 
        !          118394:        s = sphi();
        !          118395:        while (g[0]) {
        !          118396:                g[1] = 1;
        !          118397:                sleep((char *)g, CVGATE, IVGATE, SVGATE);
        !          118398:        }
        !          118399:        g[0] = 1;
        !          118400:        spl(s);
        !          118401: }
        !          118402: 
        !          118403: /*
        !          118404:  * Unlock the gate `g'.
        !          118405:  */
        !          118406: unlock(g)
        !          118407: register GATE g;
        !          118408: {
        !          118409:        g[0] = 0;
        !          118410:        if (g[1]) {
        !          118411:                g[1] = 0;
        !          118412:                disflag = 1;
        !          118413:                wakeup((char *)g);
        !          118414:        }
        !          118415: }
        !          118416: @
        !          118417: 
        !          118418: 
        !          118419: 1.3
        !          118420: log
        !          118421: @update by hal
        !          118422: @
        !          118423: text
        !          118424: @@
        !          118425: 
        !          118426: 
        !          118427: 1.2
        !          118428: log
        !          118429: @update provided by hal
        !          118430: @
        !          118431: text
        !          118432: @@
        !          118433: 
        !          118434: 
        !          118435: 1.1
        !          118436: log
        !          118437: @Initial revision
        !          118438: @
        !          118439: text
        !          118440: @d48 1
        !          118441: a48 1
        !          118442: #include <coherent.h>
        !          118443: d53 2
        !          118444: a54 2
        !          118445: #include <ptrace.h>
        !          118446: #include <sched.h>
        !          118447: @
        !          118448: 0707070064030050671004440000030000030000011777770507310736200004700000042555/newbits/kernel/USRSRC/coh/RCS/seg.c,vhead     1.4;
        !          118449: branch   ;
        !          118450: access   ;
        !          118451: symbols  ;
        !          118452: locks    bin:1.4;
        !          118453: comment  @ * @;
        !          118454: 
        !          118455: 
        !          118456: 1.4
        !          118457: date     91.07.24.07.51.50;  author bin;  state Exp;
        !          118458: branches ;
        !          118459: next     1.3;
        !          118460: 
        !          118461: 1.3
        !          118462: date     91.07.15.14.33.31;  author bin;  state Exp;
        !          118463: branches ;
        !          118464: next     1.2;
        !          118465: 
        !          118466: 1.2
        !          118467: date     91.06.20.14.31.08;  author bin;  state Exp;
        !          118468: branches ;
        !          118469: next     1.1;
        !          118470: 
        !          118471: 1.1
        !          118472: date     91.06.10.14.37.34;  author bin;  state Exp;
        !          118473: branches ;
        !          118474: next     ;
        !          118475: 
        !          118476: 
        !          118477: desc
        !          118478: @initial version prov by hal
        !          118479: @
        !          118480: 
        !          118481: 
        !          118482: 1.4
        !          118483: log
        !          118484: @update prov by hal
        !          118485: 
        !          118486: @
        !          118487: text
        !          118488: @/* $Header: /usr/src/sys/coh/RCS/seg.c,v 1.1 88/03/24 16:14:20 src Exp $ */
        !          118489: /* (lgl-
        !          118490:  *     The information contained herein is a trade secret of Mark Williams
        !          118491:  *     Company, and  is confidential information.  It is provided  under a
        !          118492:  *     license agreement,  and may be  copied or disclosed  only under the
        !          118493:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          118494:  *     material without the express written authorization of Mark Williams
        !          118495:  *     Company or persuant to the license agreement is unlawful.
        !          118496:  *
        !          118497:  *     COHERENT Version 2.3.37
        !          118498:  *     Copyright (c) 1982, 1983, 1984.
        !          118499:  *     An unpublished work by Mark Williams Company, Chicago.
        !          118500:  *     All rights reserved.
        !          118501:  -lgl) */
        !          118502: /*
        !          118503:  * Coherent.
        !          118504:  * Segment manipulation.
        !          118505:  *
        !          118506:  * $Log:       /usr/src/sys/coh/RCS/seg.c,v $
        !          118507:  * Revision 1.1        88/03/24  16:14:20      src
        !          118508:  * Initial revision
        !          118509:  * 
        !          118510:  * 88/02/26    Allan Cornish   /usr/src/sys/coh/seg.c
        !          118511:  * swapio() now avoids 64 Kbyte page [dma] straddles.
        !          118512:  *
        !          118513:  * 88/01/22    Allan Cornish   /usr/src/sys/coh/seg.c
        !          118514:  * salloc() now invokes krunch(1000) if initial allocation fails.
        !          118515:  * sfree() now invokes krunch(0).
        !          118516:  *
        !          118517:  * 88/01/21    Allan Cornish   /usr/src/sys/coh/seg.c
        !          118518:  * sfree() modified to eliminate critical race on ref cnts and segment gate.
        !          118519:  * segfinm() now properly maintains segment reference counts.
        !          118520:  *
        !          118521:  * 87/11/13    Allan Cornish   /usr/src/sys/coh/seg.c
        !          118522:  * Support for protected mode segmentation added.
        !          118523:  */
        !          118524: #include <sys/coherent.h>
        !          118525: #include <sys/buf.h>
        !          118526: #include <errno.h>
        !          118527: #include <sys/ino.h>
        !          118528: #include <sys/inode.h>
        !          118529: #include <sys/proc.h>
        !          118530: #include <sys/sched.h>
        !          118531: #include <sys/seg.h>
        !          118532: #include <sys/uproc.h>
        !          118533: 
        !          118534: /*
        !          118535:  * Initialisation code.
        !          118536:  */
        !          118537: seginit()
        !          118538: {
        !          118539:        /*
        !          118540:         * Create empty circular-list of memory segments.
        !          118541:         */
        !          118542:        segmq.s_forw = &segmq;
        !          118543:        segmq.s_back = &segmq;
        !          118544: 
        !          118545:        /*
        !          118546:         * Create empty circular-list of disk segments.
        !          118547:         */
        !          118548:        segdq.s_forw = &segdq;
        !          118549:        segdq.s_back = &segdq;
        !          118550: 
        !          118551:        if ( holebot != holetop ) {
        !          118552:                /*
        !          118553:                 * Define the I/O mem hole between low memory and extended mem.
        !          118554:                 * NOTE: Setting lrefc to urefc+1 stopx segment from moving.
        !          118555:                 */
        !          118556:                segiom.s_paddr = holebot;
        !          118557:                segiom.s_size  = holetop - holebot;
        !          118558:                segiom.s_flags = SFCORE | SFSYST;
        !          118559:                segiom.s_urefc = 1;
        !          118560:                segiom.s_lrefc = 2;
        !          118561: 
        !          118562:                /*
        !          118563:                 * Insert I/O memory segment into memory list.
        !          118564:                 */
        !          118565:                segiom.s_forw = &segmq;
        !          118566:                segiom.s_back = &segmq;
        !          118567:                segmq.s_forw  = &segiom;
        !          118568:                segmq.s_back  = &segiom;
        !          118569:        }
        !          118570: }
        !          118571: 
        !          118572: /*
        !          118573:  * Given an inode, `ip', and flags, `ff', describing a segment associated
        !          118574:  * with the inode, see if the segment already exists and if so, return a
        !          118575:  * copy.  If the segment does not exists, allocate the segment having size
        !          118576:  * `ss', and read the segment using the inode at seek offset `dq' with a
        !          118577:  * size of `ds'.
        !          118578:  */
        !          118579: SEG *
        !          118580: ssalloc(rp, ip, ff, ss, dq, ds)
        !          118581: int *rp;
        !          118582: register INODE *ip;
        !          118583: fsize_t ss;
        !          118584: fsize_t dq;
        !          118585: fsize_t ds;
        !          118586: {
        !          118587:        register SEG *sp;
        !          118588:        register int f;
        !          118589: 
        !          118590:        *rp = -1;
        !          118591:        if (ss == 0) {
        !          118592:                *rp = 1;
        !          118593:                return (NULL);
        !          118594:        }
        !          118595:        lock(seglink);
        !          118596:        f = ff & (SFSHRX|SFTEXT);
        !          118597: 
        !          118598:        /*
        !          118599:         * Look for the segment in the memory queue.
        !          118600:         */
        !          118601:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
        !          118602:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
        !          118603:                        unlock(seglink);
        !          118604:                        if ((sp = segdupl(sp)) != NULL) {
        !          118605:                                segfinm(sp);
        !          118606:                                *rp = 1;
        !          118607:                        }
        !          118608:                        return (sp);
        !          118609:                }
        !          118610:        }
        !          118611: 
        !          118612:        /*
        !          118613:         * Look for the segment on the disk queue.
        !          118614:         */
        !          118615:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
        !          118616:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
        !          118617:                        unlock(seglink);
        !          118618:                        if ((sp = segdupl(sp)) != NULL) {
        !          118619:                                segfinm(sp);
        !          118620:                                *rp = 1;
        !          118621:                        }
        !          118622:                        return (sp);
        !          118623:                }
        !          118624:        }
        !          118625:        unlock(seglink);
        !          118626: 
        !          118627:        /*
        !          118628:         * Allocate and create the segment.
        !          118629:         */
        !          118630:        if ((sp=salloc(ss, ff)) == NULL)
        !          118631:                return (NULL);
        !          118632:        if (exsread(sp, ip, ds, dq, (fsize_t)0) == 0) {
        !          118633:                sfree(sp);
        !          118634:                return (NULL);
        !          118635:        }
        !          118636:        if ((ff&SFSHRX) != 0) {
        !          118637:                sp->s_ip = ip;
        !          118638:                ip->i_refc++;
        !          118639:        }
        !          118640:        *rp = 0;
        !          118641:        return (sp);
        !          118642: }
        !          118643: 
        !          118644: /*
        !          118645:  * Given a pointer to a newly created process, copy all of our segments
        !          118646:  * into the given process.
        !          118647:  */
        !          118648: segadup(cpp)
        !          118649: register PROC *cpp;
        !          118650: {
        !          118651:        register SEG *sp;
        !          118652:        register int n;
        !          118653:        register PROC *pp;
        !          118654: 
        !          118655:        pp = SELF;
        !          118656:        cpp->p_flags |= PFSWIO;
        !          118657:        for (n=0; n<NUSEG; n++) {
        !          118658:                if ((sp=pp->p_segp[n]) == NULL)
        !          118659:                        continue;
        !          118660:                if ((sp=segdupl(sp)) == NULL)
        !          118661:                        break;
        !          118662:                cpp->p_segp[n] = sp;
        !          118663:                if ((sp->s_flags&SFCORE) == 0)
        !          118664:                        cpp->p_flags &= ~PFCORE;
        !          118665:        }
        !          118666:        if (n < NUSEG) {
        !          118667:                while (n > 0) {
        !          118668:                        if ((sp=cpp->p_segp[--n]) != NULL) {
        !          118669:                                cpp->p_segp[n] = NULL;
        !          118670:                                sfree(sp);
        !          118671:                        }
        !          118672:                }
        !          118673:        }
        !          118674:        cpp->p_flags &= ~PFSWIO;
        !          118675:        return (n);
        !          118676: }
        !          118677: 
        !          118678: /*
        !          118679:  * Duplicate a segment.
        !          118680:  */
        !          118681: SEG *
        !          118682: segdupl(sp)
        !          118683: register SEG *sp;
        !          118684: {
        !          118685:        register SEG *sp1;
        !          118686: 
        !          118687:        if ((sp->s_flags&SFSHRX) != 0) {
        !          118688:                sp->s_urefc++;
        !          118689:                sp->s_lrefc++;
        !          118690:                return (sp);
        !          118691:        }
        !          118692:        if ((sp->s_flags&SFCORE) == 0)
        !          118693:                panic("Cannot duplicate non shared swapped segment");
        !          118694:        if ((sp1=salloc(sp->s_size, sp->s_flags|SFNSWP|SFNCLR)) == NULL)
        !          118695:                sp1 = segdupd(sp);
        !          118696:        else {
        !          118697:                sp1->s_flags = sp->s_flags;
        !          118698:                plrcopy( sp->s_paddr, sp1->s_paddr, sp->s_size );
        !          118699:        }
        !          118700:        return (sp1);
        !          118701: }
        !          118702: 
        !          118703: /*
        !          118704:  * Allocate a segment `n' bytes long.  `f' contains some pseudo flags.
        !          118705:  */
        !          118706: SEG *
        !          118707: salloc(n, f)
        !          118708: fsize_t n;
        !          118709: {
        !          118710:        register SEG *sp;
        !          118711:        register int r;
        !          118712: 
        !          118713:        r = (f&(SFSYST|SFHIGH|SFTEXT|SFSHRX|SFDOWN)) | SFCORE;
        !          118714:        n +=  (BSIZE-1);
        !          118715:        n &= ~(BSIZE-1);
        !          118716: 
        !          118717:        lock(seglink);
        !          118718:        sp = sxalloc(n, f);
        !          118719:        unlock(seglink);
        !          118720: 
        !          118721:        if ( sp == NULL ) {
        !          118722:                krunch(1000);
        !          118723:                lock(seglink);
        !          118724:                sp = sxalloc(n, f);
        !          118725:                unlock(seglink);
        !          118726:        }
        !          118727: 
        !          118728:        if (sp != NULL) {
        !          118729:                sp->s_flags = r;
        !          118730:                vremap( sp );
        !          118731:        }
        !          118732:        else {
        !          118733:                if ((f&SFNSWP) != 0)
        !          118734:                        return (NULL);
        !          118735:                if ((sp=kalloc(sizeof(SEG))) == NULL)
        !          118736:                        return (NULL);
        !          118737:                sp->s_forw = sp;
        !          118738:                sp->s_back = sp;
        !          118739:                sp->s_flags = r;
        !          118740:                sp->s_urefc = 1;
        !          118741:                sp->s_lrefc = 1;
        !          118742:                if (segsext(sp, n) == NULL) {
        !          118743:                        kfree(sp);
        !          118744:                        return (NULL);
        !          118745:                }
        !          118746:        }
        !          118747:        if ((f&SFNCLR) == 0)
        !          118748:                pclear( sp->s_paddr, n );
        !          118749:        return (sp);
        !          118750: }
        !          118751: 
        !          118752: /*
        !          118753:  * Free the given segment pointer.
        !          118754:  */
        !          118755: sfree(sp)
        !          118756: register SEG *sp;
        !          118757: {
        !          118758:        register INODE *ip;
        !          118759: 
        !          118760:        if ( sp->s_urefc != 1 ) {
        !          118761:                sp->s_urefc--;
        !          118762:                sp->s_lrefc--;
        !          118763:                return;
        !          118764:        }
        !          118765: 
        !          118766:        lock(seglink);
        !          118767:        --sp->s_lrefc;
        !          118768:        if (--sp->s_urefc != 0) {
        !          118769:                unlock(seglink);
        !          118770:                return;
        !          118771:        }
        !          118772: 
        !          118773:        sp->s_back->s_forw = sp->s_forw;
        !          118774:        sp->s_forw->s_back = sp->s_back;
        !          118775:        unlock(seglink);
        !          118776: 
        !          118777:        if (sp->s_lrefc != 0)
        !          118778:                panic("Bad segment count");
        !          118779:        if ((ip=sp->s_ip) != NULL)
        !          118780:                ldetach(ip);
        !          118781:        vrelse( sp->s_faddr );
        !          118782:        kfree(sp);
        !          118783:        krunch(0);
        !          118784: }
        !          118785: 
        !          118786: /*
        !          118787:  * Grow or shrink the segment `sp' so that it has size `n'.
        !          118788:  */
        !          118789: seggrow(sp, n)
        !          118790: register SEG *sp;
        !          118791: fsize_t n;
        !          118792: {
        !          118793:        register SEG *sp1;
        !          118794:        register fsize_t  d;
        !          118795:        register paddr_t pb;
        !          118796:        register paddr_t nb;
        !          118797:        register int dowflag;
        !          118798: 
        !          118799:        dowflag = sp->s_flags&SFDOWN;
        !          118800: 
        !          118801:        /*
        !          118802:         * Size of new segment is smaller or the same size as the old
        !          118803:         * segment.
        !          118804:         */
        !          118805:        lock(seglink);
        !          118806:        d = n - sp->s_size;
        !          118807:        if (n <= sp->s_size) {
        !          118808:                sp->s_size = n;
        !          118809:                if (dowflag)
        !          118810:                        sp->s_paddr -= d;
        !          118811: 
        !          118812:                vremap( sp );
        !          118813:                unlock(seglink);
        !          118814:                return (1);
        !          118815:        }
        !          118816: 
        !          118817:        if ((sp1=sp->s_back) == &segmq)
        !          118818:                pb = corebot;
        !          118819:        else
        !          118820:                pb = sp1->s_paddr + sp1->s_size;
        !          118821: 
        !          118822:        if ((sp1=sp->s_forw) == &segmq)
        !          118823:                nb = coretop;
        !          118824:        else
        !          118825:                nb = sp1->s_paddr;
        !          118826: 
        !          118827:        /*
        !          118828:         * If the segment does not grow down, see if there is enough
        !          118829:         * space after the segment.
        !          118830:         */
        !          118831:        if (dowflag==0 && nb-sp->s_paddr>=n) {
        !          118832:                pclear(sp->s_paddr+sp->s_size, d);
        !          118833:                sp->s_size = n;
        !          118834:                vremap( sp );
        !          118835:                unlock(seglink);
        !          118836:                return (1);
        !          118837:        }
        !          118838: 
        !          118839:        /*
        !          118840:         * If the segment grows down, see if there is enough space
        !          118841:         * before the segment.
        !          118842:         */
        !          118843:        if (dowflag!=0 && sp->s_paddr+sp->s_size-pb>=n) {
        !          118844:                sp->s_paddr -= d;
        !          118845:                sp->s_size   = n;
        !          118846:                pclear( sp->s_paddr, d );
        !          118847:                vremap( sp );
        !          118848:                unlock(seglink);
        !          118849:                return (1);
        !          118850:        }
        !          118851: 
        !          118852:        /*
        !          118853:         * Is there enough space in total counting the gaps on either
        !          118854:         * side of us?
        !          118855:         */
        !          118856:        if (nb-pb >= n) {
        !          118857:                if (dowflag == 0) {
        !          118858:                        plrcopy(sp->s_paddr, pb, sp->s_size);
        !          118859:                        pclear(pb+sp->s_size, d);
        !          118860:                        sp->s_paddr = pb;
        !          118861:                } else {
        !          118862:                        prlcopy( sp->s_paddr, nb-sp->s_size, sp->s_size );
        !          118863:                        pclear(nb-n, d);
        !          118864:                        sp->s_paddr = nb-n;
        !          118865:                }
        !          118866:                sp->s_size  = n;
        !          118867:                vremap( sp );
        !          118868:                unlock(seglink);
        !          118869:                return (1);
        !          118870:        }
        !          118871: 
        !          118872:        /*
        !          118873:         * Try to allocate a segment somewhere else on the segment queue
        !          118874:         * and copy ourselves there.
        !          118875:         */
        !          118876:        unlock(seglink);
        !          118877:        if ((sp1=salloc((fsize_t)n, sp->s_flags|SFNSWP|SFNCLR)) != NULL) {
        !          118878:                if (dowflag == 0) {
        !          118879:                        plrcopy(sp->s_paddr, sp1->s_paddr, sp->s_size);
        !          118880:                        pclear(sp1->s_paddr+sp->s_size, d);
        !          118881:                } else {
        !          118882:                        plrcopy(sp->s_paddr, sp1->s_paddr+d, sp->s_size);
        !          118883:                        pclear(sp1->s_paddr, d);
        !          118884:                }
        !          118885:                lock(seglink);
        !          118886:                satcopy(sp, sp1);
        !          118887:                unlock(seglink);
        !          118888:                return (1);
        !          118889:        }
        !          118890: 
        !          118891:        /*
        !          118892:         * Last chance.  Extend the segment by swapping it.
        !          118893:         */
        !          118894:        if (segsext(sp, n) != NULL) {
        !          118895:                if (dowflag == 0)
        !          118896:                        pclear(sp->s_paddr+n-d, d);
        !          118897:                else {
        !          118898:                        prlcopy(sp->s_paddr, sp->s_paddr+d, n-d);
        !          118899:                        pclear(sp->s_paddr, d);
        !          118900:                }
        !          118901:                return (1);
        !          118902:        }
        !          118903: 
        !          118904:        /*
        !          118905:         * At least we tried.
        !          118906:         */
        !          118907:        return (0);
        !          118908: }
        !          118909: 
        !          118910: /*
        !          118911:  * Given a segment pointer, `sp' and a segment size, grow the given segment
        !          118912:  * to the given size.
        !          118913:  */
        !          118914: segsize(sp, s2)
        !          118915: register SEG *sp;
        !          118916: vaddr_t s2;
        !          118917: {
        !          118918:        register vaddr_t s1;
        !          118919: 
        !          118920:        s1 = (vaddr_t) sp->s_size;
        !          118921:        if (seggrow(sp, (fsize_t)s2) == 0) {
        !          118922:                u.u_error = ENOMEM;
        !          118923:                return;
        !          118924:        }
        !          118925:        if (sproto() == 0)
        !          118926:                if (seggrow(sp, (fsize_t)s1)==0 || sproto()==0)
        !          118927:                        sendsig(SIGSEGV, SELF);
        !          118928:        segload();
        !          118929: }
        !          118930: 
        !          118931: /*
        !          118932:  * Grow the segment `sp1' to the size `s' in bytes by swapping it out
        !          118933:  * and back in.  The segment may not be locked.
        !          118934:  */
        !          118935: SEG *
        !          118936: segsext(sp1, s)
        !          118937: register SEG *sp1;
        !          118938: register fsize_t s;
        !          118939: {
        !          118940:        register SEG *sp2;
        !          118941: 
        !          118942: #ifndef NOMONITOR
        !          118943:        if (swmflag)
        !          118944:                printf("Segsext(%p, %u)\n", SELF, SELF->p_pid);
        !          118945: #endif
        !          118946:        if (sexflag == 0) {
        !          118947:                u.u_error = ENOMEM;
        !          118948:                return (NULL);
        !          118949:        }
        !          118950:        lock(seglink);
        !          118951:        if ((sp2=sdalloc(s)) == NULL) {
        !          118952:                unlock(seglink);
        !          118953:                return (NULL);
        !          118954:        }
        !          118955:        unlock(seglink);
        !          118956:        sp1->s_lrefc++;
        !          118957:        if (sp1->s_size != 0)
        !          118958:                swapio(1, sp1->s_paddr, sp2->s_daddr, sp1->s_size);
        !          118959:        lock(seglink);
        !          118960:        satcopy(sp1, sp2);
        !          118961:        unlock(seglink);
        !          118962:        sp1->s_flags &= ~SFCORE;
        !          118963:        sp1->s_lrefc--;
        !          118964:        vremap(sp1);
        !          118965:        segfinm(sp1);
        !          118966:        return (sp1);
        !          118967: }
        !          118968: 
        !          118969: /*
        !          118970:  * Force the given segment to be in memory.  One can only force
        !          118971:  * one segment to be in memory at a time.
        !          118972:  */
        !          118973: segfinm(sp)
        !          118974: register SEG *sp;
        !          118975: {
        !          118976:        register PROC *pp;
        !          118977:        register int s;
        !          118978: 
        !          118979:        if ((sp->s_flags&SFCORE) != 0)
        !          118980:                return;
        !          118981:        pp = SELF;
        !          118982:        sp->s_urefc++;
        !          118983:        sp->s_lrefc++;
        !          118984:        pp->p_segp[SIAUXIL] = sp;
        !          118985:        pp->p_flags &= ~PFCORE;
        !          118986: #ifndef QWAKEUP
        !          118987:        s = sphi();
        !          118988: #endif
        !          118989:        setrun(pp);
        !          118990:        dispatch();
        !          118991: #ifndef QWAKEUP
        !          118992:        spl(s);
        !          118993: #endif
        !          118994:        pp->p_segp[SIAUXIL] = NULL;
        !          118995:        sfree(sp);
        !          118996: }
        !          118997: 
        !          118998: /*
        !          118999:  * Make a copy of the segment `sp1' which is in memory by writing
        !          119000:  * it out to disk.
        !          119001:  */
        !          119002: SEG *
        !          119003: segdupd(sp1)
        !          119004: register SEG *sp1;
        !          119005: {
        !          119006:        register SEG *sp2;
        !          119007: 
        !          119008:        if (sexflag == 0)
        !          119009:                return (NULL);
        !          119010:        lock(seglink);
        !          119011:        if ((sp2=sdalloc(sp1->s_size)) == NULL) {
        !          119012:                unlock(seglink);
        !          119013:                return (NULL);
        !          119014:        }
        !          119015:        sp1->s_lrefc++;
        !          119016:        unlock(seglink);
        !          119017:        swapio(1, sp1->s_paddr, sp2->s_daddr, sp1->s_size);
        !          119018:        sp1->s_lrefc--;
        !          119019:        sp2->s_flags = sp1->s_flags & ~SFCORE;
        !          119020:        sp2->s_size  = sp1->s_size;
        !          119021:        vremap( sp2 );
        !          119022:        return (sp2);
        !          119023: }
        !          119024: 
        !          119025: /*
        !          119026:  * Given a flag, a physical core address, a disk address and a count in
        !          119027:  * bytes, perform an I/O operation between core and disk.  If `flag' is
        !          119028:  * set, the transfer is to the disk otherwise it is to memory.  As you may
        !          119029:  * have guessed, this is used by the swapper.
        !          119030:  */
        !          119031: swapio(f, p, d, n)
        !          119032: paddr_t p;
        !          119033: daddr_t d;
        !          119034: fsize_t  n;
        !          119035: {
        !          119036:        register BUF * bp;
        !          119037:        register SEG * sp;
        !          119038:        register int s;
        !          119039:        register int nb;
        !          119040:        static SEG swapseg;     /* NOTE: FP_SEL(swapseg.s_faddr) must stay */
        !          119041: 
        !          119042: #ifndef NOMONITOR
        !          119043:        if (swmflag > 1)
        !          119044:                printf("swapio(%s,%x,%x,%x)\n",f?"out":"in",(int)p,(int)d,n);
        !          119045: #endif
        !          119046:        if (d < swapbot || d+(n/BSIZE) > swaptop
        !          119047:         || p < corebot || p+n > coretop)
        !          119048:                panic("Swapio bad parameter");
        !          119049: 
        !          119050:        bp = &swapbuf;
        !          119051:        sp = &swapseg;
        !          119052:        lock(bp->b_gate);
        !          119053:        SELF->p_flags |= PFSWIO;
        !          119054:        sp->s_flags = SFCORE;
        !          119055:        sp->s_paddr = p;
        !          119056:        sp->s_size  = n;
        !          119057:        vremap( sp );
        !          119058:        bp->b_faddr = sp->s_faddr;
        !          119059: 
        !          119060:        while (n != 0) {
        !          119061:                nb = (n > SCHUNK) ? SCHUNK : n;
        !          119062:                /*
        !          119063:                 * Prevent I/O transfer from crossing 64 Kbyte boundary.
        !          119064:                 */
        !          119065:                if ( (p & 0xFFFF0000L) != ((p+nb) & 0xFFFF0000L) )
        !          119066:                        nb = 0x10000L - (p & 0x0000FFFFL);
        !          119067:                bp->b_flag  = BFNTP;
        !          119068:                bp->b_req   = f ? BWRITE : BREAD;
        !          119069:                bp->b_dev   = swapdev;
        !          119070:                bp->b_bno   = d;
        !          119071:                bp->b_paddr = p;
        !          119072:                bp->b_count = nb;
        !          119073:                s = sphi();
        !          119074:                dblock(swapdev, bp);
        !          119075:                while ((bp->b_flag&BFNTP) != 0)
        !          119076:                        sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !          119077:                spl(s);
        !          119078:                if ((bp->b_flag&BFERR) != 0)
        !          119079:                        panic("Swapio error");
        !          119080:                FP_OFF(bp->b_faddr) += nb;
        !          119081:                p += nb;
        !          119082:                d += nb / BSIZE;
        !          119083:                n -= nb;
        !          119084:        }
        !          119085:        sp->s_flags = 0;
        !          119086:        vremap( sp );
        !          119087:        unlock(bp->b_gate);
        !          119088:        SELF->p_flags &= ~PFSWIO;
        !          119089: }
        !          119090: 
        !          119091: /*
        !          119092:  * Make the segment descriptor pointed to by `sp1' have the attributes
        !          119093:  * of `sp2' including it's position in the segment queue and release
        !          119094:  * `sp2'.  `seglink' must be locked when this routine is called.
        !          119095:  */
        !          119096: satcopy(sp1, sp2)
        !          119097: register SEG *sp1;
        !          119098: register SEG *sp2;
        !          119099: {
        !          119100:        if ( FP_SEL(sp2->s_faddr) != 0 )
        !          119101:                vrelse( sp2->s_faddr );
        !          119102: 
        !          119103:        sp1->s_back->s_forw = sp1->s_forw;
        !          119104:        sp1->s_forw->s_back = sp1->s_back;
        !          119105:        sp2->s_back->s_forw = sp1;
        !          119106:        sp1->s_back = sp2->s_back;
        !          119107:        sp2->s_forw->s_back = sp1;
        !          119108:        sp1->s_forw  = sp2->s_forw;
        !          119109:        sp1->s_size  = sp2->s_size;
        !          119110:        sp1->s_paddr = sp2->s_paddr;
        !          119111:        sp1->s_daddr = sp2->s_daddr;
        !          119112:        vremap(sp1);
        !          119113:        kfree(sp2);
        !          119114: }
        !          119115: 
        !          119116: /*
        !          119117:  * Allocate a segment on disk that is `n' bytes long.
        !          119118:  * The `seglink' gate should be locked before this routine is called.
        !          119119:  */
        !          119120: SEG *
        !          119121: sdalloc( s )
        !          119122: fsize_t s;
        !          119123: {
        !          119124:        register SEG *sp1;
        !          119125:        register SEG *sp2;
        !          119126:        register daddr_t d;
        !          119127:        register daddr_t d1;
        !          119128:        register daddr_t d2;
        !          119129: 
        !          119130:        d  = s / BSIZE;
        !          119131:        d1 = swapbot;
        !          119132:        sp1 = &segdq;
        !          119133:        do {
        !          119134:                if (d1 >= swaptop)
        !          119135:                        return (NULL);
        !          119136:                if ((sp1=sp1->s_forw) != &segdq)
        !          119137:                        d2 = sp1->s_daddr;
        !          119138:                else
        !          119139:                        d2 = swaptop;
        !          119140:                if (d2-d1 >= d) {
        !          119141:                        if ((sp2=kalloc(sizeof(SEG))) == NULL)
        !          119142:                                return (NULL);
        !          119143:                        sp1->s_back->s_forw = sp2;
        !          119144:                        sp2->s_back = sp1->s_back;
        !          119145:                        sp1->s_back = sp2;
        !          119146:                        sp2->s_forw = sp1;
        !          119147:                        sp2->s_urefc = 1;
        !          119148:                        sp2->s_lrefc = 1;
        !          119149:                        sp2->s_size  = s;
        !          119150:                        sp2->s_daddr = d1;
        !          119151:                        return (sp2);
        !          119152:                }
        !          119153:                d1 = sp1->s_daddr + (sp1->s_size / BSIZE);
        !          119154:        } while (sp1 != &segdq);
        !          119155:        return (NULL);
        !          119156: }
        !          119157: 
        !          119158: /*
        !          119159:  * Allocate a segment in memory that is `n' bytes long.
        !          119160:  * The `seglink' gate should be locked before this routine is called.
        !          119161:  */
        !          119162: SEG *
        !          119163: smalloc(s)
        !          119164: fsize_t s;
        !          119165: {
        !          119166:        register SEG *sp1;
        !          119167:        register SEG *sp2;
        !          119168:        paddr_t p1;
        !          119169:        paddr_t p2;
        !          119170: 
        !          119171:        p1  = corebot;
        !          119172:        sp1 = &segmq;
        !          119173:        do {
        !          119174:                if ((sp1=sp1->s_forw) != &segmq)
        !          119175:                        p2 = sp1->s_paddr;
        !          119176:                else
        !          119177:                        p2 = coretop;
        !          119178: 
        !          119179:                if (p2-p1 >= s) {
        !          119180:                        if ((sp2=kalloc(sizeof (SEG))) == NULL)
        !          119181:                                return (NULL);
        !          119182:                        sp1->s_back->s_forw = sp2;
        !          119183:                        sp2->s_back = sp1->s_back;
        !          119184:                        sp1->s_back = sp2;
        !          119185:                        sp2->s_forw = sp1;
        !          119186:                        sp2->s_urefc = 1;
        !          119187:                        sp2->s_lrefc = 1;
        !          119188:                        sp2->s_size  = s;
        !          119189:                        sp2->s_paddr = p1;
        !          119190:                        /*   s_faddr = 0; */
        !          119191:                        /*   s_flags = 0; */
        !          119192:                        vremap( sp2 );
        !          119193:                        return (sp2);
        !          119194:                }
        !          119195:                p1 = sp1->s_paddr + sp1->s_size;
        !          119196:        } while (sp1 != &segmq);
        !          119197:        return (NULL);
        !          119198: }
        !          119199: 
        !          119200: /*
        !          119201:  * Allocate a segment from the high end of memory that is `n' bytes long.
        !          119202:  * The `seglink' gate should be locked before this routine is called.
        !          119203:  */
        !          119204: SEG *
        !          119205: shalloc( s )
        !          119206: fsize_t s;
        !          119207: {
        !          119208:        register SEG *sp1;
        !          119209:        register SEG *sp2;
        !          119210:        paddr_t p1;
        !          119211:        paddr_t p2;
        !          119212: 
        !          119213:        sp1 = &segmq;
        !          119214:        p2  = coretop;
        !          119215:        do {
        !          119216:                if ((sp1=sp1->s_back) != &segmq)
        !          119217:                        p1 = sp1->s_paddr + sp1->s_size;
        !          119218:                else
        !          119219:                        p1 = corebot;
        !          119220: 
        !          119221:                if (p2-p1 >= s) {
        !          119222:                        if ((sp2=kalloc(sizeof (SEG))) == NULL)
        !          119223:                                return (NULL);
        !          119224:                        sp1->s_forw->s_back = sp2;
        !          119225:                        sp2->s_forw = sp1->s_forw;
        !          119226:                        sp1->s_forw = sp2;
        !          119227:                        sp2->s_back = sp1;
        !          119228:                        sp2->s_urefc = 1;
        !          119229:                        sp2->s_lrefc = 1;
        !          119230:                        sp2->s_size  = s;
        !          119231:                        sp2->s_paddr = p2-s;
        !          119232:                        /*   s_faddr = 0; */
        !          119233:                        /*   s_flags = 0; */
        !          119234:                        vremap( sp2 );
        !          119235:                        return (sp2);
        !          119236:                }
        !          119237:                p2 = sp1->s_paddr;
        !          119238:        } while (sp1 != &segmq);
        !          119239:        return (NULL);
        !          119240: }
        !          119241: 
        !          119242: /*
        !          119243:  * Set up `SR' structure in user area from segments descriptors in
        !          119244:  * process structure.  Also set up the user segmentation registers.
        !          119245:  */
        !          119246: sproto()
        !          119247: {
        !          119248:        register int n;
        !          119249:        register SEG *sp;
        !          119250: 
        !          119251:        kclear(u.u_segl, sizeof(u.u_segl));
        !          119252:        for (n=0; n<NUSEG; n++) {
        !          119253:                if ((sp=SELF->p_segp[n]) == NULL)
        !          119254:                        continue;
        !          119255:                if (n == SIUSERP)
        !          119256:                        u.u_segl[n].sr_base = &u;
        !          119257:                else
        !          119258:                        u.u_segl[n].sr_flag |= SRFPMAP;
        !          119259:                if (n!=SISTEXT && n!=SISDATA)
        !          119260:                        u.u_segl[n].sr_flag |= SRFDUMP;
        !          119261:                if (n!=SIUSERP && n!=SISTEXT && n!=SIPTEXT)
        !          119262:                        u.u_segl[n].sr_flag |= SRFDATA;
        !          119263:                u.u_segl[n].sr_size = sp->s_size;
        !          119264:                u.u_segl[n].sr_segp = sp;
        !          119265:        }
        !          119266:        return (mproto());
        !          119267: }
        !          119268: 
        !          119269: /*
        !          119270:  * Search for a busy text inode.
        !          119271:  */
        !          119272: sbusy(ip)
        !          119273: register INODE *ip;
        !          119274: {
        !          119275:        register SEG *sp;
        !          119276: 
        !          119277:        lock(seglink);
        !          119278:        /*
        !          119279:         * Look for the segment in the memory queue.
        !          119280:         */
        !          119281:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
        !          119282:                if (sp->s_ip==ip
        !          119283:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
        !          119284:                        unlock(seglink);
        !          119285:                        return (1);
        !          119286:                }
        !          119287:        }
        !          119288: 
        !          119289:        /*
        !          119290:         * Look for the segment on the disk queue.
        !          119291:         */
        !          119292:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
        !          119293:                if (sp->s_ip==ip
        !          119294:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
        !          119295:                        unlock(seglink);
        !          119296:                        return (1);
        !          119297:                }
        !          119298:        }
        !          119299:        unlock(seglink);
        !          119300:        return (0);
        !          119301: }
        !          119302: 
        !          119303: /*
        !          119304:  * Segment consistency checks for the paranoid.
        !          119305: segchk()
        !          119306: {
        !          119307:        register SEG *sp;
        !          119308:        register int nbad;
        !          119309:        fsize_t s;
        !          119310:        daddr_t d;
        !          119311: 
        !          119312:        nbad = 0;
        !          119313:        sp = &segmq;
        !          119314:        s = corebot;
        !          119315:        while ((sp=sp->s_forw) != &segmq) {
        !          119316:                if (sp->s_paddr < s)
        !          119317:                        nbad += badseg("mem", sp->s_paddr, 0);
        !          119318:                s = sp->s_paddr + sp->s_size;
        !          119319:        }
        !          119320:        if (coretop < s)
        !          119321:                nbad += badseg("mem", sp->s_back->s_paddr, sp->s_back->s_size);
        !          119322:        sp = &segdq;
        !          119323:        d = swapbot;
        !          119324:        while ((sp=sp->s_forw) != &segdq) {
        !          119325:                if (sp->s_daddr < d)
        !          119326:                        nbad += badseg("disk", (int)sp->s_daddr, 0);
        !          119327:                d = sp->s_daddr + (sp->s_size / BSIZE);
        !          119328:        }
        !          119329:        if (swaptop < d)
        !          119330:                nbad += badseg("disk", sp->s_back->s_daddr, sp->s_back->s_size);
        !          119331: }
        !          119332: 
        !          119333: badseg(t, b, s)
        !          119334: char *t;
        !          119335: daddr_t b;
        !          119336: fsize_t s;
        !          119337: {
        !          119338:        printf( "Bad %s segment at %X of len %X\n", t, b, s );
        !          119339:        return (1);
        !          119340: }
        !          119341: */
        !          119342: @
        !          119343: 
        !          119344: 
        !          119345: 1.3
        !          119346: log
        !          119347: @update by hal
        !          119348: @
        !          119349: text
        !          119350: @@
        !          119351: 
        !          119352: 
        !          119353: 1.2
        !          119354: log
        !          119355: @update provided by hal
        !          119356: @
        !          119357: text
        !          119358: @@
        !          119359: 
        !          119360: 
        !          119361: 1.1
        !          119362: log
        !          119363: @Initial revision
        !          119364: @
        !          119365: text
        !          119366: @d37 1
        !          119367: a37 1
        !          119368: #include <coherent.h>
        !          119369: d43 1
        !          119370: a43 1
        !          119371: #include <sched.h>
        !          119372: @
        !          119373: 0707070064030045771004440000030000030000011777770507310736600004700000015611/newbits/kernel/USRSRC/coh/RCS/sig.c,vhead     1.4;
        !          119374: branch   ;
        !          119375: access   ;
        !          119376: symbols  ;
        !          119377: locks    bin:1.4;
        !          119378: comment  @ * @;
        !          119379: 
        !          119380: 
        !          119381: 1.4
        !          119382: date     91.07.24.07.52.13;  author bin;  state Exp;
        !          119383: branches ;
        !          119384: next     1.3;
        !          119385: 
        !          119386: 1.3
        !          119387: date     91.07.15.14.33.48;  author bin;  state Exp;
        !          119388: branches ;
        !          119389: next     1.2;
        !          119390: 
        !          119391: 1.2
        !          119392: date     91.06.20.14.31.25;  author bin;  state Exp;
        !          119393: branches ;
        !          119394: next     1.1;
        !          119395: 
        !          119396: 1.1
        !          119397: date     91.06.10.14.37.39;  author bin;  state Exp;
        !          119398: branches ;
        !          119399: next     ;
        !          119400: 
        !          119401: 
        !          119402: desc
        !          119403: @initial version prov by hal
        !          119404: @
        !          119405: 
        !          119406: 
        !          119407: 1.4
        !          119408: log
        !          119409: @update prov by hal
        !          119410: 
        !          119411: @
        !          119412: text
        !          119413: @/* $Header: /usr/src/sys/coh/RCS/sig.c,v 1.1 88/03/24 16:14:24 src Exp $ */
        !          119414: /* (lgl-
        !          119415:  *     The information contained herein is a trade secret of Mark Williams
        !          119416:  *     Company, and  is confidential information.  It is provided  under a
        !          119417:  *     license agreement,  and may be  copied or disclosed  only under the
        !          119418:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          119419:  *     material without the express written authorization of Mark Williams
        !          119420:  *     Company or persuant to the license agreement is unlawful.
        !          119421:  *
        !          119422:  *     COHERENT Version 2.3.37
        !          119423:  *     Copyright (c) 1982, 1983, 1984.
        !          119424:  *     An unpublished work by Mark Williams Company, Chicago.
        !          119425:  *     All rights reserved.
        !          119426:  -lgl) */
        !          119427: /*
        !          119428:  * Coherent.
        !          119429:  * Signal handling.
        !          119430:  *
        !          119431:  * $Log:       /usr/src/sys/coh/RCS/sig.c,v $
        !          119432:  * Revision 1.1        88/03/24  16:14:24      src
        !          119433:  * Initial revision
        !          119434:  * 
        !          119435:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/sig.c
        !          119436:  * New seg struct now used to allow extended addressing.
        !          119437:  *
        !          119438:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/sig.c
        !          119439:  * sigdump() initializes the (new) (IO).io_flag field to 0.
        !          119440:  */
        !          119441: #include <sys/coherent.h>
        !          119442: #include <errno.h>
        !          119443: #include <sys/ino.h>
        !          119444: #include <sys/inode.h>
        !          119445: #include <sys/io.h>
        !          119446: #include <sys/proc.h>
        !          119447: #include <sys/ptrace.h>
        !          119448: #include <sys/sched.h>
        !          119449: #include <sys/seg.h>
        !          119450: #include <signal.h>
        !          119451: #include <sys/uproc.h>
        !          119452: 
        !          119453: /*
        !          119454:  * Send a signal to the process `pp'.
        !          119455:  */
        !          119456: sendsig(sig, pp)
        !          119457: register unsigned sig;
        !          119458: register PROC *pp;
        !          119459: {
        !          119460:        register sig_t f;
        !          119461:        register int s;
        !          119462: 
        !          119463:        f = ((sig_t)1) << (sig-1);
        !          119464:        if ((pp->p_isig&f) != 0)
        !          119465:                return;
        !          119466:        pp->p_ssig |= f;
        !          119467:        if (pp->p_state == PSSLEEP) {
        !          119468:                s = sphi();
        !          119469:                pp->p_lback->p_lforw = pp->p_lforw;
        !          119470:                pp->p_lforw->p_lback = pp->p_lback;
        !          119471:                addu(pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK);
        !          119472:                setrun(pp);
        !          119473:                spl(s);
        !          119474:        }
        !          119475: }
        !          119476: 
        !          119477: /*
        !          119478:  * Return signal number if we have a non ignored signal, else zero.
        !          119479:  */
        !          119480: nondsig()
        !          119481: {
        !          119482:        register PROC *pp;
        !          119483:        register sig_t mask;
        !          119484:        register int signo;
        !          119485: 
        !          119486:        pp = SELF;
        !          119487:        signo = 0;
        !          119488:        pp->p_ssig &= ~pp->p_isig;
        !          119489:        if (pp->p_ssig != 0) {
        !          119490:                mask = (sig_t) 1;
        !          119491:                signo += 1;
        !          119492:                while ((pp->p_ssig&mask) == 0) {
        !          119493:                        mask <<= 1;
        !          119494:                        signo += 1;
        !          119495:                }
        !          119496:        }
        !          119497:        return (signo);
        !          119498: }
        !          119499: 
        !          119500: /*
        !          119501:  * If we have a signal that isn't ignored, activate it.
        !          119502:  */
        !          119503: actvsig()
        !          119504: {
        !          119505:        register int n;
        !          119506:        register PROC *pp;
        !          119507:        register int (*f)();
        !          119508: 
        !          119509: #if EBUG_VM > 0
        !          119510:        printf("actvsig ");     /** DEBUG **/
        !          119511: #endif
        !          119512: 
        !          119513:        if ((n = nondsig()) == 0)
        !          119514:                return;
        !          119515:        pp = SELF;
        !          119516:        --n;
        !          119517:        pp->p_ssig &= ~((sig_t)1<<n);
        !          119518:        f = u.u_sfunc[n];
        !          119519:        u.u_signo = ++n;
        !          119520:        if (f != SIG_DFL) {
        !          119521:                msigint(n, f);
        !          119522:                return;
        !          119523:        }
        !          119524:        msysgen(&u.u_sysgen);
        !          119525:        if ((pp->p_flags&PFTRAC) != 0) {
        !          119526:                pp->p_flags |= PFWAIT;
        !          119527:                n = ptret();
        !          119528:                pp->p_flags &= ~(PFWAIT|PFSTOP);
        !          119529:                if (n == 0)
        !          119530:                        return;
        !          119531:        }
        !          119532:        if (n>SIGKILL || n==SIGQUIT || n==SIGSYS) {
        !          119533:                if (sigdump())
        !          119534:                        n |= 0200;
        !          119535:        }
        !          119536:        pexit(n);
        !          119537: }
        !          119538: 
        !          119539: /*
        !          119540:  * Create a dump of ourselves onto the file `core'.
        !          119541:  */
        !          119542: sigdump()
        !          119543: {
        !          119544:        register INODE *ip;
        !          119545:        register SR *srp;
        !          119546:        register SEG * sp;
        !          119547:        register int n;
        !          119548:        register paddr_t ssize;
        !          119549: 
        !          119550:        if ((SELF->p_flags&PFNDMP) != 0)
        !          119551:                return (0);
        !          119552:        u.u_io.io_seg  = IOSYS;
        !          119553:        u.u_io.io_flag = 0;
        !          119554:        /* Make the core with the real owners */
        !          119555:        schizo();
        !          119556:        if (ftoi("core", 'c') != 0) {
        !          119557:                schizo();
        !          119558:                return (0);
        !          119559:        }
        !          119560:        if ((ip=u.u_cdiri) == NULL) {
        !          119561:                if ((ip=imake(IFREG|0644, 0)) == NULL) {
        !          119562:                        schizo();
        !          119563:                        return (0);
        !          119564:                }
        !          119565:        } else {
        !          119566:                if ((ip->i_mode&IFMT)!=IFREG
        !          119567:                 || iaccess(ip, IPW)==0
        !          119568:                 || getment(ip->i_dev, 1)==NULL) {
        !          119569:                        idetach(ip);
        !          119570:                        schizo();
        !          119571:                        return (0);
        !          119572:                }
        !          119573:                iclear(ip);
        !          119574:        }
        !          119575:        schizo();
        !          119576:        u.u_error = 0;
        !          119577:        u.u_io.io_seek = 0;
        !          119578:        for (srp=u.u_segl; u.u_error==0 && srp<&u.u_segl[NUSEG]; srp++) {
        !          119579:                if ((sp = srp->sr_segp)==NULL || (srp->sr_flag&SRFDUMP)==0)
        !          119580:                        continue;
        !          119581:                u.u_io.io_seg = IOPHY;
        !          119582:                u.u_io.io_phys = sp->s_paddr;
        !          119583:                u.u_io.io_flag = 0;
        !          119584:                ssize = sp->s_size;
        !          119585:                sp->s_lrefc++;
        !          119586:                while (u.u_error == 0 && ssize != 0) {
        !          119587:                        n = ssize > SCHUNK ? SCHUNK : ssize;
        !          119588:                        u.u_io.io_ioc = n;
        !          119589:                        iwrite(ip, &u.u_io);
        !          119590:                        u.u_io.io_phys += (paddr_t)n;
        !          119591:                        ssize -= (paddr_t)n;
        !          119592:                }
        !          119593:                sp->s_lrefc--;
        !          119594:        }
        !          119595:        idetach(ip);
        !          119596:        return (u.u_error==0);
        !          119597: }
        !          119598: 
        !          119599: /*
        !          119600:  * Send a ptrace command to the child.
        !          119601:  */
        !          119602: ptset(req, pid, addr, data)
        !          119603: unsigned req;
        !          119604: int *addr;
        !          119605: {
        !          119606: #ifdef TINY
        !          119607:        sendsig(SELF, SIGSYS);
        !          119608:        return (0);
        !          119609: #else
        !          119610:        register PROC *pp;
        !          119611: 
        !          119612:        lock(pnxgate);
        !          119613:        for (pp=procq.p_nforw; pp!=&procq; pp=pp->p_nforw)
        !          119614:                if (pp->p_pid == pid)
        !          119615:                        break;
        !          119616:        unlock(pnxgate);
        !          119617:        if (pp==&procq || (pp->p_flags&PFSTOP)==0 || pp->p_ppid!=SELF->p_pid) {
        !          119618:                u.u_error = ESRCH;
        !          119619:                return;
        !          119620:        }
        !          119621:        lock(pts.pt_gate);
        !          119622:        pts.pt_req = req;
        !          119623:        pts.pt_pid = pid;
        !          119624:        pts.pt_addr = addr;
        !          119625:        pts.pt_data = data;
        !          119626:        pts.pt_errs = 0;
        !          119627:        pts.pt_rval = 0;
        !          119628:        pts.pt_busy = 1;
        !          119629:        wakeup((char *)&pts.pt_req);
        !          119630:        while (pts.pt_busy != 0)
        !          119631:                sleep((char *)&pts.pt_busy, CVPTSET, IVPTSET, SVPTSET);
        !          119632:        u.u_error = pts.pt_errs;
        !          119633:        unlock(pts.pt_gate);
        !          119634:        return (pts.pt_rval);
        !          119635: #endif
        !          119636: }
        !          119637: 
        !          119638: /*
        !          119639:  * This routine is called when a child that is being traced receives a signal
        !          119640:  * that is not caught or ignored.  It follows up on any requests by the parent
        !          119641:  * and returns when done.
        !          119642:  */
        !          119643: ptret()
        !          119644: {
        !          119645: #ifdef TINY
        !          119646:        return (SIGKILL);
        !          119647: #else
        !          119648:        register PROC *pp;
        !          119649:        register PROC *pp1;
        !          119650:        register int sign;
        !          119651: 
        !          119652:        pp = SELF;
        !          119653: next:
        !          119654:        u.u_error = 0;
        !          119655:        if (pp->p_ppid == 1)
        !          119656:                return (SIGKILL);
        !          119657:        sign = -1;
        !          119658:        lock(pnxgate);
        !          119659:        pp1 = &procq;
        !          119660:        for (;;) {
        !          119661:                if ((pp1=pp1->p_nforw) == &procq) {
        !          119662:                        sign = SIGKILL;
        !          119663:                        break;
        !          119664:                }
        !          119665:                if (pp1->p_pid != pp->p_ppid)
        !          119666:                        continue;
        !          119667:                if (pp1->p_state == PSSLEEP)
        !          119668:                        wakeup((char *)pp1);
        !          119669:                break;
        !          119670:        }
        !          119671:        unlock(pnxgate);
        !          119672:        while (sign < 0) {
        !          119673:                if (pts.pt_busy==0 || pp->p_pid!=pts.pt_pid) {
        !          119674:                        sleep((char *)&pts.pt_req, CVPTRET, IVPTRET, SVPTRET);
        !          119675:                        goto next;
        !          119676:                }
        !          119677:                switch (pts.pt_req) {
        !          119678:                case 1:
        !          119679:                        pts.pt_rval = getuwi(pts.pt_addr);
        !          119680:                        break;
        !          119681:                case 2:
        !          119682:                        pts.pt_rval = getuwd(pts.pt_addr);
        !          119683:                        break;
        !          119684:                case 3:
        !          119685:                        if ((unsigned)pts.pt_addr < UPASIZE)
        !          119686:                                pts.pt_rval = *(int *)((char *)&u+pts.pt_addr);
        !          119687:                        else
        !          119688:                                u.u_error = EINVAL;
        !          119689:                        break;
        !          119690:                case 4:
        !          119691:                        putuwi(pts.pt_addr, pts.pt_data);
        !          119692:                        break;
        !          119693:                case 5:
        !          119694:                        putuwd(pts.pt_addr, pts.pt_data);
        !          119695:                        break;
        !          119696:                case 6:
        !          119697:                        if (msetuof(pts.pt_addr, pts.pt_data) == 0)
        !          119698:                                u.u_error = EINVAL;
        !          119699:                        break;
        !          119700:                case 7:
        !          119701:                        goto sig;
        !          119702:                case 8:
        !          119703:                        sign = SIGKILL;
        !          119704:                        break;
        !          119705:                case 9:
        !          119706:                        msigsin();
        !          119707:                sig:
        !          119708:                        if (pts.pt_data<0 || pts.pt_data>NSIG) {
        !          119709:                                u.u_error = EINVAL;
        !          119710:                                break;
        !          119711:                        }
        !          119712:                        sign = pts.pt_data;
        !          119713:                        if (pts.pt_addr != SIG_IGN)
        !          119714:                                msetppc((vaddr_t)pts.pt_addr);
        !          119715:                        break;
        !          119716:                default:
        !          119717:                        u.u_error = EINVAL;
        !          119718:                }
        !          119719:                if ((pts.pt_errs=u.u_error) == EFAULT)
        !          119720:                        pts.pt_errs = EINVAL;
        !          119721:                pts.pt_busy = 0;
        !          119722:                wakeup((char *)&pts.pt_busy);
        !          119723:        }
        !          119724:        return (sign);
        !          119725: #endif
        !          119726: }
        !          119727: @
        !          119728: 
        !          119729: 
        !          119730: 1.3
        !          119731: log
        !          119732: @update by hal
        !          119733: @
        !          119734: text
        !          119735: @@
        !          119736: 
        !          119737: 
        !          119738: 1.2
        !          119739: log
        !          119740: @update provided by hal
        !          119741: @
        !          119742: text
        !          119743: @@
        !          119744: 
        !          119745: 
        !          119746: 1.1
        !          119747: log
        !          119748: @Initial revision
        !          119749: @
        !          119750: text
        !          119751: @d29 1
        !          119752: a29 1
        !          119753: #include <coherent.h>
        !          119754: d35 2
        !          119755: a36 2
        !          119756: #include <ptrace.h>
        !          119757: #include <sched.h>
        !          119758: @
        !          119759: 0707070064030031761004440000030000030000011777770507310737000005000000025512/newbits/kernel/USRSRC/coh/RCS/sys1.c,vhead     1.4;
        !          119760: branch   ;
        !          119761: access   ;
        !          119762: symbols  ;
        !          119763: locks    bin:1.4;
        !          119764: comment  @ * @;
        !          119765: 
        !          119766: 
        !          119767: 1.4
        !          119768: date     91.07.24.07.52.21;  author bin;  state Exp;
        !          119769: branches ;
        !          119770: next     1.3;
        !          119771: 
        !          119772: 1.3
        !          119773: date     91.07.15.14.33.56;  author bin;  state Exp;
        !          119774: branches ;
        !          119775: next     1.2;
        !          119776: 
        !          119777: 1.2
        !          119778: date     91.06.20.14.31.32;  author bin;  state Exp;
        !          119779: branches ;
        !          119780: next     1.1;
        !          119781: 
        !          119782: 1.1
        !          119783: date     91.06.10.14.37.41;  author bin;  state Exp;
        !          119784: branches ;
        !          119785: next     ;
        !          119786: 
        !          119787: 
        !          119788: desc
        !          119789: @initial version prov by hal
        !          119790: @
        !          119791: 
        !          119792: 
        !          119793: 1.4
        !          119794: log
        !          119795: @update prov by hal
        !          119796: 
        !          119797: @
        !          119798: text
        !          119799: @/* $Header: /usr/src/sys/coh/RCS/sys1.c,v 1.1 88/03/24 16:14:27 src Exp $ */
        !          119800: /* (lgl-
        !          119801:  *     The information contained herein is a trade secret of Mark Williams
        !          119802:  *     Company, and  is confidential information.  It is provided  under a
        !          119803:  *     license agreement,  and may be  copied or disclosed  only under the
        !          119804:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          119805:  *     material without the express written authorization of Mark Williams
        !          119806:  *     Company or persuant to the license agreement is unlawful.
        !          119807:  *
        !          119808:  *     COHERENT Version 2.3.37
        !          119809:  *     Copyright (c) 1982, 1983, 1984.
        !          119810:  *     An unpublished work by Mark Williams Company, Chicago.
        !          119811:  *     All rights reserved.
        !          119812:  -lgl) */
        !          119813: /*
        !          119814:  * Coherent.
        !          119815:  * General system calls.
        !          119816:  *
        !          119817:  * $Log:       /usr/src/sys/coh/RCS/sys1.c,v $
        !          119818:  * Revision 1.1        88/03/24  16:14:27      src
        !          119819:  * Initial revision
        !          119820:  * 
        !          119821:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          119822:  * New seg struct now used to allow extended addressing.
        !          119823:  *
        !          119824:  * 87/10/21    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          119825:  * ukill() no longer signals kernel processes if pid is -1.
        !          119826:  * usload() changed to new loadable driver format.
        !          119827:  *
        !          119828:  * 87/08/14    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          119829:  * utick() system call added. Returns elapsed clock ticks since system startup.
        !          119830:  *
        !          119831:  * 87/07/23    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          119832:  * ualarm2() now takes the delay interval as a long instead of an unsigned.
        !          119833:  *
        !          119834:  * 87/07/08    Allan Cornish           /usr/src/sys/coh/sys1.c
        !          119835:  * ualarm() modified to use timed functions to send alarm signal.
        !          119836:  * ualarm2() added to allow alarm times in clock ticks rather than seconds.
        !          119837:  *
        !          119838:  * 85/07/25    Allan Cornish
        !          119839:  * ukill() modified to allow a signal of 0 to check process existence.
        !          119840:  *
        !          119841:  * 85/07/9     Allan Cornish
        !          119842:  * ukill() modified to allow signals to be sent to other process groups.
        !          119843:  * usetpgrp() modified to be System V compatible (group set to pid).
        !          119844:  * ugetpgrp() system call added.
        !          119845:  */
        !          119846: #include <sys/coherent.h>
        !          119847: #include <acct.h>
        !          119848: #include <sys/con.h>
        !          119849: #include <errno.h>
        !          119850: #include <sys/proc.h>
        !          119851: #include <sys/sched.h>
        !          119852: #include <sys/seg.h>
        !          119853: #include <signal.h>
        !          119854: #include <sys/timeb.h>
        !          119855: #include <sys/times.h>
        !          119856: #include <sys/uproc.h>
        !          119857: 
        !          119858: /*
        !          119859:  * Send alarm signal to specified process - function timed by ualarm()
        !          119860:  */
        !          119861: static
        !          119862: sigalrm( pp )
        !          119863: register PROC * pp;
        !          119864: {
        !          119865:        sendsig( SIGALRM, pp );
        !          119866: }
        !          119867: 
        !          119868: /*
        !          119869:  * Send a SIGALARM signal in `n' seconds.
        !          119870:  */
        !          119871: ualarm(n)
        !          119872: unsigned n;
        !          119873: {
        !          119874:        register PROC * pp = SELF;
        !          119875:        register unsigned s;
        !          119876: 
        !          119877:        /*
        !          119878:         * Calculate time left before current alarm timeout.
        !          119879:         */
        !          119880:        s = 0;
        !          119881:        if ( pp->p_alrmtim.t_last != NULL )
        !          119882:                s = (pp->p_alrmtim.t_lbolt - lbolt + HZ - 1) / HZ;
        !          119883: 
        !          119884:        /*
        !          119885:         * Cancel previous alarm [if any], start new alarm [if n != 0].
        !          119886:         */
        !          119887:        timeout2( &pp->p_alrmtim, (long) n * HZ, sigalrm, pp );
        !          119888: 
        !          119889:        /*
        !          119890:         * Return time left before previous alarm timeout.
        !          119891:         */
        !          119892:        return( s );
        !          119893: }
        !          119894: 
        !          119895: /*
        !          119896:  * Send a SIGALARM signal in `n' clock ticks.
        !          119897:  */
        !          119898: long
        !          119899: ualarm2(n)
        !          119900: long n;
        !          119901: {
        !          119902:        register PROC * pp = SELF;
        !          119903:        long s;
        !          119904: 
        !          119905:        /*
        !          119906:         * Calculate time left before current alarm timeout.
        !          119907:         */
        !          119908:        s = 0;
        !          119909:        if ( pp->p_alrmtim.t_last != NULL )
        !          119910:                s = pp->p_alrmtim.t_lbolt - lbolt;
        !          119911: 
        !          119912:        /*
        !          119913:         * Cancel previous alarm [if any], start new alarm [if n != 0].
        !          119914:         */
        !          119915:        timeout2( &pp->p_alrmtim, (long) n, sigalrm, pp );
        !          119916: 
        !          119917:        /*
        !          119918:         * Return time left before previous alarm timeout.
        !          119919:         */
        !          119920:        return( s );
        !          119921: }
        !          119922: 
        !          119923: /*
        !          119924:  * Change the size of our data segment.
        !          119925:  */
        !          119926: char *
        !          119927: ubrk(cp)
        !          119928: char *cp;
        !          119929: {
        !          119930:        register SEG *sp;
        !          119931:        register vaddr_t sb;
        !          119932: 
        !          119933:        sp = SELF->p_segp[SIPDATA];
        !          119934:        sb = u.u_segl[SIPDATA].sr_base;
        !          119935:        if (cp != NULL)
        !          119936:                segsize(sp, (vaddr_t)cp-sb);
        !          119937: #ifdef OLD
        !          119938:        return (0);
        !          119939: #else
        !          119940:        sb += sp->s_size;
        !          119941:        return ((char *)sb);
        !          119942: #endif
        !          119943: }
        !          119944: 
        !          119945: /*
        !          119946:  * Execute a l.out.
        !          119947:  */
        !          119948: uexece(np, argp, envp)
        !          119949: char *np;
        !          119950: char *argp[];
        !          119951: char *envp[];
        !          119952: {
        !          119953:        pexece(np, argp, envp);
        !          119954: }
        !          119955: 
        !          119956: /*
        !          119957:  * Exit.
        !          119958:  */
        !          119959: uexit(s)
        !          119960: {
        !          119961:        pexit(s<<8);
        !          119962: }
        !          119963: 
        !          119964: /*
        !          119965:  * Fork.
        !          119966:  */
        !          119967: ufork()
        !          119968: {
        !          119969:        return (pfork());
        !          119970: }
        !          119971: 
        !          119972: /*
        !          119973:  * Return date and time.
        !          119974:  */
        !          119975: uftime(tbp)
        !          119976: struct timeb *tbp;
        !          119977: {
        !          119978:        register int s;
        !          119979:        struct timeb timeb;
        !          119980: 
        !          119981:        timeb.time = timer.t_time;
        !          119982:        /* This should be a machine.h macro to avoid
        !          119983:         * unnecessary long arithmetic and roundoff errors
        !          119984:         */
        !          119985:        timeb.millitm = timer.t_tick*(1000/HZ);
        !          119986:        timeb.timezone = timer.t_zone;
        !          119987:        timeb.dstflag = timer.t_dstf;
        !          119988:        s = sphi();
        !          119989:        kucopy(&timeb, tbp, sizeof(timeb));
        !          119990:        spl(s);
        !          119991: }
        !          119992: 
        !          119993: /*
        !          119994:  * Get effective group id.
        !          119995:  */
        !          119996: ugetegid()
        !          119997: {
        !          119998:        return (u.u_gid);
        !          119999: }
        !          120000: 
        !          120001: /*
        !          120002:  * Get effective user id.
        !          120003:  */
        !          120004: ugeteuid()
        !          120005: {
        !          120006:        return (u.u_uid);
        !          120007: }
        !          120008: 
        !          120009: /*
        !          120010:  * Get group id.
        !          120011:  */
        !          120012: ugetgid()
        !          120013: {
        !          120014:        return (u.u_rgid);
        !          120015: }
        !          120016: 
        !          120017: /*
        !          120018:  * Get process id.
        !          120019:  */
        !          120020: ugetpid()
        !          120021: {
        !          120022:        return (SELF->p_pid);
        !          120023: }
        !          120024: 
        !          120025: /*
        !          120026:  * Get user id.
        !          120027:  */
        !          120028: ugetuid()
        !          120029: {
        !          120030:        return (u.u_ruid);
        !          120031: }
        !          120032: 
        !          120033: /*
        !          120034:  * Get process group.
        !          120035:  */
        !          120036: ugetpgrp()
        !          120037: {
        !          120038:        return (SELF->p_group);
        !          120039: }
        !          120040: 
        !          120041: /*
        !          120042:  * Set the process group.
        !          120043:  * When process group is 0 and a terminal is
        !          120044:  * opened, this process is made the base of
        !          120045:  * processes associated with that terminal.
        !          120046:  */
        !          120047: usetpgrp()
        !          120048: {
        !          120049:        register PROC * pp = SELF;
        !          120050: 
        !          120051:        return (pp->p_group = pp->p_pid);
        !          120052: }
        !          120053: 
        !          120054: /*
        !          120055:  * Send the signal `sig' to the process with id `pid'.
        !          120056:  */
        !          120057: ukill(pid, sig)
        !          120058: int pid;
        !          120059: register unsigned sig;
        !          120060: {
        !          120061:        register PROC *pp;
        !          120062:        register int sigflag;
        !          120063: 
        !          120064:        if ( sig > NSIG ) {
        !          120065:                u.u_error = EINVAL;
        !          120066:                return;
        !          120067:        }
        !          120068:        sigflag = 0;
        !          120069:        lock(pnxgate);
        !          120070:        if (pid > 0) {  /* send to matching process */
        !          120071:                for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) {
        !          120072:                        if (pp->p_state == PSDEAD)
        !          120073:                                continue;
        !          120074:                        if (pp->p_pid == pid) {
        !          120075:                                sigflag = 1;
        !          120076:                                if ( sig ) {
        !          120077:                                        if (sigperm(sig, pp))
        !          120078:                                                sendsig(sig, pp);
        !          120079:                                        else
        !          120080:                                                u.u_error = EPERM;
        !          120081:                                }
        !          120082:                                break;
        !          120083:                        }
        !          120084:                }
        !          120085:        }
        !          120086:        else if (pid < -1) {
        !          120087:                pid = -pid;
        !          120088:                for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) {
        !          120089:                        if (pp->p_state == PSDEAD)
        !          120090:                                continue;
        !          120091:                        if (pp->p_group == pid) {
        !          120092:                                sigflag = 1;
        !          120093:                                if (sig) {
        !          120094:                                        if (sigperm(sig, pp))
        !          120095:                                                sendsig(sig,pp);
        !          120096:                                        else
        !          120097:                                                u.u_error = EPERM;
        !          120098:                                }
        !          120099:                        }
        !          120100:                }
        !          120101:        }
        !          120102:        else if (pid == 0) {
        !          120103:                for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) {
        !          120104:                        if (pp->p_state == PSDEAD)
        !          120105:                                continue;
        !          120106:                        if (pp->p_group == SELF->p_group) {
        !          120107:                                sigflag = 1;
        !          120108:                                if (sig && sigperm(sig, pp))
        !          120109:                                        sendsig(sig, pp);
        !          120110:                        }
        !          120111:                }
        !          120112:        }
        !          120113:        else if (pid == -1) {
        !          120114:                for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) {
        !          120115:                        if (pp->p_state == PSDEAD)
        !          120116:                                continue;
        !          120117:                        if (pp->p_pid == 0)
        !          120118:                                continue;
        !          120119:                        if (pp->p_pid == 1)
        !          120120:                                continue;
        !          120121:                        if ( pp->p_flags & PFKERN )
        !          120122:                                continue;
        !          120123:                        sigflag = 1;
        !          120124:                        if (sig && super())
        !          120125:                                sendsig(sig, pp);
        !          120126:                }
        !          120127:        }
        !          120128:        unlock(pnxgate);
        !          120129:        if (sigflag == 0)
        !          120130:                u.u_error = ESRCH;
        !          120131:        return (0);
        !          120132: }
        !          120133: 
        !          120134: /*
        !          120135:  * See if we have permission to send the signal, `sig' to the process, `pp'.
        !          120136:  */
        !          120137: sigperm(sig, pp)
        !          120138: register PROC *pp;
        !          120139: {
        !          120140:        if (u.u_uid == pp->p_uid)
        !          120141:                return (1);
        !          120142:        if (u.u_ruid == pp->p_ruid) {
        !          120143:                if (sig == SIGHUP
        !          120144:                ||  sig == SIGINT
        !          120145:                ||  sig == SIGQUIT
        !          120146:                ||  sig == SIGTERM)
        !          120147:                        return (1);
        !          120148:        }
        !          120149:        if (u.u_uid == 0) {
        !          120150:                u.u_flag |= ASU;
        !          120151:                return (1);
        !          120152:        }
        !          120153:        return (0);
        !          120154: }
        !          120155: 
        !          120156: /*
        !          120157:  * Lock a process in core.
        !          120158:  */
        !          120159: ulock(f)
        !          120160: {
        !          120161:        if (super() == 0)
        !          120162:                return;
        !          120163:        if (f)
        !          120164:                SELF->p_flags |= PFLOCK;
        !          120165:        else
        !          120166:                SELF->p_flags &= ~PFLOCK;
        !          120167:        return (0);
        !          120168: }
        !          120169: 
        !          120170: /*
        !          120171:  * Change priority by the given increment.
        !          120172:  */
        !          120173: unice(n)
        !          120174: register int n;
        !          120175: {
        !          120176:        n += SELF->p_nice;
        !          120177:        if (n < MINNICE)
        !          120178:                n = MINNICE;
        !          120179:        if (n > MAXNICE)
        !          120180:                n = MAXNICE;
        !          120181:        if (n<SELF->p_nice && super()==0)
        !          120182:                return;
        !          120183:        SELF->p_nice = n;
        !          120184:        return (0);
        !          120185: }
        !          120186: 
        !          120187: /*
        !          120188:  * Non existant system call.
        !          120189:  */
        !          120190: unone()
        !          120191: {
        !          120192:        u.u_error = EFAULT;
        !          120193: }
        !          120194: 
        !          120195: /*
        !          120196:  * Null system call.
        !          120197:  */
        !          120198: unull()
        !          120199: {
        !          120200: }
        !          120201: 
        !          120202: /*
        !          120203:  * Pause.  Go to sleep on a channel that nobody will wakeup so that only
        !          120204:  * signals will wake us up.
        !          120205:  */
        !          120206: upause()
        !          120207: {
        !          120208:        for (;;)
        !          120209:                sleep((char *)&u, CVPAUSE, IVPAUSE, SVPAUSE);
        !          120210: }
        !          120211: 
        !          120212: /*
        !          120213:  * Start profiling.  `bp' is the profile buffer, `n' is the size, `off'
        !          120214:  * is the offset in the users programme and `scale' is the scaling
        !          120215:  * factor.
        !          120216:  */
        !          120217: uprofil(bp, n, off, scale)
        !          120218: register char *bp;
        !          120219: {
        !          120220:        u.u_pbase = bp;
        !          120221:        u.u_pbend = bp + n;
        !          120222:        u.u_pofft = off;
        !          120223:        u.u_pscale = scale;
        !          120224: }
        !          120225: 
        !          120226: /*
        !          120227:  * Process trace.
        !          120228:  */
        !          120229: uptrace(req, pid, add, data)
        !          120230: int *add;
        !          120231: {
        !          120232:        if (req == 0) {
        !          120233:                SELF->p_flags |= PFTRAC;
        !          120234:                return (0);
        !          120235:        }
        !          120236:        return (ptset(req, pid, add, data));
        !          120237: }
        !          120238: 
        !          120239: /*
        !          120240:  * Set group id.
        !          120241:  */
        !          120242: usetgid(gid)
        !          120243: register int gid;
        !          120244: {
        !          120245:        if (u.u_gid!=gid && super()==0)
        !          120246:                return;
        !          120247:        u.u_gid = gid;
        !          120248:        u.u_rgid = gid;
        !          120249:        SELF->p_rgid = gid;
        !          120250:        return (0);
        !          120251: }
        !          120252: 
        !          120253: /*
        !          120254:  * Set user id.
        !          120255:  */
        !          120256: usetuid(uid)
        !          120257: register int uid;
        !          120258: {
        !          120259:        if (uid!=u.u_ruid && super()==0)
        !          120260:                return;
        !          120261:        u.u_uid = uid;
        !          120262:        u.u_ruid = uid;
        !          120263:        SELF->p_uid = uid;
        !          120264:        SELF->p_ruid = uid;
        !          120265:        return (0);
        !          120266: }
        !          120267: 
        !          120268: /*
        !          120269:  * Set up the action to be taken on a signal.
        !          120270:  */
        !          120271: int *
        !          120272: usignal(sig, f)
        !          120273: register int sig;
        !          120274: int (*f)();
        !          120275: {
        !          120276:        register PROC *pp;
        !          120277:        register sig_t s;
        !          120278:        register int (*o)();
        !          120279: 
        !          120280:        pp = SELF;
        !          120281:        if (sig<=0 || sig>NSIG || sig==SIGKILL) {
        !          120282:                u.u_error = EINVAL;
        !          120283:                return;
        !          120284:        }
        !          120285:        s = (sig_t)1 << --sig;
        !          120286:        o = u.u_sfunc[sig];
        !          120287:        /* This order is critical to isig's use */
        !          120288:        if (f == SIG_IGN) {
        !          120289:                pp->p_isig |= s;
        !          120290:                u.u_sfunc[sig] = f;
        !          120291:        } else {
        !          120292:                u.u_sfunc[sig] = f;
        !          120293:                pp->p_isig &= ~s;
        !          120294:        }
        !          120295:        pp->p_ssig &= ~s;
        !          120296:        return (o);
        !          120297: }
        !          120298: 
        !          120299: /*
        !          120300:  * Load a device driver.
        !          120301:  */
        !          120302: usload( np )
        !          120303: char *np;
        !          120304: {
        !          120305:        return( pload( np ) );
        !          120306: }
        !          120307: 
        !          120308: /*
        !          120309:  * Set time and date.
        !          120310:  */
        !          120311: ustime(tp)
        !          120312: register time_t *tp;
        !          120313: {
        !          120314:        register int s;
        !          120315: 
        !          120316:        if (super() == 0)
        !          120317:                return;
        !          120318:        s = sphi();
        !          120319:        ukcopy(tp, &timer.t_time, sizeof(*tp));
        !          120320:        spl(s);
        !          120321:        return (0);
        !          120322: }
        !          120323: 
        !          120324: /*
        !          120325:  * Return elapsed ticks since system startup.
        !          120326:  */
        !          120327: long
        !          120328: utick()
        !          120329: {
        !          120330:        return( lbolt );
        !          120331: }
        !          120332: 
        !          120333: /*
        !          120334:  * Return process times.
        !          120335:  */
        !          120336: utimes(tp)
        !          120337: struct tbuffer *tp;
        !          120338: {
        !          120339:        register PROC *pp;
        !          120340:        struct tbuffer tbuffer;
        !          120341: 
        !          120342:        pp = SELF;
        !          120343:        tbuffer.tb_utime = pp->p_utime;
        !          120344:        tbuffer.tb_stime = pp->p_stime;
        !          120345:        tbuffer.tb_cutime = pp->p_cutime;
        !          120346:        tbuffer.tb_cstime = pp->p_cstime;
        !          120347:        kucopy(&tbuffer, tp, sizeof(tbuffer));
        !          120348:        return (0);
        !          120349: }
        !          120350: 
        !          120351: /*
        !          120352:  * Unload a device driver.
        !          120353:  */
        !          120354: usuload(m)
        !          120355: register int m;
        !          120356: {
        !          120357:        if (super() == 0)
        !          120358:                return;
        !          120359:        puload(m);
        !          120360:        return (0);
        !          120361: }
        !          120362: 
        !          120363: 
        !          120364: /*
        !          120365:  * Wait for a child to terminate.
        !          120366:  */
        !          120367: uwait(stp)
        !          120368: int *stp;
        !          120369: {
        !          120370:        register PROC *pp;
        !          120371:        register PROC *ppp;
        !          120372:        register PROC *cpp;
        !          120373:        register int pid;
        !          120374: 
        !          120375:        ppp = SELF;
        !          120376:        for (;;) {
        !          120377:                lock(pnxgate);
        !          120378:                cpp = NULL;
        !          120379:                pp = &procq;
        !          120380:                while ((pp=pp->p_nforw) != &procq) {
        !          120381:                        if (pp == ppp)
        !          120382:                                continue;
        !          120383:                        if (pp->p_ppid != ppp->p_pid)
        !          120384:                                continue;
        !          120385:                        if ((pp->p_flags&PFSTOP) != 0)
        !          120386:                                continue;
        !          120387:                        if ((pp->p_flags&PFWAIT) != 0) {
        !          120388:                                pp->p_flags &= ~PFWAIT;
        !          120389:                                pp->p_flags |= PFSTOP;
        !          120390:                                unlock(pnxgate);
        !          120391:                                if (stp != NULL)
        !          120392:                                        putuwd(stp, 0177);
        !          120393:                                return (pp->p_pid);
        !          120394:                        }
        !          120395:                        if (pp->p_state == PSDEAD) {
        !          120396:                                ppp->p_cutime += pp->p_utime + pp->p_cutime;
        !          120397:                                ppp->p_cstime += pp->p_stime + pp->p_cstime;
        !          120398:                                if (stp != NULL)
        !          120399:                                        putuwd(stp, pp->p_exit);
        !          120400:                                pid = pp->p_pid;
        !          120401:                                unlock(pnxgate);
        !          120402:                                relproc(pp);
        !          120403:                                return (pid);
        !          120404:                        }
        !          120405:                        cpp = pp;
        !          120406:                }
        !          120407:                unlock(pnxgate);
        !          120408:                if (cpp == NULL) {
        !          120409:                        u.u_error = ECHILD;
        !          120410:                        return;
        !          120411:                }
        !          120412:                sleep((char *)ppp, CVWAIT, IVWAIT, SVWAIT);
        !          120413:        }
        !          120414: }
        !          120415: @
        !          120416: 
        !          120417: 
        !          120418: 1.3
        !          120419: log
        !          120420: @update by hal
        !          120421: @
        !          120422: text
        !          120423: @@
        !          120424: 
        !          120425: 
        !          120426: 1.2
        !          120427: log
        !          120428: @update provided by hal
        !          120429: @
        !          120430: text
        !          120431: @@
        !          120432: 
        !          120433: 
        !          120434: 1.1
        !          120435: log
        !          120436: @Initial revision
        !          120437: @
        !          120438: text
        !          120439: @d48 1
        !          120440: a48 1
        !          120441: #include <coherent.h>
        !          120442: d53 1
        !          120443: a53 1
        !          120444: #include <sched.h>
        !          120445: @
        !          120446: 0707070064030031171004440000030000030000011777770507310737200005000000020271/newbits/kernel/USRSRC/coh/RCS/sys3.c,vhead     1.4;
        !          120447: branch   ;
        !          120448: access   ;
        !          120449: symbols  ;
        !          120450: locks    bin:1.4;
        !          120451: comment  @ * @;
        !          120452: 
        !          120453: 
        !          120454: 1.4
        !          120455: date     91.07.24.07.52.41;  author bin;  state Exp;
        !          120456: branches ;
        !          120457: next     1.3;
        !          120458: 
        !          120459: 1.3
        !          120460: date     91.07.15.14.34.20;  author bin;  state Exp;
        !          120461: branches ;
        !          120462: next     1.2;
        !          120463: 
        !          120464: 1.2
        !          120465: date     91.06.20.14.31.54;  author bin;  state Exp;
        !          120466: branches ;
        !          120467: next     1.1;
        !          120468: 
        !          120469: 1.1
        !          120470: date     91.06.10.14.37.53;  author bin;  state Exp;
        !          120471: branches ;
        !          120472: next     ;
        !          120473: 
        !          120474: 
        !          120475: desc
        !          120476: @initial version prov by hal
        !          120477: @
        !          120478: 
        !          120479: 
        !          120480: 1.4
        !          120481: log
        !          120482: @update prov by hal
        !          120483: 
        !          120484: @
        !          120485: text
        !          120486: @/* $Header: /usr/src/sys/coh/RCS/sys3.c,v 1.3 89/02/07 18:50:27 src Exp $ */
        !          120487: /* (lgl-
        !          120488:  *     The information contained herein is a trade secret of Mark Williams
        !          120489:  *     Company, and  is confidential information.  It is provided  under a
        !          120490:  *     license agreement,  and may be  copied or disclosed  only under the
        !          120491:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          120492:  *     material without the express written authorization of Mark Williams
        !          120493:  *     Company or persuant to the license agreement is unlawful.
        !          120494:  *
        !          120495:  *     COHERENT Version 2.3.37
        !          120496:  *     Copyright (c) 1982, 1983, 1984.
        !          120497:  *     An unpublished work by Mark Williams Company, Chicago.
        !          120498:  *     All rights reserved.
        !          120499:  -lgl) */
        !          120500: /*
        !          120501:  * Coherent.
        !          120502:  * System calls (more filesystem related calls).
        !          120503:  *
        !          120504:  * $Log:       /usr/src/sys/coh/RCS/sys3.c,v $
        !          120505:  * Revision 1.3        89/02/07  18:50:27      src
        !          120506:  * Bug:        Console driver did not validate user addresses before initiating a
        !          120507:  *     transfer.  This resulted in a system trap in protected mode if a write
        !          120508:  *     outside of user data space was attempted.
        !          120509:  * Fix:        Reads and writes now validate user addresses via 'useracc' prior to
        !          120510:  *     calling drivers. (ABC)
        !          120511:  * 
        !          120512:  * Revision 1.2        88/08/02  15:01:04      src
        !          120513:  * O_APPEND flag now supported on open/fcntl system calls.
        !          120514:  * 
        !          120515:  * Revision 1.1        88/03/24  16:14:35      src
        !          120516:  * Initial revision
        !          120517:  * 
        !          120518:  * 88/01/22    Allan Cornish           /usr/src/sys/coh/sys3.c
        !          120519:  * sysio() inode lock extended to cover getting/modifying file seek offset.
        !          120520:  *
        !          120521:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/sys3.c
        !          120522:  * uopen() now checks mode for O_NDELAY and sets IPNDLY bit in fdp->f_flag.
        !          120523:  * sysio() now checks fdp->f_flag for IPNDLY and sets IONDLY bit in io_flag.
        !          120524:  */
        !          120525: #include <sys/coherent.h>
        !          120526: #include <sys/buf.h>
        !          120527: #include <errno.h>
        !          120528: #include <sys/fcntl.h>
        !          120529: #include <sys/fd.h>
        !          120530: #include <sys/filsys.h>
        !          120531: #include <sys/ino.h>
        !          120532: #include <sys/inode.h>
        !          120533: #include <sys/io.h>
        !          120534: #include <sys/mount.h>
        !          120535: #include <sys/stat.h>
        !          120536: #include <sys/uproc.h>
        !          120537: 
        !          120538: /*
        !          120539:  * Open the file `np' with the mode `mode'.
        !          120540:  */
        !          120541: uopen(np, mode)
        !          120542: char *np;
        !          120543: {
        !          120544:        register int f;
        !          120545:        register INODE *ip;
        !          120546:        register int fd;
        !          120547: 
        !          120548:        switch (mode & 3) {
        !          120549:        case O_RDONLY:
        !          120550:                f = IPR;
        !          120551:                break;
        !          120552:        case O_WRONLY:
        !          120553:                f = IPW;
        !          120554:                break;
        !          120555:        case O_RDWR:
        !          120556:                f = IPR|IPW;
        !          120557:                break;
        !          120558:        default:
        !          120559:                u.u_error = EINVAL;
        !          120560:                return;
        !          120561:        }
        !          120562:        if (ftoi(np, 'r') != 0)
        !          120563:                return;
        !          120564:        ip = u.u_cdiri;
        !          120565:        if (iaccess(ip, f) == 0) {
        !          120566:                idetach(ip);
        !          120567:                return;
        !          120568:        }
        !          120569:        if ( mode & O_NDELAY )
        !          120570:                f |= IPNDLY;
        !          120571:        if ( mode & O_APPEND )
        !          120572:                f |= IPAPPEND;
        !          120573:        if ((fd=fdopen(ip, f)) < 0) {
        !          120574:                idetach(ip);
        !          120575:                return;
        !          120576:        }
        !          120577:        iunlock(ip);
        !          120578:        return (fd);
        !          120579: }
        !          120580: 
        !          120581: /*
        !          120582:  * Create a pipe.
        !          120583:  */
        !          120584: upipe(fdp)
        !          120585: int fdp[2];
        !          120586: {
        !          120587:        register INODE *ip;
        !          120588:        register int fd1;
        !          120589:        register int fd2;
        !          120590: 
        !          120591:        if ((ip=pmake(0)) == NULL)
        !          120592:                return;
        !          120593:        if ((fd1=fdopen(ip, IPR)) >= 0) {
        !          120594:                ip->i_refc++;
        !          120595:                if ((fd2=fdopen(ip, IPW)) >= 0) {
        !          120596:                        putuwd(&fdp[0], fd1);
        !          120597:                        putuwd(&fdp[1], fd2);
        !          120598:                        iunlock(ip);
        !          120599:                        return (0);
        !          120600:                }
        !          120601:                --ip->i_refc;
        !          120602:                iunlock(ip);
        !          120603:                fdclose(fd1);
        !          120604:                return (0);
        !          120605:        }
        !          120606:        idetach(ip);
        !          120607:        return (0);
        !          120608: }
        !          120609: 
        !          120610: /*
        !          120611:  * Read `n' bytes into the buffer `bp' from file number `fd'.
        !          120612:  */
        !          120613: uread(fd, bp, n)
        !          120614: char *bp;
        !          120615: unsigned n;
        !          120616: {
        !          120617:        return (sysio(fd, bp, n, 0));
        !          120618: }
        !          120619: 
        !          120620: /*
        !          120621:  * Read or write `n' bytes from the file number `fd' using the buffer
        !          120622:  * `bp'.  If `f' is 0, we read, else write.
        !          120623:  */
        !          120624: sysio(fd, bp, n, f)
        !          120625: char *bp;
        !          120626: unsigned n;
        !          120627: {
        !          120628:        register FD *fdp;
        !          120629:        register INODE *ip;
        !          120630:        register int type;
        !          120631: 
        !          120632:        if ((fdp=fdget(fd)) == NULL)
        !          120633:                return (0);
        !          120634:        if ((fdp->f_flag&(f?IPW:IPR)) == 0) {
        !          120635:                u.u_error = EBADF;
        !          120636:                return (0);
        !          120637:        }
        !          120638:        if ( ! useracc( bp, n ) ) {
        !          120639:                u.u_error = EFAULT;
        !          120640:                return(0);
        !          120641:        }
        !          120642: 
        !          120643:        ip = fdp->f_ip;
        !          120644:        type = ip->i_mode&IFMT;
        !          120645:        if (type != IFCHR)
        !          120646:                ilock(ip);
        !          120647:        if ( fdp->f_flag & IPAPPEND )
        !          120648:                fdp->f_seek = ip->i_size;
        !          120649:        u.u_io.io_seek = fdp->f_seek;
        !          120650:        u.u_io.io_base = bp;
        !          120651:        u.u_io.io_ioc  = n;
        !          120652:        u.u_io.io_flag = (fdp->f_flag & IPNDLY) ? IONDLY : 0;
        !          120653:        if (f == 0) {
        !          120654:                iread(ip, &u.u_io);
        !          120655:                iacc(ip);               /* read - atime */
        !          120656:        } else {
        !          120657:                iwrite(ip, &u.u_io);
        !          120658:        }
        !          120659:        n -= u.u_io.io_ioc;
        !          120660:        fdp->f_seek += n;
        !          120661:        if (type != IFCHR)
        !          120662:                iunlock(ip);
        !          120663:        return (n);
        !          120664: }
        !          120665: 
        !          120666: /*
        !          120667:  * Return a status structure for the given file name.
        !          120668:  */
        !          120669: ustat(np, stp)
        !          120670: char *np;
        !          120671: struct stat *stp;
        !          120672: {
        !          120673:        register INODE *ip;
        !          120674:        struct stat stat;
        !          120675: 
        !          120676:        if (ftoi(np, 'r') != 0)
        !          120677:                return;
        !          120678:        ip = u.u_cdiri;
        !          120679:        istat(ip, &stat);
        !          120680:        idetach(ip);
        !          120681:        kucopy(&stat, stp, sizeof(stat));
        !          120682:        return (0);
        !          120683: }
        !          120684: 
        !          120685: /*
        !          120686:  * Write out all modified buffers, inodes and super blocks to disk.
        !          120687:  */
        !          120688: usync()
        !          120689: {
        !          120690:        register MOUNT *mp;
        !          120691:        static GATE syngate;
        !          120692: 
        !          120693:        lock(syngate);
        !          120694:        for (mp=mountp; mp!=NULL; mp=mp->m_next)
        !          120695:                msync(mp);
        !          120696:        bsync();
        !          120697:        unlock(syngate);
        !          120698:        return (0);
        !          120699: }
        !          120700: 
        !          120701: /*
        !          120702:  * Set the mask for file access.
        !          120703:  */
        !          120704: uumask(mask)
        !          120705: {
        !          120706:        register int omask;
        !          120707: 
        !          120708:        omask = u.u_umask;
        !          120709:        u.u_umask = mask & 0777;
        !          120710:        return (omask);
        !          120711: }
        !          120712: 
        !          120713: /*
        !          120714:  * Unmount the given device.
        !          120715:  */
        !          120716: uumount(sp)
        !          120717: char *sp;
        !          120718: {
        !          120719:        register INODE *ip;
        !          120720:        register MOUNT *mp;
        !          120721:        register MOUNT **mpp;
        !          120722:        register dev_t rdev;
        !          120723:        register int mode;
        !          120724: 
        !          120725:        if (ftoi(sp, 'r') != 0)
        !          120726:                return;
        !          120727:        ip = u.u_cdiri;
        !          120728:        if (iaccess(ip, IPR|IPW) == 0) {
        !          120729:                idetach(ip);
        !          120730:                return;
        !          120731:        }
        !          120732:        rdev = ip->i_a.i_rdev;
        !          120733:        mode = ip->i_mode;
        !          120734:        idetach(ip);
        !          120735:        if ((mode&IFMT) != IFBLK) {
        !          120736:                u.u_error = ENOTBLK;
        !          120737:                return;
        !          120738:        }
        !          120739:        for (mpp=&mountp; (mp=*mpp)!=NULL; mpp=&mp->m_next)
        !          120740:                if (mp->m_dev == rdev)
        !          120741:                        break;
        !          120742:        if (mp == NULL) {
        !          120743:                u.u_error = EINVAL;
        !          120744:                return;
        !          120745:        }
        !          120746:        msync(mp);
        !          120747:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          120748:                if (ip->i_refc>0 && ip->i_dev==rdev) {
        !          120749:                        u.u_error = EBUSY;
        !          120750:                        return;
        !          120751:                }
        !          120752:        }
        !          120753:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
        !          120754:                if (ip->i_dev == rdev)
        !          120755:                        ip->i_ino = 0;
        !          120756:        }
        !          120757:        bflush(rdev);
        !          120758:        dclose(rdev);
        !          120759:        *mpp = mp->m_next;
        !          120760:        mp->m_ip->i_flag &= ~IFMNT;
        !          120761:        ldetach(mp->m_ip);
        !          120762:        kfree(mp);
        !          120763:        return (0);
        !          120764: }
        !          120765: 
        !          120766: /*
        !          120767:  * Return an unique number.
        !          120768:  */
        !          120769: long
        !          120770: uunique()
        !          120771: {
        !          120772:        register MOUNT *mp;
        !          120773:        register struct filsys *fsp;
        !          120774: 
        !          120775:        if ((mp=getment(rootdev, 1)) == NULL)
        !          120776:                return;
        !          120777:        fsp = &mp->m_super;
        !          120778:        fsp->s_fmod = 1;
        !          120779:        return (++fsp->s_unique);
        !          120780: }
        !          120781: 
        !          120782: /*
        !          120783:  * Unlink the given file.
        !          120784:  */
        !          120785: uunlink(np)
        !          120786: char *np;
        !          120787: {
        !          120788:        register INODE *ip;
        !          120789:        register dev_t dev;
        !          120790: 
        !          120791:        if (ftoi(np, 'u') != 0)
        !          120792:                return;
        !          120793:        ip = u.u_pdiri;
        !          120794:        if (iaccess(ip, IPW) == 0) {
        !          120795:                u.u_error = EACCES;
        !          120796:                goto err;
        !          120797:        }
        !          120798:        dev = ip->i_dev;
        !          120799:        if (iucheck(dev, u.u_cdirn) == 0)
        !          120800:                goto err;
        !          120801:        idirent(0);
        !          120802:        idetach(ip);
        !          120803:        if ((ip=iattach(dev, u.u_cdirn)) == NULL)
        !          120804:                return;
        !          120805:        if (ip->i_nlink > 0)
        !          120806:                --ip->i_nlink;
        !          120807:        icrt(ip);       /* unlink - ctime */
        !          120808:        if ((ip->i_mode&IFMT)==IFPIPE && ip->i_nlink==0 && ip->i_refc==2)
        !          120809:                pevent(ip);
        !          120810: err:
        !          120811:        idetach(ip);
        !          120812:        return (0);
        !          120813: }
        !          120814: 
        !          120815: /*
        !          120816:  * Set file times.
        !          120817:  */
        !          120818: uutime(np, utime)
        !          120819: char *np;
        !          120820: time_t utime[2];
        !          120821: {
        !          120822:        register INODE *ip;
        !          120823:        time_t stime[2];
        !          120824: 
        !          120825:        if (ftoi(np, 'r') != 0)
        !          120826:                return;
        !          120827:        ip = u.u_cdiri;
        !          120828:        if (owner(ip->i_uid)) {
        !          120829:                iamc(ip);       /* utime - atime/mtime/ctime */
        !          120830:                if (utime != NULL) {
        !          120831:                        ukcopy(utime, stime, sizeof(time_t[2]));
        !          120832:                        ip->i_atime = stime[0];
        !          120833:                        ip->i_mtime = stime[1];
        !          120834:                }
        !          120835:        }
        !          120836:        idetach(ip);
        !          120837:        return (0);
        !          120838: }
        !          120839: 
        !          120840: /*
        !          120841:  * Write `n' bytes from buffer `bp' on file number `fd'.
        !          120842:  */
        !          120843: uwrite(fd, bp, n)
        !          120844: char *bp;
        !          120845: unsigned n;
        !          120846: {
        !          120847:        return (sysio(fd, bp, n, 1));
        !          120848: }
        !          120849: 
        !          120850: /**
        !          120851:  *
        !          120852:  * int
        !          120853:  * useracc( base, count, mode )        -- determine user accessibility
        !          120854:  * caddr_t base;
        !          120855:  * int count;
        !          120856:  * int mode;
        !          120857:  *
        !          120858:  *     Input:  base  = offset in user data space of the region to be accessed.
        !          120859:  *             count = size of access region in bytes.
        !          120860:  *             mode  = access mode desired [B_READ or B_WRITE].
        !          120861:  *
        !          120862:  *     Action: Verify user has desired access mode into specified region.
        !          120863:  *
        !          120864:  *     Return: 0 = permission denied.
        !          120865:  *             1 = access allowed.
        !          120866:  *
        !          120867:  *     Notes:  Mode is ignored for now, but is required for compatibility
        !          120868:  *             with System V, and future protected mode extensions.
        !          120869:  */
        !          120870: 
        !          120871: int
        !          120872: useracc( base, count, mode )
        !          120873: register char * base;
        !          120874: int count;
        !          120875: int mode;
        !          120876: {
        !          120877:        register char * end;
        !          120878:        extern char * udl;
        !          120879: 
        !          120880:        if ( (count == 0) && (base <= udl) )
        !          120881:                return( 1 );
        !          120882: 
        !          120883:        /*
        !          120884:         * Compute address of last byte to be accessed.
        !          120885:         */
        !          120886:        end = base + count - 1;
        !          120887: 
        !          120888:        /*
        !          120889:         * Address has wrapped, or is past legal limit.
        !          120890:         */
        !          120891:        if ( (end < base) || (end > udl) )
        !          120892:                return( 0 );
        !          120893: 
        !          120894:        return( 1 );
        !          120895: }
        !          120896: 
        !          120897: 
        !          120898: @
        !          120899: 
        !          120900: 
        !          120901: 1.3
        !          120902: log
        !          120903: @update by hal
        !          120904: @
        !          120905: text
        !          120906: @@
        !          120907: 
        !          120908: 
        !          120909: 1.2
        !          120910: log
        !          120911: @update provided by hal
        !          120912: @
        !          120913: text
        !          120914: @@
        !          120915: 
        !          120916: 
        !          120917: 1.1
        !          120918: log
        !          120919: @Initial revision
        !          120920: @
        !          120921: text
        !          120922: @d40 1
        !          120923: a40 1
        !          120924: #include <coherent.h>
        !          120925: @
        !          120926: 0707070064030031061004440000030000030000011777770507310737400005300000007567/newbits/kernel/USRSRC/coh/RCS/timeout.c,vhead     1.4;
        !          120927: branch   ;
        !          120928: access   ;
        !          120929: symbols  ;
        !          120930: locks    bin:1.4;
        !          120931: comment  @ * @;
        !          120932: 
        !          120933: 
        !          120934: 1.4
        !          120935: date     91.07.24.07.52.49;  author bin;  state Exp;
        !          120936: branches ;
        !          120937: next     1.3;
        !          120938: 
        !          120939: 1.3
        !          120940: date     91.07.15.14.34.29;  author bin;  state Exp;
        !          120941: branches ;
        !          120942: next     1.2;
        !          120943: 
        !          120944: 1.2
        !          120945: date     91.06.20.14.32.13;  author bin;  state Exp;
        !          120946: branches ;
        !          120947: next     1.1;
        !          120948: 
        !          120949: 1.1
        !          120950: date     91.06.10.14.37.55;  author bin;  state Exp;
        !          120951: branches ;
        !          120952: next     ;
        !          120953: 
        !          120954: 
        !          120955: desc
        !          120956: @initial version prov by hal
        !          120957: initial version prov by hal
        !          120958: @
        !          120959: 
        !          120960: 
        !          120961: 1.4
        !          120962: log
        !          120963: @update prov by hal
        !          120964: 
        !          120965: @
        !          120966: text
        !          120967: @/* $Header: /usr/src/sys/coh/RCS/timeout.c,v 1.2 89/08/01 13:56:42 src Exp $ */
        !          120968: /* (lgl-
        !          120969:  *     The information contained herein is a trade secret of Mark Williams
        !          120970:  *     Company, and  is confidential information.  It is provided  under a
        !          120971:  *     license agreement,  and may be  copied or disclosed  only under the
        !          120972:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          120973:  *     material without the express written authorization of Mark Williams
        !          120974:  *     Company or persuant to the license agreement is unlawful.
        !          120975:  *
        !          120976:  *     COHERENT Version 2.3.37
        !          120977:  *     Copyright (c) 1982, 1983, 1984.
        !          120978:  *     An unpublished work by Mark Williams Company, Chicago.
        !          120979:  *     All rights reserved.
        !          120980:  -lgl) */
        !          120981: /*
        !          120982:  * Coherent.
        !          120983:  * Timeout management.
        !          120984:  *
        !          120985:  * $Log:       /usr/src/sys/coh/RCS/timeout.c,v $
        !          120986:  * Revision 1.2        89/08/01  13:56:42      src
        !          120987:  * Bug:        #include <timeout.h> not accurate; timeout.h now in /usr/include/sys.
        !          120988:  * Fix:        #include <sys/timeout.h> now used. (ABC)
        !          120989:  * 
        !          120990:  * Revision 1.1        88/03/24  08:14:38      src
        !          120991:  * Initial revision
        !          120992:  * 
        !          120993:  * 87/07/23    Allan Cornish           /usr/src/sys/coh/timeout.c
        !          120994:  * Timeout2 function now cancels timer if delay value is 0.
        !          120995:  *
        !          120996:  * 87/07/08    Allan Cornish           /usr/src/sys/coh/timeout.c
        !          120997:  * Timeout2 function added to support long timeouts.
        !          120998:  *
        !          120999:  * 87/07/07    Allan Cornish           /usr/src/sys/coh/timeout.c
        !          121000:  * Support for multiple timing queues ported from RTX.
        !          121001:  *
        !          121002:  * 86/11/24    Allan Cornish           /usr/src/sys/coh/timeout.c
        !          121003:  * Added support for new t_last field in tim struct.
        !          121004:  */
        !          121005: #include <sys/coherent.h>
        !          121006: #include <sys/timeout.h>
        !          121007: #include <sys/fun.h>
        !          121008: 
        !          121009: /*
        !          121010:  * Given a pointer to a timeout structure, `tp', call the function `f'
        !          121011:  * with integer argument `a' in `n' ticks of the clock. The list is
        !          121012:  * searched to see if the specified timeout structure is already in a
        !          121013:  * list, and it is removed if already there.
        !          121014:  */
        !          121015: timeout(tp, n, f, a)
        !          121016: register TIM *tp;
        !          121017: unsigned n;
        !          121018: int (*f)();
        !          121019: char *a;
        !          121020: {
        !          121021:        register TIM ** qp;
        !          121022:        int s;
        !          121023: 
        !          121024:        /*
        !          121025:         * Already on a timing queue.
        !          121026:         */
        !          121027:        s = sphi();
        !          121028:        if ( qp = tp->t_last ) {
        !          121029:                tp->t_last = NULL;
        !          121030:                if ( *qp = tp->t_next )
        !          121031:                        tp->t_next->t_last = qp;
        !          121032:        }
        !          121033:        spl( s );
        !          121034: 
        !          121035:        if ( f == NULL )
        !          121036:                return;
        !          121037: 
        !          121038:        /*
        !          121039:         * Calculate clock tick at which timeout is to occur.
        !          121040:         * Record function and argument to be invoked upon timeout.
        !          121041:         */
        !          121042:        tp->t_lbolt = lbolt + n;
        !          121043:        tp->t_func  = f;
        !          121044:        tp->t_farg  = a;
        !          121045: 
        !          121046:        /*
        !          121047:         * Identify timeout queue.
        !          121048:         */
        !          121049:        qp = &timq[ tp->t_lbolt % nel(timq) ];
        !          121050: 
        !          121051:        /*
        !          121052:         * Insert at head of timeout queue.
        !          121053:         */
        !          121054:        s = sphi();
        !          121055:        if ( tp->t_next = *qp )
        !          121056:                tp->t_next->t_last = tp;
        !          121057:        tp->t_last = qp;
        !          121058:        *qp = tp;
        !          121059:        spl(s);
        !          121060: }
        !          121061: 
        !          121062: timeout2(tp, n, f, a)
        !          121063: register TIM *tp;
        !          121064: long n;
        !          121065: int (*f)();
        !          121066: char *a;
        !          121067: {
        !          121068:        register TIM ** qp;
        !          121069:        int s;
        !          121070: 
        !          121071:        /*
        !          121072:         * Already on a timing queue.
        !          121073:         */
        !          121074:        s = sphi();
        !          121075:        if ( qp = tp->t_last ) {
        !          121076:                tp->t_last = NULL;
        !          121077:                if ( *qp = tp->t_next )
        !          121078:                        tp->t_next->t_last = qp;
        !          121079:        }
        !          121080:        spl( s );
        !          121081: 
        !          121082:        /*
        !          121083:         * Do not schedule new timer if no function or delay interval.
        !          121084:         */
        !          121085:        if ( (f == NULL) || (n == 0) )
        !          121086:                return;
        !          121087: 
        !          121088:        /*
        !          121089:         * Calculate clock tick at which timeout is to occur.
        !          121090:         * Record function and argument to be invoked upon timeout.
        !          121091:         */
        !          121092:        tp->t_lbolt = lbolt + n;
        !          121093:        tp->t_func  = f;
        !          121094:        tp->t_farg  = a;
        !          121095: 
        !          121096:        /*
        !          121097:         * Identify timeout queue.
        !          121098:         */
        !          121099:        qp = &timq[ tp->t_lbolt % nel(timq) ];
        !          121100: 
        !          121101:        /*
        !          121102:         * Insert at head of timeout queue.
        !          121103:         */
        !          121104:        s = sphi();
        !          121105:        if ( tp->t_next = *qp )
        !          121106:                tp->t_next->t_last = tp;
        !          121107:        tp->t_last = qp;
        !          121108:        *qp = tp;
        !          121109:        spl(s);
        !          121110: }
        !          121111: @
        !          121112: 
        !          121113: 
        !          121114: 1.3
        !          121115: log
        !          121116: @update by hal
        !          121117: @
        !          121118: text
        !          121119: @@
        !          121120: 
        !          121121: 
        !          121122: 1.2
        !          121123: log
        !          121124: @update provided by hal
        !          121125: @
        !          121126: text
        !          121127: @@
        !          121128: 
        !          121129: 
        !          121130: 1.1
        !          121131: log
        !          121132: @Initial revision
        !          121133: @
        !          121134: text
        !          121135: @d39 1
        !          121136: a39 1
        !          121137: #include <coherent.h>
        !          121138: @
        !          121139: 0707070064030056261004440000030000030000011777770507310737500004700000010734/newbits/kernel/USRSRC/coh/RCS/var.c,vhead     1.4;
        !          121140: branch   ;
        !          121141: access   ;
        !          121142: symbols  ;
        !          121143: locks    bin:1.4;
        !          121144: comment  @ * @;
        !          121145: 
        !          121146: 
        !          121147: 1.4
        !          121148: date     91.07.24.07.52.52;  author bin;  state Exp;
        !          121149: branches ;
        !          121150: next     1.3;
        !          121151: 
        !          121152: 1.3
        !          121153: date     91.07.15.14.34.33;  author bin;  state Exp;
        !          121154: branches ;
        !          121155: next     1.2;
        !          121156: 
        !          121157: 1.2
        !          121158: date     91.06.20.14.32.17;  author bin;  state Exp;
        !          121159: branches ;
        !          121160: next     1.1;
        !          121161: 
        !          121162: 1.1
        !          121163: date     91.06.10.14.37.59;  author bin;  state Exp;
        !          121164: branches ;
        !          121165: next     ;
        !          121166: 
        !          121167: 
        !          121168: desc
        !          121169: @initial version prov by hal
        !          121170: @
        !          121171: 
        !          121172: 
        !          121173: 1.4
        !          121174: log
        !          121175: @update prov by hal
        !          121176: 
        !          121177: @
        !          121178: text
        !          121179: @/* $Header: /usr/src/sys/coh/RCS/var.c,v 1.2 89/08/01 13:57:35 src Exp $ */
        !          121180: /* (lgl-
        !          121181:  *     The information contained herein is a trade secret of Mark Williams
        !          121182:  *     Company, and  is confidential information.  It is provided  under a
        !          121183:  *     license agreement,  and may be  copied or disclosed  only under the
        !          121184:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          121185:  *     material without the express written authorization of Mark Williams
        !          121186:  *     Company or persuant to the license agreement is unlawful.
        !          121187:  *
        !          121188:  *     COHERENT Version 2.3.37
        !          121189:  *     Copyright (c) 1982, 1983, 1984.
        !          121190:  *     An unpublished work by Mark Williams Company, Chicago.
        !          121191:  *     All rights reserved.
        !          121192:  -lgl) */
        !          121193: /*
        !          121194:  * Coherent.
        !          121195:  * Variables.
        !          121196:  *
        !          121197:  * $Log:       /usr/src/sys/coh/RCS/var.c,v $
        !          121198:  * Revision 1.2        89/08/01  13:57:35      src
        !          121199:  * Bug:        #include <timeout.h> not accurate; timeout.h now in /usr/include/sys.
        !          121200:  * Fix:        #include <sys/timeout.h> now used. (ABC)
        !          121201:  * 
        !          121202:  * Revision 1.1        88/03/24  08:14:41      src
        !          121203:  * Initial revision
        !          121204:  * 
        !          121205:  * 88/01/23    Allan Cornish           /usr/src/sys/coh/var.c
        !          121206:  * Default NSLOT increased from 10 to 64.
        !          121207:  *
        !          121208:  * 87/11/22    Allan Cornish           /usr/src/sys/coh/var.c
        !          121209:  * Holebot/holetop variables added to support extended memory.
        !          121210:  *
        !          121211:  * 87/11/14    Allan Cornish           /usr/src/sys/coh/var.c
        !          121212:  * Init code+data now split into icodep/icodes and idatap/idatas.
        !          121213:  *
        !          121214:  * 87/11/12    Allan Cornish           /usr/src/sys/coh/var.c
        !          121215:  * Corebot/coretop now paddr_t rather than saddr_t to support protected mode.
        !          121216:  *
        !          121217:  * 87/10/05    Allan Cornish           /usrs/rc/sys/coh/var.c
        !          121218:  * NSLOT, slotsz, and slotp variables added - loadable driver specific.
        !          121219:  *
        !          121220:  * 87/07/07    Allan Cornish           /usr/src/sys/coh/var.c
        !          121221:  * Lbolt variable added - clock ticks since startup - incremented by stand().
        !          121222:  * Timl variable replaced with timq variable.
        !          121223:  *
        !          121224:  * 87/02/01    Allan Cornish           /usr/src/sys/coh/var.c
        !          121225:  * ISTSIZE [stack size] changed from a define in /usr/include/sys/const.h to a
        !          121226:  * extern int in /usr/include/sys/param.h, with 4 Kbyte default set in var.c
        !          121227:  */
        !          121228: #include <sys/coherent.h>
        !          121229: #include <sys/buf.h>
        !          121230: #include <sys/con.h>
        !          121231: #include <sys/inode.h>
        !          121232: #include <sys/mount.h>
        !          121233: #include <sys/proc.h>
        !          121234: #include <sys/ptrace.h>
        !          121235: #include <sys/seg.h>
        !          121236: 
        !          121237: int     debflag = 0;                   /* coherent.h */
        !          121238: 
        !          121239: int     batflag;                       /* coherent.h */
        !          121240: int     outflag;                       /* coherent.h */
        !          121241: int     ttyflag;                       /* coherent.h */
        !          121242: unsigned utimer;                       /* coherent.h */
        !          121243: long    lbolt;                         /* coherent.h */
        !          121244: TIM    stimer;                         /* coherent.h */
        !          121245: unsigned msize;                                /* coherent.h */
        !          121246: unsigned asize;                                /* coherent.h */
        !          121247: char    *icodep;                       /* coherent.h */
        !          121248: int     icodes;                        /* coherent.h */
        !          121249: char    *idatap;                       /* coherent.h */
        !          121250: int     idatas;                        /* coherent.h */
        !          121251: paddr_t         corebot;                       /* coherent.h */
        !          121252: paddr_t         coretop;                       /* coherent.h */
        !          121253: paddr_t         holebot;                       /* coherent.h */
        !          121254: paddr_t         holetop;                       /* coherent.h */
        !          121255: paddr_t         blockp;                        /* coherent.h */
        !          121256: paddr_t         clistp;                        /* coherent.h */
        !          121257: struct  all *allkp;                    /* coherent.h */
        !          121258: int    NSLOT   = 64;                   /* coherent.h */
        !          121259: int    slotsz  = 64;                   /* coherent.h */
        !          121260: int *  slotp;                          /* coherent.h */
        !          121261: 
        !          121262: unsigned bufseqn;                      /* buf.h */
        !          121263: int     bufneed;                       /* buf.h */
        !          121264: BUF     swapbuf;                       /* buf.h */
        !          121265: BUF    *bufl;                          /* buf.h */
        !          121266: 
        !          121267: int    cltwant;                        /* clist.h */
        !          121268: cmap_t cltfree;                        /* clist.h */
        !          121269: 
        !          121270: INODE  *inodep;                        /* inode.h */
        !          121271: INODE  *acctip;                        /* inode.h */
        !          121272: 
        !          121273: MOUNT  *mountp;                        /* mount.h */
        !          121274: 
        !          121275: int    ISTSIZE = 4096;                 /* sys/param.h */
        !          121276: 
        !          121277: int    quantum;                        /* proc.h */
        !          121278: int    disflag;                        /* proc.h */
        !          121279: int    intflag;                        /* proc.h */
        !          121280: int    cpid;                           /* proc.h */
        !          121281: #ifdef QWAKEUP
        !          121282: int    ntowake;                        /* proc.h */
        !          121283: #endif
        !          121284: GATE   pnxgate;                        /* proc.h */
        !          121285: PROC   procq;                          /* proc.h */
        !          121286: PROC   *iprocp;                        /* proc.h */
        !          121287: PROC   *eprocp;                        /* proc.h */
        !          121288: PROC   *cprocp;                        /* proc.h */
        !          121289: PLINK  linkq[NHPLINK];                 /* proc.h */
        !          121290: 
        !          121291: struct ptrace pts;                     /* ptrace.h */
        !          121292: 
        !          121293: int    sexflag;                        /* seg.h */
        !          121294: GATE   seglink;                        /* seg.h */
        !          121295: #ifndef NOMONITOR
        !          121296: int    swmflag;                        /* seg.h */
        !          121297: #endif
        !          121298: SEG    segswap;                        /* seg.h */
        !          121299: SEG    segmq;                          /* seg.h */
        !          121300: SEG    segdq;                          /* seg.h */
        !          121301: SEG    segiom;                         /* seg.h */
        !          121302: 
        !          121303: TIM *  timq[256];                      /* timeout.h */
        !          121304: @
        !          121305: 
        !          121306: 
        !          121307: 1.3
        !          121308: log
        !          121309: @update by hal
        !          121310: @
        !          121311: text
        !          121312: @@
        !          121313: 
        !          121314: 
        !          121315: 1.2
        !          121316: log
        !          121317: @update provided by hal
        !          121318: @
        !          121319: text
        !          121320: @@
        !          121321: 
        !          121322: 
        !          121323: 1.1
        !          121324: log
        !          121325: @Initial revision
        !          121326: @
        !          121327: text
        !          121328: @d50 1
        !          121329: a50 1
        !          121330: #include <coherent.h>
        !          121331: d56 1
        !          121332: a56 1
        !          121333: #include <ptrace.h>
        !          121334: a57 1
        !          121335: #include <sys/timeout.h>
        !          121336: @
        !          121337: 0707070064030103110407550000030000030000011777770507310737600003600000000000/newbits/kernel/USRSRC/ttydrv0707070064030103131004440000030000030000011777770507310737600004300000004203/newbits/kernel/USRSRC/ttydrv/ct.c/* $Header: /usr/src/sys/drv/RCS/ct.c,v 1.1 88/03/24 16:18:09 src Exp $ */
        !          121338: /* (lgl-
        !          121339:  *     The information contained herein is a trade secret of Mark Williams
        !          121340:  *     Company, and  is confidential information.  It is provided  under a
        !          121341:  *     license agreement,  and may be  copied or disclosed  only under the
        !          121342:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          121343:  *     material without the express written authorization of Mark Williams
        !          121344:  *     Company or persuant to the license agreement is unlawful.
        !          121345:  *
        !          121346:  *     COHERENT Version 2.3.37
        !          121347:  *     Copyright (c) 1982, 1983, 1984.
        !          121348:  *     An unpublished work by Mark Williams Company, Chicago.
        !          121349:  *     All rights reserved.
        !          121350:  -lgl) */
        !          121351: /*
        !          121352:  * Coherent
        !          121353:  * Console terminal driver.
        !          121354:  *
        !          121355:  * $Log:       /usr/src/sys/drv/RCS/ct.c,v $
        !          121356:  * Revision 1.1        88/03/24  16:18:09      src
        !          121357:  * Initial revision
        !          121358:  * 
        !          121359:  * 86/11/19    Allan Cornish           /usr/src/sys/drv/ct.c
        !          121360:  * Added support for System V.3 compatible polls.
        !          121361:  */
        !          121362: #include <sys/coherent.h>
        !          121363: #include <sys/con.h>
        !          121364: #include <errno.h>
        !          121365: #include <sys/proc.h>
        !          121366: #include <sys/stat.h>
        !          121367: #include <sys/uproc.h>
        !          121368: 
        !          121369: /*
        !          121370:  * Functions for configuration.
        !          121371:  */
        !          121372: int    ctopen();
        !          121373: int    ctclose();
        !          121374: int    ctread();
        !          121375: int    ctwrite();
        !          121376: int    ctioctl();
        !          121377: int    ctpoll();
        !          121378: int    nulldev();
        !          121379: int    nonedev();
        !          121380: 
        !          121381: /*
        !          121382:  * Configuration table.
        !          121383:  */
        !          121384: CON ctcon ={
        !          121385:        DFCHR|DFPOL,                    /* Flags */
        !          121386:        1,                              /* Major index */
        !          121387:        ctopen,                         /* Open */
        !          121388:        ctclose,                        /* Close */
        !          121389:        nulldev,                        /* Block */
        !          121390:        ctread,                         /* Read */
        !          121391:        ctwrite,                        /* Write */
        !          121392:        ctioctl,                        /* Ioctl */
        !          121393:        nulldev,                        /* Powerfail */
        !          121394:        nulldev,                        /* Timeout */
        !          121395:        nulldev,                        /* Load */
        !          121396:        nulldev,                        /* Unload */
        !          121397:        ctpoll                          /* Poll */
        !          121398: };
        !          121399: 
        !          121400: /*
        !          121401:  * Open.
        !          121402:  */
        !          121403: ctopen(dev, m)
        !          121404: dev_t dev;
        !          121405: {
        !          121406:        register dev_t ttdev;
        !          121407: 
        !          121408:        if ((ttdev=SELF->p_ttdev) == NODEV) {
        !          121409:                u.u_error = ENXIO;
        !          121410:                return;
        !          121411:        }
        !          121412:        dopen(ttdev, m, DFCHR);
        !          121413: }
        !          121414: 
        !          121415: /*
        !          121416:  * Close.
        !          121417:  */
        !          121418: ctclose(dev)
        !          121419: dev_t dev;
        !          121420: {
        !          121421:        dclose(SELF->p_ttdev);
        !          121422: }
        !          121423: 
        !          121424: /*
        !          121425:  * Read.
        !          121426:  */
        !          121427: ctread(dev, iop)
        !          121428: dev_t dev;
        !          121429: IO *iop;
        !          121430: {
        !          121431:        dread(SELF->p_ttdev, iop);
        !          121432: }
        !          121433: 
        !          121434: /*
        !          121435:  * Write.
        !          121436:  */
        !          121437: ctwrite(dev, iop)
        !          121438: dev_t dev;
        !          121439: IO *iop;
        !          121440: {
        !          121441:        dwrite(SELF->p_ttdev, iop);
        !          121442: }
        !          121443: 
        !          121444: /*
        !          121445:  * Ioctl.
        !          121446:  */
        !          121447: ctioctl(dev, com, vec)
        !          121448: dev_t dev;
        !          121449: struct sgttyb *vec;
        !          121450: {
        !          121451:        dioctl(SELF->p_ttdev, com, vec);
        !          121452: }
        !          121453: 
        !          121454: /*
        !          121455:  * Poll.
        !          121456:  */
        !          121457: ctpoll(dev, ev)
        !          121458: dev_t dev;
        !          121459: int ev;
        !          121460: {
        !          121461:        return dpoll(SELF->p_ttdev, ev);
        !          121462: }
        !          121463: 0707070064030066271006440000030000030000011777770507310737700004400000042737/newbits/kernel/USRSRC/ttydrv/tty.c/*
        !          121464:  * File:       $USRSRC/ttydrv/tty.c
        !          121465:  *
        !          121466:  * Purpose:    COHERENT line discipline module.
        !          121467:  *     This is the common part of typewriter service. It handles all device-
        !          121468:  *     independent aspects of a typewriter, including tandem flow control,
        !          121469:  *     erase and kill, stop and start, and common ioctl functions.
        !          121470:  *
        !          121471:  * $Log:       tty.c,v $
        !          121472:  * Revision 1.9  91/09/17  06:06:42  bin
        !          121473:  * updated by hal
        !          121474:  * 
        !          121475:  * Revision 1.8  91/09/13  18:01:39  piggy
        !          121476:  * Only do XON/XOFF flow control if TANDEM is set.
        !          121477:  * 
        !          121478:  * Revision 1.7  91/09/13  17:58:00  hal
        !          121479:  * Drop 3rd arg (was writing PSW directly from it!) for ttread/ttwrite.
        !          121480:  * General face lift.
        !          121481:  *
        !          121482:  *
        !          121483:  * Bug: no support for 8-bit characters.
        !          121484:  * Fix: don't strip keyboard input. 01/22/91.  (norm)
        !          121485:  *
        !          121486:  * Bug:        Switching modes between cooked and CBREAK/RAW left buffered input
        !          121487:  *     in the input buffer until returning to cooked mode. 05/13/91 norm
        !          121488:  *
        !          121489:  * Bug: setting speed to default in ttopen() was conditioned to
        !          121490:  *      use hard constants.  90/08/28.  hws
        !          121491:  *
        !          121492:  * Revision 1.5  91/06/06  18:28:53  norm
        !          121493:  * Restore 8-bit fix.
        !          121494:  *
        !          121495:  * Revision 1.2        89/07/17  11:51:20      src
        !          121496:  * Bug:        Terminal could lock up when setting it to RAWIN mode, if
        !          121497:  *     output was suspended due to X-OFF, and output data was present.
        !          121498:  * Fix:        Setting terminal to RAWIN mode now clears X-OFF, starts output
        !          121499:  *     BEFORE waiting for output to drain.  Received signals now cause
        !          121500:  *     operation to complete without waiting for drain. (ABC)
        !          121501:  *
        !          121502:  * Revision 1.1        88/03/24  16:18:12      src
        !          121503:  * Initial revision
        !          121504:  *
        !          121505:  * 86/12/12    Allan Cornish           /usr/src/sys/drv/tty.c
        !          121506:  * Added 3rd argument to ttpoll() to support non-blocking polls.
        !          121507:  *
        !          121508:  * 86/11/19    Allan Cornish           /usr/src/sys/drv/tty.c
        !          121509:  * Made ttread() and ttwrite() recognize the IONDLY flag in iop->io_flag.
        !          121510:  * wakeup() and pollwake() now have delayed invocation by defer().
        !          121511:  * Added poll [System V.3] capability.
        !          121512:  *
        !          121513:  * 85/06/28    Allan Cornish
        !          121514:  * made ttioctl() clear T_STOP flag if ISRIN.
        !          121515:  *
        !          121516:  * 85/03/04    Allan Cornish
        !          121517:  * made ttread()  interruptible.
        !          121518:  *
        !          121519:  * 85/03/01    Allan Cornish
        !          121520:  * made ttclose() interruptible.
        !          121521:  */
        !          121522: 
        !          121523: /*
        !          121524:  * Includes.
        !          121525:  */
        !          121526: #include <sys/clist.h>
        !          121527: #include <sys/coherent.h>
        !          121528: #include <sys/con.h>
        !          121529: #include <sys/deftty.h>
        !          121530: #include <sys/io.h>
        !          121531: #include <sys/proc.h>
        !          121532: #include <sys/sched.h>
        !          121533: #include <sys/stat.h>
        !          121534: #include <sys/tty.h>
        !          121535: #include <sys/uproc.h>
        !          121536: #include <errno.h>
        !          121537: 
        !          121538: /*
        !          121539:  * Definitions.
        !          121540:  *     Constants.
        !          121541:  *     Macros with argument lists.
        !          121542:  *     Typedefs.
        !          121543:  *     Enums.
        !          121544:  */
        !          121545: 
        !          121546: /* NEAR_OR_FAR_CALL is for invoking t_param and t_start */
        !          121547: #define         NEAR_OR_FAR_CALL(tp_fn)  {\
        !          121548:        if (tp->t_cs_sel) \
        !          121549:                ld_call(tp->t_cs_sel, tp->tp_fn, tp); \
        !          121550:        else \
        !          121551:                (*tp->tp_fn)(tp); }
        !          121552: 
        !          121553: /*
        !          121554:  * Functions.
        !          121555:  *     Import Functions.
        !          121556:  *     Export Functions.
        !          121557:  *     Local Functions.
        !          121558:  */
        !          121559: void ttclose();
        !          121560: void ttflush();
        !          121561: void tthup();
        !          121562: void ttin();
        !          121563: void ttioctl();
        !          121564: void ttopen();
        !          121565: int  ttout();
        !          121566: int  ttpoll();
        !          121567: void ttread();
        !          121568: void ttsetgrp();
        !          121569: void ttsignal();
        !          121570: void ttstart();
        !          121571: void ttstash();
        !          121572: void ttwrite();
        !          121573: 
        !          121574: /*
        !          121575:  * Global Data.
        !          121576:  *     Import Variables.
        !          121577:  *     Export Variables.
        !          121578:  *     Local Variables.
        !          121579:  */
        !          121580: extern int     wakeup();
        !          121581: extern void    pollwake();
        !          121582: 
        !          121583: /*
        !          121584:  * ttopen()
        !          121585:  *
        !          121586:  *     Called by driver on first open.
        !          121587:  *     Set up defaults.
        !          121588:  */
        !          121589: void ttopen(tp)
        !          121590: register TTY *tp;
        !          121591: {
        !          121592:        tp->t_escape = 0;
        !          121593:        tp->t_sgttyb.sg_ispeed = tp->t_dispeed;
        !          121594:        tp->t_sgttyb.sg_ospeed = tp->t_dospeed;
        !          121595:        tp->t_sgttyb.sg_erase  = DEF_SG_ERASE;
        !          121596:        tp->t_sgttyb.sg_kill   = DEF_SG_KILL;
        !          121597:        tp->t_sgttyb.sg_flags  = DEF_SG_FLAGS;
        !          121598:        tp->t_tchars.t_intrc   = DEF_T_INTRC;
        !          121599:        tp->t_tchars.t_quitc   = DEF_T_QUITC;
        !          121600:        tp->t_tchars.t_startc  = DEF_T_STARTC;
        !          121601:        tp->t_tchars.t_stopc   = DEF_T_STOPC;
        !          121602:        tp->t_tchars.t_eofc    = DEF_T_EOFC;
        !          121603:        tp->t_tchars.t_brkc    = DEF_T_BRKC;
        !          121604:        if (tp->t_param != NULL) {
        !          121605:                NEAR_OR_FAR_CALL(t_param)
        !          121606:        }
        !          121607: }
        !          121608: 
        !          121609: /*
        !          121610:  * ttsetgrp()
        !          121611:  *
        !          121612:  *     Set process group when process does not have one.
        !          121613:  *     Also set up process's controlling terminal.
        !          121614:  */
        !          121615: void ttsetgrp(tp, ctdev)
        !          121616: register TTY *tp;
        !          121617: dev_t ctdev;
        !          121618: {
        !          121619:        register PROC *pp;
        !          121620: 
        !          121621:        pp = SELF;
        !          121622:        if (pp->p_group == 0) {
        !          121623:                if (tp->t_group == 0)
        !          121624:                        tp->t_group = pp->p_pid;
        !          121625:                pp->p_group = tp->t_group;
        !          121626:        }
        !          121627:        if (pp->p_ttdev == NODEV)
        !          121628:                pp->p_ttdev = ctdev;
        !          121629: }
        !          121630: 
        !          121631: /*
        !          121632:  * ttyclose()
        !          121633:  *
        !          121634:  *     Called by driver on the last close.
        !          121635:  *     Wait for all pending output to go out.
        !          121636:  *     Kill input.
        !          121637:  */
        !          121638: void ttclose(tp)
        !          121639: register TTY *tp;
        !          121640: {
        !          121641:        register int s;
        !          121642: 
        !          121643:        while (tp->t_oq.cq_cc != 0) {
        !          121644:                s = sphi();
        !          121645:                if (tp->t_oq.cq_cc != 0) {
        !          121646:                        tp->t_flags |= T_DRAIN;
        !          121647:                        sleep((char *)&tp->t_oq, CVTTOUT, IVTTOUT, SVTTOUT);
        !          121648:                }
        !          121649:                spl(s);
        !          121650:                if (SELF->p_ssig && nondsig())
        !          121651:                        break;
        !          121652:        }
        !          121653:        ttflush(tp);
        !          121654:        tp->t_flags = tp->t_group = 0;
        !          121655: }
        !          121656: 
        !          121657: /*
        !          121658:  * ttread()
        !          121659:  *
        !          121660:  *     The read routine for a tty device driver will call this function.
        !          121661:  *
        !          121662:  *     Move data from tp->t_iq to io segment iop.
        !          121663:  *     Number of characters to copy is in iop->ioc.
        !          121664:  *
        !          121665:  *     In cooked mode, copy up to the first newline or break character, or
        !          121666:  *     until the count runs out.
        !          121667:  *     In CBREAK or RAW modes, return when count runs out or when input clist
        !          121668:  *     is empty and we're returning at least one byte.
        !          121669:  */
        !          121670: void ttread(tp, iop)
        !          121671: register TTY *tp;
        !          121672: register IO *iop;
        !          121673: {
        !          121674:        register c;
        !          121675:        int o;
        !          121676:        int sioc = iop->io_ioc;  /* number of bytes to read */
        !          121677: 
        !          121678:        while (iop->io_ioc) {
        !          121679:                o = sphi();
        !          121680:                while ((c = getq(&tp->t_iq)) < 0) {
        !          121681:                        if ((tp->t_flags & T_CARR) == 0) {
        !          121682:                           u.u_error = EIO;  /* error since no carrier */
        !          121683:                           spl(o);
        !          121684:                           return;
        !          121685:                        }
        !          121686: 
        !          121687:                        /* If we're in CBREAK or RAW mode, and we don't */
        !          121688:                        /* have the special "blocking read" bit set for */
        !          121689:                        /* these modes, and we read at least one byte   */
        !          121690:                        /* of input, return immediately, since we have  */
        !          121691:                        /* run out of characters from the clist.        */
        !          121692: 
        !          121693:                        if (ISBBYB && ((tp->t_flags & T_BRD) == 0)
        !          121694:                           && iop->io_ioc < sioc) {
        !          121695:                           spl(o);
        !          121696:                           return;
        !          121697:                        }
        !          121698: 
        !          121699:                        /*
        !          121700:                         * Non-blocking reads.
        !          121701:                         * Tell user process to try again later.
        !          121702:                         */
        !          121703:                        if ( iop->io_flag & IONDLY ) {
        !          121704:                                u.u_error = EAGAIN;
        !          121705:                                spl(o);
        !          121706:                                return;
        !          121707:                        }
        !          121708: 
        !          121709:                        tp->t_flags |= T_INPUT;  /* wait for more data */
        !          121710:                        sleep((char *)&tp->t_iq, CVTTIN, IVTTIN, SVTTIN);
        !          121711: 
        !          121712:                        if (SELF->p_ssig && nondsig()) {
        !          121713:                                if (iop->io_ioc == sioc)
        !          121714:                                        u.u_error = EINTR;
        !          121715:                                spl(o);
        !          121716:                                return;
        !          121717:                        }
        !          121718:                }
        !          121719:                /*
        !          121720:                 * Flow control - can we turn on input from the driver yet?
        !          121721:                 */
        !          121722:                if (tp->t_iq.cq_cc <= ILOLIM) {
        !          121723:                        if ((tp->t_flags&T_ISTOP) != 0)
        !          121724:                                tp->t_flags &= ~T_ISTOP;
        !          121725:                        if ((tp->t_flags&T_TSTOP) != 0) {
        !          121726:                                tp->t_flags &= ~T_TSTOP;
        !          121727:                                while (putq(&tp->t_oq, startc) < 0) {
        !          121728:                                        ttstart(tp);
        !          121729:                                        waitq();
        !          121730:                                }
        !          121731:                                ttstart(tp);
        !          121732:                        }
        !          121733:                }
        !          121734:                spl(o);
        !          121735:                if (!ISBBYB && ISEOF)
        !          121736:                        return;
        !          121737:                if (ioputc(c, iop) < 0)
        !          121738:                        return;
        !          121739:                if (!ISBBYB && (c=='\n' || ISBRK))
        !          121740:                        return;
        !          121741:        }
        !          121742: }
        !          121743: 
        !          121744: /*
        !          121745:  * ttwrite()
        !          121746:  *
        !          121747:  *     Write routine.
        !          121748:  *     Transfer stuff to the character list.
        !          121749:  */
        !          121750: void ttwrite(tp, iop)
        !          121751: register TTY *tp;
        !          121752: register IO *iop;
        !          121753: {
        !          121754:        register c;
        !          121755:        int o;
        !          121756: 
        !          121757:        /*
        !          121758:         * Non-blocking writes which can fit.
        !          121759:         * NOTE: exhaustion of clists can still cause blocking writes.
        !          121760:         */
        !          121761:        if ( (iop->io_flag & IONDLY) && (OHILIM >= iop->io_ioc) ) {
        !          121762: 
        !          121763:                /*
        !          121764:                 * No room.
        !          121765:                 */
        !          121766:                if ( tp->t_oq.cq_cc >= OHILIM-iop->io_ioc ) {
        !          121767:                        u.u_error = EAGAIN;
        !          121768:                        return;
        !          121769:                }
        !          121770:        }
        !          121771: 
        !          121772:        while ((c = iogetc(iop)) >= 0) {
        !          121773:                if ((tp->t_flags & T_CARR) == 0) {
        !          121774:                        u.u_error = EIO;  /* error since no carrier */
        !          121775:                        return;
        !          121776:                }
        !          121777:                o = sphi();
        !          121778:                while (tp->t_oq.cq_cc >= OHILIM) {
        !          121779:                        ttstart(tp);
        !          121780:                        if (tp->t_oq.cq_cc < OHILIM)
        !          121781:                                break;
        !          121782:                        tp->t_flags |= T_HILIM;
        !          121783:                        sleep((char *)&tp->t_oq, CVTTOUT, IVTTOUT, SVTTOUT);
        !          121784:                        if (SELF->p_ssig && nondsig()) {
        !          121785:                                u.u_error = EINTR;
        !          121786:                                spl(o);
        !          121787:                                return;
        !          121788:                        }
        !          121789:                }
        !          121790:                while (putq(&tp->t_oq, c) < 0) {
        !          121791:                        ttstart(tp);
        !          121792:                        waitq();
        !          121793:                }
        !          121794:                spl(o);
        !          121795:        }
        !          121796:        o = sphi();
        !          121797:        ttstart(tp);
        !          121798:        spl(o);
        !          121799: }
        !          121800: 
        !          121801: /*
        !          121802:  * ttioctl()
        !          121803:  *
        !          121804:  *     This routine handles common typewriter ioctl functions.
        !          121805:  *     Note that flushing the stream now means drain the output
        !          121806:  *     and clear the input.
        !          121807:  */
        !          121808: void ttioctl(tp, com, vec)
        !          121809: register TTY *tp;
        !          121810: register struct sgttyb *vec;
        !          121811: {
        !          121812:        register int    flush = 0;
        !          121813:        register int    drain = 0;
        !          121814:        register char   *p1, *p2;
        !          121815:                 int    rload = 0;
        !          121816:                 int    was_bbyb = 0;
        !          121817: 
        !          121818:        switch (com) {
        !          121819:        case TIOCQUERY:
        !          121820:                kucopy(&tp->t_iq.cq_cc, vec, sizeof(int));
        !          121821:                break;
        !          121822:        case TIOCGETP:
        !          121823:                kucopy(&tp->t_sgttyb, vec, sizeof (struct sgttyb));
        !          121824:                break;
        !          121825:        case TIOCSETP:
        !          121826:                ++flush;          /* flush input */
        !          121827:                ++drain;          /* delay for output */
        !          121828:                ++rload;
        !          121829:                ukcopy(vec, &tp->t_sgttyb, sizeof (struct sgttyb));
        !          121830:                break;
        !          121831:        case TIOCSETN:
        !          121832:                was_bbyb = ISBBYB;      /* previous mode */
        !          121833:                ++rload;
        !          121834:                ukcopy(vec, &tp->t_sgttyb, sizeof (struct sgttyb));
        !          121835:                if (!was_bbyb && ISBBYB && tp->t_ibx != 0) {
        !          121836:                        p1 = &tp->t_ib[0];
        !          121837:                        p2 = &tp->t_ib[tp->t_ibx];
        !          121838:                        while (p1 < p2)
        !          121839: #if NOT_8_BIT
        !          121840:                                putq(&tp->t_iq, (*p1++) & 0177);
        !          121841: #else
        !          121842:                                putq(&tp->t_iq, (*p1++));
        !          121843: #endif
        !          121844:                        tp->t_ibx = 0;
        !          121845:                }
        !          121846:                break;
        !          121847:        case TIOCGETC:
        !          121848:                kucopy(&tp->t_tchars, vec, sizeof (struct tchars));
        !          121849:                break;
        !          121850:        case TIOCSETC:
        !          121851:                ++rload;
        !          121852:                ++drain;
        !          121853:                ukcopy(vec, &tp->t_tchars, sizeof (struct tchars));
        !          121854:                break;
        !          121855:        case TIOCEXCL:
        !          121856:                tp->t_flags |= T_EXCL;
        !          121857:                break;
        !          121858:        case TIOCNXCL:
        !          121859:                tp->t_flags &= ~T_EXCL;
        !          121860:                break;
        !          121861:        case TIOCHPCL:          /* set hangup on last close */
        !          121862:                tp->t_flags |= T_HPCL;
        !          121863:                break;
        !          121864:        case TIOCCHPCL:         /* don't hangup on last close */
        !          121865:                if (!super())   /* only superuser may do this */
        !          121866:                   u.u_error = EPERM;        /* not su */
        !          121867:                else
        !          121868:                   tp->t_flags &= ~T_HPCL;   /* turn off hangup bit */
        !          121869:                break;
        !          121870:        case TIOCGETTF:         /* get tty flag word */
        !          121871:                kucopy(&tp->t_flags, (unsigned *) vec, sizeof(unsigned));
        !          121872:                break;
        !          121873:        case TIOCFLUSH:
        !          121874:                ++flush;        /* flush both input and output */
        !          121875:                ++drain;
        !          121876:                break;
        !          121877:        case TIOCBREAD:         /* blocking read for CBREAK/RAW mode */
        !          121878:                tp->t_flags |= T_BRD;
        !          121879:                break;
        !          121880:        case TIOCCBREAD:        /* turn off CBREAK/RAW blocking read mode */
        !          121881:                tp->t_flags &= ~T_BRD;
        !          121882:                break;
        !          121883:        default:
        !          121884:                u.u_error = EINVAL;
        !          121885:        }
        !          121886: 
        !          121887:        /*
        !          121888:         * Ensure output is enabled BEFORE waiting for output to drain.
        !          121889:         */
        !          121890:        if ( (ISRIN) && (tp->t_flags & T_STOP) ) {
        !          121891:                tp->t_flags &= ~T_STOP;
        !          121892:                ttstart( tp );
        !          121893:        }
        !          121894: 
        !          121895:        /*
        !          121896:         * Wait for output to drain, or signal to arrive.
        !          121897:         */
        !          121898:        if (drain != 0) {
        !          121899:                while (tp->t_oq.cq_cc != 0) {
        !          121900:                        tp->t_flags |= T_DRAIN;
        !          121901:                        sleep((char *)&tp->t_oq, CVTTOUT, IVTTOUT, SVTTOUT);
        !          121902:                        if (SELF->p_ssig && nondsig())
        !          121903:                                break;
        !          121904:                }
        !          121905:        }
        !          121906: 
        !          121907:        /*
        !          121908:         * Flush input.
        !          121909:         */
        !          121910:        if (flush != 0)
        !          121911:                ttflush(tp);
        !          121912: 
        !          121913:        /*
        !          121914:         * Re-initialize hardware.
        !          121915:         */
        !          121916:        if ( (rload != 0) && (tp->t_param != NULL) )
        !          121917:                NEAR_OR_FAR_CALL(t_param)
        !          121918: }
        !          121919: 
        !          121920: /*
        !          121921:  * ttpoll()
        !          121922:  *
        !          121923:  *     Polling routine.
        !          121924:  *     [System V.3 Compatible]
        !          121925:  */
        !          121926: int ttpoll( tp, ev, msec )
        !          121927: register TTY * tp;
        !          121928: int ev;
        !          121929: int msec;
        !          121930: {
        !          121931:        /*
        !          121932:         * Priority polls not supported.
        !          121933:         */
        !          121934:        ev &= ~POLLPRI;
        !          121935: 
        !          121936:        /*
        !          121937:         * Input poll with no data present.
        !          121938:         */
        !          121939:        if ( (ev & POLLIN) && (tp->t_iq.cq_cc == 0) ) {
        !          121940: 
        !          121941:                /*
        !          121942:                 * Blocking input poll.
        !          121943:                 */
        !          121944:                if ( msec != 0 )
        !          121945:                        pollopen( &tp->t_ipolls );
        !          121946: 
        !          121947:                /*
        !          121948:                 * Second look to avoid interrupt race.
        !          121949:                 */
        !          121950:                if ( tp->t_iq.cq_cc == 0 )
        !          121951:                        ev &= ~POLLIN;
        !          121952:        }
        !          121953: 
        !          121954:        /*
        !          121955:         * Output poll with no space.
        !          121956:         */
        !          121957:        if ( (ev & POLLOUT) && (tp->t_oq.cq_cc >= OLOLIM) ) {
        !          121958: 
        !          121959:                /*
        !          121960:                 * Blocking output poll.
        !          121961:                 */
        !          121962:                if ( msec != 0 )
        !          121963:                        pollopen( &tp->t_opolls );
        !          121964: 
        !          121965:                /*
        !          121966:                 * Second look to avoid interrupt race.
        !          121967:                 */
        !          121968:                if ( tp->t_oq.cq_cc >= OLOLIM )
        !          121969:                        ev &= ~POLLIN;
        !          121970:        }
        !          121971: 
        !          121972:        if ( ((ev & POLLIN) == 0) && ((tp->t_flags & T_CARR) == 0) )
        !          121973:                ev |= POLLHUP;
        !          121974: 
        !          121975:        return ev;
        !          121976: }
        !          121977: 
        !          121978: /*
        !          121979:  * ttout()
        !          121980:  *
        !          121981:  *     Pull a character from the output queues of the typewriter.
        !          121982:  *     Doing fills, newline insert, tab expansion, etc.
        !          121983:  *
        !          121984:  *     If the stream is empty return a -1.
        !          121985:  *     Called at high priority.
        !          121986:  */
        !          121987: int ttout(tp)
        !          121988: register TTY *tp;
        !          121989: {
        !          121990:        register c;
        !          121991: 
        !          121992:        if (tp->t_nfill) {
        !          121993:                --tp->t_nfill;
        !          121994:                c = tp->t_fillb;
        !          121995:        } else if ((tp->t_flags&T_INL) != 0) {
        !          121996:                tp->t_flags &= ~T_INL;
        !          121997:                c = '\n';
        !          121998:        } else {
        !          121999:                if ((c=getq(&tp->t_oq)) < 0)
        !          122000:                        return -1;
        !          122001:                if (!ISROUT) {
        !          122002:                        if (c=='\n' && ISCRMOD) {
        !          122003:                                tp->t_flags |= T_INL;
        !          122004:                                c = '\r';
        !          122005:                        } else if (c=='\t' && ISXTABS) {
        !          122006:                                tp->t_nfill = ~(tp->t_hpos|~07);
        !          122007:                                tp->t_fillb = ' ';
        !          122008:                                c = ' ';
        !          122009:                        }
        !          122010:                }
        !          122011:        }
        !          122012:        if (!ISROUT) {
        !          122013:                if (c == '\b') {
        !          122014:                        if (tp->t_hpos)
        !          122015:                                --tp->t_hpos;
        !          122016:                } else if (c == '\r')
        !          122017:                        tp->t_hpos = 0;
        !          122018:                else if (c == '\t')
        !          122019:                        tp->t_hpos = (tp->t_hpos|07) + 1;
        !          122020: #if NOT_8_BIT
        !          122021:                else if (c >= ' ' && c <= '~')
        !          122022: #else
        !          122023:                else if ((c >= ' ' && c <= '~') || (c >= 0200 && c <= 0376))
        !          122024: #endif
        !          122025:                        ++tp->t_hpos;
        !          122026:        }
        !          122027:        return c;
        !          122028: }
        !          122029: 
        !          122030: /*
        !          122031:  * ttin()
        !          122032:  *
        !          122033:  *     Pass a character to the device independent typewriter routines.
        !          122034:  *     Handle erase and kill, tandem flow control, and other magic.
        !          122035:  *     Called at high priority from  the driver's interrupt processor.
        !          122036:  */
        !          122037: void ttin(tp, c)
        !          122038: register TTY *tp;
        !          122039: register c;
        !          122040: {
        !          122041:        int dc, i, n;
        !          122042: 
        !          122043:        if (!ISRIN) {
        !          122044: #if NOT_8_BIT
        !          122045:                c &= 0177;
        !          122046: #endif
        !          122047:                if (ISINTR) {
        !          122048:                        ttsignal(tp, SIGINT);
        !          122049:                        return;
        !          122050:                }
        !          122051:                if (ISQUIT) {
        !          122052:                        ttsignal(tp, SIGQUIT);
        !          122053:                        return;
        !          122054:                }
        !          122055: 
        !          122056:                /*
        !          122057:                 * Only do flow control if TANDEM is set.
        !          122058:                 */
        !          122059:                if (ISTAND) {
        !          122060:                        if (ISSTOP) {
        !          122061:                                if ((tp->t_flags&T_STOP) == 0)
        !          122062:                                        tp->t_flags |= T_STOP;
        !          122063:                                return;
        !          122064:                        }
        !          122065:                        if (ISSTART) {
        !          122066:                                tp->t_flags &= ~T_STOP;
        !          122067:                                ttstart(tp);
        !          122068:                                return;
        !          122069:                        }
        !          122070:                }
        !          122071:        }
        !          122072:        if ((tp->t_flags&T_ISTOP) != 0)
        !          122073:                return;
        !          122074:        if (!ISRIN) {
        !          122075:                if (c=='\r' && ISCRMOD)
        !          122076:                        c = '\n';
        !          122077:                if (tp->t_escape != 0) {
        !          122078:                        if (c == ESC)
        !          122079:                                ++tp->t_escape;
        !          122080:                        else {
        !          122081:                                if (ISERASE || ISKILL) {
        !          122082:                                        c |= 0200;
        !          122083:                                        --tp->t_escape;
        !          122084:                                }
        !          122085:                                while (tp->t_escape!=0 && tp->t_ibx<NCIB-1) {
        !          122086:                                        tp->t_ib[tp->t_ibx++] = ESC;
        !          122087:                                        --tp->t_escape;
        !          122088:                                }
        !          122089:                                ttstash(tp, c);
        !          122090:                        }
        !          122091:                        if (ISECHO) {
        !          122092: #if NOT_8_BIT
        !          122093:                                putq(&tp->t_oq, c&0177);
        !          122094: #else
        !          122095:                                putq(&tp->t_oq, c); /* no strip for 8-bit */
        !          122096: #endif
        !          122097:                                ttstart(tp);
        !          122098:                        }
        !          122099:                        return;
        !          122100:                }
        !          122101:                if (ISERASE && !ISCBRK) {
        !          122102:                        while (tp->t_escape!=0 && tp->t_ibx<NCIB-1) {
        !          122103:                                tp->t_ib[tp->t_ibx++] = ESC;
        !          122104:                                --tp->t_escape;
        !          122105:                        }
        !          122106:                        if (tp->t_ibx == 0)
        !          122107:                                return;
        !          122108:                        dc = tp->t_ib[--tp->t_ibx];
        !          122109:                        if (ISECHO) {
        !          122110:                                if (!ISCRT)
        !          122111:                                        putq(&tp->t_oq, c);
        !          122112:                                /* don't erase for bell, null, or rubout */
        !          122113: #if NOT_8_BIT
        !          122114:                                else if (((c = dc&0177) == '\007')
        !          122115:                                        || c == 0 || c == 0177)
        !          122116: #else
        !          122117:                                else if (((c = dc) == '\007')
        !          122118:                                        || c == 0 || c == 0177 || c == 0377)
        !          122119: #endif
        !          122120:                                        return;
        !          122121:                                else if (c != '\b' && c != '\t') {
        !          122122:                                        putq(&tp->t_oq, '\b');
        !          122123:                                        putq(&tp->t_oq,  ' ');
        !          122124:                                        putq(&tp->t_oq, '\b');
        !          122125:                                } else if (c == '\t') {
        !          122126:                                        n = tp->t_opos + tp->t_escape;
        !          122127:                                        for (i=0; i<tp->t_ibx; ++i) {
        !          122128:                                                c = tp->t_ib[i];
        !          122129: #if NOT_8_BIT
        !          122130:                                                if ((c&0200) != 0) {
        !          122131:                                                        ++n;
        !          122132:                                                        c &= 0177;
        !          122133:                                                }
        !          122134: #endif
        !          122135:                                                if (c == '\b')
        !          122136:                                                        --n;
        !          122137:                                                else {
        !          122138:                                                        if (c == '\t')
        !          122139:                                                                n |= 07;
        !          122140:                                                        ++n;
        !          122141:                                                }
        !          122142:                                        }
        !          122143:                                        while (n++ < tp->t_hpos)
        !          122144:                                                putq(&tp->t_oq, '\b');
        !          122145:                                }
        !          122146: #if NOT_8_BIT
        !          122147:                                if ((dc&0200) != 0) {
        !          122148:                                        if ((dc&0177) != '\b')
        !          122149:                                                putq(&tp->t_oq, '\b');
        !          122150:                                        putq(&tp->t_oq,  ' ');
        !          122151:                                        putq(&tp->t_oq, '\b');
        !          122152:                                }
        !          122153: #endif
        !          122154:                                ttstart(tp);
        !          122155:                        }
        !          122156:                        return;
        !          122157:                }
        !          122158:                if (ISKILL && !ISCBRK) {
        !          122159:                        tp->t_ibx = 0;
        !          122160:                        tp->t_escape = 0;
        !          122161:                        if (ISECHO) {
        !          122162:                                if (c < 0x20) {
        !          122163:                                        putq(&tp->t_oq, '^');
        !          122164:                                        c += 0x40;
        !          122165:                                }
        !          122166:                                putq(&tp->t_oq, c);
        !          122167:                                putq(&tp->t_oq, '\n');
        !          122168:                                ttstart(tp);
        !          122169:                        }
        !          122170:                        return;
        !          122171:                }
        !          122172:        }
        !          122173:        if (ISBBYB) {
        !          122174:                putq(&tp->t_iq, c);
        !          122175:                if ((tp->t_flags&T_INPUT) != 0) {
        !          122176:                        tp->t_flags &= ~T_INPUT;
        !          122177:                        defer( wakeup, (char *) &tp->t_iq );
        !          122178:                }
        !          122179:                if ( tp->t_ipolls.e_procp ) {
        !          122180:                        tp->t_ipolls.e_procp = 0;
        !          122181:                        defer( pollwake, (char *) &tp->t_ipolls );
        !          122182:                }
        !          122183:        } else {
        !          122184:                if (tp->t_ibx == 0)
        !          122185:                        tp->t_opos = tp->t_hpos;
        !          122186:                if (c == ESC)
        !          122187:                        ++tp->t_escape;
        !          122188:                else
        !          122189:                        ttstash(tp, c);
        !          122190:        }
        !          122191:        if (ISECHO) {
        !          122192:                if (ISRIN || !ISEOF) {
        !          122193:                        putq(&tp->t_oq, c);
        !          122194:                        ttstart(tp);
        !          122195:                }
        !          122196:        }
        !          122197:        if ((n=tp->t_iq.cq_cc)>=IHILIM)
        !          122198:                tp->t_flags |= T_ISTOP;
        !          122199:        else if (ISTAND && (tp->t_flags&T_TSTOP)==0 && n>=ITSLIM) {
        !          122200:                tp->t_flags |= T_TSTOP;
        !          122201:                putq(&tp->t_oq, stopc);
        !          122202:                ttstart(tp);
        !          122203:        }
        !          122204: }
        !          122205: 
        !          122206: /*
        !          122207:  * ttstash()
        !          122208:  *
        !          122209:  *     Cooked mode.
        !          122210:  *     Put character in the buffer and check for end of line.
        !          122211:  *     Only a legal end of line can take the last character position.
        !          122212:  */
        !          122213: void ttstash(tp, c)
        !          122214: register TTY *tp;
        !          122215: {
        !          122216:        register char *p1, *p2;
        !          122217: 
        !          122218:        if (c=='\n' || ISEOF || ISBRK) {
        !          122219:                p1 = &tp->t_ib[0];
        !          122220:                p2 = &tp->t_ib[tp->t_ibx];
        !          122221:                *p2++ = c;                      /* Always room */
        !          122222:                while (p1 < p2)
        !          122223: #if NOT_8_BIT
        !          122224:                        putq(&tp->t_iq, (*p1++)&0177);
        !          122225: #else
        !          122226:                        putq(&tp->t_iq, (*p1++));
        !          122227: #endif
        !          122228:                tp->t_ibx = 0;
        !          122229:                tp->t_escape = 0;
        !          122230: 
        !          122231:                if ( tp->t_flags & T_INPUT ) {
        !          122232:                        tp->t_flags &= ~T_INPUT;
        !          122233:                        defer( wakeup, (char *) &tp->t_iq );
        !          122234:                }
        !          122235: 
        !          122236:                if ( tp->t_ipolls.e_procp ) {
        !          122237:                        tp->t_ipolls.e_procp = 0;
        !          122238:                        defer( pollwake, (char *) &tp->t_ipolls );
        !          122239:                }
        !          122240: 
        !          122241:        } else if (tp->t_ibx < NCIB-1)
        !          122242:                tp->t_ib[tp->t_ibx++] = c;
        !          122243: }
        !          122244: 
        !          122245: /*
        !          122246:  * ttstart()
        !          122247:  *
        !          122248:  *     Start output on a tty.
        !          122249:  *     Duck out if stopped.  Do wakeups.
        !          122250:  */
        !          122251: void ttstart(tp)
        !          122252: register TTY *tp;
        !          122253: {
        !          122254:        register int n;
        !          122255: 
        !          122256:        n = tp->t_flags;
        !          122257:        if ( n & T_STOP )
        !          122258:                return;
        !          122259: 
        !          122260:        if ((n&T_DRAIN)!=0 && tp->t_oq.cq_cc==0
        !          122261:           && (n&T_INL)==0 && tp->t_nfill==0)
        !          122262:        {       tp->t_flags &= ~T_DRAIN;
        !          122263:                defer( wakeup, (char *) &tp->t_oq );
        !          122264:                return;
        !          122265:        }
        !          122266: 
        !          122267:        NEAR_OR_FAR_CALL(t_start)
        !          122268: 
        !          122269:        if ( tp->t_oq.cq_cc > OLOLIM )
        !          122270:                return;
        !          122271: 
        !          122272:        if ( n & T_HILIM ) {
        !          122273:                tp->t_flags &= ~T_HILIM;
        !          122274:                defer( wakeup, (char *) &tp->t_oq );
        !          122275:        }
        !          122276: 
        !          122277:        if ( tp->t_opolls.e_procp ) {
        !          122278:                tp->t_opolls.e_procp = 0;
        !          122279:                defer( pollwake, (char *) &tp->t_opolls );
        !          122280:        }
        !          122281: }
        !          122282: 
        !          122283: /*
        !          122284:  * ttflush()
        !          122285:  *
        !          122286:  *     Flush a tty.
        !          122287:  *     Called to clear out queues.
        !          122288:  */
        !          122289: void ttflush(tp)
        !          122290: register TTY *tp;
        !          122291: {
        !          122292:        clrq(&tp->t_iq);
        !          122293:        clrq(&tp->t_oq);
        !          122294: 
        !          122295:        if ( tp->t_flags & T_INPUT )
        !          122296:                defer( wakeup, (char *) &tp->t_iq );
        !          122297: 
        !          122298:        if ( tp->t_flags & (T_DRAIN|T_HILIM) )
        !          122299:                defer( wakeup, (char *) &tp->t_oq );
        !          122300: 
        !          122301:        if ( tp->t_ipolls.e_procp != 0 ) {
        !          122302:                tp->t_ipolls.e_procp = 0;
        !          122303:                defer( pollwake, (char *) &tp->t_ipolls );
        !          122304:        }
        !          122305: 
        !          122306:        if ( tp->t_opolls.e_procp != 0 ) {
        !          122307:                tp->t_opolls.e_procp = 0;
        !          122308:                defer( pollwake, (char *) &tp->t_opolls );
        !          122309:        }
        !          122310: 
        !          122311:        tp->t_ibx = 0;
        !          122312:        tp->t_escape = 0;
        !          122313:        tp->t_flags &= T_SAVE;  /* reset most flag bits */
        !          122314: }
        !          122315: 
        !          122316: /*
        !          122317:  * ttsignal()
        !          122318:  *
        !          122319:  *     Send a signal to every process in the given process group.
        !          122320:  */
        !          122321: void ttsignal(tp, sig)
        !          122322: TTY *tp;
        !          122323: int sig;
        !          122324: {
        !          122325:        register int g;
        !          122326:        register PROC *pp;
        !          122327: 
        !          122328:        g = tp->t_group;
        !          122329:        if (g == 0)
        !          122330:                return;
        !          122331:        ttflush(tp);
        !          122332:        pp = &procq;
        !          122333:        while ((pp=pp->p_nforw) != &procq)
        !          122334:                if (pp->p_group == g)
        !          122335:                        sendsig(sig, pp);
        !          122336: }
        !          122337: 
        !          122338: /*
        !          122339:  * tthup()
        !          122340:  *
        !          122341:  *     Flag hangup internally to force errors on tty read/write, flush tty,
        !          122342:  *     then send hangup signal.
        !          122343:  */
        !          122344: void tthup(tp)
        !          122345: register TTY *tp;
        !          122346: {
        !          122347:        tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          122348:        ttflush(tp);
        !          122349:        ttsignal(tp, SIGHUP);
        !          122350: }
        !          122351: 0707070064030000770407550000030000030000011777770507310740300004200000000000/newbits/kernel/USRSRC/ttydrv/RCS0707070064030066241004440000030000030000011777770507310740300005200000061511/newbits/kernel/USRSRC/ttydrv/RCS/tty.c,vhead     1.9;
        !          122352: branch   ;
        !          122353: access   ;
        !          122354: symbols  ;
        !          122355: locks    bin:1.9;
        !          122356: comment  @ * @;
        !          122357: 
        !          122358: 
        !          122359: 1.9
        !          122360: date     91.09.17.06.06.42;  author bin;  state Exp;
        !          122361: branches ;
        !          122362: next     1.8;
        !          122363: 
        !          122364: 1.8
        !          122365: date     91.08.01.13.49.39;  author bin;  state Exp;
        !          122366: branches ;
        !          122367: next     1.7;
        !          122368: 
        !          122369: 1.7
        !          122370: date     91.07.15.14.36.29;  author bin;  state Exp;
        !          122371: branches ;
        !          122372: next     1.6;
        !          122373: 
        !          122374: 1.6
        !          122375: date     91.06.20.14.28.36;  author bin;  state Exp;
        !          122376: branches ;
        !          122377: next     1.5;
        !          122378: 
        !          122379: 1.5
        !          122380: date     91.06.06.18.28.53;  author norm;  state Exp;
        !          122381: branches ;
        !          122382: next     1.4;
        !          122383: 
        !          122384: 1.4
        !          122385: date     91.06.04.14.24.20;  author hal;  state Exp;
        !          122386: branches ;
        !          122387: next     1.3;
        !          122388: 
        !          122389: 1.3
        !          122390: date     91.04.05.15.43.29;  author root;  state Exp;
        !          122391: branches ;
        !          122392: next     1.2;
        !          122393: 
        !          122394: 1.2
        !          122395: date     91.04.05.15.24.35;  author root;  state Exp;
        !          122396: branches ;
        !          122397: next     1.1;
        !          122398: 
        !          122399: 1.1
        !          122400: date     91.04.05.15.23.07;  author root;  state Exp;
        !          122401: branches ;
        !          122402: next     ;
        !          122403: 
        !          122404: 
        !          122405: desc
        !          122406: @Line discipline module for character devices.
        !          122407: @
        !          122408: 
        !          122409: 
        !          122410: 1.9
        !          122411: log
        !          122412: @updated by hal
        !          122413: @
        !          122414: text
        !          122415: @/*
        !          122416:  * File:       $USRSRC/ttydrv/tty.c
        !          122417:  *
        !          122418:  * Purpose:    COHERENT line discipline module.
        !          122419:  *     This is the common part of typewriter service. It handles all device-
        !          122420:  *     independent aspects of a typewriter, including tandem flow control,
        !          122421:  *     erase and kill, stop and start, and common ioctl functions.
        !          122422:  *
        !          122423:  * $Log:       tty.c,v $
        !          122424:  * Revision 1.8  91/09/13  18:01:39  piggy
        !          122425:  * Only do XON/XOFF flow control if TANDEM is set.
        !          122426:  * 
        !          122427:  * Revision 1.7  91/09/13  17:58:00  hal
        !          122428:  * Drop 3rd arg (was writing PSW directly from it!) for ttread/ttwrite.
        !          122429:  * General face lift.
        !          122430:  *
        !          122431:  *
        !          122432:  * Bug: no support for 8-bit characters.
        !          122433:  * Fix: don't strip keyboard input. 01/22/91.  (norm)
        !          122434:  *
        !          122435:  * Bug:        Switching modes between cooked and CBREAK/RAW left buffered input
        !          122436:  *     in the input buffer until returning to cooked mode. 05/13/91 norm
        !          122437:  *
        !          122438:  * Bug: setting speed to default in ttopen() was conditioned to
        !          122439:  *      use hard constants.  90/08/28.  hws
        !          122440:  *
        !          122441:  * Revision 1.5  91/06/06  18:28:53  norm
        !          122442:  * Restore 8-bit fix.
        !          122443:  *
        !          122444:  * Revision 1.2        89/07/17  11:51:20      src
        !          122445:  * Bug:        Terminal could lock up when setting it to RAWIN mode, if
        !          122446:  *     output was suspended due to X-OFF, and output data was present.
        !          122447:  * Fix:        Setting terminal to RAWIN mode now clears X-OFF, starts output
        !          122448:  *     BEFORE waiting for output to drain.  Received signals now cause
        !          122449:  *     operation to complete without waiting for drain. (ABC)
        !          122450:  *
        !          122451:  * Revision 1.1        88/03/24  16:18:12      src
        !          122452:  * Initial revision
        !          122453:  *
        !          122454:  * 86/12/12    Allan Cornish           /usr/src/sys/drv/tty.c
        !          122455:  * Added 3rd argument to ttpoll() to support non-blocking polls.
        !          122456:  *
        !          122457:  * 86/11/19    Allan Cornish           /usr/src/sys/drv/tty.c
        !          122458:  * Made ttread() and ttwrite() recognize the IONDLY flag in iop->io_flag.
        !          122459:  * wakeup() and pollwake() now have delayed invocation by defer().
        !          122460:  * Added poll [System V.3] capability.
        !          122461:  *
        !          122462:  * 85/06/28    Allan Cornish
        !          122463:  * made ttioctl() clear T_STOP flag if ISRIN.
        !          122464:  *
        !          122465:  * 85/03/04    Allan Cornish
        !          122466:  * made ttread()  interruptible.
        !          122467:  *
        !          122468:  * 85/03/01    Allan Cornish
        !          122469:  * made ttclose() interruptible.
        !          122470:  */
        !          122471: 
        !          122472: /*
        !          122473:  * Includes.
        !          122474:  */
        !          122475: #include <sys/clist.h>
        !          122476: #include <sys/coherent.h>
        !          122477: #include <sys/con.h>
        !          122478: #include <sys/deftty.h>
        !          122479: #include <sys/io.h>
        !          122480: #include <sys/proc.h>
        !          122481: #include <sys/sched.h>
        !          122482: #include <sys/stat.h>
        !          122483: #include <sys/tty.h>
        !          122484: #include <sys/uproc.h>
        !          122485: #include <errno.h>
        !          122486: 
        !          122487: /*
        !          122488:  * Definitions.
        !          122489:  *     Constants.
        !          122490:  *     Macros with argument lists.
        !          122491:  *     Typedefs.
        !          122492:  *     Enums.
        !          122493:  */
        !          122494: 
        !          122495: /* NEAR_OR_FAR_CALL is for invoking t_param and t_start */
        !          122496: #define         NEAR_OR_FAR_CALL(tp_fn)  {\
        !          122497:        if (tp->t_cs_sel) \
        !          122498:                ld_call(tp->t_cs_sel, tp->tp_fn, tp); \
        !          122499:        else \
        !          122500:                (*tp->tp_fn)(tp); }
        !          122501: 
        !          122502: /*
        !          122503:  * Functions.
        !          122504:  *     Import Functions.
        !          122505:  *     Export Functions.
        !          122506:  *     Local Functions.
        !          122507:  */
        !          122508: void ttclose();
        !          122509: void ttflush();
        !          122510: void tthup();
        !          122511: void ttin();
        !          122512: void ttioctl();
        !          122513: void ttopen();
        !          122514: int  ttout();
        !          122515: int  ttpoll();
        !          122516: void ttread();
        !          122517: void ttsetgrp();
        !          122518: void ttsignal();
        !          122519: void ttstart();
        !          122520: void ttstash();
        !          122521: void ttwrite();
        !          122522: 
        !          122523: /*
        !          122524:  * Global Data.
        !          122525:  *     Import Variables.
        !          122526:  *     Export Variables.
        !          122527:  *     Local Variables.
        !          122528:  */
        !          122529: extern int     wakeup();
        !          122530: extern void    pollwake();
        !          122531: 
        !          122532: /*
        !          122533:  * ttopen()
        !          122534:  *
        !          122535:  *     Called by driver on first open.
        !          122536:  *     Set up defaults.
        !          122537:  */
        !          122538: void ttopen(tp)
        !          122539: register TTY *tp;
        !          122540: {
        !          122541:        tp->t_escape = 0;
        !          122542:        tp->t_sgttyb.sg_ispeed = tp->t_dispeed;
        !          122543:        tp->t_sgttyb.sg_ospeed = tp->t_dospeed;
        !          122544:        tp->t_sgttyb.sg_erase  = DEF_SG_ERASE;
        !          122545:        tp->t_sgttyb.sg_kill   = DEF_SG_KILL;
        !          122546:        tp->t_sgttyb.sg_flags  = DEF_SG_FLAGS;
        !          122547:        tp->t_tchars.t_intrc   = DEF_T_INTRC;
        !          122548:        tp->t_tchars.t_quitc   = DEF_T_QUITC;
        !          122549:        tp->t_tchars.t_startc  = DEF_T_STARTC;
        !          122550:        tp->t_tchars.t_stopc   = DEF_T_STOPC;
        !          122551:        tp->t_tchars.t_eofc    = DEF_T_EOFC;
        !          122552:        tp->t_tchars.t_brkc    = DEF_T_BRKC;
        !          122553:        if (tp->t_param != NULL) {
        !          122554:                NEAR_OR_FAR_CALL(t_param)
        !          122555:        }
        !          122556: }
        !          122557: 
        !          122558: /*
        !          122559:  * ttsetgrp()
        !          122560:  *
        !          122561:  *     Set process group when process does not have one.
        !          122562:  *     Also set up process's controlling terminal.
        !          122563:  */
        !          122564: void ttsetgrp(tp, ctdev)
        !          122565: register TTY *tp;
        !          122566: dev_t ctdev;
        !          122567: {
        !          122568:        register PROC *pp;
        !          122569: 
        !          122570:        pp = SELF;
        !          122571:        if (pp->p_group == 0) {
        !          122572:                if (tp->t_group == 0)
        !          122573:                        tp->t_group = pp->p_pid;
        !          122574:                pp->p_group = tp->t_group;
        !          122575:        }
        !          122576:        if (pp->p_ttdev == NODEV)
        !          122577:                pp->p_ttdev = ctdev;
        !          122578: }
        !          122579: 
        !          122580: /*
        !          122581:  * ttyclose()
        !          122582:  *
        !          122583:  *     Called by driver on the last close.
        !          122584:  *     Wait for all pending output to go out.
        !          122585:  *     Kill input.
        !          122586:  */
        !          122587: void ttclose(tp)
        !          122588: register TTY *tp;
        !          122589: {
        !          122590:        register int s;
        !          122591: 
        !          122592:        while (tp->t_oq.cq_cc != 0) {
        !          122593:                s = sphi();
        !          122594:                if (tp->t_oq.cq_cc != 0) {
        !          122595:                        tp->t_flags |= T_DRAIN;
        !          122596:                        sleep((char *)&tp->t_oq, CVTTOUT, IVTTOUT, SVTTOUT);
        !          122597:                }
        !          122598:                spl(s);
        !          122599:                if (SELF->p_ssig && nondsig())
        !          122600:                        break;
        !          122601:        }
        !          122602:        ttflush(tp);
        !          122603:        tp->t_flags = tp->t_group = 0;
        !          122604: }
        !          122605: 
        !          122606: /*
        !          122607:  * ttread()
        !          122608:  *
        !          122609:  *     The read routine for a tty device driver will call this function.
        !          122610:  *
        !          122611:  *     Move data from tp->t_iq to io segment iop.
        !          122612:  *     Number of characters to copy is in iop->ioc.
        !          122613:  *
        !          122614:  *     In cooked mode, copy up to the first newline or break character, or
        !          122615:  *     until the count runs out.
        !          122616:  *     In CBREAK or RAW modes, return when count runs out or when input clist
        !          122617:  *     is empty and we're returning at least one byte.
        !          122618:  */
        !          122619: void ttread(tp, iop)
        !          122620: register TTY *tp;
        !          122621: register IO *iop;
        !          122622: {
        !          122623:        register c;
        !          122624:        int o;
        !          122625:        int sioc = iop->io_ioc;  /* number of bytes to read */
        !          122626: 
        !          122627:        while (iop->io_ioc) {
        !          122628:                o = sphi();
        !          122629:                while ((c = getq(&tp->t_iq)) < 0) {
        !          122630:                        if ((tp->t_flags & T_CARR) == 0) {
        !          122631:                           u.u_error = EIO;  /* error since no carrier */
        !          122632:                           spl(o);
        !          122633:                           return;
        !          122634:                        }
        !          122635: 
        !          122636:                        /* If we're in CBREAK or RAW mode, and we don't */
        !          122637:                        /* have the special "blocking read" bit set for */
        !          122638:                        /* these modes, and we read at least one byte   */
        !          122639:                        /* of input, return immediately, since we have  */
        !          122640:                        /* run out of characters from the clist.        */
        !          122641: 
        !          122642:                        if (ISBBYB && ((tp->t_flags & T_BRD) == 0)
        !          122643:                           && iop->io_ioc < sioc) {
        !          122644:                           spl(o);
        !          122645:                           return;
        !          122646:                        }
        !          122647: 
        !          122648:                        /*
        !          122649:                         * Non-blocking reads.
        !          122650:                         * Tell user process to try again later.
        !          122651:                         */
        !          122652:                        if ( iop->io_flag & IONDLY ) {
        !          122653:                                u.u_error = EAGAIN;
        !          122654:                                spl(o);
        !          122655:                                return;
        !          122656:                        }
        !          122657: 
        !          122658:                        tp->t_flags |= T_INPUT;  /* wait for more data */
        !          122659:                        sleep((char *)&tp->t_iq, CVTTIN, IVTTIN, SVTTIN);
        !          122660: 
        !          122661:                        if (SELF->p_ssig && nondsig()) {
        !          122662:                                if (iop->io_ioc == sioc)
        !          122663:                                        u.u_error = EINTR;
        !          122664:                                spl(o);
        !          122665:                                return;
        !          122666:                        }
        !          122667:                }
        !          122668:                /*
        !          122669:                 * Flow control - can we turn on input from the driver yet?
        !          122670:                 */
        !          122671:                if (tp->t_iq.cq_cc <= ILOLIM) {
        !          122672:                        if ((tp->t_flags&T_ISTOP) != 0)
        !          122673:                                tp->t_flags &= ~T_ISTOP;
        !          122674:                        if ((tp->t_flags&T_TSTOP) != 0) {
        !          122675:                                tp->t_flags &= ~T_TSTOP;
        !          122676:                                while (putq(&tp->t_oq, startc) < 0) {
        !          122677:                                        ttstart(tp);
        !          122678:                                        waitq();
        !          122679:                                }
        !          122680:                                ttstart(tp);
        !          122681:                        }
        !          122682:                }
        !          122683:                spl(o);
        !          122684:                if (!ISBBYB && ISEOF)
        !          122685:                        return;
        !          122686:                if (ioputc(c, iop) < 0)
        !          122687:                        return;
        !          122688:                if (!ISBBYB && (c=='\n' || ISBRK))
        !          122689:                        return;
        !          122690:        }
        !          122691: }
        !          122692: 
        !          122693: /*
        !          122694:  * ttwrite()
        !          122695:  *
        !          122696:  *     Write routine.
        !          122697:  *     Transfer stuff to the character list.
        !          122698:  */
        !          122699: void ttwrite(tp, iop)
        !          122700: register TTY *tp;
        !          122701: register IO *iop;
        !          122702: {
        !          122703:        register c;
        !          122704:        int o;
        !          122705: 
        !          122706:        /*
        !          122707:         * Non-blocking writes which can fit.
        !          122708:         * NOTE: exhaustion of clists can still cause blocking writes.
        !          122709:         */
        !          122710:        if ( (iop->io_flag & IONDLY) && (OHILIM >= iop->io_ioc) ) {
        !          122711: 
        !          122712:                /*
        !          122713:                 * No room.
        !          122714:                 */
        !          122715:                if ( tp->t_oq.cq_cc >= OHILIM-iop->io_ioc ) {
        !          122716:                        u.u_error = EAGAIN;
        !          122717:                        return;
        !          122718:                }
        !          122719:        }
        !          122720: 
        !          122721:        while ((c = iogetc(iop)) >= 0) {
        !          122722:                if ((tp->t_flags & T_CARR) == 0) {
        !          122723:                        u.u_error = EIO;  /* error since no carrier */
        !          122724:                        return;
        !          122725:                }
        !          122726:                o = sphi();
        !          122727:                while (tp->t_oq.cq_cc >= OHILIM) {
        !          122728:                        ttstart(tp);
        !          122729:                        if (tp->t_oq.cq_cc < OHILIM)
        !          122730:                                break;
        !          122731:                        tp->t_flags |= T_HILIM;
        !          122732:                        sleep((char *)&tp->t_oq, CVTTOUT, IVTTOUT, SVTTOUT);
        !          122733:                        if (SELF->p_ssig && nondsig()) {
        !          122734:                                u.u_error = EINTR;
        !          122735:                                spl(o);
        !          122736:                                return;
        !          122737:                        }
        !          122738:                }
        !          122739:                while (putq(&tp->t_oq, c) < 0) {
        !          122740:                        ttstart(tp);
        !          122741:                        waitq();
        !          122742:                }
        !          122743:                spl(o);
        !          122744:        }
        !          122745:        o = sphi();
        !          122746:        ttstart(tp);
        !          122747:        spl(o);
        !          122748: }
        !          122749: 
        !          122750: /*
        !          122751:  * ttioctl()
        !          122752:  *
        !          122753:  *     This routine handles common typewriter ioctl functions.
        !          122754:  *     Note that flushing the stream now means drain the output
        !          122755:  *     and clear the input.
        !          122756:  */
        !          122757: void ttioctl(tp, com, vec)
        !          122758: register TTY *tp;
        !          122759: register struct sgttyb *vec;
        !          122760: {
        !          122761:        register int    flush = 0;
        !          122762:        register int    drain = 0;
        !          122763:        register char   *p1, *p2;
        !          122764:                 int    rload = 0;
        !          122765:                 int    was_bbyb = 0;
        !          122766: 
        !          122767:        switch (com) {
        !          122768:        case TIOCQUERY:
        !          122769:                kucopy(&tp->t_iq.cq_cc, vec, sizeof(int));
        !          122770:                break;
        !          122771:        case TIOCGETP:
        !          122772:                kucopy(&tp->t_sgttyb, vec, sizeof (struct sgttyb));
        !          122773:                break;
        !          122774:        case TIOCSETP:
        !          122775:                ++flush;          /* flush input */
        !          122776:                ++drain;          /* delay for output */
        !          122777:                ++rload;
        !          122778:                ukcopy(vec, &tp->t_sgttyb, sizeof (struct sgttyb));
        !          122779:                break;
        !          122780:        case TIOCSETN:
        !          122781:                was_bbyb = ISBBYB;      /* previous mode */
        !          122782:                ++rload;
        !          122783:                ukcopy(vec, &tp->t_sgttyb, sizeof (struct sgttyb));
        !          122784:                if (!was_bbyb && ISBBYB && tp->t_ibx != 0) {
        !          122785:                        p1 = &tp->t_ib[0];
        !          122786:                        p2 = &tp->t_ib[tp->t_ibx];
        !          122787:                        while (p1 < p2)
        !          122788: #if NOT_8_BIT
        !          122789:                                putq(&tp->t_iq, (*p1++) & 0177);
        !          122790: #else
        !          122791:                                putq(&tp->t_iq, (*p1++));
        !          122792: #endif
        !          122793:                        tp->t_ibx = 0;
        !          122794:                }
        !          122795:                break;
        !          122796:        case TIOCGETC:
        !          122797:                kucopy(&tp->t_tchars, vec, sizeof (struct tchars));
        !          122798:                break;
        !          122799:        case TIOCSETC:
        !          122800:                ++rload;
        !          122801:                ++drain;
        !          122802:                ukcopy(vec, &tp->t_tchars, sizeof (struct tchars));
        !          122803:                break;
        !          122804:        case TIOCEXCL:
        !          122805:                tp->t_flags |= T_EXCL;
        !          122806:                break;
        !          122807:        case TIOCNXCL:
        !          122808:                tp->t_flags &= ~T_EXCL;
        !          122809:                break;
        !          122810:        case TIOCHPCL:          /* set hangup on last close */
        !          122811:                tp->t_flags |= T_HPCL;
        !          122812:                break;
        !          122813:        case TIOCCHPCL:         /* don't hangup on last close */
        !          122814:                if (!super())   /* only superuser may do this */
        !          122815:                   u.u_error = EPERM;        /* not su */
        !          122816:                else
        !          122817:                   tp->t_flags &= ~T_HPCL;   /* turn off hangup bit */
        !          122818:                break;
        !          122819:        case TIOCGETTF:         /* get tty flag word */
        !          122820:                kucopy(&tp->t_flags, (unsigned *) vec, sizeof(unsigned));
        !          122821:                break;
        !          122822:        case TIOCFLUSH:
        !          122823:                ++flush;        /* flush both input and output */
        !          122824:                ++drain;
        !          122825:                break;
        !          122826:        case TIOCBREAD:         /* blocking read for CBREAK/RAW mode */
        !          122827:                tp->t_flags |= T_BRD;
        !          122828:                break;
        !          122829:        case TIOCCBREAD:        /* turn off CBREAK/RAW blocking read mode */
        !          122830:                tp->t_flags &= ~T_BRD;
        !          122831:                break;
        !          122832:        default:
        !          122833:                u.u_error = EINVAL;
        !          122834:        }
        !          122835: 
        !          122836:        /*
        !          122837:         * Ensure output is enabled BEFORE waiting for output to drain.
        !          122838:         */
        !          122839:        if ( (ISRIN) && (tp->t_flags & T_STOP) ) {
        !          122840:                tp->t_flags &= ~T_STOP;
        !          122841:                ttstart( tp );
        !          122842:        }
        !          122843: 
        !          122844:        /*
        !          122845:         * Wait for output to drain, or signal to arrive.
        !          122846:         */
        !          122847:        if (drain != 0) {
        !          122848:                while (tp->t_oq.cq_cc != 0) {
        !          122849:                        tp->t_flags |= T_DRAIN;
        !          122850:                        sleep((char *)&tp->t_oq, CVTTOUT, IVTTOUT, SVTTOUT);
        !          122851:                        if (SELF->p_ssig && nondsig())
        !          122852:                                break;
        !          122853:                }
        !          122854:        }
        !          122855: 
        !          122856:        /*
        !          122857:         * Flush input.
        !          122858:         */
        !          122859:        if (flush != 0)
        !          122860:                ttflush(tp);
        !          122861: 
        !          122862:        /*
        !          122863:         * Re-initialize hardware.
        !          122864:         */
        !          122865:        if ( (rload != 0) && (tp->t_param != NULL) )
        !          122866:                NEAR_OR_FAR_CALL(t_param)
        !          122867: }
        !          122868: 
        !          122869: /*
        !          122870:  * ttpoll()
        !          122871:  *
        !          122872:  *     Polling routine.
        !          122873:  *     [System V.3 Compatible]
        !          122874:  */
        !          122875: int ttpoll( tp, ev, msec )
        !          122876: register TTY * tp;
        !          122877: int ev;
        !          122878: int msec;
        !          122879: {
        !          122880:        /*
        !          122881:         * Priority polls not supported.
        !          122882:         */
        !          122883:        ev &= ~POLLPRI;
        !          122884: 
        !          122885:        /*
        !          122886:         * Input poll with no data present.
        !          122887:         */
        !          122888:        if ( (ev & POLLIN) && (tp->t_iq.cq_cc == 0) ) {
        !          122889: 
        !          122890:                /*
        !          122891:                 * Blocking input poll.
        !          122892:                 */
        !          122893:                if ( msec != 0 )
        !          122894:                        pollopen( &tp->t_ipolls );
        !          122895: 
        !          122896:                /*
        !          122897:                 * Second look to avoid interrupt race.
        !          122898:                 */
        !          122899:                if ( tp->t_iq.cq_cc == 0 )
        !          122900:                        ev &= ~POLLIN;
        !          122901:        }
        !          122902: 
        !          122903:        /*
        !          122904:         * Output poll with no space.
        !          122905:         */
        !          122906:        if ( (ev & POLLOUT) && (tp->t_oq.cq_cc >= OLOLIM) ) {
        !          122907: 
        !          122908:                /*
        !          122909:                 * Blocking output poll.
        !          122910:                 */
        !          122911:                if ( msec != 0 )
        !          122912:                        pollopen( &tp->t_opolls );
        !          122913: 
        !          122914:                /*
        !          122915:                 * Second look to avoid interrupt race.
        !          122916:                 */
        !          122917:                if ( tp->t_oq.cq_cc >= OLOLIM )
        !          122918:                        ev &= ~POLLIN;
        !          122919:        }
        !          122920: 
        !          122921:        if ( ((ev & POLLIN) == 0) && ((tp->t_flags & T_CARR) == 0) )
        !          122922:                ev |= POLLHUP;
        !          122923: 
        !          122924:        return ev;
        !          122925: }
        !          122926: 
        !          122927: /*
        !          122928:  * ttout()
        !          122929:  *
        !          122930:  *     Pull a character from the output queues of the typewriter.
        !          122931:  *     Doing fills, newline insert, tab expansion, etc.
        !          122932:  *
        !          122933:  *     If the stream is empty return a -1.
        !          122934:  *     Called at high priority.
        !          122935:  */
        !          122936: int ttout(tp)
        !          122937: register TTY *tp;
        !          122938: {
        !          122939:        register c;
        !          122940: 
        !          122941:        if (tp->t_nfill) {
        !          122942:                --tp->t_nfill;
        !          122943:                c = tp->t_fillb;
        !          122944:        } else if ((tp->t_flags&T_INL) != 0) {
        !          122945:                tp->t_flags &= ~T_INL;
        !          122946:                c = '\n';
        !          122947:        } else {
        !          122948:                if ((c=getq(&tp->t_oq)) < 0)
        !          122949:                        return -1;
        !          122950:                if (!ISROUT) {
        !          122951:                        if (c=='\n' && ISCRMOD) {
        !          122952:                                tp->t_flags |= T_INL;
        !          122953:                                c = '\r';
        !          122954:                        } else if (c=='\t' && ISXTABS) {
        !          122955:                                tp->t_nfill = ~(tp->t_hpos|~07);
        !          122956:                                tp->t_fillb = ' ';
        !          122957:                                c = ' ';
        !          122958:                        }
        !          122959:                }
        !          122960:        }
        !          122961:        if (!ISROUT) {
        !          122962:                if (c == '\b') {
        !          122963:                        if (tp->t_hpos)
        !          122964:                                --tp->t_hpos;
        !          122965:                } else if (c == '\r')
        !          122966:                        tp->t_hpos = 0;
        !          122967:                else if (c == '\t')
        !          122968:                        tp->t_hpos = (tp->t_hpos|07) + 1;
        !          122969: #if NOT_8_BIT
        !          122970:                else if (c >= ' ' && c <= '~')
        !          122971: #else
        !          122972:                else if ((c >= ' ' && c <= '~') || (c >= 0200 && c <= 0376))
        !          122973: #endif
        !          122974:                        ++tp->t_hpos;
        !          122975:        }
        !          122976:        return c;
        !          122977: }
        !          122978: 
        !          122979: /*
        !          122980:  * ttin()
        !          122981:  *
        !          122982:  *     Pass a character to the device independent typewriter routines.
        !          122983:  *     Handle erase and kill, tandem flow control, and other magic.
        !          122984:  *     Called at high priority from  the driver's interrupt processor.
        !          122985:  */
        !          122986: void ttin(tp, c)
        !          122987: register TTY *tp;
        !          122988: register c;
        !          122989: {
        !          122990:        int dc, i, n;
        !          122991: 
        !          122992:        if (!ISRIN) {
        !          122993: #if NOT_8_BIT
        !          122994:                c &= 0177;
        !          122995: #endif
        !          122996:                if (ISINTR) {
        !          122997:                        ttsignal(tp, SIGINT);
        !          122998:                        return;
        !          122999:                }
        !          123000:                if (ISQUIT) {
        !          123001:                        ttsignal(tp, SIGQUIT);
        !          123002:                        return;
        !          123003:                }
        !          123004: 
        !          123005:                /*
        !          123006:                 * Only do flow control if TANDEM is set.
        !          123007:                 */
        !          123008:                if (ISTAND) {
        !          123009:                        if (ISSTOP) {
        !          123010:                                if ((tp->t_flags&T_STOP) == 0)
        !          123011:                                        tp->t_flags |= T_STOP;
        !          123012:                                return;
        !          123013:                        }
        !          123014:                        if (ISSTART) {
        !          123015:                                tp->t_flags &= ~T_STOP;
        !          123016:                                ttstart(tp);
        !          123017:                                return;
        !          123018:                        }
        !          123019:                }
        !          123020:        }
        !          123021:        if ((tp->t_flags&T_ISTOP) != 0)
        !          123022:                return;
        !          123023:        if (!ISRIN) {
        !          123024:                if (c=='\r' && ISCRMOD)
        !          123025:                        c = '\n';
        !          123026:                if (tp->t_escape != 0) {
        !          123027:                        if (c == ESC)
        !          123028:                                ++tp->t_escape;
        !          123029:                        else {
        !          123030:                                if (ISERASE || ISKILL) {
        !          123031:                                        c |= 0200;
        !          123032:                                        --tp->t_escape;
        !          123033:                                }
        !          123034:                                while (tp->t_escape!=0 && tp->t_ibx<NCIB-1) {
        !          123035:                                        tp->t_ib[tp->t_ibx++] = ESC;
        !          123036:                                        --tp->t_escape;
        !          123037:                                }
        !          123038:                                ttstash(tp, c);
        !          123039:                        }
        !          123040:                        if (ISECHO) {
        !          123041: #if NOT_8_BIT
        !          123042:                                putq(&tp->t_oq, c&0177);
        !          123043: #else
        !          123044:                                putq(&tp->t_oq, c); /* no strip for 8-bit */
        !          123045: #endif
        !          123046:                                ttstart(tp);
        !          123047:                        }
        !          123048:                        return;
        !          123049:                }
        !          123050:                if (ISERASE && !ISCBRK) {
        !          123051:                        while (tp->t_escape!=0 && tp->t_ibx<NCIB-1) {
        !          123052:                                tp->t_ib[tp->t_ibx++] = ESC;
        !          123053:                                --tp->t_escape;
        !          123054:                        }
        !          123055:                        if (tp->t_ibx == 0)
        !          123056:                                return;
        !          123057:                        dc = tp->t_ib[--tp->t_ibx];
        !          123058:                        if (ISECHO) {
        !          123059:                                if (!ISCRT)
        !          123060:                                        putq(&tp->t_oq, c);
        !          123061:                                /* don't erase for bell, null, or rubout */
        !          123062: #if NOT_8_BIT
        !          123063:                                else if (((c = dc&0177) == '\007')
        !          123064:                                        || c == 0 || c == 0177)
        !          123065: #else
        !          123066:                                else if (((c = dc) == '\007')
        !          123067:                                        || c == 0 || c == 0177 || c == 0377)
        !          123068: #endif
        !          123069:                                        return;
        !          123070:                                else if (c != '\b' && c != '\t') {
        !          123071:                                        putq(&tp->t_oq, '\b');
        !          123072:                                        putq(&tp->t_oq,  ' ');
        !          123073:                                        putq(&tp->t_oq, '\b');
        !          123074:                                } else if (c == '\t') {
        !          123075:                                        n = tp->t_opos + tp->t_escape;
        !          123076:                                        for (i=0; i<tp->t_ibx; ++i) {
        !          123077:                                                c = tp->t_ib[i];
        !          123078: #if NOT_8_BIT
        !          123079:                                                if ((c&0200) != 0) {
        !          123080:                                                        ++n;
        !          123081:                                                        c &= 0177;
        !          123082:                                                }
        !          123083: #endif
        !          123084:                                                if (c == '\b')
        !          123085:                                                        --n;
        !          123086:                                                else {
        !          123087:                                                        if (c == '\t')
        !          123088:                                                                n |= 07;
        !          123089:                                                        ++n;
        !          123090:                                                }
        !          123091:                                        }
        !          123092:                                        while (n++ < tp->t_hpos)
        !          123093:                                                putq(&tp->t_oq, '\b');
        !          123094:                                }
        !          123095: #if NOT_8_BIT
        !          123096:                                if ((dc&0200) != 0) {
        !          123097:                                        if ((dc&0177) != '\b')
        !          123098:                                                putq(&tp->t_oq, '\b');
        !          123099:                                        putq(&tp->t_oq,  ' ');
        !          123100:                                        putq(&tp->t_oq, '\b');
        !          123101:                                }
        !          123102: #endif
        !          123103:                                ttstart(tp);
        !          123104:                        }
        !          123105:                        return;
        !          123106:                }
        !          123107:                if (ISKILL && !ISCBRK) {
        !          123108:                        tp->t_ibx = 0;
        !          123109:                        tp->t_escape = 0;
        !          123110:                        if (ISECHO) {
        !          123111:                                if (c < 0x20) {
        !          123112:                                        putq(&tp->t_oq, '^');
        !          123113:                                        c += 0x40;
        !          123114:                                }
        !          123115:                                putq(&tp->t_oq, c);
        !          123116:                                putq(&tp->t_oq, '\n');
        !          123117:                                ttstart(tp);
        !          123118:                        }
        !          123119:                        return;
        !          123120:                }
        !          123121:        }
        !          123122:        if (ISBBYB) {
        !          123123:                putq(&tp->t_iq, c);
        !          123124:                if ((tp->t_flags&T_INPUT) != 0) {
        !          123125:                        tp->t_flags &= ~T_INPUT;
        !          123126:                        defer( wakeup, (char *) &tp->t_iq );
        !          123127:                }
        !          123128:                if ( tp->t_ipolls.e_procp ) {
        !          123129:                        tp->t_ipolls.e_procp = 0;
        !          123130:                        defer( pollwake, (char *) &tp->t_ipolls );
        !          123131:                }
        !          123132:        } else {
        !          123133:                if (tp->t_ibx == 0)
        !          123134:                        tp->t_opos = tp->t_hpos;
        !          123135:                if (c == ESC)
        !          123136:                        ++tp->t_escape;
        !          123137:                else
        !          123138:                        ttstash(tp, c);
        !          123139:        }
        !          123140:        if (ISECHO) {
        !          123141:                if (ISRIN || !ISEOF) {
        !          123142:                        putq(&tp->t_oq, c);
        !          123143:                        ttstart(tp);
        !          123144:                }
        !          123145:        }
        !          123146:        if ((n=tp->t_iq.cq_cc)>=IHILIM)
        !          123147:                tp->t_flags |= T_ISTOP;
        !          123148:        else if (ISTAND && (tp->t_flags&T_TSTOP)==0 && n>=ITSLIM) {
        !          123149:                tp->t_flags |= T_TSTOP;
        !          123150:                putq(&tp->t_oq, stopc);
        !          123151:                ttstart(tp);
        !          123152:        }
        !          123153: }
        !          123154: 
        !          123155: /*
        !          123156:  * ttstash()
        !          123157:  *
        !          123158:  *     Cooked mode.
        !          123159:  *     Put character in the buffer and check for end of line.
        !          123160:  *     Only a legal end of line can take the last character position.
        !          123161:  */
        !          123162: void ttstash(tp, c)
        !          123163: register TTY *tp;
        !          123164: {
        !          123165:        register char *p1, *p2;
        !          123166: 
        !          123167:        if (c=='\n' || ISEOF || ISBRK) {
        !          123168:                p1 = &tp->t_ib[0];
        !          123169:                p2 = &tp->t_ib[tp->t_ibx];
        !          123170:                *p2++ = c;                      /* Always room */
        !          123171:                while (p1 < p2)
        !          123172: #if NOT_8_BIT
        !          123173:                        putq(&tp->t_iq, (*p1++)&0177);
        !          123174: #else
        !          123175:                        putq(&tp->t_iq, (*p1++));
        !          123176: #endif
        !          123177:                tp->t_ibx = 0;
        !          123178:                tp->t_escape = 0;
        !          123179: 
        !          123180:                if ( tp->t_flags & T_INPUT ) {
        !          123181:                        tp->t_flags &= ~T_INPUT;
        !          123182:                        defer( wakeup, (char *) &tp->t_iq );
        !          123183:                }
        !          123184: 
        !          123185:                if ( tp->t_ipolls.e_procp ) {
        !          123186:                        tp->t_ipolls.e_procp = 0;
        !          123187:                        defer( pollwake, (char *) &tp->t_ipolls );
        !          123188:                }
        !          123189: 
        !          123190:        } else if (tp->t_ibx < NCIB-1)
        !          123191:                tp->t_ib[tp->t_ibx++] = c;
        !          123192: }
        !          123193: 
        !          123194: /*
        !          123195:  * ttstart()
        !          123196:  *
        !          123197:  *     Start output on a tty.
        !          123198:  *     Duck out if stopped.  Do wakeups.
        !          123199:  */
        !          123200: void ttstart(tp)
        !          123201: register TTY *tp;
        !          123202: {
        !          123203:        register int n;
        !          123204: 
        !          123205:        n = tp->t_flags;
        !          123206:        if ( n & T_STOP )
        !          123207:                return;
        !          123208: 
        !          123209:        if ((n&T_DRAIN)!=0 && tp->t_oq.cq_cc==0
        !          123210:           && (n&T_INL)==0 && tp->t_nfill==0)
        !          123211:        {       tp->t_flags &= ~T_DRAIN;
        !          123212:                defer( wakeup, (char *) &tp->t_oq );
        !          123213:                return;
        !          123214:        }
        !          123215: 
        !          123216:        NEAR_OR_FAR_CALL(t_start)
        !          123217: 
        !          123218:        if ( tp->t_oq.cq_cc > OLOLIM )
        !          123219:                return;
        !          123220: 
        !          123221:        if ( n & T_HILIM ) {
        !          123222:                tp->t_flags &= ~T_HILIM;
        !          123223:                defer( wakeup, (char *) &tp->t_oq );
        !          123224:        }
        !          123225: 
        !          123226:        if ( tp->t_opolls.e_procp ) {
        !          123227:                tp->t_opolls.e_procp = 0;
        !          123228:                defer( pollwake, (char *) &tp->t_opolls );
        !          123229:        }
        !          123230: }
        !          123231: 
        !          123232: /*
        !          123233:  * ttflush()
        !          123234:  *
        !          123235:  *     Flush a tty.
        !          123236:  *     Called to clear out queues.
        !          123237:  */
        !          123238: void ttflush(tp)
        !          123239: register TTY *tp;
        !          123240: {
        !          123241:        clrq(&tp->t_iq);
        !          123242:        clrq(&tp->t_oq);
        !          123243: 
        !          123244:        if ( tp->t_flags & T_INPUT )
        !          123245:                defer( wakeup, (char *) &tp->t_iq );
        !          123246: 
        !          123247:        if ( tp->t_flags & (T_DRAIN|T_HILIM) )
        !          123248:                defer( wakeup, (char *) &tp->t_oq );
        !          123249: 
        !          123250:        if ( tp->t_ipolls.e_procp != 0 ) {
        !          123251:                tp->t_ipolls.e_procp = 0;
        !          123252:                defer( pollwake, (char *) &tp->t_ipolls );
        !          123253:        }
        !          123254: 
        !          123255:        if ( tp->t_opolls.e_procp != 0 ) {
        !          123256:                tp->t_opolls.e_procp = 0;
        !          123257:                defer( pollwake, (char *) &tp->t_opolls );
        !          123258:        }
        !          123259: 
        !          123260:        tp->t_ibx = 0;
        !          123261:        tp->t_escape = 0;
        !          123262:        tp->t_flags &= T_SAVE;  /* reset most flag bits */
        !          123263: }
        !          123264: 
        !          123265: /*
        !          123266:  * ttsignal()
        !          123267:  *
        !          123268:  *     Send a signal to every process in the given process group.
        !          123269:  */
        !          123270: void ttsignal(tp, sig)
        !          123271: TTY *tp;
        !          123272: int sig;
        !          123273: {
        !          123274:        register int g;
        !          123275:        register PROC *pp;
        !          123276: 
        !          123277:        g = tp->t_group;
        !          123278:        if (g == 0)
        !          123279:                return;
        !          123280:        ttflush(tp);
        !          123281:        pp = &procq;
        !          123282:        while ((pp=pp->p_nforw) != &procq)
        !          123283:                if (pp->p_group == g)
        !          123284:                        sendsig(sig, pp);
        !          123285: }
        !          123286: 
        !          123287: /*
        !          123288:  * tthup()
        !          123289:  *
        !          123290:  *     Flag hangup internally to force errors on tty read/write, flush tty,
        !          123291:  *     then send hangup signal.
        !          123292:  */
        !          123293: void tthup(tp)
        !          123294: register TTY *tp;
        !          123295: {
        !          123296:        tp->t_flags &= ~T_CARR;  /* indicate no carrier */
        !          123297:        ttflush(tp);
        !          123298:        ttsignal(tp, SIGHUP);
        !          123299: }
        !          123300: @
        !          123301: 
        !          123302: 
        !          123303: 1.8
        !          123304: log
        !          123305: @updated by hal to include rts/cts handshaking.
        !          123306: @
        !          123307: text
        !          123308: @d9 7
        !          123309: a15 1
        !          123310:  * $Log$
        !          123311: d17 1
        !          123312: d29 1
        !          123313: a29 1
        !          123314:  * 
        !          123315: d36 1
        !          123316: a36 1
        !          123317:  * 
        !          123318: d39 1
        !          123319: a39 1
        !          123320:  * 
        !          123321: d80 1
        !          123322: a80 1
        !          123323:  
        !          123324: d218 1
        !          123325: a218 1
        !          123326:                           spl(o);  
        !          123327: d226 1
        !          123328: a226 1
        !          123329:                        /* run out of characters from the clist.        */ 
        !          123330: d228 1
        !          123331: a228 1
        !          123332:                        if (ISBBYB && ((tp->t_flags & T_BRD) == 0) 
        !          123333: d230 1
        !          123334: a230 1
        !          123335:                           spl(o);  
        !          123336: d347 1
        !          123337: a347 1
        !          123338:        register int    flush = 0;  
        !          123339: d398 1
        !          123340: a398 1
        !          123341:                break;  
        !          123342: d401 1
        !          123343: a401 1
        !          123344:                   u.u_error = EPERM;        /* not su */ 
        !          123345: d407 2
        !          123346: a408 2
        !          123347:                break;  
        !          123348:        case TIOCFLUSH: 
        !          123349: d410 1
        !          123350: a410 1
        !          123351:                ++drain;        
        !          123352: d413 1
        !          123353: a413 1
        !          123354:                tp->t_flags |= T_BRD;           
        !          123355: d416 1
        !          123356: a416 1
        !          123357:                tp->t_flags &= ~T_BRD;          
        !          123358: d590 15
        !          123359: a604 9
        !          123360:                if (ISSTOP) {
        !          123361:                        if ((tp->t_flags&T_STOP) == 0)
        !          123362:                                tp->t_flags |= T_STOP;
        !          123363:                        return;
        !          123364:                } 
        !          123365:                if (ISSTART) {
        !          123366:                        tp->t_flags &= ~T_STOP;
        !          123367:                        ttstart(tp);
        !          123368:                        return;
        !          123369: @
        !          123370: 
        !          123371: 
        !          123372: 1.7
        !          123373: log
        !          123374: @update by hal
        !          123375: @
        !          123376: text
        !          123377: @d1 2
        !          123378: a2 7
        !          123379: /*          
        !          123380:  * This is the common part of
        !          123381:  * typewriter service. It handles all
        !          123382:  * device independent aspects of
        !          123383:  * a typewriter, including tandem flow
        !          123384:  * control, erase and kill, stop and
        !          123385:  * start and common ioctl functions.
        !          123386: d4 7
        !          123387: a19 1
        !          123388:  * $Log:       tty.c,v $
        !          123389: d50 5
        !          123390: d56 3
        !          123391: a58 1
        !          123392: #include <sys/clist.h>
        !          123393: d60 3
        !          123394: a64 6
        !          123395: #include <sys/sched.h>
        !          123396: #include <sys/io.h>
        !          123397: #include <sys/tty.h>
        !          123398: #include <sys/deftty.h>
        !          123399: #include <sys/stat.h>
        !          123400: #include <sys/con.h>
        !          123401: d67 5
        !          123402: a71 1
        !          123403:  * NEAR_OR_FAR_CALL is for invoking t_param and t_start
        !          123404: d73 2
        !          123405: d81 27
        !          123406: d112 4
        !          123407: a115 3
        !          123408:  * Tty open.
        !          123409:  * Called by driver on first open.
        !          123410:  * Set up defaults.
        !          123411: d117 1
        !          123412: a117 1
        !          123413: ttopen(tp)
        !          123414: d138 4
        !          123415: a141 3
        !          123416:  * ttsetgrp - set process group when process
        !          123417:  * does not have one.
        !          123418:  * Also set up process's controlling terminal.
        !          123419: d143 1
        !          123420: a143 1
        !          123421: ttsetgrp(tp, ctdev)
        !          123422: d160 5
        !          123423: a164 4
        !          123424:  * Tty close.
        !          123425:  * Called by driver on the last
        !          123426:  * close. Wait for all pending output
        !          123427:  * to go out. Kill input.
        !          123428: d166 1
        !          123429: a166 1
        !          123430: ttclose(tp)
        !          123431: d186 11
        !          123432: a196 6
        !          123433:  * Read routine.
        !          123434:  * In cooked mode, copy up to the first newline or
        !          123435:  * break character, or until the count runs out.
        !          123436:  * In CBREAK or RAW modes, return when count runs out
        !          123437:  * or when input clist is empty and we're returning
        !          123438:  * at least one byte.
        !          123439: d198 1
        !          123440: a198 1
        !          123441: ttread(tp, iop, s)
        !          123442: d207 1
        !          123443: a207 1
        !          123444:                o = spl(s);
        !          123445: d222 2
        !          123446: a223 2
        !          123447:                           && iop->io_ioc < sioc)
        !          123448:                        {  spl(o);  
        !          123449: d229 1
        !          123450: d247 3
        !          123451: d273 4
        !          123452: a276 3
        !          123453:  * Write routine.
        !          123454:  * Transfer stuff to the character
        !          123455:  * list.
        !          123456: d278 1
        !          123457: a278 1
        !          123458: ttwrite(tp, iop, s)
        !          123459: d305 1
        !          123460: a305 1
        !          123461:                o = spl(s);
        !          123462: d324 1
        !          123463: a324 1
        !          123464:        o = spl(s);
        !          123465: d330 5
        !          123466: a334 4
        !          123467:  * This routine handles common
        !          123468:  * typewriter ioctl functions. Note that
        !          123469:  * flushing the stream now means drain the
        !          123470:  * output and clear the input.
        !          123471: d336 1
        !          123472: a336 1
        !          123473: ttioctl(tp, com, vec)
        !          123474: d449 4
        !          123475: a452 2
        !          123476:  * Polling routine.
        !          123477:  * [System V.3 Compatible]
        !          123478: d454 1
        !          123479: a454 1
        !          123480: ttpoll( tp, ev, msec )
        !          123481: d507 7
        !          123482: a513 7
        !          123483:  * Pull a character from the
        !          123484:  * output queues of the typewriter.
        !          123485:  * Doing fills, newline insert,
        !          123486:  * tab expansion and all other good
        !          123487:  * things. If the stream is empty
        !          123488:  * return a -1.
        !          123489:  * Called at high priority.
        !          123490: d515 1
        !          123491: a515 1
        !          123492: ttout(tp)
        !          123493: d528 1
        !          123494: a528 1
        !          123495:                        return (-1);
        !          123496: d555 1
        !          123497: a555 1
        !          123498:        return (c);
        !          123499: d559 5
        !          123500: a563 7
        !          123501:  * Pass a character to the
        !          123502:  * device independent typewriter
        !          123503:  * routines. Handle erase and
        !          123504:  * kill, tandem flow control things
        !          123505:  * and other magic.
        !          123506:  * Called at high priority from 
        !          123507:  * the driver's interrupt processor.
        !          123508: d565 1
        !          123509: a565 1
        !          123510: ttin(tp, c)
        !          123511: d729 5
        !          123512: a733 5
        !          123513:  * Cooked mode.
        !          123514:  * Put character in the buffer and
        !          123515:  * check for end of line. Only a legal
        !          123516:  * end of line can take the last character
        !          123517:  * position.
        !          123518: d735 1
        !          123519: a735 1
        !          123520: ttstash(tp, c)
        !          123521: d768 4
        !          123522: a771 3
        !          123523:  * Start output on a tty.
        !          123524:  * Duck out if stopped.
        !          123525:  * Do wakeups.
        !          123526: d773 1
        !          123527: a773 1
        !          123528: ttstart(tp)
        !          123529: d806 4
        !          123530: a809 2
        !          123531:  * Flush a tty.
        !          123532:  * Called to clear out queues.
        !          123533: d811 1
        !          123534: a811 1
        !          123535: ttflush(tp)
        !          123536: d839 3
        !          123537: a841 1
        !          123538:  * Send a signal to every process in the given process group.
        !          123539: d843 1
        !          123540: a843 1
        !          123541: ttsignal(tp, sig)
        !          123542: d861 4
        !          123543: a864 2
        !          123544:  * Flag hangup internally to force errors
        !          123545:  * on tty read/write, flush tty, then send hangup signal.
        !          123546: d866 1
        !          123547: a866 1
        !          123548: tthup(tp)
        !          123549: @
        !          123550: 
        !          123551: 
        !          123552: 1.6
        !          123553: log
        !          123554: @update provided by hal
        !          123555: @
        !          123556: text
        !          123557: @@
        !          123558: 
        !          123559: 
        !          123560: 1.5
        !          123561: log
        !          123562: @Restore 8-bit fix.
        !          123563: @
        !          123564: text
        !          123565: @d18 4
        !          123566: a21 1
        !          123567:  * $Log:       /usr/src/sys/ttydrv/RCS/tty.c,v $
        !          123568: d49 4
        !          123569: a52 4
        !          123570: #include <coherent.h>
        !          123571: #include <clist.h>
        !          123572: #include <proc.h>
        !          123573: #include <uproc.h>
        !          123574: d54 6
        !          123575: a59 6
        !          123576: #include <sched.h>
        !          123577: #include <io.h>
        !          123578: #include <tty.h>
        !          123579: #include <deftty.h>
        !          123580: #include <stat.h>
        !          123581: #include <con.h>
        !          123582: @
        !          123583: 
        !          123584: 
        !          123585: 1.4
        !          123586: log
        !          123587: @Fix loss of chars when switching between raw & cooked.
        !          123588: @
        !          123589: text
        !          123590: @d9 3
        !          123591: d312 1
        !          123592: d314 3
        !          123593: d491 5
        !          123594: a495 1
        !          123595:                else if (c>=' ' && c<='~')
        !          123596: d517 1
        !          123597: d519 1
        !          123598: d559 1
        !          123599: d561 3
        !          123600: d580 1
        !          123601: d583 4
        !          123602: d596 1
        !          123603: d601 1
        !          123604: d613 1
        !          123605: d620 1
        !          123606: d690 1
        !          123607: d692 3
        !          123608: @
        !          123609: 
        !          123610: 
        !          123611: 1.3
        !          123612: log
        !          123613: @COH 3.1.0 version with Norm's 8bit mods added.
        !          123614: @
        !          123615: text
        !          123616: @d9 2
        !          123617: a10 2
        !          123618:  * Bug: no support for 8-bit characters.
        !          123619:  * Fix: don't strip keyboard input. 01/22/91.  norm
        !          123620: d284 1
        !          123621: d286 1
        !          123622: d298 3
        !          123623: d302 1
        !          123624: d305 7
        !          123625: d484 1
        !          123626: a484 1
        !          123627:                else if ((c >= ' ' && c <= '~') || c >= 0200)
        !          123628: d506 1
        !          123629: a534 1
        !          123630: #if 0
        !          123631: a538 1
        !          123632: #endif
        !          123633: d546 1
        !          123634: a546 1
        !          123635:                                putq(&tp->t_oq, c);     /* not stripped */
        !          123636: d563 2
        !          123637: a564 2
        !          123638:                                else if (((c = dc) == '\007')
        !          123639:                                        || c == 0 || c == 0177 || c == 0377)
        !          123640: a573 1
        !          123641: #if 0
        !          123642: a577 1
        !          123643: #endif
        !          123644: a588 1
        !          123645: #if 0
        !          123646: a594 1
        !          123647: #endif
        !          123648: d664 1
        !          123649: a664 1
        !          123650:                        putq(&tp->t_iq, (*p1++));
        !          123651: @
        !          123652: 
        !          123653: 
        !          123654: 1.2
        !          123655: log
        !          123656: @Changes for 3.1.0, but before moving commons to support.c
        !          123657: @
        !          123658: text
        !          123659: @a0 14
        !          123660: /* $Header: /usr/src/sys/ttydrv/RCS/tty.c,v 1.2 89/07/17 11:51:20 src Exp $ */
        !          123661: /* (lgl-
        !          123662:  *     The information contained herein is a trade secret of Mark Williams
        !          123663:  *     Company, and  is confidential information.  It is provided  under a
        !          123664:  *     license agreement,  and may be  copied or disclosed  only under the
        !          123665:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          123666:  *     material without the express written authorization of Mark Williams
        !          123667:  *     Company or persuant to the license agreement is unlawful.
        !          123668:  *
        !          123669:  *     COHERENT Version 2.3.37
        !          123670:  *     Copyright (c) 1982, 1983, 1984.
        !          123671:  *     An unpublished work by Mark Williams Company, Chicago.
        !          123672:  *     All rights reserved.
        !          123673:  -lgl) */
        !          123674: d9 3
        !          123675: a43 1
        !          123676: #include <al.h>
        !          123677: d55 3
        !          123678: a57 8
        !          123679: /* the following are shared by loadable serial drivers */
        !          123680: /*   (see al.h and poll_clk.h) */
        !          123681: int    com_usage[NUM_COM_PORTS];       /* COM_UNUSED/COM_IRQ/COM_POLLED */
        !          123682: int    poll_rate;
        !          123683: int    poll_owner;
        !          123684: TTY    *(tp_table[NUM_COM_PORTS]);     /* table of pointers for polling */
        !          123685: 
        !          123686: /* NEAR_OR_FAR_CALL is for invoking t_param and t_start */
        !          123687: d471 1
        !          123688: a471 1
        !          123689:                else if (c>=' ' && c<='~')
        !          123690: a492 1
        !          123691:                c &= 0177;
        !          123692: d521 1
        !          123693: d526 1
        !          123694: d534 1
        !          123695: a534 1
        !          123696:                                putq(&tp->t_oq, c&0177);
        !          123697: d551 2
        !          123698: a552 2
        !          123699:                                else if (((c = dc&0177) == '\007')
        !          123700:                                        || c == 0 || c == 0177)
        !          123701: d562 1
        !          123702: d567 1
        !          123703: d579 1
        !          123704: d586 1
        !          123705: d656 1
        !          123706: a656 1
        !          123707:                        putq(&tp->t_iq, (*p1++)&0177);
        !          123708: @
        !          123709: 
        !          123710: 
        !          123711: 1.1
        !          123712: log
        !          123713: @Used in COHERENT 3.0.0
        !          123714: @
        !          123715: text
        !          123716: @d23 3
        !          123717: d55 1
        !          123718: d67 14
        !          123719: a92 1
        !          123720: #ifdef OLD     /* How old? */
        !          123721: a94 4
        !          123722: #else
        !          123723:        tp->t_sgttyb.sg_ispeed = DEF_SG_ISPEED;  /* default speed settings */
        !          123724:        tp->t_sgttyb.sg_ospeed = DEF_SG_OSPEED;
        !          123725: #endif
        !          123726: d104 3
        !          123727: a106 2
        !          123728:        if (tp->t_param != NULL)
        !          123729:                (*tp->t_param)(tp);
        !          123730: d387 1
        !          123731: a387 1
        !          123732:                (*tp->t_param)(tp);
        !          123733: d707 1
        !          123734: a707 1
        !          123735:        (*tp->t_start)(tp);
        !          123736: @
        !          123737: 0707070064030020701004440000030000030000011777770507310741100005100000005156/newbits/kernel/USRSRC/ttydrv/RCS/ct.c,vhead     1.3;
        !          123738: branch   ;
        !          123739: access   ;
        !          123740: symbols  ;
        !          123741: locks    bin:1.3; strict;
        !          123742: comment  @ * @;
        !          123743: 
        !          123744: 
        !          123745: 1.3
        !          123746: date     91.07.15.14.36.20;  author bin;  state Exp;
        !          123747: branches ;
        !          123748: next     1.2;
        !          123749: 
        !          123750: 1.2
        !          123751: date     91.06.20.14.28.18;  author bin;  state Exp;
        !          123752: branches ;
        !          123753: next     1.1;
        !          123754: 
        !          123755: 1.1
        !          123756: date     91.06.10.10.48.01;  author bin;  state Exp;
        !          123757: branches ;
        !          123758: next     ;
        !          123759: 
        !          123760: 
        !          123761: desc
        !          123762: @initial version prov by hal
        !          123763: @
        !          123764: 
        !          123765: 
        !          123766: 1.3
        !          123767: log
        !          123768: @update by hal
        !          123769: @
        !          123770: text
        !          123771: @/* $Header: /usr/src/sys/drv/RCS/ct.c,v 1.1 88/03/24 16:18:09 src Exp $ */
        !          123772: /* (lgl-
        !          123773:  *     The information contained herein is a trade secret of Mark Williams
        !          123774:  *     Company, and  is confidential information.  It is provided  under a
        !          123775:  *     license agreement,  and may be  copied or disclosed  only under the
        !          123776:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          123777:  *     material without the express written authorization of Mark Williams
        !          123778:  *     Company or persuant to the license agreement is unlawful.
        !          123779:  *
        !          123780:  *     COHERENT Version 2.3.37
        !          123781:  *     Copyright (c) 1982, 1983, 1984.
        !          123782:  *     An unpublished work by Mark Williams Company, Chicago.
        !          123783:  *     All rights reserved.
        !          123784:  -lgl) */
        !          123785: /*
        !          123786:  * Coherent
        !          123787:  * Console terminal driver.
        !          123788:  *
        !          123789:  * $Log:       /usr/src/sys/drv/RCS/ct.c,v $
        !          123790:  * Revision 1.1        88/03/24  16:18:09      src
        !          123791:  * Initial revision
        !          123792:  * 
        !          123793:  * 86/11/19    Allan Cornish           /usr/src/sys/drv/ct.c
        !          123794:  * Added support for System V.3 compatible polls.
        !          123795:  */
        !          123796: #include <sys/coherent.h>
        !          123797: #include <sys/con.h>
        !          123798: #include <errno.h>
        !          123799: #include <sys/proc.h>
        !          123800: #include <sys/stat.h>
        !          123801: #include <sys/uproc.h>
        !          123802: 
        !          123803: /*
        !          123804:  * Functions for configuration.
        !          123805:  */
        !          123806: int    ctopen();
        !          123807: int    ctclose();
        !          123808: int    ctread();
        !          123809: int    ctwrite();
        !          123810: int    ctioctl();
        !          123811: int    ctpoll();
        !          123812: int    nulldev();
        !          123813: int    nonedev();
        !          123814: 
        !          123815: /*
        !          123816:  * Configuration table.
        !          123817:  */
        !          123818: CON ctcon ={
        !          123819:        DFCHR|DFPOL,                    /* Flags */
        !          123820:        1,                              /* Major index */
        !          123821:        ctopen,                         /* Open */
        !          123822:        ctclose,                        /* Close */
        !          123823:        nulldev,                        /* Block */
        !          123824:        ctread,                         /* Read */
        !          123825:        ctwrite,                        /* Write */
        !          123826:        ctioctl,                        /* Ioctl */
        !          123827:        nulldev,                        /* Powerfail */
        !          123828:        nulldev,                        /* Timeout */
        !          123829:        nulldev,                        /* Load */
        !          123830:        nulldev,                        /* Unload */
        !          123831:        ctpoll                          /* Poll */
        !          123832: };
        !          123833: 
        !          123834: /*
        !          123835:  * Open.
        !          123836:  */
        !          123837: ctopen(dev, m)
        !          123838: dev_t dev;
        !          123839: {
        !          123840:        register dev_t ttdev;
        !          123841: 
        !          123842:        if ((ttdev=SELF->p_ttdev) == NODEV) {
        !          123843:                u.u_error = ENXIO;
        !          123844:                return;
        !          123845:        }
        !          123846:        dopen(ttdev, m, DFCHR);
        !          123847: }
        !          123848: 
        !          123849: /*
        !          123850:  * Close.
        !          123851:  */
        !          123852: ctclose(dev)
        !          123853: dev_t dev;
        !          123854: {
        !          123855:        dclose(SELF->p_ttdev);
        !          123856: }
        !          123857: 
        !          123858: /*
        !          123859:  * Read.
        !          123860:  */
        !          123861: ctread(dev, iop)
        !          123862: dev_t dev;
        !          123863: IO *iop;
        !          123864: {
        !          123865:        dread(SELF->p_ttdev, iop);
        !          123866: }
        !          123867: 
        !          123868: /*
        !          123869:  * Write.
        !          123870:  */
        !          123871: ctwrite(dev, iop)
        !          123872: dev_t dev;
        !          123873: IO *iop;
        !          123874: {
        !          123875:        dwrite(SELF->p_ttdev, iop);
        !          123876: }
        !          123877: 
        !          123878: /*
        !          123879:  * Ioctl.
        !          123880:  */
        !          123881: ctioctl(dev, com, vec)
        !          123882: dev_t dev;
        !          123883: struct sgttyb *vec;
        !          123884: {
        !          123885:        dioctl(SELF->p_ttdev, com, vec);
        !          123886: }
        !          123887: 
        !          123888: /*
        !          123889:  * Poll.
        !          123890:  */
        !          123891: ctpoll(dev, ev)
        !          123892: dev_t dev;
        !          123893: int ev;
        !          123894: {
        !          123895:        return dpoll(SELF->p_ttdev, ev);
        !          123896: }
        !          123897: @
        !          123898: 
        !          123899: 
        !          123900: 1.2
        !          123901: log
        !          123902: @update provided by hal
        !          123903: @
        !          123904: text
        !          123905: @@
        !          123906: 
        !          123907: 
        !          123908: 1.1
        !          123909: log
        !          123910: @Initial revision
        !          123911: @
        !          123912: text
        !          123913: @@
        !          123914: 0707070064030103060407550000030000030000011777770507310741100003300000000000/newbits/kernel/USRSRC/ker0707070064030103101006440000030000030000011777770507310741100004200000002276/newbits/kernel/USRSRC/ker/elog.c/* $Header: /usr/src/sys/ker/RCS/elog.c,v 1.1 88/03/24 16:19:48 src Exp $ */
        !          123915: /* (lgl-
        !          123916:  *     The information contained herein is a trade secret of Mark Williams
        !          123917:  *     Company, and  is confidential information.  It is provided  under a
        !          123918:  *     license agreement,  and may be  copied or disclosed  only under the
        !          123919:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          123920:  *     material without the express written authorization of Mark Williams
        !          123921:  *     Company or persuant to the license agreement is unlawful.
        !          123922:  *
        !          123923:  *     COHERENT Version 2.3.37
        !          123924:  *     Copyright (c) 1982, 1983, 1984.
        !          123925:  *     An unpublished work by Mark Williams Company, Chicago.
        !          123926:  *     All rights reserved.
        !          123927:  -lgl) */
        !          123928: /*
        !          123929:  * Coherent - event/error logging facility.
        !          123930:  *
        !          123931:  * $Log:       /usr/src/sys/ker/RCS/elog.c,v $
        !          123932:  * Revision 1.1        88/03/24  16:19:48      src
        !          123933:  * Initial revision
        !          123934:  * 
        !          123935:  */
        !          123936: #include <coherent.h>
        !          123937: 
        !          123938: #define NEVENT 256
        !          123939: typedef struct {
        !          123940:        char    *e_event;       /* Function pointer or whatever */
        !          123941:        int     e_time;         /* Timer tick of event */
        !          123942: } EVENT;
        !          123943: 
        !          123944: EVENT events[NEVENT];
        !          123945: unsigned curevent = 0;
        !          123946: unsigned totevent = 0;
        !          123947: 
        !          123948: elog(eventp)
        !          123949: char *eventp;
        !          123950: {
        !          123951:        register EVENT *ep;
        !          123952: 
        !          123953:        totevent += 1;
        !          123954:        ep = &events[curevent++];
        !          123955:        curevent %= NEVENT;
        !          123956:        ep->e_event = eventp;
        !          123957:        ep->e_time = timer.t_time;
        !          123958: }
        !          123959: 0707070064030104701006440000030000030000011777770507310741200004200000021036/newbits/kernel/USRSRC/ker/swap.c/* $Header: /usr/src/sys/ker/RCS/swap.c,v 1.1 88/03/24 16:19:51 src Exp $ */
        !          123960: /* (lgl-
        !          123961:  *     The information contained herein is a trade secret of Mark Williams
        !          123962:  *     Company, and  is confidential information.  It is provided  under a
        !          123963:  *     license agreement,  and may be  copied or disclosed  only under the
        !          123964:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          123965:  *     material without the express written authorization of Mark Williams
        !          123966:  *     Company or persuant to the license agreement is unlawful.
        !          123967:  *
        !          123968:  *     COHERENT Version 2.3.37
        !          123969:  *     Copyright (c) 1982, 1983, 1984.
        !          123970:  *     An unpublished work by Mark Williams Company, Chicago.
        !          123971:  *     All rights reserved.
        !          123972:  -lgl) */
        !          123973: /*
        !          123974:  * Coherent.
        !          123975:  * Swapper.
        !          123976:  *
        !          123977:  * $Log:       /usr/src/sys/ker/RCS/swap.c,v $
        !          123978:  * Revision 1.1        88/03/24  16:19:51      src
        !          123979:  * Initial revision
        !          123980:  * 
        !          123981:  * 87/01/05    Allan Cornish           /usr/src/sys/ker/swap.c
        !          123982:  * Swap() now waits for all processes to be swapped in before exit on signal.
        !          123983:  */
        !          123984: #include <coherent.h>
        !          123985: #include <proc.h>
        !          123986: #include <sched.h>
        !          123987: #include <sys/seg.h>
        !          123988: #include <sys/uproc.h>
        !          123989: #include <sys/buf.h>
        !          123990: 
        !          123991: /*
        !          123992:  * Functions.
        !          123993:  */
        !          123994: SEG    *xmalloc();
        !          123995: SEG    *xdalloc();
        !          123996: 
        !          123997: swap()
        !          123998: {
        !          123999:        register SEG *sp;
        !          124000:        register PROC *pp1;
        !          124001:        register PROC *pp2;
        !          124002:        register PROC *pp3;
        !          124003:        register unsigned s;
        !          124004:        register unsigned n;
        !          124005:        register unsigned t;
        !          124006:        register unsigned v;
        !          124007:        register unsigned m;
        !          124008:        register int i;
        !          124009:        static unsigned ltimer;
        !          124010: 
        !          124011:        if (sexflag != 0)
        !          124012:                uexit(1);
        !          124013:        sexflag++;
        !          124014:        while (1) {
        !          124015:                lock(pnxgate);
        !          124016:                t = (utimer-ltimer)/NSUTICK;
        !          124017:                v = t*SVCLOCK;
        !          124018:                ltimer += t*NSUTICK;
        !          124019:                m = 0;
        !          124020:                pp2 = NULL;
        !          124021:                for (pp1=procq.p_nback; pp1!=&procq; pp1=pp1->p_nback) {
        !          124022:                        if ((pp1->p_flags&PFCORE) != 0) {
        !          124023:                                pp1->p_sval >>= t;
        !          124024:                                pp1->p_ival -= t;
        !          124025:                                if (pp1->p_ival < -30000)
        !          124026:                                        pp1->p_ival = -30000;
        !          124027:                                continue;
        !          124028:                        }
        !          124029:                        addu(pp1->p_sval, v);
        !          124030:                        if (pp1->p_state != PSRUN)
        !          124031:                                continue;
        !          124032:                        s = 0;
        !          124033:                        for (i=0; i<NUSEG+1; i++)
        !          124034:                                if ((sp=pp1->p_segp[i]) != NULL)
        !          124035:                                        if ((sp->s_flags&SFCORE) == 0)
        !          124036:                                                s += sp->s_size;
        !          124037:                        if ((s=ctokrd(s)) == 0)
        !          124038:                                s = 1;
        !          124039:                        n = (pp1->p_sval+pp1->p_rval)/s;
        !          124040:                        if (n > m) {
        !          124041:                                m = n;
        !          124042:                                pp2 = pp1;
        !          124043:                        }
        !          124044:                }
        !          124045:                unlock(pnxgate);
        !          124046:                if (pp2 == NULL) {
        !          124047:                        if ( SELF->p_ssig != 0 )
        !          124048:                                break;
        !          124049:                        goto con;
        !          124050:                }
        !          124051: #ifndef        NOMONITOR
        !          124052:                if (swmflag)
        !          124053:                        printf("Swapin(%p, %d)\n", pp2, pp2->p_pid);
        !          124054: #endif
        !          124055:        xxx:
        !          124056:                while (testcore(pp2)==0 || proccore(pp2)!=0) {
        !          124057:                        if ((pp2->p_flags&PFAUXM) != 0) {
        !          124058:                                auxmdisk(pp2);
        !          124059:                                goto xxx;
        !          124060:                        }
        !          124061:                        procdisk(pp2);
        !          124062:                        i = 32767;
        !          124063:                        pp3 = NULL;
        !          124064:                        lock(pnxgate);
        !          124065:                        for (pp1=procq.p_nforw; pp1!=&procq; pp1=pp1->p_nforw){
        !          124066:                                if (pp1->p_flags&(PFSWIO|PFLOCK|PFKERN))
        !          124067:                                        continue;
        !          124068:                                if ((pp1->p_flags&PFAUXM) != 0) {
        !          124069:                                        auxmdisk(pp1);
        !          124070:                                        unlock(pnxgate);
        !          124071:                                        goto xxx;
        !          124072:                                }
        !          124073:                                if ((pp1->p_flags&PFCORE) == 0) {
        !          124074:                                        if (procdisk(pp1) != 0) {
        !          124075:                                                unlock(pnxgate);
        !          124076:                                                goto xxx;
        !          124077:                                        }
        !          124078:                                        continue;
        !          124079:                                }
        !          124080:                                if (pp1->p_ival>-64 && pp1->p_sval!=0)
        !          124081:                                        continue;
        !          124082:                                if (pp1->p_ival < i) {
        !          124083:                                        i = pp1->p_ival;
        !          124084:                                        pp3 = pp1;
        !          124085:                                }
        !          124086:                        }
        !          124087:                        unlock(pnxgate);
        !          124088:                        if (pp3 == NULL) {
        !          124089: #ifndef NOMONITOR
        !          124090:                                if (swmflag)
        !          124091:                                        printf("No one to swap out\n");
        !          124092: #endif
        !          124093:                                break;
        !          124094:                        }
        !          124095:                        if (i > 0) {
        !          124096: #ifndef NOMONITOR
        !          124097:                                if (swmflag)
        !          124098:                                        printf("Dispatch(%p, %d)\n",
        !          124099:                                                pp3, pp3->p_pid);
        !          124100: #endif
        !          124101:                                pp3->p_flags |= PFDISP;
        !          124102:                                break;
        !          124103:                        }
        !          124104: #ifndef NOMONITOR
        !          124105:                        if (swmflag)
        !          124106:                                printf("Swapout(%p, %d)\n", pp3, pp3->p_pid);
        !          124107: #endif
        !          124108:                        procdisk(pp3);
        !          124109:                }
        !          124110: #ifndef NOMONITOR
        !          124111:                if (swmflag)
        !          124112:                        printf("Swapdone\n");
        !          124113: #endif
        !          124114:        con:
        !          124115:                timeout(&stimer, NSRTICK, wakeup, (char *)&stimer);
        !          124116:                sleep((char *)&stimer, CVSWAP, IVSWAP, SVSWAP);
        !          124117:        }
        !          124118:        --sexflag;
        !          124119:        uexit(1);
        !          124120: }
        !          124121: 
        !          124122: /*
        !          124123:  * See if the given process may fit in core.
        !          124124:  */
        !          124125: testcore(pp)
        !          124126: register PROC *pp;
        !          124127: {
        !          124128:        register SEG *sp;
        !          124129:        register saddr_t s;
        !          124130:        register saddr_t s1;
        !          124131:        register saddr_t s2;
        !          124132:        register int i;
        !          124133: 
        !          124134:        s = 0;
        !          124135:        for (i=0; i<NUSEG+1; i++) {
        !          124136:                if ((sp=pp->p_segp[i]) == NULL)
        !          124137:                        continue;
        !          124138:                if ((sp->s_flags&SFCORE) != 0)
        !          124139:                        continue;
        !          124140:                if (sp->s_size > s)
        !          124141:                        s = sp->s_size;
        !          124142:        }
        !          124143:        s1 = corebot;
        !          124144:        sp = &segmq;
        !          124145:        do {
        !          124146:                sp = sp->s_forw;
        !          124147:                s2 = sp->s_mbase;
        !          124148:                if (s2-s1 >= s)
        !          124149:                        return (1);
        !          124150:                s1 = sp->s_mbase + sp->s_size;
        !          124151:        } while (sp != &segmq);
        !          124152:        return (0);
        !          124153: }
        !          124154: 
        !          124155: /*
        !          124156:  * Swap all segments associated with a particular process into core.
        !          124157:  * The number of segments still swapped out is returned.
        !          124158:  */
        !          124159: proccore(pp)
        !          124160: register PROC *pp;
        !          124161: {
        !          124162:        register SEG *sp;
        !          124163:        register int i;
        !          124164:        register int n;
        !          124165:        register int f;
        !          124166: 
        !          124167:        n = 0;
        !          124168:        f = pp->p_flags&PFSWAP;
        !          124169:        for (i=0; i<NUSEG+1; i++) {
        !          124170:                if ((sp=pp->p_segp[i]) == NULL)
        !          124171:                        continue;
        !          124172:                if (f != 0)
        !          124173:                        sp->s_lrefc++;
        !          124174:                if ((sp->s_flags&SFCORE)==0 && segcore(sp)==0)
        !          124175:                        n++;
        !          124176:        }
        !          124177:        if (n == 0)
        !          124178:                pp->p_flags |= PFCORE;
        !          124179:        pp->p_flags &= ~PFSWAP;
        !          124180:        return (n);
        !          124181: }
        !          124182: 
        !          124183: /*
        !          124184:  * Swap out all segments associated with a given process.
        !          124185:  */
        !          124186: procdisk(pp)
        !          124187: register PROC *pp;
        !          124188: {
        !          124189:        register SEG *sp;
        !          124190:        register int i;
        !          124191:        register int f;
        !          124192:        int n;
        !          124193: 
        !          124194:        n = 0;
        !          124195:        f = pp->p_flags&PFSWAP;
        !          124196:        pp->p_flags &= ~PFCORE;
        !          124197:        for (i=0; i<NUSEG+1; i++) {
        !          124198:                if ((sp=pp->p_segp[i]) == NULL)
        !          124199:                        continue;
        !          124200:                if (f == 0)
        !          124201:                        --sp->s_lrefc;
        !          124202:                if ((sp->s_flags&SFCORE) == 0)
        !          124203:                        continue;
        !          124204:                if (sp->s_lrefc == 0)
        !          124205:                        if (segdisk(sp) != 0)
        !          124206:                                n++;
        !          124207:        }
        !          124208:        pp->p_flags |= PFSWAP;
        !          124209:        return (n);
        !          124210: }
        !          124211: 
        !          124212: /*
        !          124213:  * Swap out all auxiliary segments used by a process.
        !          124214:  */
        !          124215: auxmdisk(pp)
        !          124216: register PROC *pp;
        !          124217: {
        !          124218:        register SEG *sp;
        !          124219:        register int i;
        !          124220:        register int f;
        !          124221:        register int m;
        !          124222:        SEG *segl[NUSEG];
        !          124223: 
        !          124224: #ifndef NOMONITOR
        !          124225:        if (swmflag)
        !          124226:                printf("Auxiliary(%p, %d)\n", pp, pp->p_pid);
        !          124227: #endif
        !          124228:        sp = pp->p_segp[SIUSERP];
        !          124229:        if ((sp->s_flags&SFCORE) == 0) {
        !          124230:                panic("We may be in trouble");
        !          124231:                return;
        !          124232:        }
        !          124233:        m = pp->p_flags&PFCORE;
        !          124234:        f = pp->p_flags&PFAUXM;
        !          124235:        pp->p_flags &= ~(PFAUXM|PFCORE);
        !          124236:        skcopy(sp, offset(uproc, u_sege[0]), segl, sizeof(u.u_sege));
        !          124237:        for (i=0; i<NUSEG; i++) {
        !          124238:                if ((sp=segl[i]) == NULL)
        !          124239:                        continue;
        !          124240:                if (f != 0)
        !          124241:                        --sp->s_lrefc;
        !          124242:                if ((sp->s_flags&SFCORE) == 0)
        !          124243:                        continue;
        !          124244:                if (sp->s_lrefc == 0)
        !          124245:                        segdisk(sp);
        !          124246:        }
        !          124247:        pp->p_flags |= m;
        !          124248: }
        !          124249: 
        !          124250: /*
        !          124251:  * Swap the given segment into core.
        !          124252:  */
        !          124253: segcore(sp1)
        !          124254: register SEG *sp1;
        !          124255: {
        !          124256:        register SEG *sp2;
        !          124257: 
        !          124258:        lock(seglink);
        !          124259:        sp2 = xmalloc(sp1->s_size);
        !          124260:        unlock(seglink);
        !          124261:        if (sp2 == NULL)
        !          124262:                return (0);
        !          124263:        sp1->s_lrefc++;
        !          124264:        swapio(0, sp2->s_mbase, sp1->s_dbase, sp2->s_size);
        !          124265:        lock(seglink);
        !          124266:        sp1->s_back->s_forw = sp1->s_forw;
        !          124267:        sp1->s_forw->s_back = sp1->s_back;
        !          124268:        sp2->s_back->s_forw = sp1;
        !          124269:        sp1->s_back = sp2->s_back;
        !          124270:        sp2->s_forw->s_back = sp1;
        !          124271:        sp1->s_forw = sp2->s_forw;
        !          124272:        sp1->s_flags |= SFCORE;
        !          124273:        sp1->s_mbase = sp2->s_mbase;
        !          124274:        --sp1->s_lrefc;
        !          124275:        unlock(seglink);
        !          124276:        return (1);
        !          124277: }
        !          124278: 
        !          124279: /*
        !          124280:  * Swap the given segment out onto disk.
        !          124281:  */
        !          124282: segdisk(sp1)
        !          124283: register SEG *sp1;
        !          124284: {
        !          124285:        register SEG *sp2;
        !          124286: 
        !          124287:        lock(seglink);
        !          124288:        sp2 = xdalloc(sp1->s_size);
        !          124289:        unlock(seglink);
        !          124290:        if (sp2 == NULL)
        !          124291:                return (0);
        !          124292:        sp1->s_lrefc++;
        !          124293:        swapio(1, sp1->s_mbase, sp2->s_dbase, sp1->s_size);
        !          124294:        lock(seglink);
        !          124295:        sp1->s_back->s_forw = sp1->s_forw;
        !          124296:        sp1->s_forw->s_back = sp1->s_back;
        !          124297:        sp2->s_back->s_forw = sp1;
        !          124298:        sp1->s_back = sp2->s_back;
        !          124299:        sp2->s_forw->s_back = sp1;
        !          124300:        sp1->s_forw = sp2->s_forw;
        !          124301:        sp1->s_flags &= ~SFCORE;
        !          124302:        sp1->s_dbase = sp2->s_dbase;
        !          124303:        --sp1->s_lrefc;
        !          124304:        unlock(seglink);
        !          124305:        return (1);
        !          124306: }
        !          124307: 
        !          124308: /*
        !          124309:  * Allocate a segment on disk that is `n' clicks long.
        !          124310:  * The `seglink' gate should be locked before this routine is called.
        !          124311:  * This routine is the same as `sdalloc' except that we can't run out of
        !          124312:  * alloc space to allocate the segment and we allocate in high regions.
        !          124313:  */
        !          124314: SEG *
        !          124315: xdalloc(s)
        !          124316: saddr_t s;
        !          124317: {
        !          124318:        register SEG *sp1;
        !          124319:        register SEG *sp2;
        !          124320:        register daddr_t d;
        !          124321:        register daddr_t d1;
        !          124322:        register daddr_t d2;
        !          124323: 
        !          124324:        d = stod(s);
        !          124325:        d2 = swaptop;
        !          124326:        sp1 = &segdq;
        !          124327:        do {
        !          124328:                if ((sp1=sp1->s_back) != &segdq)
        !          124329:                        d1 = sp1->s_dbase + stod(sp1->s_size);
        !          124330:                else
        !          124331:                        d1 = swapbot;
        !          124332:                if (d2-d1 >= d) {
        !          124333:                        sp2 = &segswap;
        !          124334:                        kclear((char *)sp2, sizeof(SEG));
        !          124335:                        sp1->s_forw->s_back = sp2;
        !          124336:                        sp2->s_forw = sp1->s_forw;
        !          124337:                        sp1->s_forw = sp2;
        !          124338:                        sp2->s_back = sp1;
        !          124339:                        sp2->s_urefc = 1;
        !          124340:                        sp2->s_lrefc = 1;
        !          124341:                        sp2->s_size = s;
        !          124342:                        sp2->s_dbase = d2 - d;
        !          124343:                        return (sp2);
        !          124344:                }
        !          124345:                d2 = sp1->s_dbase;
        !          124346:        } while (sp1 != &segdq);
        !          124347:        return (NULL);
        !          124348: }
        !          124349: 
        !          124350: /*
        !          124351:  * Allocate a segment in memory that is `n' clicks long.
        !          124352:  * The `seglink' gate should be locked before this routine is called.
        !          124353:  * This routine is the same as `smalloc' except that we can't run out of
        !          124354:  * alloc space to allocate the segment.
        !          124355:  */
        !          124356: SEG *
        !          124357: xmalloc(s)
        !          124358: register saddr_t s;
        !          124359: {
        !          124360:        register SEG *sp1;
        !          124361:        register SEG *sp2;
        !          124362:        register saddr_t s1;
        !          124363:        register saddr_t s2;
        !          124364: 
        !          124365:        s1 = corebot;
        !          124366:        sp1 = &segmq;
        !          124367:        do {
        !          124368:                if ((sp1=sp1->s_forw) != &segmq)
        !          124369:                        s2 = sp1->s_mbase;
        !          124370:                else
        !          124371:                        s2 = coretop;
        !          124372:                if (s2-s1 >= s) {
        !          124373:                        sp2 = &segswap;
        !          124374:                        kclear((char *)sp2, sizeof(SEG));
        !          124375:                        sp1->s_back->s_forw = sp2;
        !          124376:                        sp2->s_back = sp1->s_back;
        !          124377:                        sp1->s_back = sp2;
        !          124378:                        sp2->s_forw = sp1;
        !          124379:                        sp2->s_urefc = 1;
        !          124380:                        sp2->s_lrefc = 1;
        !          124381:                        sp2->s_size = s;
        !          124382:                        sp2->s_mbase = s1;
        !          124383:                        return (sp2);
        !          124384:                }
        !          124385:                s1 = sp1->s_mbase + sp1->s_size;
        !          124386:        } while (sp1 != &segmq);
        !          124387:        return (NULL);
        !          124388: }
        !          124389: 0707070064030104760407550000030000030000011777770507310741400003700000000000/newbits/kernel/USRSRC/ker/RCS0707070064030105341004440000030000030000011777770507310741400005000000003262/newbits/kernel/USRSRC/ker/RCS/elog.c,vhead     1.3;
        !          124390: branch   ;
        !          124391: access   ;
        !          124392: symbols  ;
        !          124393: locks    bin:1.3; strict;
        !          124394: comment  @ * @;
        !          124395: 
        !          124396: 
        !          124397: 1.3
        !          124398: date     91.07.15.14.38.03;  author bin;  state Exp;
        !          124399: branches ;
        !          124400: next     1.2;
        !          124401: 
        !          124402: 1.2
        !          124403: date     91.06.20.14.37.26;  author bin;  state Exp;
        !          124404: branches ;
        !          124405: next     1.1;
        !          124406: 
        !          124407: 1.1
        !          124408: date     91.06.10.10.42.07;  author bin;  state Exp;
        !          124409: branches ;
        !          124410: next     ;
        !          124411: 
        !          124412: 
        !          124413: desc
        !          124414: @initial version provided by stevesf 
        !          124415: @
        !          124416: 
        !          124417: 
        !          124418: 1.3
        !          124419: log
        !          124420: @update by hal
        !          124421: @
        !          124422: text
        !          124423: @/* $Header: /usr/src/sys/ker/RCS/elog.c,v 1.1 88/03/24 16:19:48 src Exp $ */
        !          124424: /* (lgl-
        !          124425:  *     The information contained herein is a trade secret of Mark Williams
        !          124426:  *     Company, and  is confidential information.  It is provided  under a
        !          124427:  *     license agreement,  and may be  copied or disclosed  only under the
        !          124428:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          124429:  *     material without the express written authorization of Mark Williams
        !          124430:  *     Company or persuant to the license agreement is unlawful.
        !          124431:  *
        !          124432:  *     COHERENT Version 2.3.37
        !          124433:  *     Copyright (c) 1982, 1983, 1984.
        !          124434:  *     An unpublished work by Mark Williams Company, Chicago.
        !          124435:  *     All rights reserved.
        !          124436:  -lgl) */
        !          124437: /*
        !          124438:  * Coherent - event/error logging facility.
        !          124439:  *
        !          124440:  * $Log:       /usr/src/sys/ker/RCS/elog.c,v $
        !          124441:  * Revision 1.1        88/03/24  16:19:48      src
        !          124442:  * Initial revision
        !          124443:  * 
        !          124444:  */
        !          124445: #include <coherent.h>
        !          124446: 
        !          124447: #define NEVENT 256
        !          124448: typedef struct {
        !          124449:        char    *e_event;       /* Function pointer or whatever */
        !          124450:        int     e_time;         /* Timer tick of event */
        !          124451: } EVENT;
        !          124452: 
        !          124453: EVENT events[NEVENT];
        !          124454: unsigned curevent = 0;
        !          124455: unsigned totevent = 0;
        !          124456: 
        !          124457: elog(eventp)
        !          124458: char *eventp;
        !          124459: {
        !          124460:        register EVENT *ep;
        !          124461: 
        !          124462:        totevent += 1;
        !          124463:        ep = &events[curevent++];
        !          124464:        curevent %= NEVENT;
        !          124465:        ep->e_event = eventp;
        !          124466:        ep->e_time = timer.t_time;
        !          124467: }
        !          124468: @
        !          124469: 
        !          124470: 
        !          124471: 1.2
        !          124472: log
        !          124473: @update provided by hal
        !          124474: @
        !          124475: text
        !          124476: @@
        !          124477: 
        !          124478: 
        !          124479: 1.1
        !          124480: log
        !          124481: @Initial revision
        !          124482: @
        !          124483: text
        !          124484: @@
        !          124485: 0707070064030104711004440000030000030000011777770507310741400005000000022022/newbits/kernel/USRSRC/ker/RCS/swap.c,vhead     1.3;
        !          124486: branch   ;
        !          124487: access   ;
        !          124488: symbols  ;
        !          124489: locks    bin:1.3; strict;
        !          124490: comment  @ * @;
        !          124491: 
        !          124492: 
        !          124493: 1.3
        !          124494: date     91.07.15.14.38.09;  author bin;  state Exp;
        !          124495: branches ;
        !          124496: next     1.2;
        !          124497: 
        !          124498: 1.2
        !          124499: date     91.06.20.14.37.37;  author bin;  state Exp;
        !          124500: branches ;
        !          124501: next     1.1;
        !          124502: 
        !          124503: 1.1
        !          124504: date     91.06.10.10.42.08;  author bin;  state Exp;
        !          124505: branches ;
        !          124506: next     ;
        !          124507: 
        !          124508: 
        !          124509: desc
        !          124510: @initial version provided by stevesf 
        !          124511: @
        !          124512: 
        !          124513: 
        !          124514: 1.3
        !          124515: log
        !          124516: @update by hal
        !          124517: @
        !          124518: text
        !          124519: @/* $Header: /usr/src/sys/ker/RCS/swap.c,v 1.1 88/03/24 16:19:51 src Exp $ */
        !          124520: /* (lgl-
        !          124521:  *     The information contained herein is a trade secret of Mark Williams
        !          124522:  *     Company, and  is confidential information.  It is provided  under a
        !          124523:  *     license agreement,  and may be  copied or disclosed  only under the
        !          124524:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          124525:  *     material without the express written authorization of Mark Williams
        !          124526:  *     Company or persuant to the license agreement is unlawful.
        !          124527:  *
        !          124528:  *     COHERENT Version 2.3.37
        !          124529:  *     Copyright (c) 1982, 1983, 1984.
        !          124530:  *     An unpublished work by Mark Williams Company, Chicago.
        !          124531:  *     All rights reserved.
        !          124532:  -lgl) */
        !          124533: /*
        !          124534:  * Coherent.
        !          124535:  * Swapper.
        !          124536:  *
        !          124537:  * $Log:       /usr/src/sys/ker/RCS/swap.c,v $
        !          124538:  * Revision 1.1        88/03/24  16:19:51      src
        !          124539:  * Initial revision
        !          124540:  * 
        !          124541:  * 87/01/05    Allan Cornish           /usr/src/sys/ker/swap.c
        !          124542:  * Swap() now waits for all processes to be swapped in before exit on signal.
        !          124543:  */
        !          124544: #include <coherent.h>
        !          124545: #include <proc.h>
        !          124546: #include <sched.h>
        !          124547: #include <sys/seg.h>
        !          124548: #include <sys/uproc.h>
        !          124549: #include <sys/buf.h>
        !          124550: 
        !          124551: /*
        !          124552:  * Functions.
        !          124553:  */
        !          124554: SEG    *xmalloc();
        !          124555: SEG    *xdalloc();
        !          124556: 
        !          124557: swap()
        !          124558: {
        !          124559:        register SEG *sp;
        !          124560:        register PROC *pp1;
        !          124561:        register PROC *pp2;
        !          124562:        register PROC *pp3;
        !          124563:        register unsigned s;
        !          124564:        register unsigned n;
        !          124565:        register unsigned t;
        !          124566:        register unsigned v;
        !          124567:        register unsigned m;
        !          124568:        register int i;
        !          124569:        static unsigned ltimer;
        !          124570: 
        !          124571:        if (sexflag != 0)
        !          124572:                uexit(1);
        !          124573:        sexflag++;
        !          124574:        while (1) {
        !          124575:                lock(pnxgate);
        !          124576:                t = (utimer-ltimer)/NSUTICK;
        !          124577:                v = t*SVCLOCK;
        !          124578:                ltimer += t*NSUTICK;
        !          124579:                m = 0;
        !          124580:                pp2 = NULL;
        !          124581:                for (pp1=procq.p_nback; pp1!=&procq; pp1=pp1->p_nback) {
        !          124582:                        if ((pp1->p_flags&PFCORE) != 0) {
        !          124583:                                pp1->p_sval >>= t;
        !          124584:                                pp1->p_ival -= t;
        !          124585:                                if (pp1->p_ival < -30000)
        !          124586:                                        pp1->p_ival = -30000;
        !          124587:                                continue;
        !          124588:                        }
        !          124589:                        addu(pp1->p_sval, v);
        !          124590:                        if (pp1->p_state != PSRUN)
        !          124591:                                continue;
        !          124592:                        s = 0;
        !          124593:                        for (i=0; i<NUSEG+1; i++)
        !          124594:                                if ((sp=pp1->p_segp[i]) != NULL)
        !          124595:                                        if ((sp->s_flags&SFCORE) == 0)
        !          124596:                                                s += sp->s_size;
        !          124597:                        if ((s=ctokrd(s)) == 0)
        !          124598:                                s = 1;
        !          124599:                        n = (pp1->p_sval+pp1->p_rval)/s;
        !          124600:                        if (n > m) {
        !          124601:                                m = n;
        !          124602:                                pp2 = pp1;
        !          124603:                        }
        !          124604:                }
        !          124605:                unlock(pnxgate);
        !          124606:                if (pp2 == NULL) {
        !          124607:                        if ( SELF->p_ssig != 0 )
        !          124608:                                break;
        !          124609:                        goto con;
        !          124610:                }
        !          124611: #ifndef        NOMONITOR
        !          124612:                if (swmflag)
        !          124613:                        printf("Swapin(%p, %d)\n", pp2, pp2->p_pid);
        !          124614: #endif
        !          124615:        xxx:
        !          124616:                while (testcore(pp2)==0 || proccore(pp2)!=0) {
        !          124617:                        if ((pp2->p_flags&PFAUXM) != 0) {
        !          124618:                                auxmdisk(pp2);
        !          124619:                                goto xxx;
        !          124620:                        }
        !          124621:                        procdisk(pp2);
        !          124622:                        i = 32767;
        !          124623:                        pp3 = NULL;
        !          124624:                        lock(pnxgate);
        !          124625:                        for (pp1=procq.p_nforw; pp1!=&procq; pp1=pp1->p_nforw){
        !          124626:                                if (pp1->p_flags&(PFSWIO|PFLOCK|PFKERN))
        !          124627:                                        continue;
        !          124628:                                if ((pp1->p_flags&PFAUXM) != 0) {
        !          124629:                                        auxmdisk(pp1);
        !          124630:                                        unlock(pnxgate);
        !          124631:                                        goto xxx;
        !          124632:                                }
        !          124633:                                if ((pp1->p_flags&PFCORE) == 0) {
        !          124634:                                        if (procdisk(pp1) != 0) {
        !          124635:                                                unlock(pnxgate);
        !          124636:                                                goto xxx;
        !          124637:                                        }
        !          124638:                                        continue;
        !          124639:                                }
        !          124640:                                if (pp1->p_ival>-64 && pp1->p_sval!=0)
        !          124641:                                        continue;
        !          124642:                                if (pp1->p_ival < i) {
        !          124643:                                        i = pp1->p_ival;
        !          124644:                                        pp3 = pp1;
        !          124645:                                }
        !          124646:                        }
        !          124647:                        unlock(pnxgate);
        !          124648:                        if (pp3 == NULL) {
        !          124649: #ifndef NOMONITOR
        !          124650:                                if (swmflag)
        !          124651:                                        printf("No one to swap out\n");
        !          124652: #endif
        !          124653:                                break;
        !          124654:                        }
        !          124655:                        if (i > 0) {
        !          124656: #ifndef NOMONITOR
        !          124657:                                if (swmflag)
        !          124658:                                        printf("Dispatch(%p, %d)\n",
        !          124659:                                                pp3, pp3->p_pid);
        !          124660: #endif
        !          124661:                                pp3->p_flags |= PFDISP;
        !          124662:                                break;
        !          124663:                        }
        !          124664: #ifndef NOMONITOR
        !          124665:                        if (swmflag)
        !          124666:                                printf("Swapout(%p, %d)\n", pp3, pp3->p_pid);
        !          124667: #endif
        !          124668:                        procdisk(pp3);
        !          124669:                }
        !          124670: #ifndef NOMONITOR
        !          124671:                if (swmflag)
        !          124672:                        printf("Swapdone\n");
        !          124673: #endif
        !          124674:        con:
        !          124675:                timeout(&stimer, NSRTICK, wakeup, (char *)&stimer);
        !          124676:                sleep((char *)&stimer, CVSWAP, IVSWAP, SVSWAP);
        !          124677:        }
        !          124678:        --sexflag;
        !          124679:        uexit(1);
        !          124680: }
        !          124681: 
        !          124682: /*
        !          124683:  * See if the given process may fit in core.
        !          124684:  */
        !          124685: testcore(pp)
        !          124686: register PROC *pp;
        !          124687: {
        !          124688:        register SEG *sp;
        !          124689:        register saddr_t s;
        !          124690:        register saddr_t s1;
        !          124691:        register saddr_t s2;
        !          124692:        register int i;
        !          124693: 
        !          124694:        s = 0;
        !          124695:        for (i=0; i<NUSEG+1; i++) {
        !          124696:                if ((sp=pp->p_segp[i]) == NULL)
        !          124697:                        continue;
        !          124698:                if ((sp->s_flags&SFCORE) != 0)
        !          124699:                        continue;
        !          124700:                if (sp->s_size > s)
        !          124701:                        s = sp->s_size;
        !          124702:        }
        !          124703:        s1 = corebot;
        !          124704:        sp = &segmq;
        !          124705:        do {
        !          124706:                sp = sp->s_forw;
        !          124707:                s2 = sp->s_mbase;
        !          124708:                if (s2-s1 >= s)
        !          124709:                        return (1);
        !          124710:                s1 = sp->s_mbase + sp->s_size;
        !          124711:        } while (sp != &segmq);
        !          124712:        return (0);
        !          124713: }
        !          124714: 
        !          124715: /*
        !          124716:  * Swap all segments associated with a particular process into core.
        !          124717:  * The number of segments still swapped out is returned.
        !          124718:  */
        !          124719: proccore(pp)
        !          124720: register PROC *pp;
        !          124721: {
        !          124722:        register SEG *sp;
        !          124723:        register int i;
        !          124724:        register int n;
        !          124725:        register int f;
        !          124726: 
        !          124727:        n = 0;
        !          124728:        f = pp->p_flags&PFSWAP;
        !          124729:        for (i=0; i<NUSEG+1; i++) {
        !          124730:                if ((sp=pp->p_segp[i]) == NULL)
        !          124731:                        continue;
        !          124732:                if (f != 0)
        !          124733:                        sp->s_lrefc++;
        !          124734:                if ((sp->s_flags&SFCORE)==0 && segcore(sp)==0)
        !          124735:                        n++;
        !          124736:        }
        !          124737:        if (n == 0)
        !          124738:                pp->p_flags |= PFCORE;
        !          124739:        pp->p_flags &= ~PFSWAP;
        !          124740:        return (n);
        !          124741: }
        !          124742: 
        !          124743: /*
        !          124744:  * Swap out all segments associated with a given process.
        !          124745:  */
        !          124746: procdisk(pp)
        !          124747: register PROC *pp;
        !          124748: {
        !          124749:        register SEG *sp;
        !          124750:        register int i;
        !          124751:        register int f;
        !          124752:        int n;
        !          124753: 
        !          124754:        n = 0;
        !          124755:        f = pp->p_flags&PFSWAP;
        !          124756:        pp->p_flags &= ~PFCORE;
        !          124757:        for (i=0; i<NUSEG+1; i++) {
        !          124758:                if ((sp=pp->p_segp[i]) == NULL)
        !          124759:                        continue;
        !          124760:                if (f == 0)
        !          124761:                        --sp->s_lrefc;
        !          124762:                if ((sp->s_flags&SFCORE) == 0)
        !          124763:                        continue;
        !          124764:                if (sp->s_lrefc == 0)
        !          124765:                        if (segdisk(sp) != 0)
        !          124766:                                n++;
        !          124767:        }
        !          124768:        pp->p_flags |= PFSWAP;
        !          124769:        return (n);
        !          124770: }
        !          124771: 
        !          124772: /*
        !          124773:  * Swap out all auxiliary segments used by a process.
        !          124774:  */
        !          124775: auxmdisk(pp)
        !          124776: register PROC *pp;
        !          124777: {
        !          124778:        register SEG *sp;
        !          124779:        register int i;
        !          124780:        register int f;
        !          124781:        register int m;
        !          124782:        SEG *segl[NUSEG];
        !          124783: 
        !          124784: #ifndef NOMONITOR
        !          124785:        if (swmflag)
        !          124786:                printf("Auxiliary(%p, %d)\n", pp, pp->p_pid);
        !          124787: #endif
        !          124788:        sp = pp->p_segp[SIUSERP];
        !          124789:        if ((sp->s_flags&SFCORE) == 0) {
        !          124790:                panic("We may be in trouble");
        !          124791:                return;
        !          124792:        }
        !          124793:        m = pp->p_flags&PFCORE;
        !          124794:        f = pp->p_flags&PFAUXM;
        !          124795:        pp->p_flags &= ~(PFAUXM|PFCORE);
        !          124796:        skcopy(sp, offset(uproc, u_sege[0]), segl, sizeof(u.u_sege));
        !          124797:        for (i=0; i<NUSEG; i++) {
        !          124798:                if ((sp=segl[i]) == NULL)
        !          124799:                        continue;
        !          124800:                if (f != 0)
        !          124801:                        --sp->s_lrefc;
        !          124802:                if ((sp->s_flags&SFCORE) == 0)
        !          124803:                        continue;
        !          124804:                if (sp->s_lrefc == 0)
        !          124805:                        segdisk(sp);
        !          124806:        }
        !          124807:        pp->p_flags |= m;
        !          124808: }
        !          124809: 
        !          124810: /*
        !          124811:  * Swap the given segment into core.
        !          124812:  */
        !          124813: segcore(sp1)
        !          124814: register SEG *sp1;
        !          124815: {
        !          124816:        register SEG *sp2;
        !          124817: 
        !          124818:        lock(seglink);
        !          124819:        sp2 = xmalloc(sp1->s_size);
        !          124820:        unlock(seglink);
        !          124821:        if (sp2 == NULL)
        !          124822:                return (0);
        !          124823:        sp1->s_lrefc++;
        !          124824:        swapio(0, sp2->s_mbase, sp1->s_dbase, sp2->s_size);
        !          124825:        lock(seglink);
        !          124826:        sp1->s_back->s_forw = sp1->s_forw;
        !          124827:        sp1->s_forw->s_back = sp1->s_back;
        !          124828:        sp2->s_back->s_forw = sp1;
        !          124829:        sp1->s_back = sp2->s_back;
        !          124830:        sp2->s_forw->s_back = sp1;
        !          124831:        sp1->s_forw = sp2->s_forw;
        !          124832:        sp1->s_flags |= SFCORE;
        !          124833:        sp1->s_mbase = sp2->s_mbase;
        !          124834:        --sp1->s_lrefc;
        !          124835:        unlock(seglink);
        !          124836:        return (1);
        !          124837: }
        !          124838: 
        !          124839: /*
        !          124840:  * Swap the given segment out onto disk.
        !          124841:  */
        !          124842: segdisk(sp1)
        !          124843: register SEG *sp1;
        !          124844: {
        !          124845:        register SEG *sp2;
        !          124846: 
        !          124847:        lock(seglink);
        !          124848:        sp2 = xdalloc(sp1->s_size);
        !          124849:        unlock(seglink);
        !          124850:        if (sp2 == NULL)
        !          124851:                return (0);
        !          124852:        sp1->s_lrefc++;
        !          124853:        swapio(1, sp1->s_mbase, sp2->s_dbase, sp1->s_size);
        !          124854:        lock(seglink);
        !          124855:        sp1->s_back->s_forw = sp1->s_forw;
        !          124856:        sp1->s_forw->s_back = sp1->s_back;
        !          124857:        sp2->s_back->s_forw = sp1;
        !          124858:        sp1->s_back = sp2->s_back;
        !          124859:        sp2->s_forw->s_back = sp1;
        !          124860:        sp1->s_forw = sp2->s_forw;
        !          124861:        sp1->s_flags &= ~SFCORE;
        !          124862:        sp1->s_dbase = sp2->s_dbase;
        !          124863:        --sp1->s_lrefc;
        !          124864:        unlock(seglink);
        !          124865:        return (1);
        !          124866: }
        !          124867: 
        !          124868: /*
        !          124869:  * Allocate a segment on disk that is `n' clicks long.
        !          124870:  * The `seglink' gate should be locked before this routine is called.
        !          124871:  * This routine is the same as `sdalloc' except that we can't run out of
        !          124872:  * alloc space to allocate the segment and we allocate in high regions.
        !          124873:  */
        !          124874: SEG *
        !          124875: xdalloc(s)
        !          124876: saddr_t s;
        !          124877: {
        !          124878:        register SEG *sp1;
        !          124879:        register SEG *sp2;
        !          124880:        register daddr_t d;
        !          124881:        register daddr_t d1;
        !          124882:        register daddr_t d2;
        !          124883: 
        !          124884:        d = stod(s);
        !          124885:        d2 = swaptop;
        !          124886:        sp1 = &segdq;
        !          124887:        do {
        !          124888:                if ((sp1=sp1->s_back) != &segdq)
        !          124889:                        d1 = sp1->s_dbase + stod(sp1->s_size);
        !          124890:                else
        !          124891:                        d1 = swapbot;
        !          124892:                if (d2-d1 >= d) {
        !          124893:                        sp2 = &segswap;
        !          124894:                        kclear((char *)sp2, sizeof(SEG));
        !          124895:                        sp1->s_forw->s_back = sp2;
        !          124896:                        sp2->s_forw = sp1->s_forw;
        !          124897:                        sp1->s_forw = sp2;
        !          124898:                        sp2->s_back = sp1;
        !          124899:                        sp2->s_urefc = 1;
        !          124900:                        sp2->s_lrefc = 1;
        !          124901:                        sp2->s_size = s;
        !          124902:                        sp2->s_dbase = d2 - d;
        !          124903:                        return (sp2);
        !          124904:                }
        !          124905:                d2 = sp1->s_dbase;
        !          124906:        } while (sp1 != &segdq);
        !          124907:        return (NULL);
        !          124908: }
        !          124909: 
        !          124910: /*
        !          124911:  * Allocate a segment in memory that is `n' clicks long.
        !          124912:  * The `seglink' gate should be locked before this routine is called.
        !          124913:  * This routine is the same as `smalloc' except that we can't run out of
        !          124914:  * alloc space to allocate the segment.
        !          124915:  */
        !          124916: SEG *
        !          124917: xmalloc(s)
        !          124918: register saddr_t s;
        !          124919: {
        !          124920:        register SEG *sp1;
        !          124921:        register SEG *sp2;
        !          124922:        register saddr_t s1;
        !          124923:        register saddr_t s2;
        !          124924: 
        !          124925:        s1 = corebot;
        !          124926:        sp1 = &segmq;
        !          124927:        do {
        !          124928:                if ((sp1=sp1->s_forw) != &segmq)
        !          124929:                        s2 = sp1->s_mbase;
        !          124930:                else
        !          124931:                        s2 = coretop;
        !          124932:                if (s2-s1 >= s) {
        !          124933:                        sp2 = &segswap;
        !          124934:                        kclear((char *)sp2, sizeof(SEG));
        !          124935:                        sp1->s_back->s_forw = sp2;
        !          124936:                        sp2->s_back = sp1->s_back;
        !          124937:                        sp1->s_back = sp2;
        !          124938:                        sp2->s_forw = sp1;
        !          124939:                        sp2->s_urefc = 1;
        !          124940:                        sp2->s_lrefc = 1;
        !          124941:                        sp2->s_size = s;
        !          124942:                        sp2->s_mbase = s1;
        !          124943:                        return (sp2);
        !          124944:                }
        !          124945:                s1 = sp1->s_mbase + sp1->s_size;
        !          124946:        } while (sp1 != &segmq);
        !          124947:        return (NULL);
        !          124948: }
        !          124949: @
        !          124950: 
        !          124951: 
        !          124952: 1.2
        !          124953: log
        !          124954: @update provided by hal
        !          124955: @
        !          124956: text
        !          124957: @@
        !          124958: 
        !          124959: 
        !          124960: 1.1
        !          124961: log
        !          124962: @Initial revision
        !          124963: @
        !          124964: text
        !          124965: @@
        !          124966: 0707070064030103030407550000030000030000011777770507310741700003400000000000/newbits/kernel/USRSRC/ldrv0707070064030131121006440000030000030000011777770507310741700004500000020214/newbits/kernel/USRSRC/ldrv/Makefile# $Header: /newbits/kernel/USRSRC/ldrv/RCS/Makefile,v 1.6 91/09/26 17:13:55 bin Exp Locker: bin $(USRSRC)/ldrv/RCS/Makefile,v 1.2 91/04/30 18:38:22 root Exp $
        !          124967: 
        !          124968: # Loadable Drivers - Makefile
        !          124969: #
        !          124970: 
        !          124971: # Include directories
        !          124972: USRINC=/usr/include
        !          124973: SYSINC=/usr/include/sys
        !          124974: 
        !          124975: CC=exec /bin/cc
        !          124976: CFLAGS=
        !          124977: 
        !          124978: TARGETS=$(USRSYS)/lib/ldrts0.o \
        !          124979:        $(USRSYS)/lib/ldmain.o  \
        !          124980:        $(USRSYS)/lib/ldswap.o  \
        !          124981:        $(USRSYS)/lib/ldlib.a
        !          124982: 
        !          124983: ld_support:    $(TARGETS)
        !          124984:        @sync
        !          124985: 
        !          124986: $(USRSYS)/lib/ldrts0.o:        ldrts0.s
        !          124987:        as -xo $@ $<
        !          124988: 
        !          124989: $(USRSYS)/lib/ldmain.o:        ldmain.c
        !          124990:        $(CC) $(CFLAGS) -c -o $@ $<
        !          124991: 
        !          124992: $(USRSYS)/lib/ldswap.o:        ldswap.c
        !          124993:        $(CC) $(CFLAGS) -DNOMONITOR -c -o $@ $<
        !          124994: 
        !          124995: # The following script extracts a module from a library.
        !          124996: X_LIB= OBJFIL=`basename $@ | sed 's/L//'` ;\
        !          124997:        ar x $< $$OBJFIL ;\
        !          124998:        mv $$OBJFIL $@
        !          124999: 
        !          125000: # The following modules are supported in loadable drivers.
        !          125001: # NOTE: Most of them are interface stubs to kernel code.
        !          125002: #      Some of them are entirely driver resident.
        !          125003: LIBOBJ1=$(LOBJ)/absL.o         \
        !          125004:        $(LOBJ)/allocL.o        \
        !          125005:        $(LOBJ)/bclaimL.o       \
        !          125006:        $(LOBJ)/bdoneL.o        \
        !          125007:        $(LOBJ)/blkmvL.o        \
        !          125008:        $(LOBJ)/bootL.o         \
        !          125009:        $(LOBJ)/breadL.o        \
        !          125010:        $(LOBJ)/breleaseL.o     \
        !          125011:        $(LOBJ)/clockedfL.o     \
        !          125012:        $(LOBJ)/clrqL.o         \
        !          125013:        $(LOBJ)/cs_selfL.o      \
        !          125014:        $(LOBJ)/dblockL.o       \
        !          125015:        $(LOBJ)/dcloseL.o       \
        !          125016:        $(LOBJ)/deferL.o        \
        !          125017:        $(LOBJ)/devmsgL.o       \
        !          125018:        $(LOBJ)/dmagoL.o        \
        !          125019:        $(LOBJ)/dmalockL.o      \
        !          125020:        $(LOBJ)/dmaoffL.o       \
        !          125021:        $(LOBJ)/dmaonL.o        \
        !          125022:        $(LOBJ)/dmareqL.o       \
        !          125023:        $(LOBJ)/dopenL.o        \
        !          125024:        $(LOBJ)/drvmapL.o       \
        !          125025:        $(LOBJ)/dwriteL.o       \
        !          125026:        $(LOBJ)/fclearL.o       \
        !          125027:        $(LOBJ)/fdiskL.o        \
        !          125028:        $(LOBJ)/ffbyteL.o       \
        !          125029:        $(LOBJ)/ffwordL.o       \
        !          125030:        $(LOBJ)/ffmemL.o        \
        !          125031:        $(LOBJ)/fkcopyL.o       \
        !          125032:        $(LOBJ)/fpxcopyL.o      \
        !          125033:        $(LOBJ)/freeL.o         \
        !          125034:        $(LOBJ)/fucopyL.o       \
        !          125035:        $(LOBJ)/getcsL.o        \
        !          125036:        $(LOBJ)/getqL.o         \
        !          125037:        $(LOBJ)/getubdL.o       \
        !          125038:        $(LOBJ)/getuwdL.o       \
        !          125039:        $(LOBJ)/inbL.o          \
        !          125040:        $(LOBJ)/int11L.o        \
        !          125041:        $(LOBJ)/iogetcL.o       \
        !          125042:        $(LOBJ)/iomapvpL.o      \
        !          125043:        $(LOBJ)/ioputcL.o       \
        !          125044:        $(LOBJ)/ioreadL.o       \
        !          125045:        $(LOBJ)/ioreqL.o        \
        !          125046:        $(LOBJ)/iowriteL.o      \
        !          125047:        $(LOBJ)/ipcaccessL.o    \
        !          125048:        $(LOBJ)/kcallL.o        \
        !          125049:        $(LOBJ)/kfcopyL.o       \
        !          125050:        $(LOBJ)/kclearL.o       \
        !          125051:        $(LOBJ)/kpcopyL.o       \
        !          125052:        $(LOBJ)/kucopyL.o       \
        !          125053:        $(LOBJ)/lockL.o         \
        !          125054:        $(LOBJ)/lxdivL.o        \
        !          125055:        $(LOBJ)/lxmulL.o        \
        !          125056:        $(LOBJ)/lxremL.o        \
        !          125057:        $(LOBJ)/lxsgnL.o        \
        !          125058:        $(LOBJ)/memsetL.o       \
        !          125059:        $(LOBJ)/memtestL.o      \
        !          125060:        $(LOBJ)/nmidisableL.o   \
        !          125061:        $(LOBJ)/nmienableL.o    \
        !          125062:        $(LOBJ)/nondsigL.o      \
        !          125063:        $(LOBJ)/nonedevL.o      \
        !          125064:        $(LOBJ)/nulldevL.o      \
        !          125065: 
        !          125066: LIBOBJ2=$(LOBJ)/outbL.o                \
        !          125067:        $(LOBJ)/panicL.o        \
        !          125068:        $(LOBJ)/pclearL.o       \
        !          125069:        $(LOBJ)/pkcopyL.o       \
        !          125070:        $(LOBJ)/plrcopyL.o      \
        !          125071:        $(LOBJ)/pollopenL.o     \
        !          125072:        $(LOBJ)/pollwakeL.o     \
        !          125073:        $(LOBJ)/printfL.o       \
        !          125074:        $(LOBJ)/prlcopyL.o      \
        !          125075:        $(LOBJ)/ptovL.o         \
        !          125076:        $(LOBJ)/pucopyL.o       \
        !          125077:        $(LOBJ)/putcharL.o      \
        !          125078:        $(LOBJ)/putqL.o         \
        !          125079:        $(LOBJ)/putubdL.o       \
        !          125080:        $(LOBJ)/putuwdL.o       \
        !          125081:        $(LOBJ)/rucopyL.o       \
        !          125082:        $(LOBJ)/s5_to_sgL.o     \
        !          125083:        $(LOBJ)/s5_to_tcL.o     \
        !          125084:        $(LOBJ)/sallocL.o       \
        !          125085:        $(LOBJ)/sclearL.o       \
        !          125086:        $(LOBJ)/sendsigL.o      \
        !          125087:        $(LOBJ)/setivecL.o      \
        !          125088:        $(LOBJ)/sfreeL.o        \
        !          125089:        $(LOBJ)/sfbyteL.o       \
        !          125090:        $(LOBJ)/sfwordL.o       \
        !          125091:        $(LOBJ)/sfmemL.o        \
        !          125092:        $(LOBJ)/sg_to_s5L.o     \
        !          125093:        $(LOBJ)/sleepL.o        \
        !          125094:        $(LOBJ)/slrcopyL.o      \
        !          125095:        $(LOBJ)/sphiL.o         \
        !          125096:        $(LOBJ)/splL.o          \
        !          125097:        $(LOBJ)/sploL.o         \
        !          125098:        $(LOBJ)/superL.o        \
        !          125099:        $(LOBJ)/swapioL.o       \
        !          125100:        $(LOBJ)/tc_to_s5L.o     \
        !          125101:        $(LOBJ)/timeoutL.o      \
        !          125102:        $(LOBJ)/ttcloseL.o      \
        !          125103:        $(LOBJ)/tthupL.o        \
        !          125104:        $(LOBJ)/ttflushL.o      \
        !          125105:        $(LOBJ)/ttinL.o         \
        !          125106:        $(LOBJ)/ttioctlL.o      \
        !          125107:        $(LOBJ)/ttopenL.o       \
        !          125108:        $(LOBJ)/ttoutL.o        \
        !          125109:        $(LOBJ)/ttpollL.o       \
        !          125110:        $(LOBJ)/ttreadL.o       \
        !          125111:        $(LOBJ)/ttsetgrpL.o     \
        !          125112:        $(LOBJ)/ttsignalL.o     \
        !          125113:        $(LOBJ)/ttstartL.o      \
        !          125114:        $(LOBJ)/ttwriteL.o      \
        !          125115:        $(LOBJ)/uexitL.o        \
        !          125116:        $(LOBJ)/ufcopyL.o       \
        !          125117:        $(LOBJ)/ukcopyL.o       \
        !          125118:        $(LOBJ)/unlockL.o       \
        !          125119:        $(LOBJ)/upcopyL.o       \
        !          125120:        $(LOBJ)/urcopyL.o       \
        !          125121:        $(LOBJ)/vprintL.o       \
        !          125122:        $(LOBJ)/vrelseL.o       \
        !          125123:        $(LOBJ)/vremapL.o       \
        !          125124:        $(LOBJ)/vtopL.o         \
        !          125125:        $(LOBJ)/vxdivL.o        \
        !          125126:        $(LOBJ)/vxmulL.o        \
        !          125127:        $(LOBJ)/vxremL.o        \
        !          125128:        $(LOBJ)/waitqL.o        \
        !          125129:        $(LOBJ)/wakeupL.o       \
        !          125130: 
        !          125131: $(USRSYS)/lib/ldlib.a: mkstub.m4 $(LIBOBJ1) $(LIBOBJ2)
        !          125132:        rm -f  $@
        !          125133:        ar rc  $@ $(LIBOBJ1)
        !          125134:        ar rc  $@ $(LIBOBJ2)
        !          125135:        ranlib $@
        !          125136: 
        !          125137: # Here is mkstub.m4:
        !          125138: #define(sym, substr(basename, -2, ))dnl
        !          125139: #      .globl  sym`_'
        !          125140: #sym`_':       mov     ax,`$K'sym`_'
        !          125141: #      .byte   0x9A
        !          125142: #      .word   xcalled
        !          125143: #      .word   0x0060
        !          125144: #      ret
        !          125145: 
        !          125146: MKSTUB=        echo "define(basename, `basename $*`)dnl" | m4 - mkstub.m4 > $*.s ;\
        !          125147:        as -gxo $@ $*.s; rm $*.s
        !          125148: 
        !          125149: $(LOBJ)/absL.o:
        !          125150:        $(MKSTUB)
        !          125151: 
        !          125152: $(LOBJ)/allocL.o:
        !          125153:        $(MKSTUB)
        !          125154: 
        !          125155: $(LOBJ)/bclaimL.o:
        !          125156:        $(MKSTUB)
        !          125157: 
        !          125158: $(LOBJ)/bdoneL.o:
        !          125159:        $(MKSTUB)
        !          125160: 
        !          125161: $(LOBJ)/blkmvL.o:      /lib/libc.a
        !          125162:        $(X_LIB)
        !          125163: 
        !          125164: $(LOBJ)/bootL.o:
        !          125165:        $(MKSTUB)
        !          125166: 
        !          125167: $(LOBJ)/breadL.o:
        !          125168:        $(MKSTUB)
        !          125169: 
        !          125170: $(LOBJ)/breleaseL.o:
        !          125171:        $(MKSTUB)
        !          125172: 
        !          125173: $(LOBJ)/clockedfL.o:   clockedf.c
        !          125174:        $(CC) $(CFLAGS) -c -o $@ $<
        !          125175: 
        !          125176: $(LOBJ)/clrivecL.o:
        !          125177:        $(MKSTUB)
        !          125178: 
        !          125179: $(LOBJ)/clrqL.o:
        !          125180:        $(MKSTUB)
        !          125181: 
        !          125182: $(LOBJ)/cs_selfL.o:    cs_self.s
        !          125183:        as -gxo $@ $<
        !          125184: 
        !          125185: $(LOBJ)/dblockL.o:
        !          125186:        $(MKSTUB)
        !          125187: 
        !          125188: $(LOBJ)/dcloseL.o:
        !          125189:        $(MKSTUB)
        !          125190: 
        !          125191: $(LOBJ)/deferL.o:      defer.s
        !          125192:        as -gxo $@ $<
        !          125193: 
        !          125194: $(LOBJ)/devmsgL.o:
        !          125195:        $(MKSTUB)
        !          125196: 
        !          125197: $(LOBJ)/dmagoL.o:
        !          125198:        $(MKSTUB)
        !          125199: 
        !          125200: $(LOBJ)/dmalockL.o:    dmalock.c
        !          125201:        $(CC) $(CFLAGS) -c -o $@ $<
        !          125202: 
        !          125203: $(LOBJ)/dmaoffL.o:
        !          125204:        $(MKSTUB)
        !          125205: 
        !          125206: $(LOBJ)/dmaonL.o:
        !          125207:        $(MKSTUB)
        !          125208: 
        !          125209: $(LOBJ)/dmareqL.o:
        !          125210:        $(MKSTUB)
        !          125211: 
        !          125212: $(LOBJ)/dopenL.o:
        !          125213:        $(MKSTUB)
        !          125214: 
        !          125215: $(LOBJ)/drvmapL.o:
        !          125216:        $(MKSTUB)
        !          125217: 
        !          125218: $(LOBJ)/dwriteL.o:
        !          125219:        $(MKSTUB)
        !          125220: 
        !          125221: $(LOBJ)/fclearL.o:
        !          125222:        $(MKSTUB)
        !          125223: 
        !          125224: $(LOBJ)/fdiskL.o:
        !          125225:        $(MKSTUB)
        !          125226: 
        !          125227: $(LOBJ)/ffbyteL.o:     ffbyte.s
        !          125228:        as -gxo $@ $<
        !          125229: 
        !          125230: $(LOBJ)/ffwordL.o:     ffword.s
        !          125231:        as -gxo $@ $<
        !          125232: 
        !          125233: $(LOBJ)/ffmemL.o:      ffmem.s
        !          125234:        as -gxo $@ $<
        !          125235: 
        !          125236: $(LOBJ)/fkcopyL.o:
        !          125237:        $(MKSTUB)
        !          125238: 
        !          125239: $(LOBJ)/fpxcopyL.o:
        !          125240:        $(MKSTUB)
        !          125241: 
        !          125242: $(LOBJ)/freeL.o:
        !          125243:        $(MKSTUB)
        !          125244: 
        !          125245: $(LOBJ)/fucopyL.o:
        !          125246:        $(MKSTUB)
        !          125247: 
        !          125248: $(LOBJ)/getcsL.o:      getcs.s
        !          125249:        as -gxo $@ $<
        !          125250: 
        !          125251: $(LOBJ)/getqL.o:
        !          125252:        $(MKSTUB)
        !          125253: 
        !          125254: $(LOBJ)/getubdL.o:
        !          125255:        $(MKSTUB)
        !          125256: 
        !          125257: $(LOBJ)/getuwdL.o:
        !          125258:        $(MKSTUB)
        !          125259: 
        !          125260: $(LOBJ)/inbL.o:                inb.s
        !          125261:        as -gxo $@ $<
        !          125262: 
        !          125263: $(LOBJ)/int11L.o:
        !          125264:        $(MKSTUB)
        !          125265: 
        !          125266: $(LOBJ)/iogetcL.o:
        !          125267:        $(MKSTUB)
        !          125268: 
        !          125269: $(LOBJ)/iomapvpL.o:
        !          125270:        $(MKSTUB)
        !          125271: 
        !          125272: $(LOBJ)/ioputcL.o:
        !          125273:        $(MKSTUB)
        !          125274: 
        !          125275: $(LOBJ)/ioreadL.o:
        !          125276:        $(MKSTUB)
        !          125277: 
        !          125278: $(LOBJ)/ioreqL.o:
        !          125279:        $(MKSTUB)
        !          125280: 
        !          125281: $(LOBJ)/iowriteL.o:
        !          125282:        $(MKSTUB)
        !          125283: 
        !          125284: $(LOBJ)/ipcaccessL.o:
        !          125285:        $(MKSTUB)
        !          125286: 
        !          125287: $(LOBJ)/kcallL.o:      kcall.s
        !          125288:        as -gxo $@ $<
        !          125289: 
        !          125290: $(LOBJ)/kclearL.o:
        !          125291:        $(MKSTUB)
        !          125292: 
        !          125293: $(LOBJ)/kfcopyL.o:
        !          125294:        $(MKSTUB)
        !          125295: 
        !          125296: $(LOBJ)/kpcopyL.o:
        !          125297:        $(MKSTUB)
        !          125298: 
        !          125299: $(LOBJ)/kucopyL.o:
        !          125300:        $(MKSTUB)
        !          125301: 
        !          125302: $(LOBJ)/lockL.o:
        !          125303:        $(MKSTUB)
        !          125304: 
        !          125305: $(LOBJ)/lxdivL.o:      /lib/libc.a
        !          125306:        $(X_LIB)
        !          125307: 
        !          125308: $(LOBJ)/lxmulL.o:      /lib/libc.a
        !          125309:        $(X_LIB)
        !          125310: 
        !          125311: $(LOBJ)/lxremL.o:      /lib/libc.a
        !          125312:        $(X_LIB)
        !          125313: 
        !          125314: $(LOBJ)/lxsgnL.o:      /lib/libc.a
        !          125315:        $(X_LIB)
        !          125316: 
        !          125317: $(LOBJ)/memsetL.o:     /lib/libc.a
        !          125318:        $(X_LIB)
        !          125319: 
        !          125320: $(LOBJ)/memtestL.o:
        !          125321:        $(MKSTUB)
        !          125322: 
        !          125323: $(LOBJ)/nmidisableL.o:
        !          125324:        $(MKSTUB)
        !          125325: 
        !          125326: $(LOBJ)/nmienableL.o:
        !          125327:        $(MKSTUB)
        !          125328: 
        !          125329: $(LOBJ)/nondsigL.o:
        !          125330:        $(MKSTUB)
        !          125331: 
        !          125332: $(LOBJ)/nonedevL.o:    nonedev.c
        !          125333:        $(CC) $(CFLAGS) -c -o $@ $<
        !          125334: 
        !          125335: $(LOBJ)/nulldevL.o:    nulldev.c
        !          125336:        $(CC) $(CFLAGS) -c -o $@ $<
        !          125337: 
        !          125338: $(LOBJ)/outbL.o:               outb.s
        !          125339:        as -gxo $@ $<
        !          125340: 
        !          125341: $(LOBJ)/panicL.o:
        !          125342:        $(MKSTUB)
        !          125343: 
        !          125344: $(LOBJ)/pclearL.o:
        !          125345:        $(MKSTUB)
        !          125346: 
        !          125347: $(LOBJ)/plrcopyL.o:
        !          125348:        $(MKSTUB)
        !          125349: 
        !          125350: $(LOBJ)/pkcopyL.o:
        !          125351:        $(MKSTUB)
        !          125352: 
        !          125353: $(LOBJ)/pollopenL.o:
        !          125354:        $(MKSTUB)
        !          125355: 
        !          125356: $(LOBJ)/pollwakeL.o:
        !          125357:        $(MKSTUB)
        !          125358: 
        !          125359: $(LOBJ)/printfL.o:
        !          125360:        $(MKSTUB)
        !          125361: 
        !          125362: $(LOBJ)/prlcopyL.o:
        !          125363:        $(MKSTUB)
        !          125364: 
        !          125365: $(LOBJ)/ptovL.o:
        !          125366:        $(MKSTUB)
        !          125367: 
        !          125368: $(LOBJ)/pucopyL.o:
        !          125369:        $(MKSTUB)
        !          125370: 
        !          125371: $(LOBJ)/putcharL.o:
        !          125372:        $(MKSTUB)
        !          125373: 
        !          125374: $(LOBJ)/putqL.o:
        !          125375:        $(MKSTUB)
        !          125376: 
        !          125377: $(LOBJ)/putubdL.o:
        !          125378:        $(MKSTUB)
        !          125379: 
        !          125380: $(LOBJ)/putuwdL.o:
        !          125381:        $(MKSTUB)
        !          125382: 
        !          125383: $(LOBJ)/rucopyL.o:
        !          125384:        $(MKSTUB)
        !          125385: 
        !          125386: $(LOBJ)/s5_to_sgL.o:
        !          125387:        $(MKSTUB)
        !          125388: 
        !          125389: $(LOBJ)/s5_to_tcL.o:
        !          125390:        $(MKSTUB)
        !          125391: 
        !          125392: $(LOBJ)/sallocL.o:
        !          125393:        $(MKSTUB)
        !          125394: 
        !          125395: $(LOBJ)/sclearL.o:
        !          125396:        $(MKSTUB)
        !          125397: 
        !          125398: $(LOBJ)/sendsigL.o:
        !          125399:        $(MKSTUB)
        !          125400: 
        !          125401: $(LOBJ)/setivecL.o:    setivec.c
        !          125402:        $(CC) $(CFLAGS) -c -o $@ $<
        !          125403: 
        !          125404: $(LOBJ)/sfreeL.o:
        !          125405:        $(MKSTUB)
        !          125406: 
        !          125407: $(LOBJ)/sfbyteL.o:     sfbyte.s
        !          125408:        as -gxo $@ $<
        !          125409: 
        !          125410: $(LOBJ)/sfwordL.o:     sfword.s
        !          125411:        as -gxo $@ $<
        !          125412: 
        !          125413: $(LOBJ)/sfmemL.o:      sfmem.s
        !          125414:        as -gxo $@ $<
        !          125415: 
        !          125416: $(LOBJ)/sg_to_s5L.o:
        !          125417:        $(MKSTUB)
        !          125418: 
        !          125419: $(LOBJ)/sleepL.o:
        !          125420:        $(MKSTUB)
        !          125421: 
        !          125422: $(LOBJ)/slrcopyL.o:
        !          125423:        $(MKSTUB)
        !          125424: 
        !          125425: $(LOBJ)/sphiL.o:       sphi.s
        !          125426:        as -gxo $@ $<
        !          125427: 
        !          125428: $(LOBJ)/splL.o:        spl.s
        !          125429:        as -gxo $@ $<
        !          125430: 
        !          125431: $(LOBJ)/sploL.o:       splo.s
        !          125432:        as -gxo $@ $<
        !          125433: 
        !          125434: $(LOBJ)/superL.o:
        !          125435:        $(MKSTUB)
        !          125436: 
        !          125437: $(LOBJ)/swapioL.o:
        !          125438:        $(MKSTUB)
        !          125439: 
        !          125440: $(LOBJ)/tc_to_s5L.o:
        !          125441:        $(MKSTUB)
        !          125442: 
        !          125443: $(LOBJ)/timeoutL.o:    timeout.c
        !          125444:        $(CC) $(CFLAGS) -c -o $@ $<
        !          125445: 
        !          125446: $(LOBJ)/ttcloseL.o:
        !          125447:        $(MKSTUB)
        !          125448: 
        !          125449: $(LOBJ)/ttflushL.o:
        !          125450:        $(MKSTUB)
        !          125451: 
        !          125452: $(LOBJ)/tthupL.o:
        !          125453:        $(MKSTUB)
        !          125454: 
        !          125455: $(LOBJ)/ttinL.o:
        !          125456:        $(MKSTUB)
        !          125457: 
        !          125458: $(LOBJ)/ttioctlL.o:
        !          125459:        $(MKSTUB)
        !          125460: 
        !          125461: $(LOBJ)/ttopenL.o:
        !          125462:        $(MKSTUB)
        !          125463: 
        !          125464: $(LOBJ)/ttoutL.o:
        !          125465:        $(MKSTUB)
        !          125466: 
        !          125467: $(LOBJ)/ttpollL.o:
        !          125468:        $(MKSTUB)
        !          125469: 
        !          125470: $(LOBJ)/ttreadL.o:
        !          125471:        $(MKSTUB)
        !          125472: 
        !          125473: $(LOBJ)/ttsetgrpL.o:
        !          125474:        $(MKSTUB)
        !          125475: 
        !          125476: $(LOBJ)/ttsignalL.o:
        !          125477:        $(MKSTUB)
        !          125478: 
        !          125479: $(LOBJ)/ttstartL.o:
        !          125480:        $(MKSTUB)
        !          125481: 
        !          125482: $(LOBJ)/ttwriteL.o:
        !          125483:        $(MKSTUB)
        !          125484: 
        !          125485: $(LOBJ)/uexitL.o:
        !          125486:        $(MKSTUB)
        !          125487: 
        !          125488: $(LOBJ)/ufcopyL.o:
        !          125489:        $(MKSTUB)
        !          125490: 
        !          125491: $(LOBJ)/ukcopyL.o:
        !          125492:        $(MKSTUB)
        !          125493: 
        !          125494: $(LOBJ)/unlockL.o:
        !          125495:        $(MKSTUB)
        !          125496: 
        !          125497: $(LOBJ)/upcopyL.o:
        !          125498:        $(MKSTUB)
        !          125499: 
        !          125500: $(LOBJ)/urcopyL.o:
        !          125501:        $(MKSTUB)
        !          125502: 
        !          125503: $(LOBJ)/vprintL.o:
        !          125504:        $(MKSTUB)
        !          125505: 
        !          125506: $(LOBJ)/vrelseL.o:
        !          125507:        $(MKSTUB)
        !          125508: 
        !          125509: $(LOBJ)/vremapL.o:
        !          125510:        $(MKSTUB)
        !          125511: 
        !          125512: $(LOBJ)/vtopL.o:
        !          125513:        $(MKSTUB)
        !          125514: 
        !          125515: $(LOBJ)/vxdivL.o:      /lib/libc.a
        !          125516:        $(X_LIB)
        !          125517: 
        !          125518: $(LOBJ)/vxmulL.o:      /lib/libc.a
        !          125519:        $(X_LIB)
        !          125520: 
        !          125521: $(LOBJ)/vxremL.o:      /lib/libc.a
        !          125522:        $(X_LIB)
        !          125523: 
        !          125524: $(LOBJ)/waitqL.o:
        !          125525:        $(MKSTUB)
        !          125526: 
        !          125527: $(LOBJ)/wakeupL.o:
        !          125528:        $(MKSTUB)
        !          125529: 0707070064030103021004440000030000030000011777770507310742100004400000001545/newbits/kernel/USRSRC/ldrv/blkmv.s/ $Header: /usr/src/sys/ldrv/RCS/blkmv.s,v 1.1 88/03/24 16:30:25 src Exp $
        !          125530: /
        !          125531: /      The  information  contained herein  is a trade secret  of INETCO
        !          125532: /      Systems, and is confidential information.   It is provided under
        !          125533: /      a license agreement,  and may be copied or disclosed  only under
        !          125534: /      the terms of that agreement.   Any reproduction or disclosure of
        !          125535: /      this  material  without  the express  written  authorization  of
        !          125536: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          125537: /
        !          125538: /      Copyright (c) 1988
        !          125539: /      An unpublished work by INETCO Systems, Ltd.
        !          125540: /      All rights reserved.
        !          125541: /
        !          125542: / $Log:        /usr/src/sys/ldrv/RCS/blkmv.s,v $
        !          125543: / Revision 1.1 88/03/24  16:30:25      src
        !          125544: / Initial revision
        !          125545: / 
        !          125546: /
        !          125547: ////////
        !          125548: 
        !          125549:        .globl  blkmv
        !          125550: 
        !          125551: blkmv: push    si
        !          125552:        push    di
        !          125553:        push    bp
        !          125554:        mov     bp, sp
        !          125555: 
        !          125556:        mov     di, 8(bp)
        !          125557:        mov     si, 10(bp)
        !          125558:        mov     cx, 12(bp)
        !          125559:        cld
        !          125560:        rep
        !          125561:        movsb
        !          125562: 
        !          125563:        mov     ax, 8(bp)
        !          125564:        mov     sp, bp
        !          125565:        pop     bp
        !          125566:        pop     di
        !          125567:        pop     si
        !          125568:        ret
        !          125569: 0707070064030103011006440000030000030000011777770507310742100004700000003747/newbits/kernel/USRSRC/ldrv/clockedf.c/* clockedf.c - support routines for alternate clock rate
        !          125570:               - this is the FAR version of clocked.c for loadable drivers
        !          125571: 
        !          125572:   altclk_in(hz, fn) - install routine with specified rate
        !          125573:                           "hz" should be a multiple of system rate of 100 Hz
        !          125574: 
        !          125575:   altclk_out()      - uninstall alternate clock routine and restore system rate
        !          125576:                        return old value of "altclk"
        !          125577: 
        !          125578:   altclk_rate(hz)   - set clock interrupt rate
        !          125579:                        new rate must be an even multiple of system rate "HZ"
        !          125580:                        return 0 if completed ok, -1 otherwise
        !          125581: 
        !          125582:   History:
        !          125583:     90/08/08 hws       initial version, works with hs.c modified for com[1-4]
        !          125584:     90/08/14 hws       make it more like a Unix system call
        !          125585:     90/09/12 hws       add far version
        !          125586: */
        !          125587: 
        !          125588: #include       <sys/coherent.h>        /* altclk */
        !          125589: #include       <sys/const.h>   /* HZ */
        !          125590: 
        !          125591: #define        PIT     0x40    /* 8253 port */
        !          125592: #define        TMR0_M3 0x36    /* timer 0, mode 3 */
        !          125593: #if 0
        !          125594: /* nominal IBM rate is 1.1900 MHz */
        !          125595: #define        SYS_HZ  1190000L        /* rate of input clock to timer 0 */
        !          125596: #else
        !          125597: /* current kernel rate is 1.1932 MHz */
        !          125598: #define        SYS_HZ  1193200L        /* rate of input clock to timer 0 */
        !          125599: #endif
        !          125600: 
        !          125601: typedef int (*PFI)();  /* pointer to function returning int */
        !          125602: 
        !          125603: extern saddr_t ucs;
        !          125604: 
        !          125605: static int altclk_rate(hz)
        !          125606: unsigned int hz;
        !          125607: {
        !          125608:   int s;       /* to save CPU irpt flag */
        !          125609:   unsigned int interval;       /* period for hz, in units of 1.19 MHz ticks */
        !          125610:   int ret;
        !          125611: 
        !          125612:   if (hz >= HZ && hz % HZ == 0) {      /* can't go slower than HZ! */
        !          125613:     interval = SYS_HZ/hz;
        !          125614:     s = sphi();        /* disable irpts */
        !          125615:     outb(PIT+3, TMR0_M3);
        !          125616:     outb(PIT, interval & 0xff);
        !          125617:     outb(PIT, interval >> 8);  /* unsigned shift */
        !          125618:     spl(s);    /* restore previous irpt state */
        !          125619:     ret = 0;
        !          125620:   }
        !          125621:   else {
        !          125622:     ret = -1;
        !          125623:   }
        !          125624:   return ret;
        !          125625: }
        !          125626: 
        !          125627: int altclk_in(hz, fn)
        !          125628: int hz;
        !          125629: PFI fn;
        !          125630: {
        !          125631:   int ret;
        !          125632:   int s;
        !          125633: 
        !          125634:   if ((ret = altclk_rate(hz)) == 0) {
        !          125635:     s = sphi();
        !          125636:     altclk = fn;
        !          125637:     altsel = cs_sel();
        !          125638:     spl(s);
        !          125639:   }
        !          125640:   return ret;
        !          125641: }
        !          125642: 
        !          125643: PFI altclk_out()
        !          125644: {
        !          125645:   PFI ret;
        !          125646:   int s;
        !          125647: 
        !          125648:   ret = altclk;
        !          125649:   if (ret) {
        !          125650:     altclk_rate(HZ);
        !          125651:     s = sphi();
        !          125652:     altclk = 0;
        !          125653:     altsel = 0;
        !          125654:     spl(s);
        !          125655:   }
        !          125656:   return ret;
        !          125657: }
        !          125658: 0707070064030102771004440000030000030000011777770507310742200004600000000375/newbits/kernel/USRSRC/ldrv/cs_self.s////////
        !          125659: /
        !          125660: / Get cs selector - return 0 if in kernel, CS if not in kernel.
        !          125661: /
        !          125662: / This version is for loadable drivers.
        !          125663: / There is a different version (cs_sel.s) for resident drivers.
        !          125664: /
        !          125665: / int  cs_sel();
        !          125666: /
        !          125667: ////////
        !          125668: 
        !          125669:        .globl  cs_sel_
        !          125670: cs_sel_:
        !          125671:        mov     ax, cs
        !          125672:        ret
        !          125673: 0707070064030103001004440000030000030000011777770507310742200004400000002401/newbits/kernel/USRSRC/ldrv/defer.s/ $Header: /usr/src/sys/ldrv/RCS/defer.s,v 1.1 88/04/04 16:40:21 src Exp $
        !          125674: /
        !          125675: /      The  information  contained herein  is a trade secret  of INETCO
        !          125676: /      Systems, and is confidential information.   It is provided under
        !          125677: /      a license agreement,  and may be copied or disclosed  only under
        !          125678: /      the terms of that agreement.   Any reproduction or disclosure of
        !          125679: /      this  material  without  the express  written  authorization  of
        !          125680: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          125681: /
        !          125682: /      Copyright (c) 1988
        !          125683: /      An unpublished work by INETCO Systems, Ltd.
        !          125684: /      All rights reserved.
        !          125685: /
        !          125686: / $Log:        /usr/src/sys/ldrv/RCS/defer.s,v $
        !          125687: / Revision 1.1 88/04/04  16:40:21      src
        !          125688: / Initial revision
        !          125689: / 
        !          125690: /
        !          125691: ////////
        !          125692: 
        !          125693: ////////
        !          125694: /
        !          125695: / void
        !          125696: / defer( f, a )                - defer local function from loadable driver.
        !          125697: / void (*f)();
        !          125698: / int a;
        !          125699: /
        !          125700: /      Input:  f = pointer to function to be deferred.
        !          125701: /              a = argument to be passed to function.
        !          125702: /
        !          125703: /      Action: Schedule local function 'f' to be invoked with argument 'a'
        !          125704: /              at next transition from kernel to user mode.
        !          125705: /
        !          125706: /      Return: None.
        !          125707: /
        !          125708: ////////
        !          125709: 
        !          125710:        .globl  defer_
        !          125711: 
        !          125712: defer_:        push    bp                      / defer( f, a )
        !          125713:        mov     bp, sp                  / void (*f)();
        !          125714:        push    6(bp)                   / int a;
        !          125715:        push    cs                      / {
        !          125716:        push    4(bp)                   /       kcall( Kldefer, f, cs, a );
        !          125717:        mov     ax, $Kldefer            /
        !          125718:        push    ax                      /
        !          125719:        call    kcall_                  /
        !          125720:        mov     sp, bp                  /
        !          125721:        pop     bp                      / }
        !          125722:        ret
        !          125723: 0707070064030060261004440000030000030000011777770507310742300004600000004374/newbits/kernel/USRSRC/ldrv/dmalock.c/* $Header: /usr/src/sys/ldrv/RCS/dmalock.c,v 1.1 89/06/30 16:29:52 src Exp $
        !          125724:  *
        !          125725:  *     The  information  contained herein  is a trade secret  of INETCO
        !          125726:  *     Systems, Ltd, and is  confidential information.   It is provided
        !          125727:  *     under a license agreement,  and may be copied or disclosed  only
        !          125728:  *     under  the  terms  of  that  agreement.    Any  reproduction  or
        !          125729:  *     disclosure  of  this   material   without  the  express  written
        !          125730:  *     authorization of INETCO Systems, Ltd. or persuant to the license
        !          125731:  *     agreement is unlawful.
        !          125732:  *
        !          125733:  *     Copyright (c) 1989
        !          125734:  *     An unpublished work by INETCO Systems, Ltd.
        !          125735:  *     All rights reserved.
        !          125736:  *
        !          125737:  * $Description: $
        !          125738:  *     Routines to lock/unlock the DMA controller chip from a loadable driver.
        !          125739:  *
        !          125740:  * $Author: src $
        !          125741:  *
        !          125742:  * $Creation: June 29, 1989 $
        !          125743:  *
        !          125744:  * $Log:       /usr/src/sys/ldrv/RCS/dmalock.c,v $
        !          125745:  * Revision 1.1        89/06/30  16:29:52      src
        !          125746:  * Initial revision
        !          125747:  * 
        !          125748:  */
        !          125749: 
        !          125750: #include <sys/coherent.h>
        !          125751: 
        !          125752: typedef void (* vfp_t)();              /* Void function pointer type.       */
        !          125753: 
        !          125754: /*
        !          125755:  * External functions.
        !          125756:  */
        !          125757: extern void Kdmalock();
        !          125758: extern void Kdmaunlock();
        !          125759: extern void Kldtimcall();
        !          125760: extern saddr_t getcs();
        !          125761: 
        !          125762: /*
        !          125763:  * int
        !          125764:  * dmalock( tp, fun, arg )
        !          125765:  * TIM * tp;
        !          125766:  * vfp_t fun;
        !          125767:  * int  arg;
        !          125768:  *
        !          125769:  *     Inputs: tp  = Deferred function structure pointer.
        !          125770:  *             fun = Function to call if request is deferred.
        !          125771:  *             arg = Argument to pass to function.
        !          125772:  *
        !          125773:  *     Action: Calls kernel dmalock() routine.
        !          125774:  *
        !          125775:  *     Return: 0 = Lock granted or -1 = Lock deferred.
        !          125776:  *
        !          125777:  *     Notes:  DMA controller locking was introduced to cure a bug on the
        !          125778:  *             NCR DMA controller, where overlapped DMA caused problems.
        !          125779:  *             No action is taken if DMA locking is disabled.
        !          125780:  */
        !          125781: 
        !          125782: int
        !          125783: dmalock( tp, fun, arg )
        !          125784: register TIM  * tp;
        !          125785: vfp_t          fun;
        !          125786: int            arg;
        !          125787: {
        !          125788:        /*
        !          125789:         * Define loadable driver interface.
        !          125790:         * Kldtimcall will be invoked when a deferred function is executed.
        !          125791:         * It will in turn invoke FP_SEL(tp->t_ldrv):4 (the calling drivers
        !          125792:         * function call entry point), passing FP_OFF(tp->t_ldrv) (the function
        !          125793:         * to call) in AX.
        !          125794:         */
        !          125795:        FP_SEL(tp->t_ldrv) = getcs();
        !          125796:        FP_OFF(tp->t_ldrv) = fun;
        !          125797:        return( kcall( Kdmalock, tp, Kldtimcall, arg ) );
        !          125798: }
        !          125799: 
        !          125800: /*
        !          125801:  * void
        !          125802:  * dmaunlock( tp )
        !          125803:  * TIM * tp;
        !          125804:  *
        !          125805:  *     Inputs: tp = Deferred function structure pointer.
        !          125806:  *
        !          125807:  *     Action: Calls the kernel dmaunlock().
        !          125808:  */
        !          125809: 
        !          125810: void
        !          125811: dmaunlock( tp )
        !          125812: register TIM * tp;
        !          125813: {
        !          125814:        kcall( Kdmaunlock, tp );
        !          125815: }
        !          125816: 
        !          125817: 0707070064030060251004440000030000030000011777770507310742300004500000001751/newbits/kernel/USRSRC/ldrv/ffbyte.s/ $Header: /usr/src/sys/ldrv/RCS/ffbyte.s,v 1.1 88/03/24 16:30:28 src Exp $
        !          125818: /
        !          125819: /      The  information  contained herein  is a trade secret  of INETCO
        !          125820: /      Systems, and is confidential information.   It is provided under
        !          125821: /      a license agreement,  and may be copied or disclosed  only under
        !          125822: /      the terms of that agreement.   Any reproduction or disclosure of
        !          125823: /      this  material  without  the express  written  authorization  of
        !          125824: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          125825: /
        !          125826: /      Copyright (c) 1986
        !          125827: /      An unpublished work by INETCO Systems, Ltd.
        !          125828: /      All rights reserved.
        !          125829: /
        !          125830: / $Log:        /usr/src/sys/ldrv/RCS/ffbyte.s,v $
        !          125831: / Revision 1.1 88/03/24  16:30:28      src
        !          125832: / Initial revision
        !          125833: / 
        !          125834: /
        !          125835: ////////
        !          125836: 
        !          125837: ////////
        !          125838: /
        !          125839: / ffbyte( fp )         -- fetch far byte
        !          125840: / int far * fp;
        !          125841: /
        !          125842: ////////
        !          125843: 
        !          125844:        .globl  ffbyte_
        !          125845: 
        !          125846: ffbyte_:push   es              / ffbyte( fp )
        !          125847:        push    di              / register char far * fp;       /* ES:DI */
        !          125848:        push    bp              / {
        !          125849:        mov     bp, sp          /
        !          125850:        les     di, 8(bp)       /
        !          125851:                                /
        !          125852:        sub     ax, ax          /
        !          125853:        movb    al, es:(di)     /       return( *fp );
        !          125854:                                /
        !          125855:        pop     bp              / }
        !          125856:        pop     di
        !          125857:        pop     es
        !          125858:        ret
        !          125859: 0707070064030060241004440000030000030000011777770507310742300004400000002663/newbits/kernel/USRSRC/ldrv/ffmem.s/ $Header: /usr/src/sys/ldrv/RCS/ffmem.s,v 1.1 88/03/24 16:30:31 src Exp $
        !          125860: /
        !          125861: /      The  information  contained herein  is a trade secret  of INETCO
        !          125862: /      Systems, and is confidential information.   It is provided under
        !          125863: /      a license agreement,  and may be copied or disclosed  only under
        !          125864: /      the terms of that agreement.   Any reproduction or disclosure of
        !          125865: /      this  material  without  the express  written  authorization  of
        !          125866: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          125867: /
        !          125868: /      Copyright (c) 1986
        !          125869: /      An unpublished work by INETCO Systems, Ltd.
        !          125870: /      All rights reserved.
        !          125871: /
        !          125872: / $Log:        /usr/src/sys/ldrv/RCS/ffmem.s,v $
        !          125873: / Revision 1.1 88/03/24  16:30:31      src
        !          125874: / Initial revision
        !          125875: / 
        !          125876: /
        !          125877: ////////
        !          125878: 
        !          125879: ////////
        !          125880: /
        !          125881: / void
        !          125882: / ffmem( fp, m, n )    -- fetch far memory
        !          125883: / faddr_t fp;
        !          125884: / char * m;
        !          125885: / int n;
        !          125886: /
        !          125887: /      Input:  fp = far pointer [32 bit selector:offset] to source
        !          125888: /              m  = destination
        !          125889: /              n  = number of bytes to transfer.
        !          125890: /
        !          125891: /      Action: Transfer 'n' bytes from far address 'fp' to offset 'm'
        !          125892: /              in the current data space.
        !          125893: /
        !          125894: /      Return: None.
        !          125895: /
        !          125896: ////////
        !          125897: 
        !          125898:        .globl  ffmem_
        !          125899: 
        !          125900: ffmem_:        push    si              / void
        !          125901:        push    di              / ffmem( fp, m, n )
        !          125902:        push    bp              /
        !          125903:        mov     bp, sp          / register faddr_t fp;          /* DS:SI */
        !          125904:        push    ds              / register char * m;            /* DI */
        !          125905:        lds     si, 8(bp)       / register int n;               /* CX */
        !          125906:        mov     di, 12(bp)      /
        !          125907:        mov     cx, 14(bp)      / {
        !          125908:                                /
        !          125909:        cld                     /
        !          125910:        clc                     /       for ( ; n != 0; --n )
        !          125911:        rcr     cx, $1          /
        !          125912:        rep                     /               *m++ = *fp++;
        !          125913:        movsw                   /
        !          125914:        rcl     cx, $1          /
        !          125915:        rep                     /
        !          125916:        movsb                   /
        !          125917:                                /
        !          125918:        pop     ds              / }
        !          125919:        pop     bp
        !          125920:        pop     di
        !          125921:        pop     si
        !          125922:        ret
        !          125923: 0707070064030060231004440000030000030000011777770507310742400004500000001725/newbits/kernel/USRSRC/ldrv/ffword.s/ $Header: /usr/src/sys/ldrv/RCS/ffword.s,v 1.1 88/03/24 16:30:33 src Exp $
        !          125924: /
        !          125925: /      The  information  contained herein  is a trade secret  of INETCO
        !          125926: /      Systems, and is confidential information.   It is provided under
        !          125927: /      a license agreement,  and may be copied or disclosed  only under
        !          125928: /      the terms of that agreement.   Any reproduction or disclosure of
        !          125929: /      this  material  without  the express  written  authorization  of
        !          125930: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          125931: /
        !          125932: /      Copyright (c) 1986
        !          125933: /      An unpublished work by INETCO Systems, Ltd.
        !          125934: /      All rights reserved.
        !          125935: /
        !          125936: / $Log:        /usr/src/sys/ldrv/RCS/ffword.s,v $
        !          125937: / Revision 1.1 88/03/24  16:30:33      src
        !          125938: / Initial revision
        !          125939: / 
        !          125940: /
        !          125941: ////////
        !          125942: 
        !          125943: ////////
        !          125944: /
        !          125945: / ffword( fp )         -- fetch far word
        !          125946: / int far * fp;
        !          125947: /
        !          125948: ////////
        !          125949: 
        !          125950:        .globl  ffword_
        !          125951: 
        !          125952: ffword_:push   es              / ffword( fp )
        !          125953:        push    di              / register int far * fp;        /* ES:DI */
        !          125954:        push    bp              / {
        !          125955:        mov     bp, sp          /
        !          125956:        les     di, 8(bp)       /
        !          125957:                                /
        !          125958:        mov     ax, es:(di)     /       return *fp;
        !          125959:                                /
        !          125960:        pop     bp              / }
        !          125961:        pop     di
        !          125962:        pop     es
        !          125963:        ret
        !          125964: 0707070064030060221004440000030000030000011777770507310742400004400000001601/newbits/kernel/USRSRC/ldrv/getcs.s/ $Header: /usr/src/sys/ldrv/RCS/getcs.s,v 1.1 88/03/24 16:30:36 src Exp $
        !          125965: /
        !          125966: /      The  information  contained herein  is a trade secret  of INETCO
        !          125967: /      Systems, and is confidential information.   It is provided under
        !          125968: /      a license agreement,  and may be copied or disclosed  only under
        !          125969: /      the terms of that agreement.   Any reproduction or disclosure of
        !          125970: /      this  material  without  the express  written  authorization  of
        !          125971: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          125972: /
        !          125973: /      Copyright (c) 1986
        !          125974: /      An unpublished work by INETCO Systems, Ltd.
        !          125975: /      All rights reserved.
        !          125976: /
        !          125977: / $Log:        /usr/src/sys/ldrv/RCS/getcs.s,v $
        !          125978: / Revision 1.1 88/03/24  16:30:36      src
        !          125979: / Initial revision
        !          125980: / 
        !          125981: / 87/12/08     Allan Cornish   /usr/src/sys/ldrv/getcs.s
        !          125982: / Getcs() function obtains current code segment.
        !          125983: /
        !          125984: ////////
        !          125985: 
        !          125986: ////////
        !          125987: /
        !          125988: / Get code selector.
        !          125989: /
        !          125990: ////////
        !          125991: 
        !          125992:        .globl  getcs_
        !          125993: 
        !          125994: getcs_:        mov     ax, cs                  / Return code selector.
        !          125995:        ret
        !          125996: 0707070064030060211004440000030000030000011777770507310742400004200000001470/newbits/kernel/USRSRC/ldrv/inb.s/ $Header: /usr/src/sys/ldrv/RCS/inb.s,v 1.1 88/03/24 16:30:39 src Exp $
        !          125997: /
        !          125998: /      The  information  contained herein  is a trade secret  of INETCO
        !          125999: /      Systems, and is confidential information.   It is provided under
        !          126000: /      a license agreement,  and may be copied or disclosed  only under
        !          126001: /      the terms of that agreement.   Any reproduction or disclosure of
        !          126002: /      this  material  without  the express  written  authorization  of
        !          126003: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          126004: /
        !          126005: /      Copyright (c) 1988
        !          126006: /      An unpublished work by INETCO Systems, Ltd.
        !          126007: /      All rights reserved.
        !          126008: /
        !          126009: / $Log:        /usr/src/sys/ldrv/RCS/inb.s,v $
        !          126010: / Revision 1.1 88/03/24  16:30:39      src
        !          126011: / Initial revision
        !          126012: / 
        !          126013: /
        !          126014: ////////
        !          126015: 
        !          126016: ////////
        !          126017: /
        !          126018: / Basic port level I/O.
        !          126019: /
        !          126020: / int  inb(port);
        !          126021: /
        !          126022: ////////
        !          126023: 
        !          126024:        .globl  inb_
        !          126025: 
        !          126026: inb_:  mov     bx, sp
        !          126027:        mov     dx, 2(bx)
        !          126028:        sub     ax, ax
        !          126029:        inb     al, dx
        !          126030:        ret
        !          126031: 0707070064030060201004440000030000030000011777770507310742400004400000002522/newbits/kernel/USRSRC/ldrv/kcall.s/ $Header: /usr/src/sys/ldrv/RCS/kcall.s,v 1.1 88/03/24 16:30:41 src Exp $
        !          126032: /
        !          126033: /      The  information  contained herein  is a trade secret  of INETCO
        !          126034: /      Systems, and is confidential information.   It is provided under
        !          126035: /      a license agreement,  and may be copied or disclosed  only under
        !          126036: /      the terms of that agreement.   Any reproduction or disclosure of
        !          126037: /      this  material  without  the express  written  authorization  of
        !          126038: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          126039: /
        !          126040: /      Copyright (c) 1988
        !          126041: /      An unpublished work by INETCO Systems, Ltd.
        !          126042: /      All rights reserved.
        !          126043: /
        !          126044: / $Log:        /usr/src/sys/ldrv/RCS/kcall.s,v $
        !          126045: / Revision 1.1 88/03/24  16:30:41      src
        !          126046: / Initial revision
        !          126047: / 
        !          126048: /
        !          126049: ////////
        !          126050: 
        !          126051: ////////
        !          126052: /
        !          126053: / kcall( func, arg, ... )
        !          126054: /
        !          126055: /      Input:  func = kernel function to be invoked.
        !          126056: /              arg  = optional argument(s) to be passed to kernel function.
        !          126057: /
        !          126058: /      Action: Invoke kernel function.
        !          126059: /
        !          126060: ////////
        !          126061:        .globl  kcall_
        !          126062: 
        !          126063: kcall_:
        !          126064:        pop     bx              / Convert stack from (retIP dstIP arg ...)
        !          126065:        pop     ax              /                 to (      retIP arg ...)
        !          126066:        push    bx              / Leaving dstIP in AX register.
        !          126067:                                /
        !          126068:        .byte 0x9A              / Request kernel to perform far call.
        !          126069:        .word xcalled           /
        !          126070:        .word 0x0060            /
        !          126071:                                /
        !          126072:        pop     bx              / Convert stack from (      retIP arg ...)
        !          126073:        push    bx              /                 to (retIP retIP arg ...)
        !          126074:        push    bx              / This allows caller to cleanup normally.
        !          126075:                                / NOTE: DO NOT MODIFY DX:AX RETURN VALUE.
        !          126076:                                /
        !          126077:        ret                     / Return to caller.
        !          126078: 0707070064030060171006440000030000030000011777770507310742500004500000002043/newbits/kernel/USRSRC/ldrv/ldconfig: '$Header: /usr/src/sys/ldrv/RCS/ldconfig,v 1.1 88/04/04 16:59:20 src Exp $'
        !          126079: :
        !          126080: :      configure a loadable driver
        !          126081: :
        !          126082: : usage: ldconfig [swap] [DRV ...]
        !          126083: :
        !          126084: BUILD=0
        !          126085: DEV=/tmp/dev
        !          126086: PATCH=""
        !          126087: UNDEF=""
        !          126088: LDMOD=""
        !          126089: PASS1=""
        !          126090: 
        !          126091: for ARG in $*
        !          126092: do
        !          126093:        case "${ARG}" in
        !          126094:        DEV\=*)
        !          126095:                DEV=`/bin/echo "${ARG}" | /bin/sed -e 's/^....//'`
        !          126096:                ;;
        !          126097:        *)
        !          126098:                PASS1="${PASS1} ${ARG}"
        !          126099:                ;;
        !          126100:        esac
        !          126101: done
        !          126102: 
        !          126103: for ARG in ${PASS1}
        !          126104: do
        !          126105:        case "$ARG" in
        !          126106: 
        !          126107:        swap)
        !          126108:                /bin/echo "ldrv/swap: "
        !          126109:                ld -r -o ldrv/swap lib/ldrts0.o lib/ldswap.o lib/ldlib.a
        !          126110:                LDMOD=""
        !          126111:                ;;
        !          126112: 
        !          126113:        *\=*)
        !          126114:                LDMOD="${LDMOD} ${ARG}"
        !          126115:                ;;
        !          126116: 
        !          126117:        *)
        !          126118:                case "${ARG}" in
        !          126119:                *[0123][abcdx])
        !          126120:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          126121:                        ;;
        !          126122:                *)
        !          126123:                        FILE="${ARG}"
        !          126124:                        ;;
        !          126125:                esac
        !          126126: 
        !          126127:                /bin/echo "ldrv/${FILE}: "
        !          126128:                if /bin/test -r confdrv/${FILE}
        !          126129:                then
        !          126130:                        UNDEF=""
        !          126131:                        . confdrv/${FILE}
        !          126132:                        /bin/ld -r -o ldrv/${FILE} lib/ldrts0.o \
        !          126133:                                lib/ldmain.o ${UNDEF} \
        !          126134:                                lib/ldlib.a || exit 1
        !          126135:                        case "${LDMOD}" in
        !          126136:                        "")     ;;
        !          126137:                        *)      /conf/patch ldrv/${FILE} ${LDMOD}
        !          126138:                        esac
        !          126139:                else
        !          126140:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          126141:                        exit 1
        !          126142:                fi
        !          126143:                LDMOD=""
        !          126144:                ;;
        !          126145:        esac
        !          126146: done
        !          126147: 0707070064030104731004440000030000030000011777770507310742500004500000012013/newbits/kernel/USRSRC/ldrv/ldmain.c/* $Header: /usr/src/sys/ldrv/RCS/ldmain.c,v 1.2 89/03/31 16:19:36 src Exp $ */
        !          126148: /*
        !          126149:  *     The  information  contained herein  is a trade secret  of INETCO
        !          126150:  *     Systems, and is confidential information.   It is provided under
        !          126151:  *     a license agreement,  and may be copied or disclosed  only under
        !          126152:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          126153:  *     this  material  without  the express  written  authorization  of
        !          126154:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          126155:  *
        !          126156:  *     Copyright (c) 1987
        !          126157:  *     An unpublished work by INETCO Systems, Ltd.
        !          126158:  *     All rights reserved.
        !          126159:  */
        !          126160: 
        !          126161: /*
        !          126162:  * Loadable Driver - Process Handler.
        !          126163:  *
        !          126164:  * $Log:       /usr/src/sys/ldrv/RCS/ldmain.c,v $
        !          126165:  * Revision 1.2        89/03/31  16:19:36      src
        !          126166:  * Bug:        Did not cancel either attached timed functions or deferred functions
        !          126167:  *     during an unload.  As a result, if a driver did not explicitly do
        !          126168:  *     this, then unloading the driver could cause a system panic.
        !          126169:  * Fix:        Now cancels the functions. (ABC)
        !          126170:  * 
        !          126171:  * Revision 1.1        88/03/24  08:30:44      src
        !          126172:  * Initial revision
        !          126173:  * 
        !          126174:  * 87/12/03    Allan Cornish           /usr/src/sys/ldrv/ldmain.c
        !          126175:  * Initial version.
        !          126176:  */
        !          126177: #include <sys/coherent.h>
        !          126178: #include <sys/proc.h>
        !          126179: #include <sys/sched.h>
        !          126180: #include <sys/con.h>
        !          126181: #include <sys/seg.h>
        !          126182: #include <sys/stat.h>
        !          126183: #include <sys/uproc.h>
        !          126184: 
        !          126185: extern CON con;
        !          126186: 
        !          126187: extern saddr_t ldrvsel[NDRV];
        !          126188: extern saddr_t ldrvics[16];
        !          126189: extern void  (*ldrvipc[16])();
        !          126190: extern CON *   ldrvcon[NDRV];
        !          126191: extern CON     ldrvpsy;
        !          126192: extern saddr_t ucs;
        !          126193: 
        !          126194: /*
        !          126195:  * Local variable - keeps track of the number of opens.
        !          126196:  * The loadable driver can't terminate until after the last close.
        !          126197:  * Openf is the loadable driver open routine.
        !          126198:  * Closef points to the driver's close routine.
        !          126199:  * The configuration table entries are taken over
        !          126200:  */
        !          126201: static int     nopen = 0;
        !          126202: static void    (*openf)() = NULL;
        !          126203: static void    (*closef)() = NULL;
        !          126204: 
        !          126205: main()
        !          126206: {
        !          126207:        register int mind = con.c_mind;
        !          126208:        register int level;
        !          126209:        extern  void myopen();
        !          126210:        extern  void myclose();
        !          126211:        extern  void Kdefend();
        !          126212: 
        !          126213:        /*
        !          126214:         * Loadable devices must identify the desired major device.
        !          126215:         */
        !          126216:        if ( (mind == 0) || (mind >= drvn) ) {
        !          126217:                printf("ldrv:%d: bad dev\n", mind );
        !          126218:                uexit( 1 );
        !          126219:        }
        !          126220: 
        !          126221:        /*
        !          126222:         * Loadable devices must use a unique [not in use] major device.
        !          126223:         */
        !          126224:        if ( (drvl[mind].d_conp != NULL) || (ldrvcon[mind] != NULL) ) {
        !          126225:                printf("ldrv:%d: dev bsy\n", mind );
        !          126226:                uexit( 0 );
        !          126227:        }
        !          126228: 
        !          126229:        /*
        !          126230:         * Intercept driver open/close requests.
        !          126231:         * This allows the driver process to terminate after the last close,
        !          126232:         *      if one or more signals have been received.
        !          126233:         */
        !          126234:        openf           = con.c_open;
        !          126235:        closef          = con.c_close;
        !          126236:        con.c_open      = myopen;
        !          126237:        con.c_close     = myclose;
        !          126238: 
        !          126239:        /*
        !          126240:         * Install the loadable driver pseudo device interface.
        !          126241:         * The O/S will call the pseudo-device, which will call us.
        !          126242:         * Record our driver configuration and code segment.
        !          126243:         */
        !          126244:        drvl[mind].d_conp = &ldrvpsy;
        !          126245:        ldrvcon[mind] = &con;
        !          126246:        ldrvsel[mind] = ucs;
        !          126247: 
        !          126248:        /*
        !          126249:         * Load the device driver.
        !          126250:         */
        !          126251:        if ( con.c_load != NULL )
        !          126252:                (*con.c_load)( makedev(mind,0) );
        !          126253: 
        !          126254:        /*
        !          126255:         * Sleep until a kill signal has arrived, and no device is open.
        !          126256:         */
        !          126257:        do {
        !          126258:                sleep( (char *)&nopen, CVSWAP, IVSWAP, SVSWAP );
        !          126259: 
        !          126260:        } while ( ((SELF->p_ssig & 0x0100) == 0) || (nopen != 0) );
        !          126261: 
        !          126262:        /*
        !          126263:         * Unload the device driver.
        !          126264:         */
        !          126265:        if ( con.c_uload != NULL )
        !          126266:                (*con.c_uload)( makedev(mind,0) );
        !          126267: 
        !          126268:        /*
        !          126269:         * Erase references to our kernel process.
        !          126270:         */
        !          126271:        drvl[mind].d_conp = NULL;
        !          126272:        ldrvcon[mind] = NULL;
        !          126273:        ldrvsel[mind] = 0;
        !          126274: 
        !          126275:        /*
        !          126276:         * Scan looking for attached interrupts.
        !          126277:         * NOTE: This is to prevent dangling interrupt vectors.
        !          126278:         */
        !          126279:        for ( level = 0; level < 16; level++ ) {
        !          126280: 
        !          126281:                /*
        !          126282:                 * Interrupt is not attached to us.
        !          126283:                 */
        !          126284:                if ( ldrvics[level] != ucs )
        !          126285:                        continue;
        !          126286: 
        !          126287:                /*
        !          126288:                 * Disable interrupt.
        !          126289:                 */
        !          126290:                clrivec( level );
        !          126291: 
        !          126292:                /*
        !          126293:                 * Release loadable driver interrupt.
        !          126294:                 */
        !          126295:                ldrvics[level] = 0;
        !          126296:                ldrvipc[level] = NULL;
        !          126297:        }
        !          126298: 
        !          126299:        /*
        !          126300:         * Service deferred functions BEFORE scanning for timed functions.
        !          126301:         * This is in case a deferred function schedules a timed function.
        !          126302:         */
        !          126303:        kcall( Kdefend );
        !          126304: 
        !          126305:        /*
        !          126306:         * Scan for attached timed functions which have to be terminated.
        !          126307:         */
        !          126308:        for ( level = 0; level < nel(timq); level++ ) {
        !          126309:                register TIM * tp;
        !          126310: 
        !          126311:                /*
        !          126312:                 * Access a specific timing queue.
        !          126313:                 */
        !          126314:                for ( tp = timq[level]; tp != NULL; ) {
        !          126315: 
        !          126316:                        /*
        !          126317:                         * Timed function is in our loadable driver.
        !          126318:                         * Restart search at start of timing queue.
        !          126319:                         */
        !          126320:                        if ( FP_SEL(tp->t_ldrv) == getcs() ) {
        !          126321:                                timeout( tp, 0, NULL, 0 );
        !          126322:                                tp = timq[ level ];
        !          126323:                        }
        !          126324: 
        !          126325:                        /*
        !          126326:                         * Not one of our timed functions.
        !          126327:                         * Advance to next function in queue.
        !          126328:                         */
        !          126329:                        else
        !          126330:                                tp = tp->t_next;
        !          126331:                }
        !          126332:        }
        !          126333: 
        !          126334:        /*
        !          126335:         * Terminate with extreme prejudice.
        !          126336:         */
        !          126337:        uexit( 0 );
        !          126338: }
        !          126339: 
        !          126340: static void
        !          126341: myopen( dev, mode )
        !          126342: dev_t dev;
        !          126343: int mode;
        !          126344: {
        !          126345:        /*
        !          126346:         * Invoke the true open routine for the loadable driver.
        !          126347:         */
        !          126348:        if ( openf != NULL )
        !          126349:                (*openf)(dev, mode );
        !          126350: 
        !          126351:        /*
        !          126352:         * Adjust reference count if open succeeded.
        !          126353:         */
        !          126354:        if ( u.u_error == 0 )
        !          126355:                nopen++;
        !          126356: }
        !          126357: 
        !          126358: static void
        !          126359: myclose( dev )
        !          126360: dev_t dev;
        !          126361: {
        !          126362:        /*
        !          126363:         * Invoke the true close routine for the loadable driver.
        !          126364:         */
        !          126365:        if ( closef != NULL )
        !          126366:                (*closef)( dev );
        !          126367: 
        !          126368:        /*
        !          126369:         * Wakeup driver process after last close.
        !          126370:         * This allows it to terminate if appropriate.
        !          126371:         */
        !          126372:        if ( --nopen == 0 )
        !          126373:                wakeup( (char*) &nopen );
        !          126374: }
        !          126375: 0707070064030060151004440000030000030000011777770507310742600004500000002766/newbits/kernel/USRSRC/ldrv/ldrts0.s/ $Header: /usr/src/sys/ldrv/RCS/ldrts0.s,v 1.1 88/03/24 16:30:47 src Exp $
        !          126376: / 
        !          126377: /      The  information  contained herein  is a trade secret  of INETCO
        !          126378: /      Systems, and is confidential information.   It is provided under
        !          126379: /      a license agreement,  and may be copied or disclosed  only under
        !          126380: /      the terms of that agreement.   Any reproduction or disclosure of
        !          126381: /      this  material  without  the express  written  authorization  of
        !          126382: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          126383: / 
        !          126384: /      Copyright (c) 1987
        !          126385: /      An unpublished work by INETCO Systems, Ltd.
        !          126386: /      All rights reserved.
        !          126387: /
        !          126388: 
        !          126389: ////////
        !          126390: /
        !          126391: / Loadable Driver Run Time Startup
        !          126392: /
        !          126393: / Notes:       This function MUST be at offset 0 in driver code segment.
        !          126394: /
        !          126395: / $Log:        /usr/src/sys/ldrv/RCS/ldrts0.s,v $
        !          126396: / Revision 1.1 88/03/24  16:30:47      src
        !          126397: / Initial revision
        !          126398: / 
        !          126399: /
        !          126400: ////////
        !          126401: 
        !          126402:        .globl  main_
        !          126403:        call    main_
        !          126404:        xret
        !          126405: 
        !          126406: ////////
        !          126407: /
        !          126408: /      Invocation mechanism for local driver functions by kernel code.
        !          126409: /
        !          126410: /      Input:  AX      = pointer to local function to be invoked.
        !          126411: /              4(BP)   = 1st parameter to be passed to local function.
        !          126412: /              6(BP)   = 2nd parameter to be passed to local function.
        !          126413: /              8(BP)   = 3rd parameter to be passed to local function.
        !          126414: /
        !          126415: /      Action: Invoke local function whose address is given in register AX,
        !          126416: /              passing parameters at offset 4,6,8 relative to register BP.
        !          126417: /              Perform a far return to operating system.
        !          126418: /
        !          126419: /      Notes:  Parameter passing convention specified by kernel.
        !          126420: /              This function MUST be at offset 4 in driver code segment.
        !          126421: /
        !          126422: ////////
        !          126423: 
        !          126424:        push    8(bp)
        !          126425:        push    6(bp)
        !          126426:        push    4(bp)
        !          126427:        icall   ax
        !          126428:        add     sp, $6
        !          126429:        xret
        !          126430: 0707070064030060141004440000030000030000011777770507310742700004500000027440/newbits/kernel/USRSRC/ldrv/ldswap.c/* $Header: /usr/src/sys/ldrv/RCS/ldswap.c,v 1.1 88/03/24 16:30:50 src Exp $ */
        !          126431: /* (lgl-
        !          126432:  *     The information contained herein is a trade secret of Mark Williams
        !          126433:  *     Company, and  is confidential information.  It is provided  under a
        !          126434:  *     license agreement,  and may be  copied or disclosed  only under the
        !          126435:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          126436:  *     material without the express written authorization of Mark Williams
        !          126437:  *     Company or persuant to the license agreement is unlawful.
        !          126438:  *
        !          126439:  *     COHERENT Version 2.3.37
        !          126440:  *     Copyright (c) 1982, 1983, 1984.
        !          126441:  *     An unpublished work by Mark Williams Company, Chicago.
        !          126442:  *     All rights reserved.
        !          126443:  -lgl) */
        !          126444: /*
        !          126445:  * Coherent.
        !          126446:  * Swapper.
        !          126447:  *
        !          126448:  * $Log:       /usr/src/sys/ldrv/RCS/ldswap.c,v $
        !          126449:  * Revision 1.1        88/03/24  16:30:50      src
        !          126450:  * Initial revision
        !          126451:  * 
        !          126452:  * 87/11/05    Allan Cornish           /usr/src/sys/ldrv/ldswap.c
        !          126453:  * New seg struct now used to allow extended addressing.
        !          126454:  *
        !          126455:  * 87/10/26    Allan Cornish           /usr/src/sys/ldrv/ldswap.c
        !          126456:  * Modified to support loadable drivers - temporary modification.
        !          126457:  * Now requires SIGKILL signal in order to terminate.
        !          126458:  *
        !          126459:  * 87/01/05    Allan Cornish           /usr/src/sys/ker/swap.c
        !          126460:  * Swap() now waits for all processes to be swapped in before exit on signal.
        !          126461:  */
        !          126462: #include <sys/coherent.h>
        !          126463: #include <sys/proc.h>
        !          126464: #include <sys/sched.h>
        !          126465: #include <sys/seg.h>
        !          126466: #include <sys/uproc.h>
        !          126467: #include <sys/buf.h>
        !          126468: 
        !          126469: /*
        !          126470:  * Functions.
        !          126471:  */
        !          126472: SEG    *xmalloc();
        !          126473: SEG    *xdalloc();
        !          126474: void   Kwakeup();
        !          126475: void   Ktimeout();
        !          126476: 
        !          126477: main()
        !          126478: {
        !          126479:        register SEG *sp;
        !          126480:        register PROC *pp1;
        !          126481:        register PROC *pp2;
        !          126482:        register PROC *pp3;
        !          126483:        register unsigned s;
        !          126484:        register unsigned n;
        !          126485:        register unsigned t;
        !          126486:        register unsigned v;
        !          126487:        register unsigned m;
        !          126488:        register int i;
        !          126489:        static unsigned ltimer;
        !          126490: 
        !          126491:        if (sexflag != 0)
        !          126492:                uexit(1);
        !          126493:        sexflag++;
        !          126494: 
        !          126495:        while (1) {
        !          126496:                lock( pnxgate );
        !          126497:                t = (utimer - ltimer) / NSUTICK;
        !          126498:                v = t * SVCLOCK;
        !          126499:                ltimer += t * NSUTICK;
        !          126500: 
        !          126501:                /*
        !          126502:                 * Search for process to swap into memory.
        !          126503:                 */
        !          126504:                pp2 = NULL;
        !          126505:                m   = 0;
        !          126506:                s   = 0;
        !          126507:                for (pp1 = procq.p_nback; pp1 != &procq; pp1 = pp1->p_nback) {
        !          126508: 
        !          126509:                        /*
        !          126510:                         * Process resides in memory.
        !          126511:                         */
        !          126512:                        if ( (pp1->p_flags & PFCORE) != 0 ) {
        !          126513:                                pp1->p_sval >>= t;
        !          126514:                                pp1->p_ival  -= t;
        !          126515:                                if (pp1->p_ival < -30000)
        !          126516:                                        pp1->p_ival = -30000;
        !          126517:                                continue;
        !          126518:                        }
        !          126519: 
        !          126520:                        /*
        !          126521:                         * Update swap value - high values swapped in first.
        !          126522:                         */
        !          126523:                        addu( pp1->p_sval, v );
        !          126524:                        s = 1;
        !          126525: 
        !          126526:                        /*
        !          126527:                         * Process is not runnable.
        !          126528:                         */
        !          126529:                        if ( pp1->p_state != PSRUN )
        !          126530:                                continue;
        !          126531: 
        !          126532:                        /*
        !          126533:                         * Calculate disk usage in Kbytes.
        !          126534:                         */
        !          126535:                        s = 0;
        !          126536:                        for ( i = 0; i < NUSEG+1; i++ )
        !          126537:                                if ( (sp = pp1->p_segp[i]) != NULL )
        !          126538:                                        if ( (sp->s_flags & SFCORE) == 0 )
        !          126539:                                                s += sp->s_size / 1024;
        !          126540:                        if ( s == 0 )
        !          126541:                                s = 1;
        !          126542: 
        !          126543:                        /*
        !          126544:                         * Compute importance:
        !          126545:                         *
        !          126546:                         *      swap value + response value
        !          126547:                         *      ---------------------------
        !          126548:                         *        Kbytes to be swapped in
        !          126549:                         */
        !          126550:                        n = (pp1->p_sval + pp1->p_rval) / s;
        !          126551: 
        !          126552:                        /*
        !          126553:                         * More important.
        !          126554:                         */
        !          126555:                        if ( n > m ) {
        !          126556:                                m = n;
        !          126557:                                pp2 = pp1;
        !          126558:                        }
        !          126559:                }
        !          126560:                unlock( pnxgate );
        !          126561: 
        !          126562:                /*
        !          126563:                 * No runnable processes swapped out.
        !          126564:                 */
        !          126565:                if ( pp2 == NULL ) {
        !          126566:                        /*
        !          126567:                         * No processes swapped out, and KILL signal received.
        !          126568:                         */
        !          126569:                        if ( (s == 0) && (SELF->p_ssig & 0x0100) )
        !          126570:                                break;
        !          126571:                        goto con;
        !          126572:                }
        !          126573: 
        !          126574: #ifndef        NOMONITOR
        !          126575:                if (swmflag)
        !          126576:                        printf("Swapin(%p, %d)\n", pp2, pp2->p_pid);
        !          126577: #endif
        !          126578:        xxx:
        !          126579:                /*
        !          126580:                 * Try to swap process into memory.
        !          126581:                 */
        !          126582:                while ( (testcore(pp2) == 0) || (proccore(pp2) != 0) ) {
        !          126583: 
        !          126584:                        /*
        !          126585:                         * Swap process out.
        !          126586:                         */
        !          126587:                        procdisk(pp2);
        !          126588:                        i   = 32767;
        !          126589:                        pp3 = NULL;
        !          126590: 
        !          126591:                        /*
        !          126592:                         * Search for process to swap out.
        !          126593:                         */
        !          126594:                        lock( pnxgate );
        !          126595:                        for (pp1=procq.p_nforw; pp1!=&procq; pp1=pp1->p_nforw){
        !          126596: 
        !          126597:                                if ( pp1->p_flags & (PFSWIO|PFLOCK|PFKERN) )
        !          126598:                                        continue;
        !          126599: 
        !          126600:                                /*
        !          126601:                                 * Process is not totally memory resident.
        !          126602:                                 */
        !          126603:                                if ( (pp1->p_flags&PFCORE) == 0 ) {
        !          126604:                                        /*
        !          126605:                                         * Swap segments out to disk.
        !          126606:                                         */
        !          126607:                                        if ( procdisk(pp1) != 0 ) {
        !          126608:                                                unlock( pnxgate );
        !          126609:                                                goto xxx;
        !          126610:                                        }
        !          126611:                                        continue;
        !          126612:                                }
        !          126613: 
        !          126614:                                /*
        !          126615:                                 * Process too important to swap out.
        !          126616:                                 */
        !          126617:                                if ((pp1->p_ival > -64) && (pp1->p_sval != 0))
        !          126618:                                        continue;
        !          126619: 
        !          126620:                                /*
        !          126621:                                 * Less important.
        !          126622:                                 */
        !          126623:                                if ( pp1->p_ival < i ) {
        !          126624:                                        i = pp1->p_ival;
        !          126625:                                        pp3 = pp1;
        !          126626:                                }
        !          126627:                        }
        !          126628:                        unlock( pnxgate );
        !          126629: 
        !          126630:                        /*
        !          126631:                         * No processes to swap out.
        !          126632:                         */
        !          126633:                        if ( pp3 == NULL ) {
        !          126634: #ifndef NOMONITOR
        !          126635:                                if (swmflag)
        !          126636:                                        printf("No one to swap out\n");
        !          126637: #endif
        !          126638:                                break;
        !          126639:                        }
        !          126640: 
        !          126641:                        /*
        !          126642:                         * Process is too important to swap out.
        !          126643:                         */
        !          126644:                        if ( i > 0 ) {
        !          126645: #ifndef NOMONITOR
        !          126646:                                if (swmflag)
        !          126647:                                        printf("Dispatch(%p, %d)\n",
        !          126648:                                                pp3, pp3->p_pid);
        !          126649: #endif
        !          126650:                                pp3->p_flags |= PFDISP;
        !          126651:                                break;
        !          126652:                        }
        !          126653: #ifndef NOMONITOR
        !          126654:                        if (swmflag)
        !          126655:                                printf("Swapout(%p, %d)\n", pp3, pp3->p_pid);
        !          126656: #endif
        !          126657:                        /*
        !          126658:                         * Swap process out to disk.
        !          126659:                         */
        !          126660:                        procdisk( pp3 );
        !          126661:                }
        !          126662: 
        !          126663: #ifndef NOMONITOR
        !          126664:                if (swmflag)
        !          126665:                        printf("Swapdone\n");
        !          126666: #endif
        !          126667:        con:
        !          126668:                kcall( Ktimeout, &stimer, NSRTICK, Kwakeup, (char *)&stimer );
        !          126669:                sleep( (char *)&stimer, CVSWAP, IVSWAP, SVSWAP );
        !          126670:        }
        !          126671:        sexflag--;
        !          126672:        uexit( 1 );
        !          126673: }
        !          126674: 
        !          126675: /*
        !          126676:  * See if the given process may fit in core.
        !          126677:  */
        !          126678: testcore( pp )
        !          126679: register PROC *pp;
        !          126680: {
        !          126681:        register SEG *sp;
        !          126682:        register fsize_t s;
        !          126683:        register paddr_t s1;
        !          126684:        register paddr_t s2;
        !          126685:        register int i;
        !          126686: 
        !          126687:        /*
        !          126688:         * Find largest segment in process.
        !          126689:         */
        !          126690:        s = 0;
        !          126691:        for ( i = 0; i < NUSEG+1; i++ ) {
        !          126692: 
        !          126693:                if ( (sp = pp->p_segp[i]) == NULL )
        !          126694:                        continue;
        !          126695: 
        !          126696:                /*
        !          126697:                 * Segment is memory resident.
        !          126698:                 */
        !          126699:                if ( (sp->s_flags & SFCORE) != 0 )
        !          126700:                        continue;
        !          126701: 
        !          126702:                /*
        !          126703:                 * Largest segment so far.
        !          126704:                 */
        !          126705:                if ( sp->s_size > s )
        !          126706:                        s = sp->s_size;
        !          126707:        }
        !          126708: 
        !          126709:        /*
        !          126710:         * See if largest segment will fit in memory.
        !          126711:         */
        !          126712:        s1 = corebot;
        !          126713:        sp = &segmq;
        !          126714:        do {
        !          126715:                /*
        !          126716:                 * Advance to next memory segment.
        !          126717:                 */
        !          126718:                sp = sp->s_forw;
        !          126719:                s2 = sp->s_paddr;
        !          126720: 
        !          126721:                /*
        !          126722:                 * It fits!
        !          126723:                 */
        !          126724:                if ( s2 - s1 >= s )
        !          126725:                        return (1);
        !          126726: 
        !          126727:                /*
        !          126728:                 * Compute start of next hole.
        !          126729:                 */
        !          126730:                s1 = sp->s_paddr + sp->s_size;
        !          126731: 
        !          126732:        } while ( sp != &segmq );
        !          126733: 
        !          126734:        return( 0 );
        !          126735: }
        !          126736: 
        !          126737: /*
        !          126738:  * Swap all segments associated with a particular process into core.
        !          126739:  * The number of segments still swapped out is returned.
        !          126740:  */
        !          126741: proccore( pp )
        !          126742: register PROC *pp;
        !          126743: {
        !          126744:        register SEG *sp;
        !          126745:        register int i;
        !          126746:        register int n;
        !          126747:        register int f;
        !          126748: 
        !          126749:        f = pp->p_flags & PFSWAP;
        !          126750: 
        !          126751:        /*
        !          126752:         * Try to swap in all user segments and the auxiliary segment.
        !          126753:         */
        !          126754:        for ( n = 0, i = 0; i < NUSEG+1; i++ ) {
        !          126755: 
        !          126756:                if ( (sp = pp->p_segp[i]) == NULL )
        !          126757:                        continue;
        !          126758: 
        !          126759:                /*
        !          126760:                 * Process was swapped out.
        !          126761:                 */
        !          126762:                if ( f != 0 )
        !          126763:                        sp->s_lrefc++;
        !          126764: 
        !          126765:                /*
        !          126766:                 * Segment is disk resident - try to swap it in.
        !          126767:                 */
        !          126768:                if ( (sp->s_flags & SFCORE) == 0 )
        !          126769:                        if ( segcore(sp) == 0 )
        !          126770:                                n++;
        !          126771:        }
        !          126772: 
        !          126773:        /*
        !          126774:         * No segments left on disk - mark process as being memory resident.
        !          126775:         */
        !          126776:        if ( n == 0 )
        !          126777:                pp->p_flags |= PFCORE;
        !          126778: 
        !          126779:        /*
        !          126780:         * Mark process as no longer being disk resident.
        !          126781:         */
        !          126782:        pp->p_flags &= ~PFSWAP;
        !          126783: 
        !          126784:        return( n );
        !          126785: }
        !          126786: 
        !          126787: /*
        !          126788:  * Swap out all segments associated with a given process.
        !          126789:  */
        !          126790: procdisk( pp )
        !          126791: register PROC *pp;
        !          126792: {
        !          126793:        register SEG *sp;
        !          126794:        register int i;
        !          126795:        register int f;
        !          126796:        int n;
        !          126797: 
        !          126798:        f = pp->p_flags & PFSWAP;
        !          126799: 
        !          126800:        /*
        !          126801:         * Mark process as no longer being memory resident BEFORE swapping.
        !          126802:         */
        !          126803:        pp->p_flags &= ~PFCORE;
        !          126804: 
        !          126805:        /*
        !          126806:         * Try to swap out all user segments and the auxiliary segment.
        !          126807:         */
        !          126808:        for ( n = 0, i = 0; i < NUSEG+1; i++ ) {
        !          126809: 
        !          126810:                if ( (sp = pp->p_segp[i]) == NULL )
        !          126811:                        continue;
        !          126812: 
        !          126813:                /*
        !          126814:                 * Process not already swapped out.
        !          126815:                 */
        !          126816:                if ( f == 0 )
        !          126817:                        sp->s_lrefc--;
        !          126818: 
        !          126819:                /*
        !          126820:                 * Segment already swapped out.
        !          126821:                 */
        !          126822:                if ( (sp->s_flags & SFCORE) == 0 )
        !          126823:                        continue;
        !          126824: 
        !          126825:                /*
        !          126826:                 * Segment no longer referenced by a memory-resident process.
        !          126827:                 */
        !          126828:                if ( (sp->s_lrefc == 0) && (segdisk(sp) != 0) )
        !          126829:                        n++;
        !          126830:        }
        !          126831: 
        !          126832:        /*
        !          126833:         * Mark process as being disk resident.
        !          126834:         */
        !          126835:        pp->p_flags |= PFSWAP;
        !          126836: 
        !          126837:        return( n );
        !          126838: }
        !          126839: 
        !          126840: /*
        !          126841:  * Swap the given segment into core.
        !          126842:  * NOTE: Although swapped out, the segment may have a descriptor table entry,
        !          126843:  *      and therefore have a valid s_faddr field.
        !          126844:  */
        !          126845: segcore( sp1 )
        !          126846: register SEG *sp1;
        !          126847: {
        !          126848:        register SEG *sp2;
        !          126849: 
        !          126850:        /*
        !          126851:         * Lock segmentation.
        !          126852:         */
        !          126853:        lock( seglink );
        !          126854: 
        !          126855:        /*
        !          126856:         * Segment has been moved to memory while we waited to lock.
        !          126857:         */
        !          126858:        if ( (sp1->s_flags & SFCORE) != 0 ) {
        !          126859:                unlock(seglink);
        !          126860:                return( 1 );
        !          126861:        }
        !          126862: 
        !          126863:        /*
        !          126864:         * Allocate a memory segment sp2.
        !          126865:         */
        !          126866:        if ((sp2 = xmalloc( sp1->s_size )) == NULL ) {
        !          126867:                unlock( seglink );
        !          126868:                return( 0 );
        !          126869:        }
        !          126870: 
        !          126871:        /*
        !          126872:         * Copy the disk segment sp1 into the memory segment sp2.
        !          126873:         */
        !          126874:        sp1->s_lrefc++;
        !          126875:        swapio(0, sp2->s_paddr, sp1->s_daddr, sp2->s_size );
        !          126876:        sp1->s_lrefc--;
        !          126877: 
        !          126878:        /*
        !          126879:         * Remove segment sp1 from the disk queue.
        !          126880:         */
        !          126881:        sp1->s_back->s_forw = sp1->s_forw;
        !          126882:        sp1->s_forw->s_back = sp1->s_back;
        !          126883: 
        !          126884:        /*
        !          126885:         * Insert segment sp1 into memory queue replacing segment sp2.
        !          126886:         */
        !          126887:        sp2->s_back->s_forw = sp1;
        !          126888:        sp1->s_back = sp2->s_back;
        !          126889:        sp2->s_forw->s_back = sp1;
        !          126890:        sp1->s_forw = sp2->s_forw;
        !          126891: 
        !          126892:        /*
        !          126893:         * Enable access to memory segment sp1.
        !          126894:         */
        !          126895:        sp1->s_flags |= SFCORE;
        !          126896:        sp1->s_paddr = sp2->s_paddr;
        !          126897:        vremap( sp1 );
        !          126898: 
        !          126899:        /*
        !          126900:         * Unlock segmentation.
        !          126901:         */
        !          126902:        unlock( seglink );
        !          126903: 
        !          126904:        return( 1 );
        !          126905: }
        !          126906: 
        !          126907: /*
        !          126908:  * Swap the given segment out onto disk.
        !          126909:  */
        !          126910: segdisk( sp1 )
        !          126911: register SEG *sp1;
        !          126912: {
        !          126913:        register SEG *sp2;
        !          126914: 
        !          126915:        /*
        !          126916:         * Lock segmentation.
        !          126917:         */
        !          126918:        lock( seglink );
        !          126919: 
        !          126920:        /*
        !          126921:         * Verify segment sp1 did not become busy while we waited to lock.
        !          126922:         * IE: raw disk i/o, or shared code fork.
        !          126923:         */
        !          126924:        if ( sp1->s_lrefc != 0 ) {
        !          126925:                unlock( seglink );
        !          126926:                return( 0 );
        !          126927:        }
        !          126928: 
        !          126929:        /*
        !          126930:         * Segment has been moved to disk while we waited to lock.
        !          126931:         */
        !          126932:        if ( (sp1->s_flags & SFCORE) == 0 ) {
        !          126933:                unlock(seglink);
        !          126934:                return( 1 );
        !          126935:        }
        !          126936: 
        !          126937:        /*
        !          126938:         * Allocate a disk segment sp2.
        !          126939:         */
        !          126940:        if ( (sp2 = xdalloc( sp1->s_size )) == NULL ) {
        !          126941:                unlock( seglink );
        !          126942:                return( 0 );
        !          126943:        }
        !          126944: 
        !          126945:        /*
        !          126946:         * Disable access to memory segment sp1.
        !          126947:         */
        !          126948:        sp1->s_flags &= ~SFCORE;
        !          126949:        sp1->s_daddr = sp2->s_daddr;
        !          126950:        vremap( sp1 );
        !          126951: 
        !          126952:        /*
        !          126953:         * Copy the memory segment sp1 into the disk segment sp2.
        !          126954:         */
        !          126955:        sp1->s_lrefc++;
        !          126956:        swapio( 1, sp1->s_paddr, sp2->s_daddr, sp1->s_size );
        !          126957:        sp1->s_lrefc--;
        !          126958: 
        !          126959:        /*
        !          126960:         * Remove segment sp1 from the memory queue.
        !          126961:         */
        !          126962:        sp1->s_back->s_forw = sp1->s_forw;
        !          126963:        sp1->s_forw->s_back = sp1->s_back;
        !          126964: 
        !          126965:        /*
        !          126966:         * Insert segment sp1 into disk queue replacing segment sp2.
        !          126967:         */
        !          126968:        sp2->s_back->s_forw = sp1;
        !          126969:        sp1->s_back = sp2->s_back;
        !          126970:        sp2->s_forw->s_back = sp1;
        !          126971:        sp1->s_forw = sp2->s_forw;
        !          126972: 
        !          126973:        /*
        !          126974:         * Unlock segmentation.
        !          126975:         */
        !          126976:        unlock( seglink );
        !          126977: 
        !          126978:        return( 1 );
        !          126979: }
        !          126980: 
        !          126981: /*
        !          126982:  * Allocate a segment on disk that is `n' bytes long.
        !          126983:  * The `seglink' gate should be locked before this routine is called.
        !          126984:  * This routine is the same as `sdalloc' except that we can't run out of
        !          126985:  * alloc space to allocate the segment and we allocate in high regions.
        !          126986:  * NOTE: descriptor table entries are not released.
        !          126987:  */
        !          126988: SEG *
        !          126989: xdalloc( s )
        !          126990: fsize_t s;
        !          126991: {
        !          126992:        register SEG *sp1;
        !          126993:        register SEG *sp2;
        !          126994:        register daddr_t d;
        !          126995:        register daddr_t d1;
        !          126996:        register daddr_t d2;
        !          126997: 
        !          126998:        d  = s / BSIZE;
        !          126999:        d2 = swaptop;
        !          127000:        sp1 = &segdq;
        !          127001:        do {
        !          127002:                if ( (sp1 = sp1->s_back) != &segdq )
        !          127003:                        d1 = sp1->s_daddr + (sp1->s_size / BSIZE);
        !          127004:                else
        !          127005:                        d1 = swapbot;
        !          127006: 
        !          127007:                if ( d2 - d1 >= d ) {
        !          127008:                        sp2 = &segswap;
        !          127009:                        kclear( (char *)sp2, sizeof(SEG) );
        !          127010:                        sp1->s_forw->s_back = sp2;
        !          127011:                        sp2->s_forw  = sp1->s_forw;
        !          127012:                        sp1->s_forw  = sp2;
        !          127013:                        sp2->s_back  = sp1;
        !          127014:                        sp2->s_urefc = 1;
        !          127015:                        sp2->s_lrefc = 1;
        !          127016:                        sp2->s_size  = s;
        !          127017:                        sp2->s_daddr = d2 - d;
        !          127018:                        return( sp2 );
        !          127019:                }
        !          127020: 
        !          127021:                d2 = sp1->s_daddr;
        !          127022: 
        !          127023:        } while ( sp1 != &segdq );
        !          127024: 
        !          127025:        return( NULL );
        !          127026: }
        !          127027: 
        !          127028: /*
        !          127029:  * Allocate a segment in memory that is `n' bytes long.
        !          127030:  * The `seglink' gate should be locked before this routine is called.
        !          127031:  * This routine is the same as `smalloc' except that we can't run out of
        !          127032:  * alloc space to allocate the segment.
        !          127033:  * NOTE: Do NOT remap virtual descriptor table entry.
        !          127034:  *      This is a scratch entry, and the s_faddr field is not retained.
        !          127035:  */
        !          127036: SEG *
        !          127037: xmalloc( s )
        !          127038: register fsize_t s;
        !          127039: {
        !          127040:        register SEG *sp1;
        !          127041:        register SEG *sp2;
        !          127042:        register paddr_t s1;
        !          127043:        register paddr_t s2;
        !          127044: 
        !          127045:        s1  = corebot;
        !          127046:        sp1 = &segmq;
        !          127047:        do {
        !          127048:                if ( (sp1 = sp1->s_forw) != &segmq )
        !          127049:                        s2 = sp1->s_paddr;
        !          127050:                else
        !          127051:                        s2 = coretop;
        !          127052: 
        !          127053:                if ( s2 - s1 >= s ) {
        !          127054:                        sp2 = &segswap;
        !          127055:                        kclear( (char *)sp2, sizeof(SEG) );
        !          127056:                        sp1->s_back->s_forw = sp2;
        !          127057:                        sp2->s_back = sp1->s_back;
        !          127058:                        sp1->s_back = sp2;
        !          127059:                        sp2->s_forw = sp1;
        !          127060:                        sp2->s_urefc = 1;
        !          127061:                        sp2->s_lrefc = 1;
        !          127062:                        sp2->s_size  = s;
        !          127063:                        sp2->s_paddr = s1;
        !          127064:                        return( sp2 );
        !          127065:                }
        !          127066: 
        !          127067:                s1 = sp1->s_paddr + sp1->s_size;
        !          127068: 
        !          127069:        } while ( sp1 != &segmq );
        !          127070: 
        !          127071:        return( NULL );
        !          127072: }
        !          127073: 0707070064030060131004440000030000030000011777770507310743100004600000000513/newbits/kernel/USRSRC/ldrv/nonedev.c/* $Header: /usr/src/sys/ldrv/RCS/nonedev.c,v 1.1 88/03/24 16:30:54 src Exp $ */
        !          127074: 
        !          127075: /*
        !          127076:  * $Log:       /usr/src/sys/ldrv/RCS/nonedev.c,v $
        !          127077:  * Revision 1.1        88/03/24  16:30:54      src
        !          127078:  * Initial revision
        !          127079:  * 
        !          127080:  */
        !          127081: #include <sys/coherent.h>
        !          127082: #include <sys/uproc.h>
        !          127083: #include <errno.h>
        !          127084: 
        !          127085: /*
        !          127086:  * Non existant device.
        !          127087:  */
        !          127088: nonedev()
        !          127089: {
        !          127090:        u.u_error = ENXIO;
        !          127091: }
        !          127092: 0707070064030060121004440000030000030000011777770507310743100004600000000352/newbits/kernel/USRSRC/ldrv/nulldev.c/* $Header: /usr/src/sys/ldrv/RCS/nulldev.c,v 1.1 88/03/24 16:30:57 src Exp $ */
        !          127093: /*
        !          127094:  * $Log:       /usr/src/sys/ldrv/RCS/nulldev.c,v $
        !          127095:  * Revision 1.1        88/03/24  16:30:57      src
        !          127096:  * Initial revision
        !          127097:  * 
        !          127098:  */
        !          127099: 
        !          127100: /*
        !          127101:  * Null device.
        !          127102:  */
        !          127103: nulldev()
        !          127104: {
        !          127105: }
        !          127106: 0707070064030060111004440000030000030000011777770507310743100004300000001507/newbits/kernel/USRSRC/ldrv/outb.s/ $Header: /usr/src/sys/ldrv/RCS/outb.s,v 1.1 88/03/24 16:31:00 src Exp $
        !          127107: /
        !          127108: /      The  information  contained herein  is a trade secret  of INETCO
        !          127109: /      Systems, and is confidential information.   It is provided under
        !          127110: /      a license agreement,  and may be copied or disclosed  only under
        !          127111: /      the terms of that agreement.   Any reproduction or disclosure of
        !          127112: /      this  material  without  the express  written  authorization  of
        !          127113: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          127114: /
        !          127115: /      Copyright (c) 1988
        !          127116: /      An unpublished work by INETCO Systems, Ltd.
        !          127117: /      All rights reserved.
        !          127118: /
        !          127119: / $Log:        /usr/src/sys/ldrv/RCS/outb.s,v $
        !          127120: / Revision 1.1 88/03/24  16:31:00      src
        !          127121: / Initial revision
        !          127122: / 
        !          127123: /
        !          127124: ////////
        !          127125: 
        !          127126: ////////
        !          127127: /
        !          127128: / Basic port level I/O.
        !          127129: /
        !          127130: / int  outb(port, data);
        !          127131: /
        !          127132: ////////
        !          127133: 
        !          127134:        .globl  outb_
        !          127135: 
        !          127136: outb_: mov     bx, sp
        !          127137:        mov     dx, 2(bx)
        !          127138:        mov     ax, 4(bx)
        !          127139:        outb    dx, al
        !          127140:        ret
        !          127141: 0707070064030060101004440000030000030000011777770507310743200004600000004313/newbits/kernel/USRSRC/ldrv/setivec.c/* $Header: /usr/src/sys/ldrv/RCS/setivec.c,v 1.1 88/03/24 16:31:02 src Exp $ */
        !          127142: /*
        !          127143:  *     The  information  contained herein  is a trade secret  of INETCO
        !          127144:  *     Systems, and is confidential information.   It is provided under
        !          127145:  *     a license agreement,  and may be copied or disclosed  only under
        !          127146:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          127147:  *     this  material  without  the express  written  authorization  of
        !          127148:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          127149:  *
        !          127150:  *     Copyright (c) 1987
        !          127151:  *     An unpublished work by INETCO Systems, Ltd.
        !          127152:  *     All rights reserved.
        !          127153:  */
        !          127154: 
        !          127155: /*
        !          127156:  * Loadable Driver - Enable/Disable Interrupts.
        !          127157:  *
        !          127158:  * $Log:       /usr/src/sys/ldrv/RCS/setivec.c,v $
        !          127159:  * Revision 1.1        88/03/24  16:31:02      src
        !          127160:  * Initial revision
        !          127161:  * 
        !          127162:  * 87/12/03    Allan Cornish           /usr/src/sys/ldrv/setivec.c
        !          127163:  * Initial version.
        !          127164:  */
        !          127165: #include <sys/coherent.h>
        !          127166: #include <errno.h>
        !          127167: #include <sys/con.h>
        !          127168: #include <sys/uproc.h>
        !          127169: 
        !          127170: /*
        !          127171:  * Interrupt entry points [within kernel] for loadable drivers.
        !          127172:  */
        !          127173: extern void (*ldrvint[16])();
        !          127174: 
        !          127175: /*
        !          127176:  * Interrupt handlers [within driver] for loadable drivers.
        !          127177:  *     ldrvics[n]:     Interrupt handler code segment.
        !          127178:  *     ldrvipc[n]:     Interrupt handler program counter.
        !          127179:  */
        !          127180: extern saddr_t ldrvics[16];
        !          127181: extern void  (*ldrvipc[16])();
        !          127182: 
        !          127183: setivec( level, func )
        !          127184: int level;
        !          127185: void (*func)();
        !          127186: {
        !          127187:        extern void Ksetivec();
        !          127188:        extern saddr_t ucs;
        !          127189: 
        !          127190:        u.u_error = 0;
        !          127191:        level &= 15;
        !          127192: 
        !          127193:        /*
        !          127194:         * Ensure interrupt is not already in use.
        !          127195:         */
        !          127196:        if ( (ldrvics[level] != 0) || (ldrvipc[level] != NULL) ) {
        !          127197:                u.u_error = EDBUSY;
        !          127198:                return;
        !          127199:        }
        !          127200: 
        !          127201:        /*
        !          127202:         * Record interrupt function BEFORE enabling interrupt.
        !          127203:         */
        !          127204:        ldrvipc[level] = func;
        !          127205:        ldrvics[level] = ucs;
        !          127206: 
        !          127207:        /*
        !          127208:         * Attempt to enable interrupt.
        !          127209:         */
        !          127210:        kcall( Ksetivec, level, ldrvint[level] );
        !          127211: 
        !          127212:        /*
        !          127213:         * Interrupt is in use by a resident driver.
        !          127214:         */
        !          127215:        if ( u.u_error ) {
        !          127216:                ldrvipc[level] = NULL;
        !          127217:                ldrvics[level] = 0;
        !          127218:        }
        !          127219: }
        !          127220: 
        !          127221: clrivec( level )
        !          127222: register int level;
        !          127223: {
        !          127224:        extern void Kclrivec();
        !          127225:        extern saddr_t ucs;
        !          127226: 
        !          127227:        level &= 15;
        !          127228: 
        !          127229:        /*
        !          127230:         * Ensure interrupt belongs to our process.
        !          127231:         */
        !          127232:        if ( ldrvics[level] != ucs ) {
        !          127233:                u.u_error = EPERM;
        !          127234:                return;
        !          127235:        }
        !          127236: 
        !          127237:        /*
        !          127238:         * Disable interrupt.
        !          127239:         */
        !          127240:        kcall( Kclrivec, level );
        !          127241: 
        !          127242:        /*
        !          127243:         * Erase interrupt function AFTER disabling interrupt.
        !          127244:         */
        !          127245:        ldrvipc[level] = NULL;
        !          127246:        ldrvics[level] = 0;
        !          127247: }
        !          127248: 0707070064030060071004440000030000030000011777770507310743200004500000002017/newbits/kernel/USRSRC/ldrv/sfbyte.s/ $Header: /usr/src/sys/ldrv/RCS/sfbyte.s,v 1.1 88/03/24 16:31:05 src Exp $
        !          127249: /
        !          127250: /      The  information  contained herein  is a trade secret  of INETCO
        !          127251: /      Systems, and is confidential information.   It is provided under
        !          127252: /      a license agreement,  and may be copied or disclosed  only under
        !          127253: /      the terms of that agreement.   Any reproduction or disclosure of
        !          127254: /      this  material  without  the express  written  authorization  of
        !          127255: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          127256: /
        !          127257: /      Copyright (c) 1986
        !          127258: /      An unpublished work by INETCO Systems, Ltd.
        !          127259: /      All rights reserved.
        !          127260: /
        !          127261: / $Log:        /usr/src/sys/ldrv/RCS/sfbyte.s,v $
        !          127262: / Revision 1.1 88/03/24  16:31:05      src
        !          127263: / Initial revision
        !          127264: / 
        !          127265: /
        !          127266: ////////
        !          127267: 
        !          127268: ////////
        !          127269: /
        !          127270: / sfbyte( fp, b )      -- set far byte
        !          127271: / char far * fp;
        !          127272: / char b;
        !          127273: /
        !          127274: ////////
        !          127275: 
        !          127276:        .globl  sfbyte_
        !          127277: 
        !          127278: sfbyte_:push   es              / sfbyte( fp, c )
        !          127279:        push    di              / register char far * fp;       /* ES:DI */
        !          127280:        push    bp              / register char c;              /* AX */
        !          127281:        mov     bp, sp          / {
        !          127282:        les     di, 8(bp)       /
        !          127283:        mov     ax, 12(bp)      /
        !          127284:                                /
        !          127285:        movb    es:(di), al     /       *fp = c;
        !          127286:                                /
        !          127287:        pop     bp              / }
        !          127288:        pop     di
        !          127289:        pop     es
        !          127290:        ret
        !          127291: 0707070064030060061004440000030000030000011777770507310743300004400000002663/newbits/kernel/USRSRC/ldrv/sfmem.s/ $Header: /usr/src/sys/ldrv/RCS/sfmem.s,v 1.1 88/03/24 16:31:08 src Exp $
        !          127292: /
        !          127293: /      The  information  contained herein  is a trade secret  of INETCO
        !          127294: /      Systems, and is confidential information.   It is provided under
        !          127295: /      a license agreement,  and may be copied or disclosed  only under
        !          127296: /      the terms of that agreement.   Any reproduction or disclosure of
        !          127297: /      this  material  without  the express  written  authorization  of
        !          127298: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          127299: /
        !          127300: /      Copyright (c) 1986
        !          127301: /      An unpublished work by INETCO Systems, Ltd.
        !          127302: /      All rights reserved.
        !          127303: /
        !          127304: / $Log:        /usr/src/sys/ldrv/RCS/sfmem.s,v $
        !          127305: / Revision 1.1 88/03/24  16:31:08      src
        !          127306: / Initial revision
        !          127307: / 
        !          127308: /
        !          127309: ////////
        !          127310: 
        !          127311: ////////
        !          127312: /
        !          127313: / void
        !          127314: / sfmem( fp, m, n )    -- set far memory
        !          127315: / char far * fp;
        !          127316: / char * m;
        !          127317: / int n;
        !          127318: /
        !          127319: /      Input:  fp = far pointer [32 bit selector:offset] to destination
        !          127320: /              m  = source
        !          127321: /              n  = number of bytes to transfer.
        !          127322: /
        !          127323: /      Action: Transfer 'n' bytes from offset 'm' in the current data space
        !          127324: /              to far address 'fp'.
        !          127325: /
        !          127326: /      Return: None.
        !          127327: /
        !          127328: ////////
        !          127329: 
        !          127330:        .globl  sfmem_
        !          127331: 
        !          127332: sfmem_:        push    si              / void
        !          127333:        push    di              / sfmem( fp, m, n )
        !          127334:        push    bp              /
        !          127335:        mov     bp, sp          / register char * fp;           /* ES:DI */
        !          127336:        push    es              / register char * m;            /* SI */
        !          127337:        les     di, 8(bp)       / register int n;               /* CX */
        !          127338:        mov     si, 12(bp)      /
        !          127339:        mov     cx, 14(bp)      / {
        !          127340:                                /
        !          127341:        cld                     /
        !          127342:        clc                     /       for ( ; n != 0; --n )
        !          127343:        rcr     cx, $1          /
        !          127344:        rep                     /               *fp++ = *m++;
        !          127345:        movsw                   /
        !          127346:        rcl     cx, $1          /
        !          127347:        rep                     /
        !          127348:        movsb                   /
        !          127349:                                /
        !          127350:        pop     es              / }
        !          127351:        pop     bp
        !          127352:        pop     di
        !          127353:        pop     si
        !          127354:        ret
        !          127355: 0707070064030060051004440000030000030000011777770507310743300004500000002012/newbits/kernel/USRSRC/ldrv/sfword.s/ $Header: /usr/src/sys/ldrv/RCS/sfword.s,v 1.1 88/03/24 16:31:11 src Exp $
        !          127356: /
        !          127357: /      The  information  contained herein  is a trade secret  of INETCO
        !          127358: /      Systems, and is confidential information.   It is provided under
        !          127359: /      a license agreement,  and may be copied or disclosed  only under
        !          127360: /      the terms of that agreement.   Any reproduction or disclosure of
        !          127361: /      this  material  without  the express  written  authorization  of
        !          127362: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          127363: /
        !          127364: /      Copyright (c) 1986
        !          127365: /      An unpublished work by INETCO Systems, Ltd.
        !          127366: /      All rights reserved.
        !          127367: /
        !          127368: / $Log:        /usr/src/sys/ldrv/RCS/sfword.s,v $
        !          127369: / Revision 1.1 88/03/24  16:31:11      src
        !          127370: / Initial revision
        !          127371: / 
        !          127372: /
        !          127373: ////////
        !          127374: 
        !          127375: ////////
        !          127376: /
        !          127377: / sfword( fp, w )      -- set far word
        !          127378: / int far * fp;
        !          127379: / int w;
        !          127380: /
        !          127381: ////////
        !          127382: 
        !          127383:        .globl  sfword_
        !          127384: 
        !          127385: sfword_:push   es              / sfword( fp, w )
        !          127386:        push    di              / register int far * fp;        /* ES:DI */
        !          127387:        push    bp              / register int w;               /* AX */
        !          127388:        mov     bp, sp          / {
        !          127389:        les     di, 8(bp)       /
        !          127390:        mov     ax, 12(bp)      /
        !          127391:                                /
        !          127392:        mov     es:(di), ax     /       *fp = w;
        !          127393:                                /
        !          127394:        pop     bp              / }
        !          127395:        pop     di
        !          127396:        pop     es
        !          127397:        ret
        !          127398: 0707070064030060041004440000030000030000011777770507310743400004300000001567/newbits/kernel/USRSRC/ldrv/sphi.s/ $Header: /usr/src/sys/ldrv/RCS/sphi.s,v 1.1 88/03/24 16:31:13 src Exp $
        !          127399: /
        !          127400: /      The  information  contained herein  is a trade secret  of INETCO
        !          127401: /      Systems, and is confidential information.   It is provided under
        !          127402: /      a license agreement,  and may be copied or disclosed  only under
        !          127403: /      the terms of that agreement.   Any reproduction or disclosure of
        !          127404: /      this  material  without  the express  written  authorization  of
        !          127405: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          127406: /
        !          127407: /      Copyright (c) 1988
        !          127408: /      An unpublished work by INETCO Systems, Ltd.
        !          127409: /      All rights reserved.
        !          127410: /
        !          127411: / $Log:        /usr/src/sys/ldrv/RCS/sphi.s,v $
        !          127412: / Revision 1.1 88/03/24  16:31:13      src
        !          127413: / Initial revision
        !          127414: / 
        !          127415: /
        !          127416: ////////
        !          127417: 
        !          127418: ////////
        !          127419: /
        !          127420: / Disable interrupts.  Previous value is returned.
        !          127421: /
        !          127422: ////////
        !          127423: 
        !          127424:        .globl  sphi_
        !          127425: 
        !          127426: sphi_:
        !          127427:        pushf                           / Save flags
        !          127428:        pop     ax                      / Return current value
        !          127429:        cli                             / Disable interrupts
        !          127430:        ret                             / And return
        !          127431: 0707070064030057111004440000030000030000011777770507310743400004200000001616/newbits/kernel/USRSRC/ldrv/spl.s/ $Header: /usr/src/sys/ldrv/RCS/spl.s,v 1.1 88/03/24 16:31:16 src Exp $
        !          127432: /
        !          127433: /      The  information  contained herein  is a trade secret  of INETCO
        !          127434: /      Systems, and is confidential information.   It is provided under
        !          127435: /      a license agreement,  and may be copied or disclosed  only under
        !          127436: /      the terms of that agreement.   Any reproduction or disclosure of
        !          127437: /      this  material  without  the express  written  authorization  of
        !          127438: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          127439: /
        !          127440: /      Copyright (c) 1988
        !          127441: /      An unpublished work by INETCO Systems, Ltd.
        !          127442: /      All rights reserved.
        !          127443: /
        !          127444: / $Log:        /usr/src/sys/ldrv/RCS/spl.s,v $
        !          127445: / Revision 1.1 88/03/24  16:31:16      src
        !          127446: / Initial revision
        !          127447: / 
        !          127448: /
        !          127449: ////////
        !          127450: 
        !          127451: ////////
        !          127452: /
        !          127453: / Change interrupt flag.  Previous value is returned.
        !          127454: /
        !          127455: ////////
        !          127456:        .globl  spl_
        !          127457: 
        !          127458: spl_:
        !          127459:        pop     ax                      / ip
        !          127460:        pop     bx                      / psw
        !          127461:        push    bx
        !          127462:        push    bx                      / push psw, cs, ip for iret
        !          127463:        push    cs
        !          127464:        push    ax
        !          127465:        pushf                           / old psw
        !          127466:        pop     ax
        !          127467:        iret
        !          127468: 0707070064030057051004440000030000030000011777770507310743400004300000001445/newbits/kernel/USRSRC/ldrv/splo.s/ $Header: /usr/src/sys/ldrv/RCS/splo.s,v 1.1 88/03/24 16:31:19 src Exp $
        !          127469: /
        !          127470: /      The  information  contained herein  is a trade secret  of INETCO
        !          127471: /      Systems, and is confidential information.   It is provided under
        !          127472: /      a license agreement,  and may be copied or disclosed  only under
        !          127473: /      the terms of that agreement.   Any reproduction or disclosure of
        !          127474: /      this  material  without  the express  written  authorization  of
        !          127475: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          127476: /
        !          127477: /      Copyright (c) 1988
        !          127478: /      An unpublished work by INETCO Systems, Ltd.
        !          127479: /      All rights reserved.
        !          127480: /
        !          127481: / $Log:        /usr/src/sys/ldrv/RCS/splo.s,v $
        !          127482: / Revision 1.1 88/03/24  16:31:19      src
        !          127483: / Initial revision
        !          127484: / 
        !          127485: /
        !          127486: ////////
        !          127487: 
        !          127488: ////////
        !          127489: /
        !          127490: / Enable interrupts.  Previous value is returned.
        !          127491: /
        !          127492: ////////
        !          127493: 
        !          127494:        .globl  splo_
        !          127495: 
        !          127496: splo_:
        !          127497:        pushf
        !          127498:        pop     ax
        !          127499:        sti
        !          127500:        ret
        !          127501: 0707070064030057041004440000030000030000011777770507310743400004600000003424/newbits/kernel/USRSRC/ldrv/timeout.c/* $Header: /usr/src/sys/ldrv/RCS/timeout.c,v 1.1 88/03/24 16:31:21 src Exp $ */
        !          127502: /*
        !          127503:  *     The  information  contained herein  is a trade secret  of INETCO
        !          127504:  *     Systems, and is confidential information.   It is provided under
        !          127505:  *     a license agreement,  and may be copied or disclosed  only under
        !          127506:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          127507:  *     this  material  without  the express  written  authorization  of
        !          127508:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          127509:  *
        !          127510:  *     Copyright (c) 1987
        !          127511:  *     An unpublished work by INETCO Systems, Ltd.
        !          127512:  *     All rights reserved.
        !          127513:  */
        !          127514: 
        !          127515: /*
        !          127516:  * Loadable Driver - Timed functions.
        !          127517:  *
        !          127518:  * $Log:       /usr/src/sys/ldrv/RCS/timeout.c,v $
        !          127519:  * Revision 1.1        88/03/24  16:31:21      src
        !          127520:  * Initial revision
        !          127521:  * 
        !          127522:  * 87/12/08    Allan Cornish   /usr/src/sys/ldrv/timeout.c
        !          127523:  * Timed loadable driver functions now supported.
        !          127524:  */
        !          127525: #include <sys/coherent.h>
        !          127526: 
        !          127527: /*
        !          127528:  * External functions.
        !          127529:  */
        !          127530: extern void Ktimeout();
        !          127531: extern void Kldtimcall();
        !          127532: extern saddr_t getcs();
        !          127533: 
        !          127534: /*
        !          127535:  * Given a pointer to a timeout structure, `tp', call the function `f'
        !          127536:  * with integer argument `a' in `n' ticks of the clock. The list is
        !          127537:  * searched to see if the specified timeout structure is already in a
        !          127538:  * list, and it is removed if already there.
        !          127539:  * This module is specific to loadable drivers.
        !          127540:  */
        !          127541: timeout( tp, n, f, a )
        !          127542: register TIM * tp;
        !          127543: int n;
        !          127544: void (*f)();
        !          127545: int a;
        !          127546: {
        !          127547:        register int s;
        !          127548: 
        !          127549:        /*
        !          127550:         * Cancel existing timer.
        !          127551:         */
        !          127552:        if ( (f == NULL) || (n <= 0) ) {
        !          127553:                kcall( Ktimeout, tp, 0, NULL, 0 );
        !          127554:                return;
        !          127555:        }
        !          127556: 
        !          127557:        /*
        !          127558:         * Define loadable driver interface.
        !          127559:         * Kldtimcall will be invoked when timeout occurs.
        !          127560:         * It will in turn invoke FP_SEL(tp->t_ldrv):4,
        !          127561:         *      passing FP_OFF(tp->t_ldrv) in AX.
        !          127562:         */
        !          127563:        s = sphi();
        !          127564:        FP_SEL(tp->t_ldrv) = getcs();
        !          127565:        FP_OFF(tp->t_ldrv) = f;
        !          127566:        kcall( Ktimeout, tp, n, Kldtimcall, a );
        !          127567:        spl(s);
        !          127568: }
        !          127569: 0707070064030105330407550000030000030000011777770507310743500004000000000000/newbits/kernel/USRSRC/ldrv/RCS0707070064030131011004440000030000030000011777770507310743500005300000055035/newbits/kernel/USRSRC/ldrv/RCS/Makefile,vhead     1.6;
        !          127570: branch   ;
        !          127571: access   ;
        !          127572: symbols  ;
        !          127573: locks    bin:1.6;
        !          127574: comment  @@;
        !          127575: 
        !          127576: 
        !          127577: 1.6
        !          127578: date     91.09.26.17.13.55;  author bin;  state Exp;
        !          127579: branches ;
        !          127580: next     1.5;
        !          127581: 
        !          127582: 1.5
        !          127583: date     91.07.15.14.39.54;  author bin;  state Exp;
        !          127584: branches ;
        !          127585: next     1.4;
        !          127586: 
        !          127587: 1.4
        !          127588: date     91.06.20.14.33.18;  author bin;  state Exp;
        !          127589: branches ;
        !          127590: next     1.3;
        !          127591: 
        !          127592: 1.3
        !          127593: date     91.06.10.10.42.41;  author bin;  state Exp;
        !          127594: branches ;
        !          127595: next     1.2;
        !          127596: 
        !          127597: 1.2
        !          127598: date     91.04.30.18.38.22;  author root;  state Exp;
        !          127599: branches ;
        !          127600: next     1.1;
        !          127601: 
        !          127602: 1.1
        !          127603: date     91.04.30.18.37.18;  author root;  state Exp;
        !          127604: branches ;
        !          127605: next     ;
        !          127606: 
        !          127607: 
        !          127608: desc
        !          127609: @Runtime support for loadable drivers, including ldlib.a.
        !          127610: @
        !          127611: 
        !          127612: 
        !          127613: 1.6
        !          127614: log
        !          127615: @update by hal to fix problem with ttyflush() and loadable drivers.
        !          127616: @
        !          127617: text
        !          127618: @# $Header: $(USRSRC)/ldrv/RCS/Makefile,v 1.2 91/04/30 18:38:22 root Exp $
        !          127619: 
        !          127620: # Loadable Drivers - Makefile
        !          127621: #
        !          127622: 
        !          127623: # Include directories
        !          127624: USRINC=/usr/include
        !          127625: SYSINC=/usr/include/sys
        !          127626: 
        !          127627: CC=exec /bin/cc
        !          127628: CFLAGS=
        !          127629: 
        !          127630: TARGETS=$(USRSYS)/lib/ldrts0.o \
        !          127631:        $(USRSYS)/lib/ldmain.o  \
        !          127632:        $(USRSYS)/lib/ldswap.o  \
        !          127633:        $(USRSYS)/lib/ldlib.a
        !          127634: 
        !          127635: ld_support:    $(TARGETS)
        !          127636:        @@sync
        !          127637: 
        !          127638: $(USRSYS)/lib/ldrts0.o:        ldrts0.s
        !          127639:        as -xo $@@ $<
        !          127640: 
        !          127641: $(USRSYS)/lib/ldmain.o:        ldmain.c
        !          127642:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          127643: 
        !          127644: $(USRSYS)/lib/ldswap.o:        ldswap.c
        !          127645:        $(CC) $(CFLAGS) -DNOMONITOR -c -o $@@ $<
        !          127646: 
        !          127647: # The following script extracts a module from a library.
        !          127648: X_LIB= OBJFIL=`basename $@@ | sed 's/L//'` ;\
        !          127649:        ar x $< $$OBJFIL ;\
        !          127650:        mv $$OBJFIL $@@
        !          127651: 
        !          127652: # The following modules are supported in loadable drivers.
        !          127653: # NOTE: Most of them are interface stubs to kernel code.
        !          127654: #      Some of them are entirely driver resident.
        !          127655: LIBOBJ1=$(LOBJ)/absL.o         \
        !          127656:        $(LOBJ)/allocL.o        \
        !          127657:        $(LOBJ)/bclaimL.o       \
        !          127658:        $(LOBJ)/bdoneL.o        \
        !          127659:        $(LOBJ)/blkmvL.o        \
        !          127660:        $(LOBJ)/bootL.o         \
        !          127661:        $(LOBJ)/breadL.o        \
        !          127662:        $(LOBJ)/breleaseL.o     \
        !          127663:        $(LOBJ)/clockedfL.o     \
        !          127664:        $(LOBJ)/clrqL.o         \
        !          127665:        $(LOBJ)/cs_selfL.o      \
        !          127666:        $(LOBJ)/dblockL.o       \
        !          127667:        $(LOBJ)/dcloseL.o       \
        !          127668:        $(LOBJ)/deferL.o        \
        !          127669:        $(LOBJ)/devmsgL.o       \
        !          127670:        $(LOBJ)/dmagoL.o        \
        !          127671:        $(LOBJ)/dmalockL.o      \
        !          127672:        $(LOBJ)/dmaoffL.o       \
        !          127673:        $(LOBJ)/dmaonL.o        \
        !          127674:        $(LOBJ)/dmareqL.o       \
        !          127675:        $(LOBJ)/dopenL.o        \
        !          127676:        $(LOBJ)/drvmapL.o       \
        !          127677:        $(LOBJ)/dwriteL.o       \
        !          127678:        $(LOBJ)/fclearL.o       \
        !          127679:        $(LOBJ)/fdiskL.o        \
        !          127680:        $(LOBJ)/ffbyteL.o       \
        !          127681:        $(LOBJ)/ffwordL.o       \
        !          127682:        $(LOBJ)/ffmemL.o        \
        !          127683:        $(LOBJ)/fkcopyL.o       \
        !          127684:        $(LOBJ)/fpxcopyL.o      \
        !          127685:        $(LOBJ)/freeL.o         \
        !          127686:        $(LOBJ)/fucopyL.o       \
        !          127687:        $(LOBJ)/getcsL.o        \
        !          127688:        $(LOBJ)/getqL.o         \
        !          127689:        $(LOBJ)/getubdL.o       \
        !          127690:        $(LOBJ)/getuwdL.o       \
        !          127691:        $(LOBJ)/inbL.o          \
        !          127692:        $(LOBJ)/int11L.o        \
        !          127693:        $(LOBJ)/iogetcL.o       \
        !          127694:        $(LOBJ)/iomapvpL.o      \
        !          127695:        $(LOBJ)/ioputcL.o       \
        !          127696:        $(LOBJ)/ioreadL.o       \
        !          127697:        $(LOBJ)/ioreqL.o        \
        !          127698:        $(LOBJ)/iowriteL.o      \
        !          127699:        $(LOBJ)/ipcaccessL.o    \
        !          127700:        $(LOBJ)/kcallL.o        \
        !          127701:        $(LOBJ)/kfcopyL.o       \
        !          127702:        $(LOBJ)/kclearL.o       \
        !          127703:        $(LOBJ)/kpcopyL.o       \
        !          127704:        $(LOBJ)/kucopyL.o       \
        !          127705:        $(LOBJ)/lockL.o         \
        !          127706:        $(LOBJ)/lxdivL.o        \
        !          127707:        $(LOBJ)/lxmulL.o        \
        !          127708:        $(LOBJ)/lxremL.o        \
        !          127709:        $(LOBJ)/lxsgnL.o        \
        !          127710:        $(LOBJ)/memsetL.o       \
        !          127711:        $(LOBJ)/memtestL.o      \
        !          127712:        $(LOBJ)/nmidisableL.o   \
        !          127713:        $(LOBJ)/nmienableL.o    \
        !          127714:        $(LOBJ)/nondsigL.o      \
        !          127715:        $(LOBJ)/nonedevL.o      \
        !          127716:        $(LOBJ)/nulldevL.o      \
        !          127717: 
        !          127718: LIBOBJ2=$(LOBJ)/outbL.o                \
        !          127719:        $(LOBJ)/panicL.o        \
        !          127720:        $(LOBJ)/pclearL.o       \
        !          127721:        $(LOBJ)/pkcopyL.o       \
        !          127722:        $(LOBJ)/plrcopyL.o      \
        !          127723:        $(LOBJ)/pollopenL.o     \
        !          127724:        $(LOBJ)/pollwakeL.o     \
        !          127725:        $(LOBJ)/printfL.o       \
        !          127726:        $(LOBJ)/prlcopyL.o      \
        !          127727:        $(LOBJ)/ptovL.o         \
        !          127728:        $(LOBJ)/pucopyL.o       \
        !          127729:        $(LOBJ)/putcharL.o      \
        !          127730:        $(LOBJ)/putqL.o         \
        !          127731:        $(LOBJ)/putubdL.o       \
        !          127732:        $(LOBJ)/putuwdL.o       \
        !          127733:        $(LOBJ)/rucopyL.o       \
        !          127734:        $(LOBJ)/s5_to_sgL.o     \
        !          127735:        $(LOBJ)/s5_to_tcL.o     \
        !          127736:        $(LOBJ)/sallocL.o       \
        !          127737:        $(LOBJ)/sclearL.o       \
        !          127738:        $(LOBJ)/sendsigL.o      \
        !          127739:        $(LOBJ)/setivecL.o      \
        !          127740:        $(LOBJ)/sfreeL.o        \
        !          127741:        $(LOBJ)/sfbyteL.o       \
        !          127742:        $(LOBJ)/sfwordL.o       \
        !          127743:        $(LOBJ)/sfmemL.o        \
        !          127744:        $(LOBJ)/sg_to_s5L.o     \
        !          127745:        $(LOBJ)/sleepL.o        \
        !          127746:        $(LOBJ)/slrcopyL.o      \
        !          127747:        $(LOBJ)/sphiL.o         \
        !          127748:        $(LOBJ)/splL.o          \
        !          127749:        $(LOBJ)/sploL.o         \
        !          127750:        $(LOBJ)/superL.o        \
        !          127751:        $(LOBJ)/swapioL.o       \
        !          127752:        $(LOBJ)/tc_to_s5L.o     \
        !          127753:        $(LOBJ)/timeoutL.o      \
        !          127754:        $(LOBJ)/ttcloseL.o      \
        !          127755:        $(LOBJ)/tthupL.o        \
        !          127756:        $(LOBJ)/ttflushL.o      \
        !          127757:        $(LOBJ)/ttinL.o         \
        !          127758:        $(LOBJ)/ttioctlL.o      \
        !          127759:        $(LOBJ)/ttopenL.o       \
        !          127760:        $(LOBJ)/ttoutL.o        \
        !          127761:        $(LOBJ)/ttpollL.o       \
        !          127762:        $(LOBJ)/ttreadL.o       \
        !          127763:        $(LOBJ)/ttsetgrpL.o     \
        !          127764:        $(LOBJ)/ttsignalL.o     \
        !          127765:        $(LOBJ)/ttstartL.o      \
        !          127766:        $(LOBJ)/ttwriteL.o      \
        !          127767:        $(LOBJ)/uexitL.o        \
        !          127768:        $(LOBJ)/ufcopyL.o       \
        !          127769:        $(LOBJ)/ukcopyL.o       \
        !          127770:        $(LOBJ)/unlockL.o       \
        !          127771:        $(LOBJ)/upcopyL.o       \
        !          127772:        $(LOBJ)/urcopyL.o       \
        !          127773:        $(LOBJ)/vprintL.o       \
        !          127774:        $(LOBJ)/vrelseL.o       \
        !          127775:        $(LOBJ)/vremapL.o       \
        !          127776:        $(LOBJ)/vtopL.o         \
        !          127777:        $(LOBJ)/vxdivL.o        \
        !          127778:        $(LOBJ)/vxmulL.o        \
        !          127779:        $(LOBJ)/vxremL.o        \
        !          127780:        $(LOBJ)/waitqL.o        \
        !          127781:        $(LOBJ)/wakeupL.o       \
        !          127782: 
        !          127783: $(USRSYS)/lib/ldlib.a: mkstub.m4 $(LIBOBJ1) $(LIBOBJ2)
        !          127784:        rm -f  $@@
        !          127785:        ar rc  $@@ $(LIBOBJ1)
        !          127786:        ar rc  $@@ $(LIBOBJ2)
        !          127787:        ranlib $@@
        !          127788: 
        !          127789: # Here is mkstub.m4:
        !          127790: #define(sym, substr(basename, -2, ))dnl
        !          127791: #      .globl  sym`_'
        !          127792: #sym`_':       mov     ax,`$K'sym`_'
        !          127793: #      .byte   0x9A
        !          127794: #      .word   xcalled
        !          127795: #      .word   0x0060
        !          127796: #      ret
        !          127797: 
        !          127798: MKSTUB=        echo "define(basename, `basename $*`)dnl" | m4 - mkstub.m4 > $*.s ;\
        !          127799:        as -gxo $@@ $*.s; rm $*.s
        !          127800: 
        !          127801: $(LOBJ)/absL.o:
        !          127802:        $(MKSTUB)
        !          127803: 
        !          127804: $(LOBJ)/allocL.o:
        !          127805:        $(MKSTUB)
        !          127806: 
        !          127807: $(LOBJ)/bclaimL.o:
        !          127808:        $(MKSTUB)
        !          127809: 
        !          127810: $(LOBJ)/bdoneL.o:
        !          127811:        $(MKSTUB)
        !          127812: 
        !          127813: $(LOBJ)/blkmvL.o:      /lib/libc.a
        !          127814:        $(X_LIB)
        !          127815: 
        !          127816: $(LOBJ)/bootL.o:
        !          127817:        $(MKSTUB)
        !          127818: 
        !          127819: $(LOBJ)/breadL.o:
        !          127820:        $(MKSTUB)
        !          127821: 
        !          127822: $(LOBJ)/breleaseL.o:
        !          127823:        $(MKSTUB)
        !          127824: 
        !          127825: $(LOBJ)/clockedfL.o:   clockedf.c
        !          127826:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          127827: 
        !          127828: $(LOBJ)/clrivecL.o:
        !          127829:        $(MKSTUB)
        !          127830: 
        !          127831: $(LOBJ)/clrqL.o:
        !          127832:        $(MKSTUB)
        !          127833: 
        !          127834: $(LOBJ)/cs_selfL.o:    cs_self.s
        !          127835:        as -gxo $@@ $<
        !          127836: 
        !          127837: $(LOBJ)/dblockL.o:
        !          127838:        $(MKSTUB)
        !          127839: 
        !          127840: $(LOBJ)/dcloseL.o:
        !          127841:        $(MKSTUB)
        !          127842: 
        !          127843: $(LOBJ)/deferL.o:      defer.s
        !          127844:        as -gxo $@@ $<
        !          127845: 
        !          127846: $(LOBJ)/devmsgL.o:
        !          127847:        $(MKSTUB)
        !          127848: 
        !          127849: $(LOBJ)/dmagoL.o:
        !          127850:        $(MKSTUB)
        !          127851: 
        !          127852: $(LOBJ)/dmalockL.o:    dmalock.c
        !          127853:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          127854: 
        !          127855: $(LOBJ)/dmaoffL.o:
        !          127856:        $(MKSTUB)
        !          127857: 
        !          127858: $(LOBJ)/dmaonL.o:
        !          127859:        $(MKSTUB)
        !          127860: 
        !          127861: $(LOBJ)/dmareqL.o:
        !          127862:        $(MKSTUB)
        !          127863: 
        !          127864: $(LOBJ)/dopenL.o:
        !          127865:        $(MKSTUB)
        !          127866: 
        !          127867: $(LOBJ)/drvmapL.o:
        !          127868:        $(MKSTUB)
        !          127869: 
        !          127870: $(LOBJ)/dwriteL.o:
        !          127871:        $(MKSTUB)
        !          127872: 
        !          127873: $(LOBJ)/fclearL.o:
        !          127874:        $(MKSTUB)
        !          127875: 
        !          127876: $(LOBJ)/fdiskL.o:
        !          127877:        $(MKSTUB)
        !          127878: 
        !          127879: $(LOBJ)/ffbyteL.o:     ffbyte.s
        !          127880:        as -gxo $@@ $<
        !          127881: 
        !          127882: $(LOBJ)/ffwordL.o:     ffword.s
        !          127883:        as -gxo $@@ $<
        !          127884: 
        !          127885: $(LOBJ)/ffmemL.o:      ffmem.s
        !          127886:        as -gxo $@@ $<
        !          127887: 
        !          127888: $(LOBJ)/fkcopyL.o:
        !          127889:        $(MKSTUB)
        !          127890: 
        !          127891: $(LOBJ)/fpxcopyL.o:
        !          127892:        $(MKSTUB)
        !          127893: 
        !          127894: $(LOBJ)/freeL.o:
        !          127895:        $(MKSTUB)
        !          127896: 
        !          127897: $(LOBJ)/fucopyL.o:
        !          127898:        $(MKSTUB)
        !          127899: 
        !          127900: $(LOBJ)/getcsL.o:      getcs.s
        !          127901:        as -gxo $@@ $<
        !          127902: 
        !          127903: $(LOBJ)/getqL.o:
        !          127904:        $(MKSTUB)
        !          127905: 
        !          127906: $(LOBJ)/getubdL.o:
        !          127907:        $(MKSTUB)
        !          127908: 
        !          127909: $(LOBJ)/getuwdL.o:
        !          127910:        $(MKSTUB)
        !          127911: 
        !          127912: $(LOBJ)/inbL.o:                inb.s
        !          127913:        as -gxo $@@ $<
        !          127914: 
        !          127915: $(LOBJ)/int11L.o:
        !          127916:        $(MKSTUB)
        !          127917: 
        !          127918: $(LOBJ)/iogetcL.o:
        !          127919:        $(MKSTUB)
        !          127920: 
        !          127921: $(LOBJ)/iomapvpL.o:
        !          127922:        $(MKSTUB)
        !          127923: 
        !          127924: $(LOBJ)/ioputcL.o:
        !          127925:        $(MKSTUB)
        !          127926: 
        !          127927: $(LOBJ)/ioreadL.o:
        !          127928:        $(MKSTUB)
        !          127929: 
        !          127930: $(LOBJ)/ioreqL.o:
        !          127931:        $(MKSTUB)
        !          127932: 
        !          127933: $(LOBJ)/iowriteL.o:
        !          127934:        $(MKSTUB)
        !          127935: 
        !          127936: $(LOBJ)/ipcaccessL.o:
        !          127937:        $(MKSTUB)
        !          127938: 
        !          127939: $(LOBJ)/kcallL.o:      kcall.s
        !          127940:        as -gxo $@@ $<
        !          127941: 
        !          127942: $(LOBJ)/kclearL.o:
        !          127943:        $(MKSTUB)
        !          127944: 
        !          127945: $(LOBJ)/kfcopyL.o:
        !          127946:        $(MKSTUB)
        !          127947: 
        !          127948: $(LOBJ)/kpcopyL.o:
        !          127949:        $(MKSTUB)
        !          127950: 
        !          127951: $(LOBJ)/kucopyL.o:
        !          127952:        $(MKSTUB)
        !          127953: 
        !          127954: $(LOBJ)/lockL.o:
        !          127955:        $(MKSTUB)
        !          127956: 
        !          127957: $(LOBJ)/lxdivL.o:      /lib/libc.a
        !          127958:        $(X_LIB)
        !          127959: 
        !          127960: $(LOBJ)/lxmulL.o:      /lib/libc.a
        !          127961:        $(X_LIB)
        !          127962: 
        !          127963: $(LOBJ)/lxremL.o:      /lib/libc.a
        !          127964:        $(X_LIB)
        !          127965: 
        !          127966: $(LOBJ)/lxsgnL.o:      /lib/libc.a
        !          127967:        $(X_LIB)
        !          127968: 
        !          127969: $(LOBJ)/memsetL.o:     /lib/libc.a
        !          127970:        $(X_LIB)
        !          127971: 
        !          127972: $(LOBJ)/memtestL.o:
        !          127973:        $(MKSTUB)
        !          127974: 
        !          127975: $(LOBJ)/nmidisableL.o:
        !          127976:        $(MKSTUB)
        !          127977: 
        !          127978: $(LOBJ)/nmienableL.o:
        !          127979:        $(MKSTUB)
        !          127980: 
        !          127981: $(LOBJ)/nondsigL.o:
        !          127982:        $(MKSTUB)
        !          127983: 
        !          127984: $(LOBJ)/nonedevL.o:    nonedev.c
        !          127985:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          127986: 
        !          127987: $(LOBJ)/nulldevL.o:    nulldev.c
        !          127988:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          127989: 
        !          127990: $(LOBJ)/outbL.o:               outb.s
        !          127991:        as -gxo $@@ $<
        !          127992: 
        !          127993: $(LOBJ)/panicL.o:
        !          127994:        $(MKSTUB)
        !          127995: 
        !          127996: $(LOBJ)/pclearL.o:
        !          127997:        $(MKSTUB)
        !          127998: 
        !          127999: $(LOBJ)/plrcopyL.o:
        !          128000:        $(MKSTUB)
        !          128001: 
        !          128002: $(LOBJ)/pkcopyL.o:
        !          128003:        $(MKSTUB)
        !          128004: 
        !          128005: $(LOBJ)/pollopenL.o:
        !          128006:        $(MKSTUB)
        !          128007: 
        !          128008: $(LOBJ)/pollwakeL.o:
        !          128009:        $(MKSTUB)
        !          128010: 
        !          128011: $(LOBJ)/printfL.o:
        !          128012:        $(MKSTUB)
        !          128013: 
        !          128014: $(LOBJ)/prlcopyL.o:
        !          128015:        $(MKSTUB)
        !          128016: 
        !          128017: $(LOBJ)/ptovL.o:
        !          128018:        $(MKSTUB)
        !          128019: 
        !          128020: $(LOBJ)/pucopyL.o:
        !          128021:        $(MKSTUB)
        !          128022: 
        !          128023: $(LOBJ)/putcharL.o:
        !          128024:        $(MKSTUB)
        !          128025: 
        !          128026: $(LOBJ)/putqL.o:
        !          128027:        $(MKSTUB)
        !          128028: 
        !          128029: $(LOBJ)/putubdL.o:
        !          128030:        $(MKSTUB)
        !          128031: 
        !          128032: $(LOBJ)/putuwdL.o:
        !          128033:        $(MKSTUB)
        !          128034: 
        !          128035: $(LOBJ)/rucopyL.o:
        !          128036:        $(MKSTUB)
        !          128037: 
        !          128038: $(LOBJ)/s5_to_sgL.o:
        !          128039:        $(MKSTUB)
        !          128040: 
        !          128041: $(LOBJ)/s5_to_tcL.o:
        !          128042:        $(MKSTUB)
        !          128043: 
        !          128044: $(LOBJ)/sallocL.o:
        !          128045:        $(MKSTUB)
        !          128046: 
        !          128047: $(LOBJ)/sclearL.o:
        !          128048:        $(MKSTUB)
        !          128049: 
        !          128050: $(LOBJ)/sendsigL.o:
        !          128051:        $(MKSTUB)
        !          128052: 
        !          128053: $(LOBJ)/setivecL.o:    setivec.c
        !          128054:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          128055: 
        !          128056: $(LOBJ)/sfreeL.o:
        !          128057:        $(MKSTUB)
        !          128058: 
        !          128059: $(LOBJ)/sfbyteL.o:     sfbyte.s
        !          128060:        as -gxo $@@ $<
        !          128061: 
        !          128062: $(LOBJ)/sfwordL.o:     sfword.s
        !          128063:        as -gxo $@@ $<
        !          128064: 
        !          128065: $(LOBJ)/sfmemL.o:      sfmem.s
        !          128066:        as -gxo $@@ $<
        !          128067: 
        !          128068: $(LOBJ)/sg_to_s5L.o:
        !          128069:        $(MKSTUB)
        !          128070: 
        !          128071: $(LOBJ)/sleepL.o:
        !          128072:        $(MKSTUB)
        !          128073: 
        !          128074: $(LOBJ)/slrcopyL.o:
        !          128075:        $(MKSTUB)
        !          128076: 
        !          128077: $(LOBJ)/sphiL.o:       sphi.s
        !          128078:        as -gxo $@@ $<
        !          128079: 
        !          128080: $(LOBJ)/splL.o:        spl.s
        !          128081:        as -gxo $@@ $<
        !          128082: 
        !          128083: $(LOBJ)/sploL.o:       splo.s
        !          128084:        as -gxo $@@ $<
        !          128085: 
        !          128086: $(LOBJ)/superL.o:
        !          128087:        $(MKSTUB)
        !          128088: 
        !          128089: $(LOBJ)/swapioL.o:
        !          128090:        $(MKSTUB)
        !          128091: 
        !          128092: $(LOBJ)/tc_to_s5L.o:
        !          128093:        $(MKSTUB)
        !          128094: 
        !          128095: $(LOBJ)/timeoutL.o:    timeout.c
        !          128096:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          128097: 
        !          128098: $(LOBJ)/ttcloseL.o:
        !          128099:        $(MKSTUB)
        !          128100: 
        !          128101: $(LOBJ)/ttflushL.o:
        !          128102:        $(MKSTUB)
        !          128103: 
        !          128104: $(LOBJ)/tthupL.o:
        !          128105:        $(MKSTUB)
        !          128106: 
        !          128107: $(LOBJ)/ttinL.o:
        !          128108:        $(MKSTUB)
        !          128109: 
        !          128110: $(LOBJ)/ttioctlL.o:
        !          128111:        $(MKSTUB)
        !          128112: 
        !          128113: $(LOBJ)/ttopenL.o:
        !          128114:        $(MKSTUB)
        !          128115: 
        !          128116: $(LOBJ)/ttoutL.o:
        !          128117:        $(MKSTUB)
        !          128118: 
        !          128119: $(LOBJ)/ttpollL.o:
        !          128120:        $(MKSTUB)
        !          128121: 
        !          128122: $(LOBJ)/ttreadL.o:
        !          128123:        $(MKSTUB)
        !          128124: 
        !          128125: $(LOBJ)/ttsetgrpL.o:
        !          128126:        $(MKSTUB)
        !          128127: 
        !          128128: $(LOBJ)/ttsignalL.o:
        !          128129:        $(MKSTUB)
        !          128130: 
        !          128131: $(LOBJ)/ttstartL.o:
        !          128132:        $(MKSTUB)
        !          128133: 
        !          128134: $(LOBJ)/ttwriteL.o:
        !          128135:        $(MKSTUB)
        !          128136: 
        !          128137: $(LOBJ)/uexitL.o:
        !          128138:        $(MKSTUB)
        !          128139: 
        !          128140: $(LOBJ)/ufcopyL.o:
        !          128141:        $(MKSTUB)
        !          128142: 
        !          128143: $(LOBJ)/ukcopyL.o:
        !          128144:        $(MKSTUB)
        !          128145: 
        !          128146: $(LOBJ)/unlockL.o:
        !          128147:        $(MKSTUB)
        !          128148: 
        !          128149: $(LOBJ)/upcopyL.o:
        !          128150:        $(MKSTUB)
        !          128151: 
        !          128152: $(LOBJ)/urcopyL.o:
        !          128153:        $(MKSTUB)
        !          128154: 
        !          128155: $(LOBJ)/vprintL.o:
        !          128156:        $(MKSTUB)
        !          128157: 
        !          128158: $(LOBJ)/vrelseL.o:
        !          128159:        $(MKSTUB)
        !          128160: 
        !          128161: $(LOBJ)/vremapL.o:
        !          128162:        $(MKSTUB)
        !          128163: 
        !          128164: $(LOBJ)/vtopL.o:
        !          128165:        $(MKSTUB)
        !          128166: 
        !          128167: $(LOBJ)/vxdivL.o:      /lib/libc.a
        !          128168:        $(X_LIB)
        !          128169: 
        !          128170: $(LOBJ)/vxmulL.o:      /lib/libc.a
        !          128171:        $(X_LIB)
        !          128172: 
        !          128173: $(LOBJ)/vxremL.o:      /lib/libc.a
        !          128174:        $(X_LIB)
        !          128175: 
        !          128176: $(LOBJ)/waitqL.o:
        !          128177:        $(MKSTUB)
        !          128178: 
        !          128179: $(LOBJ)/wakeupL.o:
        !          128180:        $(MKSTUB)
        !          128181: @
        !          128182: 
        !          128183: 
        !          128184: 1.5
        !          128185: log
        !          128186: @mods by hal for relocateable object directories
        !          128187: @
        !          128188: text
        !          128189: @d139 1
        !          128190: d484 3
        !          128191: @
        !          128192: 
        !          128193: 
        !          128194: 1.4
        !          128195: log
        !          128196: @update provided by hal
        !          128197: @
        !          128198: text
        !          128199: @a1 12
        !          128200: #
        !          128201: #      The  information  contained herein  is a trade secret  of INETCO
        !          128202: #      Systems, Ltd, and is  confidential information.   It is provided
        !          128203: #      under a license agreement,  and may be copied or disclosed  only
        !          128204: #      under  the  terms  of  that  agreement.    Any  reproduction  or
        !          128205: #      disclosure  of  this   material   without  the  express  written
        !          128206: #      authorization of INETCO Systems, Ltd. or persuant to the license
        !          128207: #      agreement is unlawful.
        !          128208: #
        !          128209: #      Copyright (c) 1988
        !          128210: #      An unpublished work by INETCO Systems, Ltd.
        !          128211: #      All rights reserved.
        !          128212: a4 3
        !          128213: # $Log:        $(USRSRC)/ldrv/RCS/Makefile,v $
        !          128214: # Revision 1.2 91/04/30  18:38:22      root
        !          128215: # Changes to support polled async driver "hs"
        !          128216: a5 17
        !          128217: # Revision 1.5 89/06/30  16:31:48      src
        !          128218: # Bug: Multiple simultaneous DMA transfers resulted in data being lost.
        !          128219: # Fix: Added DMA lock routines to ensure single simultaneous DMA
        !          128220: #      transfers. (JHB)
        !          128221: # 
        !          128222: # Revision 1.3 88/05/23  17:31:10      src
        !          128223: # Added vtop linkage routine (Jim had filed away in his directory) - ART
        !          128224: # 
        !          128225: # Revision 1.2 88/04/04  16:39:27      src
        !          128226: # defer() function now supported from loadable drivers.
        !          128227: # 
        !          128228: # Revision 1.1 88/03/24  16:30:21      src
        !          128229: # Initial revision
        !          128230: #
        !          128231: # 88/02/16     Jim Belton              $(USRSRC)/ldrv/Makefile
        !          128232: # Added vtop linkage routine to ldlib.a.
        !          128233: 
        !          128234: a9 13
        !          128235: # Source directories
        !          128236: COHSRC=$(USRSRC)/coh
        !          128237: DRVSRC=$(USRSRC)/i8086/drv
        !          128238: I86SRC=$(USRSRC)/i8086/src
        !          128239: IBMATSRC=$(USRSRC)/i8086/ibm_at
        !          128240: KERSRC=$(USRSRC)/ker
        !          128241: TTYSRC=$(USRSRC)/ttydrv
        !          128242: 
        !          128243: # Object directories
        !          128244: I86OBJ=$(USRSRC)/i8086/objects
        !          128245: DRVOBJ=$(USRSRC)/i8086/drv/objects
        !          128246: IBMATOBJ=$(USRSRC)/i8086/ibm_at/objects
        !          128247: 
        !          128248: d30 4
        !          128249: a33 2
        !          128250: # The following script creates a interface stub to a kernel function.
        !          128251: GEN_DRV=objects/mkstub.sh
        !          128252: a34 5
        !          128253: # The following script extracts a module from a library.
        !          128254: ARX_LIB=set -e; OBJFIL=`basename $@@` ;\
        !          128255:        eval ar x $< $${OBJFIL} ;\
        !          128256:        eval mv $${OBJFIL} $@@
        !          128257: 
        !          128258: d38 62
        !          128259: a99 62
        !          128260: LIBOBJ1=objects/abs.o          \
        !          128261:        objects/alloc.o         \
        !          128262:        objects/bclaim.o        \
        !          128263:        objects/bdone.o         \
        !          128264:        objects/blkmv.o         \
        !          128265:        objects/boot.o          \
        !          128266:        objects/bread.o         \
        !          128267:        objects/brelease.o      \
        !          128268:        objects/clockedf.o      \
        !          128269:        objects/clrq.o          \
        !          128270:        objects/cs_self.o       \
        !          128271:        objects/dblock.o        \
        !          128272:        objects/dclose.o        \
        !          128273:        objects/defer.o         \
        !          128274:        objects/devmsg.o        \
        !          128275:        objects/dmago.o         \
        !          128276:        objects/dmalock.o       \
        !          128277:        objects/dmaoff.o        \
        !          128278:        objects/dmaon.o         \
        !          128279:        objects/dmareq.o        \
        !          128280:        objects/dopen.o         \
        !          128281:        objects/drvmap.o        \
        !          128282:        objects/dwrite.o        \
        !          128283:        objects/fclear.o        \
        !          128284:        objects/fdisk.o         \
        !          128285:        objects/ffbyte.o        \
        !          128286:        objects/ffword.o        \
        !          128287:        objects/ffmem.o         \
        !          128288:        objects/fkcopy.o        \
        !          128289:        objects/fpxcopy.o       \
        !          128290:        objects/free.o          \
        !          128291:        objects/fucopy.o        \
        !          128292:        objects/getcs.o         \
        !          128293:        objects/getq.o          \
        !          128294:        objects/getubd.o        \
        !          128295:        objects/getuwd.o        \
        !          128296:        objects/inb.o           \
        !          128297:        objects/int11.o         \
        !          128298:        objects/iogetc.o        \
        !          128299:        objects/iomapvp.o       \
        !          128300:        objects/ioputc.o        \
        !          128301:        objects/ioread.o        \
        !          128302:        objects/ioreq.o         \
        !          128303:        objects/iowrite.o       \
        !          128304:        objects/ipcaccess.o     \
        !          128305:        objects/kcall.o         \
        !          128306:        objects/kfcopy.o        \
        !          128307:        objects/kclear.o        \
        !          128308:        objects/kpcopy.o        \
        !          128309:        objects/kucopy.o        \
        !          128310:        objects/lock.o          \
        !          128311:        objects/lxdiv.o         \
        !          128312:        objects/lxmul.o         \
        !          128313:        objects/lxrem.o         \
        !          128314:        objects/lxsgn.o         \
        !          128315:        objects/memset.o        \
        !          128316:        objects/memtest.o       \
        !          128317:        objects/nmidisable.o    \
        !          128318:        objects/nmienable.o     \
        !          128319:        objects/nondsig.o       \
        !          128320:        objects/nonedev.o       \
        !          128321:        objects/nulldev.o       \
        !          128322: d101 63
        !          128323: a163 63
        !          128324: LIBOBJ2=objects/outb.o         \
        !          128325:        objects/panic.o         \
        !          128326:        objects/pclear.o        \
        !          128327:        objects/pkcopy.o        \
        !          128328:        objects/plrcopy.o       \
        !          128329:        objects/pollopen.o      \
        !          128330:        objects/pollwake.o      \
        !          128331:        objects/printf.o        \
        !          128332:        objects/prlcopy.o       \
        !          128333:        objects/ptov.o          \
        !          128334:        objects/pucopy.o        \
        !          128335:        objects/putchar.o       \
        !          128336:        objects/putq.o          \
        !          128337:        objects/putubd.o        \
        !          128338:        objects/putuwd.o        \
        !          128339:        objects/rucopy.o        \
        !          128340:        objects/s5_to_sg.o      \
        !          128341:        objects/s5_to_tc.o      \
        !          128342:        objects/salloc.o        \
        !          128343:        objects/sclear.o        \
        !          128344:        objects/sendsig.o       \
        !          128345:        objects/setivec.o       \
        !          128346:        objects/sfree.o         \
        !          128347:        objects/sfbyte.o        \
        !          128348:        objects/sfword.o        \
        !          128349:        objects/sfmem.o         \
        !          128350:        objects/sg_to_s5.o      \
        !          128351:        objects/sleep.o         \
        !          128352:        objects/slrcopy.o       \
        !          128353:        objects/sphi.o          \
        !          128354:        objects/spl.o           \
        !          128355:        objects/splo.o          \
        !          128356:        objects/super.o         \
        !          128357:        objects/swapio.o        \
        !          128358:        objects/tc_to_s5.o      \
        !          128359:        objects/timeout.o       \
        !          128360:        objects/ttclose.o       \
        !          128361:        objects/tthup.o         \
        !          128362:        objects/ttin.o          \
        !          128363:        objects/ttioctl.o       \
        !          128364:        objects/ttopen.o        \
        !          128365:        objects/ttout.o         \
        !          128366:        objects/ttpoll.o        \
        !          128367:        objects/ttread.o        \
        !          128368:        objects/ttsetgrp.o      \
        !          128369:        objects/ttsignal.o      \
        !          128370:        objects/ttstart.o       \
        !          128371:        objects/ttwrite.o       \
        !          128372:        objects/uexit.o         \
        !          128373:        objects/ufcopy.o        \
        !          128374:        objects/ukcopy.o        \
        !          128375:        objects/unlock.o        \
        !          128376:        objects/upcopy.o        \
        !          128377:        objects/urcopy.o        \
        !          128378:        objects/vprint.o        \
        !          128379:        objects/vrelse.o        \
        !          128380:        objects/vremap.o        \
        !          128381:        objects/vtop.o          \
        !          128382:        objects/vxdiv.o         \
        !          128383:        objects/vxmul.o         \
        !          128384:        objects/vxrem.o         \
        !          128385:        objects/waitq.o         \
        !          128386:        objects/wakeup.o        \
        !          128387: d165 1
        !          128388: a165 3
        !          128389: $(USRSYS)/lib/ldlib.a: $(GEN_DRV)      \
        !          128390:                        $(LIBOBJ1)      \
        !          128391:                        $(LIBOBJ2)
        !          128392: d171 8
        !          128393: a178 16
        !          128394: #
        !          128395: # Create the script to create an interface stub to a kernel function.
        !          128396: #
        !          128397: $(GEN_DRV):
        !          128398:        echo ": 'Created by Makefile - do not edit.';\
        !          128399:        set -e; ENTRY=\`basename \$$1\`;(\
        !          128400:        echo \".globl \$${ENTRY}_\";\
        !          128401:        echo \"\$${ENTRY}_: mov ax,\\\\\$$K\$${ENTRY}_\";\
        !          128402:        echo .byte 0x9A;\
        !          128403:        echo .word xcalled;\
        !          128404:        echo .word 0x0060;\
        !          128405:        echo ret;)>/tmp/\$$\$$.s;\
        !          128406:        as -gxo /tmp/\$$\$$.o /tmp/\$$\$$.s;\
        !          128407:        mv /tmp/\$$\$$.o \$$1.o;\
        !          128408:        rm -f /tmp/\$$\$$.s" > $@@
        !          128409:        chmod +x $@@
        !          128410: d180 2
        !          128411: a181 2
        !          128412: objects/abs.o:
        !          128413:        $(GEN_DRV) $*
        !          128414: d183 2
        !          128415: a184 2
        !          128416: objects/alloc.o:
        !          128417:        $(GEN_DRV) $*
        !          128418: d186 2
        !          128419: a187 2
        !          128420: objects/bclaim.o:
        !          128421:        $(GEN_DRV) $*
        !          128422: d189 2
        !          128423: a190 2
        !          128424: objects/bdone.o:
        !          128425:        $(GEN_DRV) $*
        !          128426: d192 2
        !          128427: a193 2
        !          128428: objects/blkmv.o:       /lib/libc.a
        !          128429:        $(ARX_LIB)
        !          128430: d195 2
        !          128431: a196 2
        !          128432: objects/boot.o:
        !          128433:        $(GEN_DRV) $*
        !          128434: d198 2
        !          128435: a199 2
        !          128436: objects/bread.o:
        !          128437:        $(GEN_DRV) $*
        !          128438: d201 2
        !          128439: a202 2
        !          128440: objects/brelease.o:
        !          128441:        $(GEN_DRV) $*
        !          128442: d204 4
        !          128443: a207 1
        !          128444: objects/clockedf.o:    clockedf.c
        !          128445: d210 2
        !          128446: a211 2
        !          128447: objects/clrivec.o:
        !          128448:        $(GEN_DRV) $*
        !          128449: d213 2
        !          128450: a214 2
        !          128451: objects/clrq.o:
        !          128452:        $(GEN_DRV) $*
        !          128453: d216 1
        !          128454: a216 1
        !          128455: objects/cs_self.o:     cs_self.s
        !          128456: d219 2
        !          128457: a220 2
        !          128458: objects/dblock.o:
        !          128459:        $(GEN_DRV) $*
        !          128460: d222 2
        !          128461: a223 2
        !          128462: objects/dclose.o:
        !          128463:        $(GEN_DRV) $*
        !          128464: d225 1
        !          128465: a225 1
        !          128466: objects/defer.o:       defer.s
        !          128467: d228 2
        !          128468: a229 2
        !          128469: objects/devmsg.o:
        !          128470:        $(GEN_DRV) $*
        !          128471: d231 2
        !          128472: a232 2
        !          128473: objects/dmago.o:
        !          128474:        $(GEN_DRV) $*
        !          128475: d234 1
        !          128476: a234 1
        !          128477: objects/dmalock.o:     dmalock.c
        !          128478: d237 2
        !          128479: a238 2
        !          128480: objects/dmaoff.o:
        !          128481:        $(GEN_DRV) $*
        !          128482: d240 2
        !          128483: a241 2
        !          128484: objects/dmaon.o:
        !          128485:        $(GEN_DRV) $*
        !          128486: d243 2
        !          128487: a244 2
        !          128488: objects/dmareq.o:
        !          128489:        $(GEN_DRV) $*
        !          128490: d246 2
        !          128491: a247 2
        !          128492: objects/dopen.o:
        !          128493:        $(GEN_DRV) $*
        !          128494: d249 2
        !          128495: a250 2
        !          128496: objects/drvmap.o:
        !          128497:        $(GEN_DRV) $*
        !          128498: d252 2
        !          128499: a253 2
        !          128500: objects/dwrite.o:
        !          128501:        $(GEN_DRV) $*
        !          128502: d255 2
        !          128503: a256 2
        !          128504: objects/fclear.o:
        !          128505:        $(GEN_DRV) $*
        !          128506: d258 2
        !          128507: a259 2
        !          128508: objects/fdisk.o:
        !          128509:        $(GEN_DRV) $*
        !          128510: d261 1
        !          128511: a261 1
        !          128512: objects/ffbyte.o:      ffbyte.s
        !          128513: d264 1
        !          128514: a264 1
        !          128515: objects/ffword.o:      ffword.s
        !          128516: d267 1
        !          128517: a267 1
        !          128518: objects/ffmem.o:       ffmem.s
        !          128519: d270 2
        !          128520: a271 2
        !          128521: objects/fkcopy.o:
        !          128522:        $(GEN_DRV) $*
        !          128523: d273 2
        !          128524: a274 2
        !          128525: objects/fpxcopy.o:
        !          128526:        $(GEN_DRV) $*
        !          128527: d276 2
        !          128528: a277 2
        !          128529: objects/free.o:
        !          128530:        $(GEN_DRV) $*
        !          128531: d279 2
        !          128532: a280 2
        !          128533: objects/fucopy.o:
        !          128534:        $(GEN_DRV) $*
        !          128535: d282 1
        !          128536: a282 1
        !          128537: objects/getcs.o:       getcs.s
        !          128538: d285 2
        !          128539: a286 2
        !          128540: objects/getq.o:
        !          128541:        $(GEN_DRV) $*
        !          128542: d288 2
        !          128543: a289 2
        !          128544: objects/getubd.o:
        !          128545:        $(GEN_DRV) $*
        !          128546: d291 2
        !          128547: a292 2
        !          128548: objects/getuwd.o:
        !          128549:        $(GEN_DRV) $*
        !          128550: d294 1
        !          128551: a294 1
        !          128552: objects/inb.o:         inb.s
        !          128553: d297 2
        !          128554: a298 2
        !          128555: objects/int11.o:
        !          128556:        $(GEN_DRV) $*
        !          128557: d300 2
        !          128558: a301 2
        !          128559: objects/iogetc.o:
        !          128560:        $(GEN_DRV) $*
        !          128561: d303 2
        !          128562: a304 2
        !          128563: objects/iomapvp.o:
        !          128564:        $(GEN_DRV) $*
        !          128565: d306 2
        !          128566: a307 2
        !          128567: objects/ioputc.o:
        !          128568:        $(GEN_DRV) $*
        !          128569: d309 2
        !          128570: a310 2
        !          128571: objects/ioread.o:
        !          128572:        $(GEN_DRV) $*
        !          128573: d312 2
        !          128574: a313 2
        !          128575: objects/ioreq.o:
        !          128576:        $(GEN_DRV) $*
        !          128577: d315 2
        !          128578: a316 2
        !          128579: objects/iowrite.o:
        !          128580:        $(GEN_DRV) $*
        !          128581: d318 2
        !          128582: a319 2
        !          128583: objects/ipcaccess.o:
        !          128584:        $(GEN_DRV) $*
        !          128585: d321 1
        !          128586: a321 1
        !          128587: objects/kcall.o:       kcall.s
        !          128588: d324 2
        !          128589: a325 2
        !          128590: objects/kclear.o:
        !          128591:        $(GEN_DRV) $*
        !          128592: d327 2
        !          128593: a328 2
        !          128594: objects/kfcopy.o:
        !          128595:        $(GEN_DRV) $*
        !          128596: d330 2
        !          128597: a331 2
        !          128598: objects/kpcopy.o:
        !          128599:        $(GEN_DRV) $*
        !          128600: d333 2
        !          128601: a334 2
        !          128602: objects/kucopy.o:
        !          128603:        $(GEN_DRV) $*
        !          128604: d336 2
        !          128605: a337 2
        !          128606: objects/lock.o:
        !          128607:        $(GEN_DRV) $*
        !          128608: d339 2
        !          128609: a340 2
        !          128610: objects/lxdiv.o:       /lib/libc.a
        !          128611:        $(ARX_LIB)
        !          128612: d342 2
        !          128613: a343 2
        !          128614: objects/lxmul.o:       /lib/libc.a
        !          128615:        $(ARX_LIB)
        !          128616: d345 2
        !          128617: a346 2
        !          128618: objects/lxrem.o:       /lib/libc.a
        !          128619:        $(ARX_LIB)
        !          128620: d348 2
        !          128621: a349 2
        !          128622: objects/lxsgn.o:       /lib/libc.a
        !          128623:        $(ARX_LIB)
        !          128624: d351 2
        !          128625: a352 2
        !          128626: objects/memset.o:      /lib/libc.a
        !          128627:        $(ARX_LIB)
        !          128628: d354 2
        !          128629: a355 2
        !          128630: objects/memtest.o:
        !          128631:        $(GEN_DRV) $*
        !          128632: d357 2
        !          128633: a358 2
        !          128634: objects/nmidisable.o:
        !          128635:        $(GEN_DRV) $*
        !          128636: d360 2
        !          128637: a361 2
        !          128638: objects/nmienable.o:
        !          128639:        $(GEN_DRV) $*
        !          128640: d363 2
        !          128641: a364 2
        !          128642: objects/nondsig.o:
        !          128643:        $(GEN_DRV) $*
        !          128644: d366 1
        !          128645: a366 1
        !          128646: objects/nonedev.o:     nonedev.c
        !          128647: d369 1
        !          128648: a369 1
        !          128649: objects/nulldev.o:     nulldev.c
        !          128650: d372 1
        !          128651: a372 1
        !          128652: objects/outb.o:                outb.s
        !          128653: d375 2
        !          128654: a376 2
        !          128655: objects/panic.o:
        !          128656:        $(GEN_DRV) $*
        !          128657: d378 2
        !          128658: a379 2
        !          128659: objects/pclear.o:
        !          128660:        $(GEN_DRV) $*
        !          128661: d381 2
        !          128662: a382 2
        !          128663: objects/plrcopy.o:
        !          128664:        $(GEN_DRV) $*
        !          128665: d384 2
        !          128666: a385 2
        !          128667: objects/pkcopy.o:
        !          128668:        $(GEN_DRV) $*
        !          128669: d387 2
        !          128670: a388 2
        !          128671: objects/pollopen.o:
        !          128672:        $(GEN_DRV) $*
        !          128673: d390 2
        !          128674: a391 2
        !          128675: objects/pollwake.o:
        !          128676:        $(GEN_DRV) $*
        !          128677: d393 2
        !          128678: a394 2
        !          128679: objects/printf.o:
        !          128680:        $(GEN_DRV) $*
        !          128681: d396 2
        !          128682: a397 2
        !          128683: objects/prlcopy.o:
        !          128684:        $(GEN_DRV) $*
        !          128685: d399 2
        !          128686: a400 2
        !          128687: objects/ptov.o:
        !          128688:        $(GEN_DRV) $*
        !          128689: d402 2
        !          128690: a403 2
        !          128691: objects/pucopy.o:
        !          128692:        $(GEN_DRV) $*
        !          128693: d405 2
        !          128694: a406 2
        !          128695: objects/putchar.o:
        !          128696:        $(GEN_DRV) $*
        !          128697: d408 2
        !          128698: a409 2
        !          128699: objects/putq.o:
        !          128700:        $(GEN_DRV) $*
        !          128701: d411 2
        !          128702: a412 2
        !          128703: objects/putubd.o:
        !          128704:        $(GEN_DRV) $*
        !          128705: d414 2
        !          128706: a415 2
        !          128707: objects/putuwd.o:
        !          128708:        $(GEN_DRV) $*
        !          128709: d417 2
        !          128710: a418 2
        !          128711: objects/rucopy.o:
        !          128712:        $(GEN_DRV) $*
        !          128713: d420 2
        !          128714: a421 2
        !          128715: objects/s5_to_sg.o:
        !          128716:        $(GEN_DRV) $*
        !          128717: d423 2
        !          128718: a424 2
        !          128719: objects/s5_to_tc.o:
        !          128720:        $(GEN_DRV) $*
        !          128721: d426 2
        !          128722: a427 2
        !          128723: objects/salloc.o:
        !          128724:        $(GEN_DRV) $*
        !          128725: d429 2
        !          128726: a430 2
        !          128727: objects/sclear.o:
        !          128728:        $(GEN_DRV) $*
        !          128729: d432 2
        !          128730: a433 2
        !          128731: objects/sendsig.o:
        !          128732:        $(GEN_DRV) $*
        !          128733: d435 1
        !          128734: a435 1
        !          128735: objects/setivec.o:     setivec.c
        !          128736: d438 2
        !          128737: a439 2
        !          128738: objects/sfree.o:
        !          128739:        $(GEN_DRV) $*
        !          128740: d441 1
        !          128741: a441 1
        !          128742: objects/sfbyte.o:      sfbyte.s
        !          128743: d444 1
        !          128744: a444 1
        !          128745: objects/sfword.o:      sfword.s
        !          128746: d447 1
        !          128747: a447 1
        !          128748: objects/sfmem.o:       sfmem.s
        !          128749: d450 2
        !          128750: a451 2
        !          128751: objects/sg_to_s5.o:
        !          128752:        $(GEN_DRV) $*
        !          128753: d453 2
        !          128754: a454 2
        !          128755: objects/sleep.o:
        !          128756:        $(GEN_DRV) $*
        !          128757: d456 2
        !          128758: a457 2
        !          128759: objects/slrcopy.o:
        !          128760:        $(GEN_DRV) $*
        !          128761: d459 1
        !          128762: a459 1
        !          128763: objects/sphi.o:        sphi.s
        !          128764: d462 1
        !          128765: a462 1
        !          128766: objects/spl.o: spl.s
        !          128767: d465 1
        !          128768: a465 1
        !          128769: objects/splo.o:        splo.s
        !          128770: d468 2
        !          128771: a469 2
        !          128772: objects/super.o:
        !          128773:        $(GEN_DRV) $*
        !          128774: d471 2
        !          128775: a472 2
        !          128776: objects/swapio.o:
        !          128777:        $(GEN_DRV) $*
        !          128778: d474 2
        !          128779: a475 2
        !          128780: objects/tc_to_s5.o:
        !          128781:        $(GEN_DRV) $*
        !          128782: d477 1
        !          128783: a477 1
        !          128784: objects/timeout.o:     timeout.c
        !          128785: d480 2
        !          128786: a481 2
        !          128787: objects/ttclose.o:
        !          128788:        $(GEN_DRV) $*
        !          128789: d483 2
        !          128790: a484 2
        !          128791: objects/tthup.o:
        !          128792:        $(GEN_DRV) $*
        !          128793: d486 2
        !          128794: a487 2
        !          128795: objects/ttin.o:
        !          128796:        $(GEN_DRV) $*
        !          128797: d489 2
        !          128798: a490 2
        !          128799: objects/ttioctl.o:
        !          128800:        $(GEN_DRV) $*
        !          128801: d492 2
        !          128802: a493 2
        !          128803: objects/ttopen.o:
        !          128804:        $(GEN_DRV) $*
        !          128805: d495 2
        !          128806: a496 2
        !          128807: objects/ttout.o:
        !          128808:        $(GEN_DRV) $*
        !          128809: d498 2
        !          128810: a499 2
        !          128811: objects/ttpoll.o:
        !          128812:        $(GEN_DRV) $*
        !          128813: d501 2
        !          128814: a502 2
        !          128815: objects/ttread.o:
        !          128816:        $(GEN_DRV) $*
        !          128817: d504 2
        !          128818: a505 2
        !          128819: objects/ttsetgrp.o:
        !          128820:        $(GEN_DRV) $*
        !          128821: d507 2
        !          128822: a508 2
        !          128823: objects/ttsignal.o:
        !          128824:        $(GEN_DRV) $*
        !          128825: d510 2
        !          128826: a511 2
        !          128827: objects/ttstart.o:
        !          128828:        $(GEN_DRV) $*
        !          128829: d513 2
        !          128830: a514 2
        !          128831: objects/ttwrite.o:
        !          128832:        $(GEN_DRV) $*
        !          128833: d516 2
        !          128834: a517 2
        !          128835: objects/uexit.o:
        !          128836:        $(GEN_DRV) $*
        !          128837: d519 2
        !          128838: a520 2
        !          128839: objects/ufcopy.o:
        !          128840:        $(GEN_DRV) $*
        !          128841: d522 2
        !          128842: a523 2
        !          128843: objects/ukcopy.o:
        !          128844:        $(GEN_DRV) $*
        !          128845: d525 2
        !          128846: a526 2
        !          128847: objects/unlock.o:
        !          128848:        $(GEN_DRV) $*
        !          128849: d528 2
        !          128850: a529 2
        !          128851: objects/upcopy.o:
        !          128852:        $(GEN_DRV) $*
        !          128853: d531 2
        !          128854: a532 2
        !          128855: objects/urcopy.o:
        !          128856:        $(GEN_DRV) $*
        !          128857: d534 2
        !          128858: a535 2
        !          128859: objects/vprint.o:
        !          128860:        $(GEN_DRV) $*
        !          128861: d537 2
        !          128862: a538 2
        !          128863: objects/vrelse.o:
        !          128864:        $(GEN_DRV) $*
        !          128865: d540 2
        !          128866: a541 2
        !          128867: objects/vremap.o:
        !          128868:        $(GEN_DRV) $*
        !          128869: d543 2
        !          128870: a544 2
        !          128871: objects/vtop.o:
        !          128872:        $(GEN_DRV) $*
        !          128873: d546 2
        !          128874: a547 2
        !          128875: objects/vxdiv.o:       /lib/libc.a
        !          128876:        $(ARX_LIB)
        !          128877: d549 2
        !          128878: a550 2
        !          128879: objects/vxmul.o:       /lib/libc.a
        !          128880:        $(ARX_LIB)
        !          128881: d552 2
        !          128882: a553 2
        !          128883: objects/vxrem.o:       /lib/libc.a
        !          128884:        $(ARX_LIB)
        !          128885: d555 2
        !          128886: a556 2
        !          128887: objects/waitq.o:
        !          128888:        $(GEN_DRV) $*
        !          128889: d558 2
        !          128890: a559 2
        !          128891: objects/wakeup.o:
        !          128892:        $(GEN_DRV) $*
        !          128893: @
        !          128894: 
        !          128895: 
        !          128896: 1.3
        !          128897: log
        !          128898: @initial version provided by stevesf 
        !          128899: @
        !          128900: text
        !          128901: @d1 1
        !          128902: a1 1
        !          128903: # $Header: /usr/src/sys/ldrv/RCS/Makefile,v 1.2 91/04/30 18:38:22 root Exp $
        !          128904: d17 1
        !          128905: a17 1
        !          128906: # $Log:        /usr/src/sys/ldrv/RCS/Makefile,v $
        !          128907: d35 1
        !          128908: a35 1
        !          128909: # 88/02/16     Jim Belton              /usr/src/sys/ldrv/Makefile
        !          128910: a37 2
        !          128911: USRSYS=/usr/sys
        !          128912: 
        !          128913: a40 3
        !          128914: KERINC=/usr/src/sys/sys
        !          128915: DRVINC=/usr/src/sys/i8086/sys
        !          128916: USSINC=/usr/src/sys
        !          128917: d43 6
        !          128918: a48 6
        !          128919: COHSRC=/usr/src/sys/coh
        !          128920: DRVSRC=/usr/src/sys/i8086/drv
        !          128921: I86SRC=/usr/src/sys/i8086/src
        !          128922: IBMATSRC=/usr/src/sys/i8086/ibm_at
        !          128923: KERSRC=/usr/src/sys/ker
        !          128924: TTYSRC=/usr/src/sys/ttydrv
        !          128925: d51 3
        !          128926: a53 3
        !          128927: I86OBJ=/usr/src/sys/i8086/objects
        !          128928: DRVOBJ=/usr/src/sys/i8086/drv/objects
        !          128929: IBMATOBJ=/usr/src/sys/i8086/ibm_at/objects
        !          128930: d56 1
        !          128931: a56 1
        !          128932: CFLAGS=-I$(DRVINC) -I$(KERINC) -I$(SYSINC)
        !          128933: d58 4
        !          128934: a61 4
        !          128935: TARGETS=objects/ldrts0.o       \
        !          128936:        objects/ldmain.o        \
        !          128937:        objects/ldswap.o        \
        !          128938:        objects/ldlib.a
        !          128939: d63 1
        !          128940: a63 1
        !          128941: all:           $(TARGETS)
        !          128942: d66 2
        !          128943: a67 4
        !          128944: install:       $(TARGETS)      \
        !          128945:                ldconfig
        !          128946:        cp $(TARGETS) /tmp/usr/sys/lib
        !          128947:        cp ldconfig /tmp/usr/sys
        !          128948: d69 2
        !          128949: a70 2
        !          128950: shrink:
        !          128951:        rm -f objects/*
        !          128952: d72 2
        !          128953: a73 3
        !          128954: objects/ldrts0.o:      ldrts0.s
        !          128955:        as -x ldrts0.s
        !          128956:        mv l.out $@@
        !          128957: a74 9
        !          128958: objects/ldmain.o:      ldmain.c
        !          128959:        $(CC) $(CFLAGS) -c ldmain.c
        !          128960:        mv ldmain.o $@@
        !          128961: 
        !          128962: #      $(CC) $(CFLAGS) -c ldswap.c
        !          128963: objects/ldswap.o:      ldswap.c
        !          128964:        $(CC) $(CFLAGS) -DNOMONITOR -c ldswap.c
        !          128965:        mv ldswap.o $@@
        !          128966: 
        !          128967: d213 1
        !          128968: a213 1
        !          128969: objects/ldlib.a:       $(GEN_DRV)      \
        !          128970: a219 1
        !          128971:        cp $@@ /usr/sys/lib
        !          128972: d272 1
        !          128973: a272 2
        !          128974:        as -gxo cs_self.o cs_self.s
        !          128975:        mv cs_self.o $@@
        !          128976: d281 1
        !          128977: a281 2
        !          128978:        as -gxo defer.o defer.s
        !          128979:        mv defer.o $@@
        !          128980: d290 1
        !          128981: a290 2
        !          128982:        $(CC) $(CFLAGS) -c dmalock.c
        !          128983:        mv dmalock.o $@@
        !          128984: d317 1
        !          128985: a317 2
        !          128986:        as -gxo ffbyte.o ffbyte.s
        !          128987:        mv ffbyte.o $@@
        !          128988: d320 1
        !          128989: a320 2
        !          128990:        as -gxo ffword.o ffword.s
        !          128991:        mv ffword.o $@@
        !          128992: d323 1
        !          128993: a323 2
        !          128994:        as -gxo ffmem.o ffmem.s
        !          128995:        mv ffmem.o $@@
        !          128996: d338 1
        !          128997: a338 2
        !          128998:        as -gxo getcs.o getcs.s
        !          128999:        mv getcs.o $@@
        !          129000: d350 1
        !          129001: a350 2
        !          129002:        as -gxo inb.o inb.s
        !          129003:        mv inb.o $@@
        !          129004: d377 1
        !          129005: a377 2
        !          129006:        as -gxo kcall.o kcall.s
        !          129007:        mv kcall.o $@@
        !          129008: d422 1
        !          129009: a422 2
        !          129010:        $(CC) $(CFLAGS) -c nonedev.c
        !          129011:        mv nonedev.o $@@
        !          129012: d425 1
        !          129013: a425 2
        !          129014:        $(CC) $(CFLAGS) -c nulldev.c
        !          129015:        mv nulldev.o $@@
        !          129016: d428 1
        !          129017: a428 2
        !          129018:        as -gxo outb.o outb.s
        !          129019:        mv outb.o $@@
        !          129020: d491 1
        !          129021: a491 2
        !          129022:        $(CC) $(CFLAGS) -c setivec.c
        !          129023:        mv setivec.o $@@
        !          129024: d496 2
        !          129025: a497 3
        !          129026: objects/sfbyte.o:
        !          129027:        as -gxo sfbyte.o sfbyte.s
        !          129028:        mv sfbyte.o $@@
        !          129029: d499 2
        !          129030: a500 3
        !          129031: objects/sfword.o:
        !          129032:        as -gxo sfword.o sfword.s
        !          129033:        mv sfword.o $@@
        !          129034: d502 2
        !          129035: a503 3
        !          129036: objects/sfmem.o:
        !          129037:        as -gxo sfmem.o sfmem.s
        !          129038:        mv sfmem.o $@@
        !          129039: d514 2
        !          129040: a515 3
        !          129041: objects/sphi.o:
        !          129042:        as -gxo sphi.o sphi.s
        !          129043:        mv sphi.o $@@
        !          129044: d517 2
        !          129045: a518 3
        !          129046: objects/spl.o:
        !          129047:        as -gxo spl.o spl.s
        !          129048:        mv spl.o $@@
        !          129049: d520 2
        !          129050: a521 3
        !          129051: objects/splo.o:
        !          129052:        as -gxo splo.o splo.s
        !          129053:        mv splo.o $@@
        !          129054: d533 1
        !          129055: a533 2
        !          129056:        $(CC) $(CFLAGS) -c timeout.c
        !          129057:        mv timeout.o $@@
        !          129058: a614 1
        !          129059: 
        !          129060: @
        !          129061: 
        !          129062: 
        !          129063: 1.2
        !          129064: log
        !          129065: @Changes to support polled async driver "hs"
        !          129066: @
        !          129067: text
        !          129068: @d1 1
        !          129069: a1 1
        !          129070: # $Header: /usr/src/sys/ldrv/RCS/Makefile,v 1.5 89/06/30 16:31:48 src Exp $
        !          129071: d18 3
        !          129072: d220 1
        !          129073: d627 3
        !          129074: @
        !          129075: 
        !          129076: 
        !          129077: 1.1
        !          129078: log
        !          129079: @Shipped with 3.0.0 COHERENT.
        !          129080: @
        !          129081: text
        !          129082: @d35 1
        !          129083: a35 4
        !          129084: CC=/bin/cc
        !          129085: #IFLAGS=-I/usr/include/sys -I/usr/src/sys/sys -I/usr/src/sys/i8086/sys
        !          129086: IFLAGS=-I/tmp/usr/include/sys -I/tmp/usr/src/sys/sys -I/tmp/usr/src/sys/i8086/sys
        !          129087: CFLAGS=$(IFLAGS)
        !          129088: d37 23
        !          129089: d108 1
        !          129090: a108 1
        !          129091:        objects/clocked.o       \
        !          129092: d110 1
        !          129093: d146 1
        !          129094: a147 1
        !          129095:        objects/kfcopy.o        \
        !          129096: d167 1
        !          129097: d171 1
        !          129098: d233 1
        !          129099: d276 2
        !          129100: a277 2
        !          129101: objects/clocked.o:
        !          129102:        $(GEN_DRV) $*
        !          129103: d285 4
        !          129104: d462 3
        !          129105: d477 3
        !          129106: @
        !          129107: 0707070064030005001004440000030000030000011777770507310744200005200000002340/newbits/kernel/USRSRC/ldrv/RCS/blkmv.s,vhead     1.2;
        !          129108: branch   ;
        !          129109: access   ;
        !          129110: symbols  ;
        !          129111: locks    bin:1.2; strict;
        !          129112: comment  @@;
        !          129113: 
        !          129114: 
        !          129115: 1.2
        !          129116: date     91.06.20.14.33.43;  author bin;  state Exp;
        !          129117: branches ;
        !          129118: next     1.1;
        !          129119: 
        !          129120: 1.1
        !          129121: date     91.06.10.10.42.53;  author bin;  state Exp;
        !          129122: branches ;
        !          129123: next     ;
        !          129124: 
        !          129125: 
        !          129126: desc
        !          129127: @initial version provided by stevesf 
        !          129128: @
        !          129129: 
        !          129130: 
        !          129131: 1.2
        !          129132: log
        !          129133: @update provided by hal
        !          129134: @
        !          129135: text
        !          129136: @/ $Header: /usr/src/sys/ldrv/RCS/blkmv.s,v 1.1 88/03/24 16:30:25 src Exp $
        !          129137: /
        !          129138: /      The  information  contained herein  is a trade secret  of INETCO
        !          129139: /      Systems, and is confidential information.   It is provided under
        !          129140: /      a license agreement,  and may be copied or disclosed  only under
        !          129141: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129142: /      this  material  without  the express  written  authorization  of
        !          129143: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129144: /
        !          129145: /      Copyright (c) 1988
        !          129146: /      An unpublished work by INETCO Systems, Ltd.
        !          129147: /      All rights reserved.
        !          129148: /
        !          129149: / $Log:        /usr/src/sys/ldrv/RCS/blkmv.s,v $
        !          129150: / Revision 1.1 88/03/24  16:30:25      src
        !          129151: / Initial revision
        !          129152: / 
        !          129153: /
        !          129154: ////////
        !          129155: 
        !          129156:        .globl  blkmv
        !          129157: 
        !          129158: blkmv: push    si
        !          129159:        push    di
        !          129160:        push    bp
        !          129161:        mov     bp, sp
        !          129162: 
        !          129163:        mov     di, 8(bp)
        !          129164:        mov     si, 10(bp)
        !          129165:        mov     cx, 12(bp)
        !          129166:        cld
        !          129167:        rep
        !          129168:        movsb
        !          129169: 
        !          129170:        mov     ax, 8(bp)
        !          129171:        mov     sp, bp
        !          129172:        pop     bp
        !          129173:        pop     di
        !          129174:        pop     si
        !          129175:        ret
        !          129176: @
        !          129177: 
        !          129178: 
        !          129179: 1.1
        !          129180: log
        !          129181: @Initial revision
        !          129182: @
        !          129183: text
        !          129184: @@
        !          129185: 0707070064030105301004440000030000030000011777770507310744200005400000000772/newbits/kernel/USRSRC/ldrv/RCS/cs_self.s,vhead     1.1;
        !          129186: branch   ;
        !          129187: access   ;
        !          129188: symbols  ;
        !          129189: locks    bin:1.1; strict;
        !          129190: comment  @@;
        !          129191: 
        !          129192: 
        !          129193: 1.1
        !          129194: date     91.06.10.10.42.57;  author bin;  state Exp;
        !          129195: branches ;
        !          129196: next     ;
        !          129197: 
        !          129198: 
        !          129199: desc
        !          129200: @initial version provided by stevesf 
        !          129201: @
        !          129202: 
        !          129203: 
        !          129204: 
        !          129205: 1.1
        !          129206: log
        !          129207: @Initial revision
        !          129208: @
        !          129209: text
        !          129210: @////////
        !          129211: /
        !          129212: / Get cs selector - return 0 if in kernel, CS if not in kernel.
        !          129213: /
        !          129214: / This version is for loadable drivers.
        !          129215: / There is a different version (cs_sel.s) for resident drivers.
        !          129216: /
        !          129217: / int  cs_sel();
        !          129218: /
        !          129219: ////////
        !          129220: 
        !          129221:        .globl  cs_sel_
        !          129222: cs_sel_:
        !          129223:        mov     ax, cs
        !          129224:        ret
        !          129225: @
        !          129226: 0707070064030105101004440000030000030000011777770507310744200005200000003174/newbits/kernel/USRSRC/ldrv/RCS/defer.s,vhead     1.2;
        !          129227: branch   ;
        !          129228: access   ;
        !          129229: symbols  ;
        !          129230: locks    bin:1.2; strict;
        !          129231: comment  @@;
        !          129232: 
        !          129233: 
        !          129234: 1.2
        !          129235: date     91.06.20.14.33.52;  author bin;  state Exp;
        !          129236: branches ;
        !          129237: next     1.1;
        !          129238: 
        !          129239: 1.1
        !          129240: date     91.06.10.10.42.59;  author bin;  state Exp;
        !          129241: branches ;
        !          129242: next     ;
        !          129243: 
        !          129244: 
        !          129245: desc
        !          129246: @initial version provided by stevesf 
        !          129247: @
        !          129248: 
        !          129249: 
        !          129250: 1.2
        !          129251: log
        !          129252: @update provided by hal
        !          129253: @
        !          129254: text
        !          129255: @/ $Header: /usr/src/sys/ldrv/RCS/defer.s,v 1.1 88/04/04 16:40:21 src Exp $
        !          129256: /
        !          129257: /      The  information  contained herein  is a trade secret  of INETCO
        !          129258: /      Systems, and is confidential information.   It is provided under
        !          129259: /      a license agreement,  and may be copied or disclosed  only under
        !          129260: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129261: /      this  material  without  the express  written  authorization  of
        !          129262: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129263: /
        !          129264: /      Copyright (c) 1988
        !          129265: /      An unpublished work by INETCO Systems, Ltd.
        !          129266: /      All rights reserved.
        !          129267: /
        !          129268: / $Log:        /usr/src/sys/ldrv/RCS/defer.s,v $
        !          129269: / Revision 1.1 88/04/04  16:40:21      src
        !          129270: / Initial revision
        !          129271: / 
        !          129272: /
        !          129273: ////////
        !          129274: 
        !          129275: ////////
        !          129276: /
        !          129277: / void
        !          129278: / defer( f, a )                - defer local function from loadable driver.
        !          129279: / void (*f)();
        !          129280: / int a;
        !          129281: /
        !          129282: /      Input:  f = pointer to function to be deferred.
        !          129283: /              a = argument to be passed to function.
        !          129284: /
        !          129285: /      Action: Schedule local function 'f' to be invoked with argument 'a'
        !          129286: /              at next transition from kernel to user mode.
        !          129287: /
        !          129288: /      Return: None.
        !          129289: /
        !          129290: ////////
        !          129291: 
        !          129292:        .globl  defer_
        !          129293: 
        !          129294: defer_:        push    bp                      / defer( f, a )
        !          129295:        mov     bp, sp                  / void (*f)();
        !          129296:        push    6(bp)                   / int a;
        !          129297:        push    cs                      / {
        !          129298:        push    4(bp)                   /       kcall( Kldefer, f, cs, a );
        !          129299:        mov     ax, $Kldefer            /
        !          129300:        push    ax                      /
        !          129301:        call    kcall_                  /
        !          129302:        mov     sp, bp                  /
        !          129303:        pop     bp                      / }
        !          129304:        ret
        !          129305: @
        !          129306: 
        !          129307: 
        !          129308: 1.1
        !          129309: log
        !          129310: @Initial revision
        !          129311: @
        !          129312: text
        !          129313: @@
        !          129314: 0707070064030105071004440000030000030000011777770507310744300005300000002544/newbits/kernel/USRSRC/ldrv/RCS/ffbyte.s,vhead     1.2;
        !          129315: branch   ;
        !          129316: access   ;
        !          129317: symbols  ;
        !          129318: locks    bin:1.2; strict;
        !          129319: comment  @@;
        !          129320: 
        !          129321: 
        !          129322: 1.2
        !          129323: date     91.06.20.14.34.01;  author bin;  state Exp;
        !          129324: branches ;
        !          129325: next     1.1;
        !          129326: 
        !          129327: 1.1
        !          129328: date     91.06.10.10.43.00;  author bin;  state Exp;
        !          129329: branches ;
        !          129330: next     ;
        !          129331: 
        !          129332: 
        !          129333: desc
        !          129334: @initial version provided by stevesf 
        !          129335: @
        !          129336: 
        !          129337: 
        !          129338: 1.2
        !          129339: log
        !          129340: @update provided by hal
        !          129341: @
        !          129342: text
        !          129343: @/ $Header: /usr/src/sys/ldrv/RCS/ffbyte.s,v 1.1 88/03/24 16:30:28 src Exp $
        !          129344: /
        !          129345: /      The  information  contained herein  is a trade secret  of INETCO
        !          129346: /      Systems, and is confidential information.   It is provided under
        !          129347: /      a license agreement,  and may be copied or disclosed  only under
        !          129348: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129349: /      this  material  without  the express  written  authorization  of
        !          129350: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129351: /
        !          129352: /      Copyright (c) 1986
        !          129353: /      An unpublished work by INETCO Systems, Ltd.
        !          129354: /      All rights reserved.
        !          129355: /
        !          129356: / $Log:        /usr/src/sys/ldrv/RCS/ffbyte.s,v $
        !          129357: / Revision 1.1 88/03/24  16:30:28      src
        !          129358: / Initial revision
        !          129359: / 
        !          129360: /
        !          129361: ////////
        !          129362: 
        !          129363: ////////
        !          129364: /
        !          129365: / ffbyte( fp )         -- fetch far byte
        !          129366: / int far * fp;
        !          129367: /
        !          129368: ////////
        !          129369: 
        !          129370:        .globl  ffbyte_
        !          129371: 
        !          129372: ffbyte_:push   es              / ffbyte( fp )
        !          129373:        push    di              / register char far * fp;       /* ES:DI */
        !          129374:        push    bp              / {
        !          129375:        mov     bp, sp          /
        !          129376:        les     di, 8(bp)       /
        !          129377:                                /
        !          129378:        sub     ax, ax          /
        !          129379:        movb    al, es:(di)     /       return( *fp );
        !          129380:                                /
        !          129381:        pop     bp              / }
        !          129382:        pop     di
        !          129383:        pop     es
        !          129384:        ret
        !          129385: @
        !          129386: 
        !          129387: 
        !          129388: 1.1
        !          129389: log
        !          129390: @Initial revision
        !          129391: @
        !          129392: text
        !          129393: @@
        !          129394: 0707070064030105261004440000030000030000011777770507310744300005200000003456/newbits/kernel/USRSRC/ldrv/RCS/ffmem.s,vhead     1.2;
        !          129395: branch   ;
        !          129396: access   ;
        !          129397: symbols  ;
        !          129398: locks    bin:1.2; strict;
        !          129399: comment  @@;
        !          129400: 
        !          129401: 
        !          129402: 1.2
        !          129403: date     91.06.20.14.34.04;  author bin;  state Exp;
        !          129404: branches ;
        !          129405: next     1.1;
        !          129406: 
        !          129407: 1.1
        !          129408: date     91.06.10.10.43.01;  author bin;  state Exp;
        !          129409: branches ;
        !          129410: next     ;
        !          129411: 
        !          129412: 
        !          129413: desc
        !          129414: @initial version provided by stevesf 
        !          129415: @
        !          129416: 
        !          129417: 
        !          129418: 1.2
        !          129419: log
        !          129420: @update provided by hal
        !          129421: @
        !          129422: text
        !          129423: @/ $Header: /usr/src/sys/ldrv/RCS/ffmem.s,v 1.1 88/03/24 16:30:31 src Exp $
        !          129424: /
        !          129425: /      The  information  contained herein  is a trade secret  of INETCO
        !          129426: /      Systems, and is confidential information.   It is provided under
        !          129427: /      a license agreement,  and may be copied or disclosed  only under
        !          129428: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129429: /      this  material  without  the express  written  authorization  of
        !          129430: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129431: /
        !          129432: /      Copyright (c) 1986
        !          129433: /      An unpublished work by INETCO Systems, Ltd.
        !          129434: /      All rights reserved.
        !          129435: /
        !          129436: / $Log:        /usr/src/sys/ldrv/RCS/ffmem.s,v $
        !          129437: / Revision 1.1 88/03/24  16:30:31      src
        !          129438: / Initial revision
        !          129439: / 
        !          129440: /
        !          129441: ////////
        !          129442: 
        !          129443: ////////
        !          129444: /
        !          129445: / void
        !          129446: / ffmem( fp, m, n )    -- fetch far memory
        !          129447: / faddr_t fp;
        !          129448: / char * m;
        !          129449: / int n;
        !          129450: /
        !          129451: /      Input:  fp = far pointer [32 bit selector:offset] to source
        !          129452: /              m  = destination
        !          129453: /              n  = number of bytes to transfer.
        !          129454: /
        !          129455: /      Action: Transfer 'n' bytes from far address 'fp' to offset 'm'
        !          129456: /              in the current data space.
        !          129457: /
        !          129458: /      Return: None.
        !          129459: /
        !          129460: ////////
        !          129461: 
        !          129462:        .globl  ffmem_
        !          129463: 
        !          129464: ffmem_:        push    si              / void
        !          129465:        push    di              / ffmem( fp, m, n )
        !          129466:        push    bp              /
        !          129467:        mov     bp, sp          / register faddr_t fp;          /* DS:SI */
        !          129468:        push    ds              / register char * m;            /* DI */
        !          129469:        lds     si, 8(bp)       / register int n;               /* CX */
        !          129470:        mov     di, 12(bp)      /
        !          129471:        mov     cx, 14(bp)      / {
        !          129472:                                /
        !          129473:        cld                     /
        !          129474:        clc                     /       for ( ; n != 0; --n )
        !          129475:        rcr     cx, $1          /
        !          129476:        rep                     /               *m++ = *fp++;
        !          129477:        movsw                   /
        !          129478:        rcl     cx, $1          /
        !          129479:        rep                     /
        !          129480:        movsb                   /
        !          129481:                                /
        !          129482:        pop     ds              / }
        !          129483:        pop     bp
        !          129484:        pop     di
        !          129485:        pop     si
        !          129486:        ret
        !          129487: @
        !          129488: 
        !          129489: 
        !          129490: 1.1
        !          129491: log
        !          129492: @Initial revision
        !          129493: @
        !          129494: text
        !          129495: @@
        !          129496: 0707070064030105251004440000030000030000011777770507310744400005300000002520/newbits/kernel/USRSRC/ldrv/RCS/ffword.s,vhead     1.2;
        !          129497: branch   ;
        !          129498: access   ;
        !          129499: symbols  ;
        !          129500: locks    bin:1.2; strict;
        !          129501: comment  @@;
        !          129502: 
        !          129503: 
        !          129504: 1.2
        !          129505: date     91.06.20.14.34.07;  author bin;  state Exp;
        !          129506: branches ;
        !          129507: next     1.1;
        !          129508: 
        !          129509: 1.1
        !          129510: date     91.06.10.10.43.01;  author bin;  state Exp;
        !          129511: branches ;
        !          129512: next     ;
        !          129513: 
        !          129514: 
        !          129515: desc
        !          129516: @initial version provided by stevesf 
        !          129517: @
        !          129518: 
        !          129519: 
        !          129520: 1.2
        !          129521: log
        !          129522: @update provided by hal
        !          129523: @
        !          129524: text
        !          129525: @/ $Header: /usr/src/sys/ldrv/RCS/ffword.s,v 1.1 88/03/24 16:30:33 src Exp $
        !          129526: /
        !          129527: /      The  information  contained herein  is a trade secret  of INETCO
        !          129528: /      Systems, and is confidential information.   It is provided under
        !          129529: /      a license agreement,  and may be copied or disclosed  only under
        !          129530: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129531: /      this  material  without  the express  written  authorization  of
        !          129532: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129533: /
        !          129534: /      Copyright (c) 1986
        !          129535: /      An unpublished work by INETCO Systems, Ltd.
        !          129536: /      All rights reserved.
        !          129537: /
        !          129538: / $Log:        /usr/src/sys/ldrv/RCS/ffword.s,v $
        !          129539: / Revision 1.1 88/03/24  16:30:33      src
        !          129540: / Initial revision
        !          129541: / 
        !          129542: /
        !          129543: ////////
        !          129544: 
        !          129545: ////////
        !          129546: /
        !          129547: / ffword( fp )         -- fetch far word
        !          129548: / int far * fp;
        !          129549: /
        !          129550: ////////
        !          129551: 
        !          129552:        .globl  ffword_
        !          129553: 
        !          129554: ffword_:push   es              / ffword( fp )
        !          129555:        push    di              / register int far * fp;        /* ES:DI */
        !          129556:        push    bp              / {
        !          129557:        mov     bp, sp          /
        !          129558:        les     di, 8(bp)       /
        !          129559:                                /
        !          129560:        mov     ax, es:(di)     /       return *fp;
        !          129561:                                /
        !          129562:        pop     bp              / }
        !          129563:        pop     di
        !          129564:        pop     es
        !          129565:        ret
        !          129566: @
        !          129567: 
        !          129568: 
        !          129569: 1.1
        !          129570: log
        !          129571: @Initial revision
        !          129572: @
        !          129573: text
        !          129574: @@
        !          129575: 0707070064030105241004440000030000030000011777770507310744400005200000002374/newbits/kernel/USRSRC/ldrv/RCS/getcs.s,vhead     1.2;
        !          129576: branch   ;
        !          129577: access   ;
        !          129578: symbols  ;
        !          129579: locks    bin:1.2; strict;
        !          129580: comment  @@;
        !          129581: 
        !          129582: 
        !          129583: 1.2
        !          129584: date     91.06.20.14.34.10;  author bin;  state Exp;
        !          129585: branches ;
        !          129586: next     1.1;
        !          129587: 
        !          129588: 1.1
        !          129589: date     91.06.10.10.43.02;  author bin;  state Exp;
        !          129590: branches ;
        !          129591: next     ;
        !          129592: 
        !          129593: 
        !          129594: desc
        !          129595: @initial version provided by stevesf 
        !          129596: @
        !          129597: 
        !          129598: 
        !          129599: 1.2
        !          129600: log
        !          129601: @update provided by hal
        !          129602: @
        !          129603: text
        !          129604: @/ $Header: /usr/src/sys/ldrv/RCS/getcs.s,v 1.1 88/03/24 16:30:36 src Exp $
        !          129605: /
        !          129606: /      The  information  contained herein  is a trade secret  of INETCO
        !          129607: /      Systems, and is confidential information.   It is provided under
        !          129608: /      a license agreement,  and may be copied or disclosed  only under
        !          129609: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129610: /      this  material  without  the express  written  authorization  of
        !          129611: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129612: /
        !          129613: /      Copyright (c) 1986
        !          129614: /      An unpublished work by INETCO Systems, Ltd.
        !          129615: /      All rights reserved.
        !          129616: /
        !          129617: / $Log:        /usr/src/sys/ldrv/RCS/getcs.s,v $
        !          129618: / Revision 1.1 88/03/24  16:30:36      src
        !          129619: / Initial revision
        !          129620: / 
        !          129621: / 87/12/08     Allan Cornish   /usr/src/sys/ldrv/getcs.s
        !          129622: / Getcs() function obtains current code segment.
        !          129623: /
        !          129624: ////////
        !          129625: 
        !          129626: ////////
        !          129627: /
        !          129628: / Get code selector.
        !          129629: /
        !          129630: ////////
        !          129631: 
        !          129632:        .globl  getcs_
        !          129633: 
        !          129634: getcs_:        mov     ax, cs                  / Return code selector.
        !          129635:        ret
        !          129636: @
        !          129637: 
        !          129638: 
        !          129639: 1.1
        !          129640: log
        !          129641: @Initial revision
        !          129642: @
        !          129643: text
        !          129644: @@
        !          129645: 0707070064030105231004440000030000030000011777770507310744400005000000002263/newbits/kernel/USRSRC/ldrv/RCS/inb.s,vhead     1.2;
        !          129646: branch   ;
        !          129647: access   ;
        !          129648: symbols  ;
        !          129649: locks    bin:1.2; strict;
        !          129650: comment  @@;
        !          129651: 
        !          129652: 
        !          129653: 1.2
        !          129654: date     91.06.20.14.34.13;  author bin;  state Exp;
        !          129655: branches ;
        !          129656: next     1.1;
        !          129657: 
        !          129658: 1.1
        !          129659: date     91.06.10.10.43.03;  author bin;  state Exp;
        !          129660: branches ;
        !          129661: next     ;
        !          129662: 
        !          129663: 
        !          129664: desc
        !          129665: @initial version provided by stevesf 
        !          129666: @
        !          129667: 
        !          129668: 
        !          129669: 1.2
        !          129670: log
        !          129671: @update provided by hal
        !          129672: @
        !          129673: text
        !          129674: @/ $Header: /usr/src/sys/ldrv/RCS/inb.s,v 1.1 88/03/24 16:30:39 src Exp $
        !          129675: /
        !          129676: /      The  information  contained herein  is a trade secret  of INETCO
        !          129677: /      Systems, and is confidential information.   It is provided under
        !          129678: /      a license agreement,  and may be copied or disclosed  only under
        !          129679: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129680: /      this  material  without  the express  written  authorization  of
        !          129681: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129682: /
        !          129683: /      Copyright (c) 1988
        !          129684: /      An unpublished work by INETCO Systems, Ltd.
        !          129685: /      All rights reserved.
        !          129686: /
        !          129687: / $Log:        /usr/src/sys/ldrv/RCS/inb.s,v $
        !          129688: / Revision 1.1 88/03/24  16:30:39      src
        !          129689: / Initial revision
        !          129690: / 
        !          129691: /
        !          129692: ////////
        !          129693: 
        !          129694: ////////
        !          129695: /
        !          129696: / Basic port level I/O.
        !          129697: /
        !          129698: / int  inb(port);
        !          129699: /
        !          129700: ////////
        !          129701: 
        !          129702:        .globl  inb_
        !          129703: 
        !          129704: inb_:  mov     bx, sp
        !          129705:        mov     dx, 2(bx)
        !          129706:        sub     ax, ax
        !          129707:        inb     al, dx
        !          129708:        ret
        !          129709: @
        !          129710: 
        !          129711: 
        !          129712: 1.1
        !          129713: log
        !          129714: @Initial revision
        !          129715: @
        !          129716: text
        !          129717: @@
        !          129718: 0707070064030105221004440000030000030000011777770507310744500005200000003315/newbits/kernel/USRSRC/ldrv/RCS/kcall.s,vhead     1.2;
        !          129719: branch   ;
        !          129720: access   ;
        !          129721: symbols  ;
        !          129722: locks    bin:1.2; strict;
        !          129723: comment  @@;
        !          129724: 
        !          129725: 
        !          129726: 1.2
        !          129727: date     91.06.20.14.34.16;  author bin;  state Exp;
        !          129728: branches ;
        !          129729: next     1.1;
        !          129730: 
        !          129731: 1.1
        !          129732: date     91.06.10.10.43.04;  author bin;  state Exp;
        !          129733: branches ;
        !          129734: next     ;
        !          129735: 
        !          129736: 
        !          129737: desc
        !          129738: @initial version provided by stevesf 
        !          129739: @
        !          129740: 
        !          129741: 
        !          129742: 1.2
        !          129743: log
        !          129744: @update provided by hal
        !          129745: @
        !          129746: text
        !          129747: @/ $Header: /usr/src/sys/ldrv/RCS/kcall.s,v 1.1 88/03/24 16:30:41 src Exp $
        !          129748: /
        !          129749: /      The  information  contained herein  is a trade secret  of INETCO
        !          129750: /      Systems, and is confidential information.   It is provided under
        !          129751: /      a license agreement,  and may be copied or disclosed  only under
        !          129752: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129753: /      this  material  without  the express  written  authorization  of
        !          129754: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129755: /
        !          129756: /      Copyright (c) 1988
        !          129757: /      An unpublished work by INETCO Systems, Ltd.
        !          129758: /      All rights reserved.
        !          129759: /
        !          129760: / $Log:        /usr/src/sys/ldrv/RCS/kcall.s,v $
        !          129761: / Revision 1.1 88/03/24  16:30:41      src
        !          129762: / Initial revision
        !          129763: / 
        !          129764: /
        !          129765: ////////
        !          129766: 
        !          129767: ////////
        !          129768: /
        !          129769: / kcall( func, arg, ... )
        !          129770: /
        !          129771: /      Input:  func = kernel function to be invoked.
        !          129772: /              arg  = optional argument(s) to be passed to kernel function.
        !          129773: /
        !          129774: /      Action: Invoke kernel function.
        !          129775: /
        !          129776: ////////
        !          129777:        .globl  kcall_
        !          129778: 
        !          129779: kcall_:
        !          129780:        pop     bx              / Convert stack from (retIP dstIP arg ...)
        !          129781:        pop     ax              /                 to (      retIP arg ...)
        !          129782:        push    bx              / Leaving dstIP in AX register.
        !          129783:                                /
        !          129784:        .byte 0x9A              / Request kernel to perform far call.
        !          129785:        .word xcalled           /
        !          129786:        .word 0x0060            /
        !          129787:                                /
        !          129788:        pop     bx              / Convert stack from (      retIP arg ...)
        !          129789:        push    bx              /                 to (retIP retIP arg ...)
        !          129790:        push    bx              / This allows caller to cleanup normally.
        !          129791:                                / NOTE: DO NOT MODIFY DX:AX RETURN VALUE.
        !          129792:                                /
        !          129793:        ret                     / Return to caller.
        !          129794: @
        !          129795: 
        !          129796: 
        !          129797: 1.1
        !          129798: log
        !          129799: @Initial revision
        !          129800: @
        !          129801: text
        !          129802: @@
        !          129803: 0707070064030105061004440000030000030000011777770507310744500005300000003561/newbits/kernel/USRSRC/ldrv/RCS/ldrts0.s,vhead     1.2;
        !          129804: branch   ;
        !          129805: access   ;
        !          129806: symbols  ;
        !          129807: locks    bin:1.2; strict;
        !          129808: comment  @@;
        !          129809: 
        !          129810: 
        !          129811: 1.2
        !          129812: date     91.06.20.14.34.55;  author bin;  state Exp;
        !          129813: branches ;
        !          129814: next     1.1;
        !          129815: 
        !          129816: 1.1
        !          129817: date     91.06.10.10.43.09;  author bin;  state Exp;
        !          129818: branches ;
        !          129819: next     ;
        !          129820: 
        !          129821: 
        !          129822: desc
        !          129823: @initial version provided by stevesf 
        !          129824: @
        !          129825: 
        !          129826: 
        !          129827: 1.2
        !          129828: log
        !          129829: @update provided by hal
        !          129830: @
        !          129831: text
        !          129832: @/ $Header: /usr/src/sys/ldrv/RCS/ldrts0.s,v 1.1 88/03/24 16:30:47 src Exp $
        !          129833: / 
        !          129834: /      The  information  contained herein  is a trade secret  of INETCO
        !          129835: /      Systems, and is confidential information.   It is provided under
        !          129836: /      a license agreement,  and may be copied or disclosed  only under
        !          129837: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129838: /      this  material  without  the express  written  authorization  of
        !          129839: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129840: / 
        !          129841: /      Copyright (c) 1987
        !          129842: /      An unpublished work by INETCO Systems, Ltd.
        !          129843: /      All rights reserved.
        !          129844: /
        !          129845: 
        !          129846: ////////
        !          129847: /
        !          129848: / Loadable Driver Run Time Startup
        !          129849: /
        !          129850: / Notes:       This function MUST be at offset 0 in driver code segment.
        !          129851: /
        !          129852: / $Log:        /usr/src/sys/ldrv/RCS/ldrts0.s,v $
        !          129853: / Revision 1.1 88/03/24  16:30:47      src
        !          129854: / Initial revision
        !          129855: / 
        !          129856: /
        !          129857: ////////
        !          129858: 
        !          129859:        .globl  main_
        !          129860:        call    main_
        !          129861:        xret
        !          129862: 
        !          129863: ////////
        !          129864: /
        !          129865: /      Invocation mechanism for local driver functions by kernel code.
        !          129866: /
        !          129867: /      Input:  AX      = pointer to local function to be invoked.
        !          129868: /              4(BP)   = 1st parameter to be passed to local function.
        !          129869: /              6(BP)   = 2nd parameter to be passed to local function.
        !          129870: /              8(BP)   = 3rd parameter to be passed to local function.
        !          129871: /
        !          129872: /      Action: Invoke local function whose address is given in register AX,
        !          129873: /              passing parameters at offset 4,6,8 relative to register BP.
        !          129874: /              Perform a far return to operating system.
        !          129875: /
        !          129876: /      Notes:  Parameter passing convention specified by kernel.
        !          129877: /              This function MUST be at offset 4 in driver code segment.
        !          129878: /
        !          129879: ////////
        !          129880: 
        !          129881:        push    8(bp)
        !          129882:        push    6(bp)
        !          129883:        push    4(bp)
        !          129884:        icall   ax
        !          129885:        add     sp, $6
        !          129886:        xret
        !          129887: @
        !          129888: 
        !          129889: 
        !          129890: 1.1
        !          129891: log
        !          129892: @Initial revision
        !          129893: @
        !          129894: text
        !          129895: @@
        !          129896: 0707070064030105031004440000030000030000011777770507310744500005100000002302/newbits/kernel/USRSRC/ldrv/RCS/outb.s,vhead     1.2;
        !          129897: branch   ;
        !          129898: access   ;
        !          129899: symbols  ;
        !          129900: locks    bin:1.2; strict;
        !          129901: comment  @@;
        !          129902: 
        !          129903: 
        !          129904: 1.2
        !          129905: date     91.06.20.14.35.16;  author bin;  state Exp;
        !          129906: branches ;
        !          129907: next     1.1;
        !          129908: 
        !          129909: 1.1
        !          129910: date     91.06.10.10.43.12;  author bin;  state Exp;
        !          129911: branches ;
        !          129912: next     ;
        !          129913: 
        !          129914: 
        !          129915: desc
        !          129916: @initial version provided by stevesf 
        !          129917: @
        !          129918: 
        !          129919: 
        !          129920: 1.2
        !          129921: log
        !          129922: @update provided by hal
        !          129923: @
        !          129924: text
        !          129925: @/ $Header: /usr/src/sys/ldrv/RCS/outb.s,v 1.1 88/03/24 16:31:00 src Exp $
        !          129926: /
        !          129927: /      The  information  contained herein  is a trade secret  of INETCO
        !          129928: /      Systems, and is confidential information.   It is provided under
        !          129929: /      a license agreement,  and may be copied or disclosed  only under
        !          129930: /      the terms of that agreement.   Any reproduction or disclosure of
        !          129931: /      this  material  without  the express  written  authorization  of
        !          129932: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          129933: /
        !          129934: /      Copyright (c) 1988
        !          129935: /      An unpublished work by INETCO Systems, Ltd.
        !          129936: /      All rights reserved.
        !          129937: /
        !          129938: / $Log:        /usr/src/sys/ldrv/RCS/outb.s,v $
        !          129939: / Revision 1.1 88/03/24  16:31:00      src
        !          129940: / Initial revision
        !          129941: / 
        !          129942: /
        !          129943: ////////
        !          129944: 
        !          129945: ////////
        !          129946: /
        !          129947: / Basic port level I/O.
        !          129948: /
        !          129949: / int  outb(port, data);
        !          129950: /
        !          129951: ////////
        !          129952: 
        !          129953:        .globl  outb_
        !          129954: 
        !          129955: outb_: mov     bx, sp
        !          129956:        mov     dx, 2(bx)
        !          129957:        mov     ax, 4(bx)
        !          129958:        outb    dx, al
        !          129959:        ret
        !          129960: @
        !          129961: 
        !          129962: 
        !          129963: 1.1
        !          129964: log
        !          129965: @Initial revision
        !          129966: @
        !          129967: text
        !          129968: @@
        !          129969: 0707070064030105021004440000030000030000011777770507310744600005300000002612/newbits/kernel/USRSRC/ldrv/RCS/sfbyte.s,vhead     1.2;
        !          129970: branch   ;
        !          129971: access   ;
        !          129972: symbols  ;
        !          129973: locks    bin:1.2; strict;
        !          129974: comment  @@;
        !          129975: 
        !          129976: 
        !          129977: 1.2
        !          129978: date     91.06.20.14.35.22;  author bin;  state Exp;
        !          129979: branches ;
        !          129980: next     1.1;
        !          129981: 
        !          129982: 1.1
        !          129983: date     91.06.10.10.43.13;  author bin;  state Exp;
        !          129984: branches ;
        !          129985: next     ;
        !          129986: 
        !          129987: 
        !          129988: desc
        !          129989: @initial version provided by stevesf 
        !          129990: @
        !          129991: 
        !          129992: 
        !          129993: 1.2
        !          129994: log
        !          129995: @update provided by hal
        !          129996: @
        !          129997: text
        !          129998: @/ $Header: /usr/src/sys/ldrv/RCS/sfbyte.s,v 1.1 88/03/24 16:31:05 src Exp $
        !          129999: /
        !          130000: /      The  information  contained herein  is a trade secret  of INETCO
        !          130001: /      Systems, and is confidential information.   It is provided under
        !          130002: /      a license agreement,  and may be copied or disclosed  only under
        !          130003: /      the terms of that agreement.   Any reproduction or disclosure of
        !          130004: /      this  material  without  the express  written  authorization  of
        !          130005: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          130006: /
        !          130007: /      Copyright (c) 1986
        !          130008: /      An unpublished work by INETCO Systems, Ltd.
        !          130009: /      All rights reserved.
        !          130010: /
        !          130011: / $Log:        /usr/src/sys/ldrv/RCS/sfbyte.s,v $
        !          130012: / Revision 1.1 88/03/24  16:31:05      src
        !          130013: / Initial revision
        !          130014: / 
        !          130015: /
        !          130016: ////////
        !          130017: 
        !          130018: ////////
        !          130019: /
        !          130020: / sfbyte( fp, b )      -- set far byte
        !          130021: / char far * fp;
        !          130022: / char b;
        !          130023: /
        !          130024: ////////
        !          130025: 
        !          130026:        .globl  sfbyte_
        !          130027: 
        !          130028: sfbyte_:push   es              / sfbyte( fp, c )
        !          130029:        push    di              / register char far * fp;       /* ES:DI */
        !          130030:        push    bp              / register char c;              /* AX */
        !          130031:        mov     bp, sp          / {
        !          130032:        les     di, 8(bp)       /
        !          130033:        mov     ax, 12(bp)      /
        !          130034:                                /
        !          130035:        movb    es:(di), al     /       *fp = c;
        !          130036:                                /
        !          130037:        pop     bp              / }
        !          130038:        pop     di
        !          130039:        pop     es
        !          130040:        ret
        !          130041: @
        !          130042: 
        !          130043: 
        !          130044: 1.1
        !          130045: log
        !          130046: @Initial revision
        !          130047: @
        !          130048: text
        !          130049: @@
        !          130050: 0707070064030105161004440000030000030000011777770507310744600005200000003456/newbits/kernel/USRSRC/ldrv/RCS/sfmem.s,vhead     1.2;
        !          130051: branch   ;
        !          130052: access   ;
        !          130053: symbols  ;
        !          130054: locks    bin:1.2; strict;
        !          130055: comment  @@;
        !          130056: 
        !          130057: 
        !          130058: 1.2
        !          130059: date     91.06.20.14.35.25;  author bin;  state Exp;
        !          130060: branches ;
        !          130061: next     1.1;
        !          130062: 
        !          130063: 1.1
        !          130064: date     91.06.10.10.43.14;  author bin;  state Exp;
        !          130065: branches ;
        !          130066: next     ;
        !          130067: 
        !          130068: 
        !          130069: desc
        !          130070: @initial version provided by stevesf 
        !          130071: @
        !          130072: 
        !          130073: 
        !          130074: 1.2
        !          130075: log
        !          130076: @update provided by hal
        !          130077: @
        !          130078: text
        !          130079: @/ $Header: /usr/src/sys/ldrv/RCS/sfmem.s,v 1.1 88/03/24 16:31:08 src Exp $
        !          130080: /
        !          130081: /      The  information  contained herein  is a trade secret  of INETCO
        !          130082: /      Systems, and is confidential information.   It is provided under
        !          130083: /      a license agreement,  and may be copied or disclosed  only under
        !          130084: /      the terms of that agreement.   Any reproduction or disclosure of
        !          130085: /      this  material  without  the express  written  authorization  of
        !          130086: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          130087: /
        !          130088: /      Copyright (c) 1986
        !          130089: /      An unpublished work by INETCO Systems, Ltd.
        !          130090: /      All rights reserved.
        !          130091: /
        !          130092: / $Log:        /usr/src/sys/ldrv/RCS/sfmem.s,v $
        !          130093: / Revision 1.1 88/03/24  16:31:08      src
        !          130094: / Initial revision
        !          130095: / 
        !          130096: /
        !          130097: ////////
        !          130098: 
        !          130099: ////////
        !          130100: /
        !          130101: / void
        !          130102: / sfmem( fp, m, n )    -- set far memory
        !          130103: / char far * fp;
        !          130104: / char * m;
        !          130105: / int n;
        !          130106: /
        !          130107: /      Input:  fp = far pointer [32 bit selector:offset] to destination
        !          130108: /              m  = source
        !          130109: /              n  = number of bytes to transfer.
        !          130110: /
        !          130111: /      Action: Transfer 'n' bytes from offset 'm' in the current data space
        !          130112: /              to far address 'fp'.
        !          130113: /
        !          130114: /      Return: None.
        !          130115: /
        !          130116: ////////
        !          130117: 
        !          130118:        .globl  sfmem_
        !          130119: 
        !          130120: sfmem_:        push    si              / void
        !          130121:        push    di              / sfmem( fp, m, n )
        !          130122:        push    bp              /
        !          130123:        mov     bp, sp          / register char * fp;           /* ES:DI */
        !          130124:        push    es              / register char * m;            /* SI */
        !          130125:        les     di, 8(bp)       / register int n;               /* CX */
        !          130126:        mov     si, 12(bp)      /
        !          130127:        mov     cx, 14(bp)      / {
        !          130128:                                /
        !          130129:        cld                     /
        !          130130:        clc                     /       for ( ; n != 0; --n )
        !          130131:        rcr     cx, $1          /
        !          130132:        rep                     /               *fp++ = *m++;
        !          130133:        movsw                   /
        !          130134:        rcl     cx, $1          /
        !          130135:        rep                     /
        !          130136:        movsb                   /
        !          130137:                                /
        !          130138:        pop     es              / }
        !          130139:        pop     bp
        !          130140:        pop     di
        !          130141:        pop     si
        !          130142:        ret
        !          130143: @
        !          130144: 
        !          130145: 
        !          130146: 1.1
        !          130147: log
        !          130148: @Initial revision
        !          130149: @
        !          130150: text
        !          130151: @@
        !          130152: 0707070064030105151004440000030000030000011777770507310744700005300000002605/newbits/kernel/USRSRC/ldrv/RCS/sfword.s,vhead     1.2;
        !          130153: branch   ;
        !          130154: access   ;
        !          130155: symbols  ;
        !          130156: locks    bin:1.2; strict;
        !          130157: comment  @@;
        !          130158: 
        !          130159: 
        !          130160: 1.2
        !          130161: date     91.06.20.14.35.28;  author bin;  state Exp;
        !          130162: branches ;
        !          130163: next     1.1;
        !          130164: 
        !          130165: 1.1
        !          130166: date     91.06.10.10.43.15;  author bin;  state Exp;
        !          130167: branches ;
        !          130168: next     ;
        !          130169: 
        !          130170: 
        !          130171: desc
        !          130172: @initial version provided by stevesf 
        !          130173: @
        !          130174: 
        !          130175: 
        !          130176: 1.2
        !          130177: log
        !          130178: @update provided by hal
        !          130179: @
        !          130180: text
        !          130181: @/ $Header: /usr/src/sys/ldrv/RCS/sfword.s,v 1.1 88/03/24 16:31:11 src Exp $
        !          130182: /
        !          130183: /      The  information  contained herein  is a trade secret  of INETCO
        !          130184: /      Systems, and is confidential information.   It is provided under
        !          130185: /      a license agreement,  and may be copied or disclosed  only under
        !          130186: /      the terms of that agreement.   Any reproduction or disclosure of
        !          130187: /      this  material  without  the express  written  authorization  of
        !          130188: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          130189: /
        !          130190: /      Copyright (c) 1986
        !          130191: /      An unpublished work by INETCO Systems, Ltd.
        !          130192: /      All rights reserved.
        !          130193: /
        !          130194: / $Log:        /usr/src/sys/ldrv/RCS/sfword.s,v $
        !          130195: / Revision 1.1 88/03/24  16:31:11      src
        !          130196: / Initial revision
        !          130197: / 
        !          130198: /
        !          130199: ////////
        !          130200: 
        !          130201: ////////
        !          130202: /
        !          130203: / sfword( fp, w )      -- set far word
        !          130204: / int far * fp;
        !          130205: / int w;
        !          130206: /
        !          130207: ////////
        !          130208: 
        !          130209:        .globl  sfword_
        !          130210: 
        !          130211: sfword_:push   es              / sfword( fp, w )
        !          130212:        push    di              / register int far * fp;        /* ES:DI */
        !          130213:        push    bp              / register int w;               /* AX */
        !          130214:        mov     bp, sp          / {
        !          130215:        les     di, 8(bp)       /
        !          130216:        mov     ax, 12(bp)      /
        !          130217:                                /
        !          130218:        mov     es:(di), ax     /       *fp = w;
        !          130219:                                /
        !          130220:        pop     bp              / }
        !          130221:        pop     di
        !          130222:        pop     es
        !          130223:        ret
        !          130224: @
        !          130225: 
        !          130226: 
        !          130227: 1.1
        !          130228: log
        !          130229: @Initial revision
        !          130230: @
        !          130231: text
        !          130232: @@
        !          130233: 0707070064030105141004440000030000030000011777770507310744700005100000002362/newbits/kernel/USRSRC/ldrv/RCS/sphi.s,vhead     1.2;
        !          130234: branch   ;
        !          130235: access   ;
        !          130236: symbols  ;
        !          130237: locks    bin:1.2; strict;
        !          130238: comment  @@;
        !          130239: 
        !          130240: 
        !          130241: 1.2
        !          130242: date     91.06.20.14.35.30;  author bin;  state Exp;
        !          130243: branches ;
        !          130244: next     1.1;
        !          130245: 
        !          130246: 1.1
        !          130247: date     91.06.10.10.43.16;  author bin;  state Exp;
        !          130248: branches ;
        !          130249: next     ;
        !          130250: 
        !          130251: 
        !          130252: desc
        !          130253: @initial version provided by stevesf 
        !          130254: @
        !          130255: 
        !          130256: 
        !          130257: 1.2
        !          130258: log
        !          130259: @update provided by hal
        !          130260: @
        !          130261: text
        !          130262: @/ $Header: /usr/src/sys/ldrv/RCS/sphi.s,v 1.1 88/03/24 16:31:13 src Exp $
        !          130263: /
        !          130264: /      The  information  contained herein  is a trade secret  of INETCO
        !          130265: /      Systems, and is confidential information.   It is provided under
        !          130266: /      a license agreement,  and may be copied or disclosed  only under
        !          130267: /      the terms of that agreement.   Any reproduction or disclosure of
        !          130268: /      this  material  without  the express  written  authorization  of
        !          130269: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          130270: /
        !          130271: /      Copyright (c) 1988
        !          130272: /      An unpublished work by INETCO Systems, Ltd.
        !          130273: /      All rights reserved.
        !          130274: /
        !          130275: / $Log:        /usr/src/sys/ldrv/RCS/sphi.s,v $
        !          130276: / Revision 1.1 88/03/24  16:31:13      src
        !          130277: / Initial revision
        !          130278: / 
        !          130279: /
        !          130280: ////////
        !          130281: 
        !          130282: ////////
        !          130283: /
        !          130284: / Disable interrupts.  Previous value is returned.
        !          130285: /
        !          130286: ////////
        !          130287: 
        !          130288:        .globl  sphi_
        !          130289: 
        !          130290: sphi_:
        !          130291:        pushf                           / Save flags
        !          130292:        pop     ax                      / Return current value
        !          130293:        cli                             / Disable interrupts
        !          130294:        ret                             / And return
        !          130295: @
        !          130296: 
        !          130297: 
        !          130298: 1.1
        !          130299: log
        !          130300: @Initial revision
        !          130301: @
        !          130302: text
        !          130303: @@
        !          130304: 0707070064030105131004440000030000030000011777770507310744700005000000002411/newbits/kernel/USRSRC/ldrv/RCS/spl.s,vhead     1.2;
        !          130305: branch   ;
        !          130306: access   ;
        !          130307: symbols  ;
        !          130308: locks    bin:1.2; strict;
        !          130309: comment  @@;
        !          130310: 
        !          130311: 
        !          130312: 1.2
        !          130313: date     91.06.20.14.35.35;  author bin;  state Exp;
        !          130314: branches ;
        !          130315: next     1.1;
        !          130316: 
        !          130317: 1.1
        !          130318: date     91.06.10.10.43.16;  author bin;  state Exp;
        !          130319: branches ;
        !          130320: next     ;
        !          130321: 
        !          130322: 
        !          130323: desc
        !          130324: @initial version provided by stevesf 
        !          130325: @
        !          130326: 
        !          130327: 
        !          130328: 1.2
        !          130329: log
        !          130330: @update provided by hal
        !          130331: @
        !          130332: text
        !          130333: @/ $Header: /usr/src/sys/ldrv/RCS/spl.s,v 1.1 88/03/24 16:31:16 src Exp $
        !          130334: /
        !          130335: /      The  information  contained herein  is a trade secret  of INETCO
        !          130336: /      Systems, and is confidential information.   It is provided under
        !          130337: /      a license agreement,  and may be copied or disclosed  only under
        !          130338: /      the terms of that agreement.   Any reproduction or disclosure of
        !          130339: /      this  material  without  the express  written  authorization  of
        !          130340: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          130341: /
        !          130342: /      Copyright (c) 1988
        !          130343: /      An unpublished work by INETCO Systems, Ltd.
        !          130344: /      All rights reserved.
        !          130345: /
        !          130346: / $Log:        /usr/src/sys/ldrv/RCS/spl.s,v $
        !          130347: / Revision 1.1 88/03/24  16:31:16      src
        !          130348: / Initial revision
        !          130349: / 
        !          130350: /
        !          130351: ////////
        !          130352: 
        !          130353: ////////
        !          130354: /
        !          130355: / Change interrupt flag.  Previous value is returned.
        !          130356: /
        !          130357: ////////
        !          130358:        .globl  spl_
        !          130359: 
        !          130360: spl_:
        !          130361:        pop     ax                      / ip
        !          130362:        pop     bx                      / psw
        !          130363:        push    bx
        !          130364:        push    bx                      / push psw, cs, ip for iret
        !          130365:        push    cs
        !          130366:        push    ax
        !          130367:        pushf                           / old psw
        !          130368:        pop     ax
        !          130369:        iret
        !          130370: @
        !          130371: 
        !          130372: 
        !          130373: 1.1
        !          130374: log
        !          130375: @Initial revision
        !          130376: @
        !          130377: text
        !          130378: @@
        !          130379: 0707070064030105121004440000030000030000011777770507310745000005100000002240/newbits/kernel/USRSRC/ldrv/RCS/splo.s,vhead     1.2;
        !          130380: branch   ;
        !          130381: access   ;
        !          130382: symbols  ;
        !          130383: locks    bin:1.2; strict;
        !          130384: comment  @@;
        !          130385: 
        !          130386: 
        !          130387: 1.2
        !          130388: date     91.06.20.14.35.41;  author bin;  state Exp;
        !          130389: branches ;
        !          130390: next     1.1;
        !          130391: 
        !          130392: 1.1
        !          130393: date     91.06.10.10.43.17;  author bin;  state Exp;
        !          130394: branches ;
        !          130395: next     ;
        !          130396: 
        !          130397: 
        !          130398: desc
        !          130399: @initial version provided by stevesf 
        !          130400: @
        !          130401: 
        !          130402: 
        !          130403: 1.2
        !          130404: log
        !          130405: @update provided by hal
        !          130406: @
        !          130407: text
        !          130408: @/ $Header: /usr/src/sys/ldrv/RCS/splo.s,v 1.1 88/03/24 16:31:19 src Exp $
        !          130409: /
        !          130410: /      The  information  contained herein  is a trade secret  of INETCO
        !          130411: /      Systems, and is confidential information.   It is provided under
        !          130412: /      a license agreement,  and may be copied or disclosed  only under
        !          130413: /      the terms of that agreement.   Any reproduction or disclosure of
        !          130414: /      this  material  without  the express  written  authorization  of
        !          130415: /      INETCO Systems or persuant to the license agreement is unlawful.
        !          130416: /
        !          130417: /      Copyright (c) 1988
        !          130418: /      An unpublished work by INETCO Systems, Ltd.
        !          130419: /      All rights reserved.
        !          130420: /
        !          130421: / $Log:        /usr/src/sys/ldrv/RCS/splo.s,v $
        !          130422: / Revision 1.1 88/03/24  16:31:19      src
        !          130423: / Initial revision
        !          130424: / 
        !          130425: /
        !          130426: ////////
        !          130427: 
        !          130428: ////////
        !          130429: /
        !          130430: / Enable interrupts.  Previous value is returned.
        !          130431: /
        !          130432: ////////
        !          130433: 
        !          130434:        .globl  splo_
        !          130435: 
        !          130436: splo_:
        !          130437:        pushf
        !          130438:        pop     ax
        !          130439:        sti
        !          130440:        ret
        !          130441: @
        !          130442: 
        !          130443: 
        !          130444: 1.1
        !          130445: log
        !          130446: @Initial revision
        !          130447: @
        !          130448: text
        !          130449: @@
        !          130450: 0707070064030103121004440000030000030000011777770507310745000005500000004624/newbits/kernel/USRSRC/ldrv/RCS/clockedf.c,vhead     1.2;
        !          130451: branch   ;
        !          130452: access   ;
        !          130453: symbols  ;
        !          130454: locks    bin:1.2; strict;
        !          130455: comment  @ * @;
        !          130456: 
        !          130457: 
        !          130458: 1.2
        !          130459: date     91.06.20.14.33.48;  author bin;  state Exp;
        !          130460: branches ;
        !          130461: next     1.1;
        !          130462: 
        !          130463: 1.1
        !          130464: date     91.06.10.10.43.18;  author bin;  state Exp;
        !          130465: branches ;
        !          130466: next     ;
        !          130467: 
        !          130468: 
        !          130469: desc
        !          130470: @initial version provided by stevesf 
        !          130471: @
        !          130472: 
        !          130473: 
        !          130474: 1.2
        !          130475: log
        !          130476: @update provided by hal
        !          130477: @
        !          130478: text
        !          130479: @/* clockedf.c - support routines for alternate clock rate
        !          130480:               - this is the FAR version of clocked.c for loadable drivers
        !          130481: 
        !          130482:   altclk_in(hz, fn) - install routine with specified rate
        !          130483:                           "hz" should be a multiple of system rate of 100 Hz
        !          130484: 
        !          130485:   altclk_out()      - uninstall alternate clock routine and restore system rate
        !          130486:                        return old value of "altclk"
        !          130487: 
        !          130488:   altclk_rate(hz)   - set clock interrupt rate
        !          130489:                        new rate must be an even multiple of system rate "HZ"
        !          130490:                        return 0 if completed ok, -1 otherwise
        !          130491: 
        !          130492:   History:
        !          130493:     90/08/08 hws       initial version, works with hs.c modified for com[1-4]
        !          130494:     90/08/14 hws       make it more like a Unix system call
        !          130495:     90/09/12 hws       add far version
        !          130496: */
        !          130497: 
        !          130498: #include       <sys/coherent.h>        /* altclk */
        !          130499: #include       <sys/const.h>   /* HZ */
        !          130500: 
        !          130501: #define        PIT     0x40    /* 8253 port */
        !          130502: #define        TMR0_M3 0x36    /* timer 0, mode 3 */
        !          130503: #if 0
        !          130504: /* nominal IBM rate is 1.1900 MHz */
        !          130505: #define        SYS_HZ  1190000L        /* rate of input clock to timer 0 */
        !          130506: #else
        !          130507: /* current kernel rate is 1.1932 MHz */
        !          130508: #define        SYS_HZ  1193200L        /* rate of input clock to timer 0 */
        !          130509: #endif
        !          130510: 
        !          130511: typedef int (*PFI)();  /* pointer to function returning int */
        !          130512: 
        !          130513: extern saddr_t ucs;
        !          130514: 
        !          130515: static int altclk_rate(hz)
        !          130516: unsigned int hz;
        !          130517: {
        !          130518:   int s;       /* to save CPU irpt flag */
        !          130519:   unsigned int interval;       /* period for hz, in units of 1.19 MHz ticks */
        !          130520:   int ret;
        !          130521: 
        !          130522:   if (hz >= HZ && hz % HZ == 0) {      /* can't go slower than HZ! */
        !          130523:     interval = SYS_HZ/hz;
        !          130524:     s = sphi();        /* disable irpts */
        !          130525:     outb(PIT+3, TMR0_M3);
        !          130526:     outb(PIT, interval & 0xff);
        !          130527:     outb(PIT, interval >> 8);  /* unsigned shift */
        !          130528:     spl(s);    /* restore previous irpt state */
        !          130529:     ret = 0;
        !          130530:   }
        !          130531:   else {
        !          130532:     ret = -1;
        !          130533:   }
        !          130534:   return ret;
        !          130535: }
        !          130536: 
        !          130537: int altclk_in(hz, fn)
        !          130538: int hz;
        !          130539: PFI fn;
        !          130540: {
        !          130541:   int ret;
        !          130542:   int s;
        !          130543: 
        !          130544:   if ((ret = altclk_rate(hz)) == 0) {
        !          130545:     s = sphi();
        !          130546:     altclk = fn;
        !          130547:     altsel = cs_sel();
        !          130548:     spl(s);
        !          130549:   }
        !          130550:   return ret;
        !          130551: }
        !          130552: 
        !          130553: PFI altclk_out()
        !          130554: {
        !          130555:   PFI ret;
        !          130556:   int s;
        !          130557: 
        !          130558:   ret = altclk;
        !          130559:   if (ret) {
        !          130560:     altclk_rate(HZ);
        !          130561:     s = sphi();
        !          130562:     altclk = 0;
        !          130563:     altsel = 0;
        !          130564:     spl(s);
        !          130565:   }
        !          130566:   return ret;
        !          130567: }
        !          130568: @
        !          130569: 
        !          130570: 
        !          130571: 1.1
        !          130572: log
        !          130573: @Initial revision
        !          130574: @
        !          130575: text
        !          130576: @d20 1
        !          130577: a20 1
        !          130578: #include       "coherent.h"    /* altclk */
        !          130579: @
        !          130580: 0707070064030105271004440000030000030000011777770507310745100005400000005234/newbits/kernel/USRSRC/ldrv/RCS/dmalock.c,vhead     1.2;
        !          130581: branch   ;
        !          130582: access   ;
        !          130583: symbols  ;
        !          130584: locks    bin:1.2; strict;
        !          130585: comment  @ * @;
        !          130586: 
        !          130587: 
        !          130588: 1.2
        !          130589: date     91.06.20.14.33.57;  author bin;  state Exp;
        !          130590: branches ;
        !          130591: next     1.1;
        !          130592: 
        !          130593: 1.1
        !          130594: date     91.06.10.10.43.19;  author bin;  state Exp;
        !          130595: branches ;
        !          130596: next     ;
        !          130597: 
        !          130598: 
        !          130599: desc
        !          130600: @initial version provided by stevesf 
        !          130601: @
        !          130602: 
        !          130603: 
        !          130604: 1.2
        !          130605: log
        !          130606: @update provided by hal
        !          130607: @
        !          130608: text
        !          130609: @/* $Header: /usr/src/sys/ldrv/RCS/dmalock.c,v 1.1 89/06/30 16:29:52 src Exp $
        !          130610:  *
        !          130611:  *     The  information  contained herein  is a trade secret  of INETCO
        !          130612:  *     Systems, Ltd, and is  confidential information.   It is provided
        !          130613:  *     under a license agreement,  and may be copied or disclosed  only
        !          130614:  *     under  the  terms  of  that  agreement.    Any  reproduction  or
        !          130615:  *     disclosure  of  this   material   without  the  express  written
        !          130616:  *     authorization of INETCO Systems, Ltd. or persuant to the license
        !          130617:  *     agreement is unlawful.
        !          130618:  *
        !          130619:  *     Copyright (c) 1989
        !          130620:  *     An unpublished work by INETCO Systems, Ltd.
        !          130621:  *     All rights reserved.
        !          130622:  *
        !          130623:  * $Description: $
        !          130624:  *     Routines to lock/unlock the DMA controller chip from a loadable driver.
        !          130625:  *
        !          130626:  * $Author: src $
        !          130627:  *
        !          130628:  * $Creation: June 29, 1989 $
        !          130629:  *
        !          130630:  * $Log:       /usr/src/sys/ldrv/RCS/dmalock.c,v $
        !          130631:  * Revision 1.1        89/06/30  16:29:52      src
        !          130632:  * Initial revision
        !          130633:  * 
        !          130634:  */
        !          130635: 
        !          130636: #include <sys/coherent.h>
        !          130637: 
        !          130638: typedef void (* vfp_t)();              /* Void function pointer type.       */
        !          130639: 
        !          130640: /*
        !          130641:  * External functions.
        !          130642:  */
        !          130643: extern void Kdmalock();
        !          130644: extern void Kdmaunlock();
        !          130645: extern void Kldtimcall();
        !          130646: extern saddr_t getcs();
        !          130647: 
        !          130648: /*
        !          130649:  * int
        !          130650:  * dmalock( tp, fun, arg )
        !          130651:  * TIM * tp;
        !          130652:  * vfp_t fun;
        !          130653:  * int  arg;
        !          130654:  *
        !          130655:  *     Inputs: tp  = Deferred function structure pointer.
        !          130656:  *             fun = Function to call if request is deferred.
        !          130657:  *             arg = Argument to pass to function.
        !          130658:  *
        !          130659:  *     Action: Calls kernel dmalock() routine.
        !          130660:  *
        !          130661:  *     Return: 0 = Lock granted or -1 = Lock deferred.
        !          130662:  *
        !          130663:  *     Notes:  DMA controller locking was introduced to cure a bug on the
        !          130664:  *             NCR DMA controller, where overlapped DMA caused problems.
        !          130665:  *             No action is taken if DMA locking is disabled.
        !          130666:  */
        !          130667: 
        !          130668: int
        !          130669: dmalock( tp, fun, arg )
        !          130670: register TIM  * tp;
        !          130671: vfp_t          fun;
        !          130672: int            arg;
        !          130673: {
        !          130674:        /*
        !          130675:         * Define loadable driver interface.
        !          130676:         * Kldtimcall will be invoked when a deferred function is executed.
        !          130677:         * It will in turn invoke FP_SEL(tp->t_ldrv):4 (the calling drivers
        !          130678:         * function call entry point), passing FP_OFF(tp->t_ldrv) (the function
        !          130679:         * to call) in AX.
        !          130680:         */
        !          130681:        FP_SEL(tp->t_ldrv) = getcs();
        !          130682:        FP_OFF(tp->t_ldrv) = fun;
        !          130683:        return( kcall( Kdmalock, tp, Kldtimcall, arg ) );
        !          130684: }
        !          130685: 
        !          130686: /*
        !          130687:  * void
        !          130688:  * dmaunlock( tp )
        !          130689:  * TIM * tp;
        !          130690:  *
        !          130691:  *     Inputs: tp = Deferred function structure pointer.
        !          130692:  *
        !          130693:  *     Action: Calls the kernel dmaunlock().
        !          130694:  */
        !          130695: 
        !          130696: void
        !          130697: dmaunlock( tp )
        !          130698: register TIM * tp;
        !          130699: {
        !          130700:        kcall( Kdmaunlock, tp );
        !          130701: }
        !          130702: 
        !          130703: @
        !          130704: 
        !          130705: 
        !          130706: 1.1
        !          130707: log
        !          130708: @Initial revision
        !          130709: @
        !          130710: text
        !          130711: @d28 1
        !          130712: a28 1
        !          130713: #include <coherent.h>
        !          130714: @
        !          130715: 0707070064030060161004440000030000030000011777770507310745100005300000012720/newbits/kernel/USRSRC/ldrv/RCS/ldmain.c,vhead     1.2;
        !          130716: branch   ;
        !          130717: access   ;
        !          130718: symbols  ;
        !          130719: locks    bin:1.2; strict;
        !          130720: comment  @ * @;
        !          130721: 
        !          130722: 
        !          130723: 1.2
        !          130724: date     91.06.20.14.34.48;  author bin;  state Exp;
        !          130725: branches ;
        !          130726: next     1.1;
        !          130727: 
        !          130728: 1.1
        !          130729: date     91.06.10.10.43.20;  author bin;  state Exp;
        !          130730: branches ;
        !          130731: next     ;
        !          130732: 
        !          130733: 
        !          130734: desc
        !          130735: @initial version provided by stevesf 
        !          130736: @
        !          130737: 
        !          130738: 
        !          130739: 1.2
        !          130740: log
        !          130741: @update provided by hal
        !          130742: @
        !          130743: text
        !          130744: @/* $Header: /usr/src/sys/ldrv/RCS/ldmain.c,v 1.2 89/03/31 16:19:36 src Exp $ */
        !          130745: /*
        !          130746:  *     The  information  contained herein  is a trade secret  of INETCO
        !          130747:  *     Systems, and is confidential information.   It is provided under
        !          130748:  *     a license agreement,  and may be copied or disclosed  only under
        !          130749:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          130750:  *     this  material  without  the express  written  authorization  of
        !          130751:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          130752:  *
        !          130753:  *     Copyright (c) 1987
        !          130754:  *     An unpublished work by INETCO Systems, Ltd.
        !          130755:  *     All rights reserved.
        !          130756:  */
        !          130757: 
        !          130758: /*
        !          130759:  * Loadable Driver - Process Handler.
        !          130760:  *
        !          130761:  * $Log:       /usr/src/sys/ldrv/RCS/ldmain.c,v $
        !          130762:  * Revision 1.2        89/03/31  16:19:36      src
        !          130763:  * Bug:        Did not cancel either attached timed functions or deferred functions
        !          130764:  *     during an unload.  As a result, if a driver did not explicitly do
        !          130765:  *     this, then unloading the driver could cause a system panic.
        !          130766:  * Fix:        Now cancels the functions. (ABC)
        !          130767:  * 
        !          130768:  * Revision 1.1        88/03/24  08:30:44      src
        !          130769:  * Initial revision
        !          130770:  * 
        !          130771:  * 87/12/03    Allan Cornish           /usr/src/sys/ldrv/ldmain.c
        !          130772:  * Initial version.
        !          130773:  */
        !          130774: #include <sys/coherent.h>
        !          130775: #include <sys/proc.h>
        !          130776: #include <sys/sched.h>
        !          130777: #include <sys/con.h>
        !          130778: #include <sys/seg.h>
        !          130779: #include <sys/stat.h>
        !          130780: #include <sys/uproc.h>
        !          130781: 
        !          130782: extern CON con;
        !          130783: 
        !          130784: extern saddr_t ldrvsel[NDRV];
        !          130785: extern saddr_t ldrvics[16];
        !          130786: extern void  (*ldrvipc[16])();
        !          130787: extern CON *   ldrvcon[NDRV];
        !          130788: extern CON     ldrvpsy;
        !          130789: extern saddr_t ucs;
        !          130790: 
        !          130791: /*
        !          130792:  * Local variable - keeps track of the number of opens.
        !          130793:  * The loadable driver can't terminate until after the last close.
        !          130794:  * Openf is the loadable driver open routine.
        !          130795:  * Closef points to the driver's close routine.
        !          130796:  * The configuration table entries are taken over
        !          130797:  */
        !          130798: static int     nopen = 0;
        !          130799: static void    (*openf)() = NULL;
        !          130800: static void    (*closef)() = NULL;
        !          130801: 
        !          130802: main()
        !          130803: {
        !          130804:        register int mind = con.c_mind;
        !          130805:        register int level;
        !          130806:        extern  void myopen();
        !          130807:        extern  void myclose();
        !          130808:        extern  void Kdefend();
        !          130809: 
        !          130810:        /*
        !          130811:         * Loadable devices must identify the desired major device.
        !          130812:         */
        !          130813:        if ( (mind == 0) || (mind >= drvn) ) {
        !          130814:                printf("ldrv:%d: bad dev\n", mind );
        !          130815:                uexit( 1 );
        !          130816:        }
        !          130817: 
        !          130818:        /*
        !          130819:         * Loadable devices must use a unique [not in use] major device.
        !          130820:         */
        !          130821:        if ( (drvl[mind].d_conp != NULL) || (ldrvcon[mind] != NULL) ) {
        !          130822:                printf("ldrv:%d: dev bsy\n", mind );
        !          130823:                uexit( 0 );
        !          130824:        }
        !          130825: 
        !          130826:        /*
        !          130827:         * Intercept driver open/close requests.
        !          130828:         * This allows the driver process to terminate after the last close,
        !          130829:         *      if one or more signals have been received.
        !          130830:         */
        !          130831:        openf           = con.c_open;
        !          130832:        closef          = con.c_close;
        !          130833:        con.c_open      = myopen;
        !          130834:        con.c_close     = myclose;
        !          130835: 
        !          130836:        /*
        !          130837:         * Install the loadable driver pseudo device interface.
        !          130838:         * The O/S will call the pseudo-device, which will call us.
        !          130839:         * Record our driver configuration and code segment.
        !          130840:         */
        !          130841:        drvl[mind].d_conp = &ldrvpsy;
        !          130842:        ldrvcon[mind] = &con;
        !          130843:        ldrvsel[mind] = ucs;
        !          130844: 
        !          130845:        /*
        !          130846:         * Load the device driver.
        !          130847:         */
        !          130848:        if ( con.c_load != NULL )
        !          130849:                (*con.c_load)( makedev(mind,0) );
        !          130850: 
        !          130851:        /*
        !          130852:         * Sleep until a kill signal has arrived, and no device is open.
        !          130853:         */
        !          130854:        do {
        !          130855:                sleep( (char *)&nopen, CVSWAP, IVSWAP, SVSWAP );
        !          130856: 
        !          130857:        } while ( ((SELF->p_ssig & 0x0100) == 0) || (nopen != 0) );
        !          130858: 
        !          130859:        /*
        !          130860:         * Unload the device driver.
        !          130861:         */
        !          130862:        if ( con.c_uload != NULL )
        !          130863:                (*con.c_uload)( makedev(mind,0) );
        !          130864: 
        !          130865:        /*
        !          130866:         * Erase references to our kernel process.
        !          130867:         */
        !          130868:        drvl[mind].d_conp = NULL;
        !          130869:        ldrvcon[mind] = NULL;
        !          130870:        ldrvsel[mind] = 0;
        !          130871: 
        !          130872:        /*
        !          130873:         * Scan looking for attached interrupts.
        !          130874:         * NOTE: This is to prevent dangling interrupt vectors.
        !          130875:         */
        !          130876:        for ( level = 0; level < 16; level++ ) {
        !          130877: 
        !          130878:                /*
        !          130879:                 * Interrupt is not attached to us.
        !          130880:                 */
        !          130881:                if ( ldrvics[level] != ucs )
        !          130882:                        continue;
        !          130883: 
        !          130884:                /*
        !          130885:                 * Disable interrupt.
        !          130886:                 */
        !          130887:                clrivec( level );
        !          130888: 
        !          130889:                /*
        !          130890:                 * Release loadable driver interrupt.
        !          130891:                 */
        !          130892:                ldrvics[level] = 0;
        !          130893:                ldrvipc[level] = NULL;
        !          130894:        }
        !          130895: 
        !          130896:        /*
        !          130897:         * Service deferred functions BEFORE scanning for timed functions.
        !          130898:         * This is in case a deferred function schedules a timed function.
        !          130899:         */
        !          130900:        kcall( Kdefend );
        !          130901: 
        !          130902:        /*
        !          130903:         * Scan for attached timed functions which have to be terminated.
        !          130904:         */
        !          130905:        for ( level = 0; level < nel(timq); level++ ) {
        !          130906:                register TIM * tp;
        !          130907: 
        !          130908:                /*
        !          130909:                 * Access a specific timing queue.
        !          130910:                 */
        !          130911:                for ( tp = timq[level]; tp != NULL; ) {
        !          130912: 
        !          130913:                        /*
        !          130914:                         * Timed function is in our loadable driver.
        !          130915:                         * Restart search at start of timing queue.
        !          130916:                         */
        !          130917:                        if ( FP_SEL(tp->t_ldrv) == getcs() ) {
        !          130918:                                timeout( tp, 0, NULL, 0 );
        !          130919:                                tp = timq[ level ];
        !          130920:                        }
        !          130921: 
        !          130922:                        /*
        !          130923:                         * Not one of our timed functions.
        !          130924:                         * Advance to next function in queue.
        !          130925:                         */
        !          130926:                        else
        !          130927:                                tp = tp->t_next;
        !          130928:                }
        !          130929:        }
        !          130930: 
        !          130931:        /*
        !          130932:         * Terminate with extreme prejudice.
        !          130933:         */
        !          130934:        uexit( 0 );
        !          130935: }
        !          130936: 
        !          130937: static void
        !          130938: myopen( dev, mode )
        !          130939: dev_t dev;
        !          130940: int mode;
        !          130941: {
        !          130942:        /*
        !          130943:         * Invoke the true open routine for the loadable driver.
        !          130944:         */
        !          130945:        if ( openf != NULL )
        !          130946:                (*openf)(dev, mode );
        !          130947: 
        !          130948:        /*
        !          130949:         * Adjust reference count if open succeeded.
        !          130950:         */
        !          130951:        if ( u.u_error == 0 )
        !          130952:                nopen++;
        !          130953: }
        !          130954: 
        !          130955: static void
        !          130956: myclose( dev )
        !          130957: dev_t dev;
        !          130958: {
        !          130959:        /*
        !          130960:         * Invoke the true close routine for the loadable driver.
        !          130961:         */
        !          130962:        if ( closef != NULL )
        !          130963:                (*closef)( dev );
        !          130964: 
        !          130965:        /*
        !          130966:         * Wakeup driver process after last close.
        !          130967:         * This allows it to terminate if appropriate.
        !          130968:         */
        !          130969:        if ( --nopen == 0 )
        !          130970:                wakeup( (char*) &nopen );
        !          130971: }
        !          130972: @
        !          130973: 
        !          130974: 
        !          130975: 1.1
        !          130976: log
        !          130977: @Initial revision
        !          130978: @
        !          130979: text
        !          130980: @d31 3
        !          130981: a33 3
        !          130982: #include <coherent.h>
        !          130983: #include <proc.h>
        !          130984: #include <sched.h>
        !          130985: @
        !          130986: 0707070064030105201004440000030000030000011777770507310745300005300000030345/newbits/kernel/USRSRC/ldrv/RCS/ldswap.c,vhead     1.2;
        !          130987: branch   ;
        !          130988: access   ;
        !          130989: symbols  ;
        !          130990: locks    bin:1.2; strict;
        !          130991: comment  @ * @;
        !          130992: 
        !          130993: 
        !          130994: 1.2
        !          130995: date     91.06.20.14.34.58;  author bin;  state Exp;
        !          130996: branches ;
        !          130997: next     1.1;
        !          130998: 
        !          130999: 1.1
        !          131000: date     91.06.10.10.43.21;  author bin;  state Exp;
        !          131001: branches ;
        !          131002: next     ;
        !          131003: 
        !          131004: 
        !          131005: desc
        !          131006: @initial version provided by stevesf 
        !          131007: @
        !          131008: 
        !          131009: 
        !          131010: 1.2
        !          131011: log
        !          131012: @update provided by hal
        !          131013: @
        !          131014: text
        !          131015: @/* $Header: /usr/src/sys/ldrv/RCS/ldswap.c,v 1.1 88/03/24 16:30:50 src Exp $ */
        !          131016: /* (lgl-
        !          131017:  *     The information contained herein is a trade secret of Mark Williams
        !          131018:  *     Company, and  is confidential information.  It is provided  under a
        !          131019:  *     license agreement,  and may be  copied or disclosed  only under the
        !          131020:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !          131021:  *     material without the express written authorization of Mark Williams
        !          131022:  *     Company or persuant to the license agreement is unlawful.
        !          131023:  *
        !          131024:  *     COHERENT Version 2.3.37
        !          131025:  *     Copyright (c) 1982, 1983, 1984.
        !          131026:  *     An unpublished work by Mark Williams Company, Chicago.
        !          131027:  *     All rights reserved.
        !          131028:  -lgl) */
        !          131029: /*
        !          131030:  * Coherent.
        !          131031:  * Swapper.
        !          131032:  *
        !          131033:  * $Log:       /usr/src/sys/ldrv/RCS/ldswap.c,v $
        !          131034:  * Revision 1.1        88/03/24  16:30:50      src
        !          131035:  * Initial revision
        !          131036:  * 
        !          131037:  * 87/11/05    Allan Cornish           /usr/src/sys/ldrv/ldswap.c
        !          131038:  * New seg struct now used to allow extended addressing.
        !          131039:  *
        !          131040:  * 87/10/26    Allan Cornish           /usr/src/sys/ldrv/ldswap.c
        !          131041:  * Modified to support loadable drivers - temporary modification.
        !          131042:  * Now requires SIGKILL signal in order to terminate.
        !          131043:  *
        !          131044:  * 87/01/05    Allan Cornish           /usr/src/sys/ker/swap.c
        !          131045:  * Swap() now waits for all processes to be swapped in before exit on signal.
        !          131046:  */
        !          131047: #include <sys/coherent.h>
        !          131048: #include <sys/proc.h>
        !          131049: #include <sys/sched.h>
        !          131050: #include <sys/seg.h>
        !          131051: #include <sys/uproc.h>
        !          131052: #include <sys/buf.h>
        !          131053: 
        !          131054: /*
        !          131055:  * Functions.
        !          131056:  */
        !          131057: SEG    *xmalloc();
        !          131058: SEG    *xdalloc();
        !          131059: void   Kwakeup();
        !          131060: void   Ktimeout();
        !          131061: 
        !          131062: main()
        !          131063: {
        !          131064:        register SEG *sp;
        !          131065:        register PROC *pp1;
        !          131066:        register PROC *pp2;
        !          131067:        register PROC *pp3;
        !          131068:        register unsigned s;
        !          131069:        register unsigned n;
        !          131070:        register unsigned t;
        !          131071:        register unsigned v;
        !          131072:        register unsigned m;
        !          131073:        register int i;
        !          131074:        static unsigned ltimer;
        !          131075: 
        !          131076:        if (sexflag != 0)
        !          131077:                uexit(1);
        !          131078:        sexflag++;
        !          131079: 
        !          131080:        while (1) {
        !          131081:                lock( pnxgate );
        !          131082:                t = (utimer - ltimer) / NSUTICK;
        !          131083:                v = t * SVCLOCK;
        !          131084:                ltimer += t * NSUTICK;
        !          131085: 
        !          131086:                /*
        !          131087:                 * Search for process to swap into memory.
        !          131088:                 */
        !          131089:                pp2 = NULL;
        !          131090:                m   = 0;
        !          131091:                s   = 0;
        !          131092:                for (pp1 = procq.p_nback; pp1 != &procq; pp1 = pp1->p_nback) {
        !          131093: 
        !          131094:                        /*
        !          131095:                         * Process resides in memory.
        !          131096:                         */
        !          131097:                        if ( (pp1->p_flags & PFCORE) != 0 ) {
        !          131098:                                pp1->p_sval >>= t;
        !          131099:                                pp1->p_ival  -= t;
        !          131100:                                if (pp1->p_ival < -30000)
        !          131101:                                        pp1->p_ival = -30000;
        !          131102:                                continue;
        !          131103:                        }
        !          131104: 
        !          131105:                        /*
        !          131106:                         * Update swap value - high values swapped in first.
        !          131107:                         */
        !          131108:                        addu( pp1->p_sval, v );
        !          131109:                        s = 1;
        !          131110: 
        !          131111:                        /*
        !          131112:                         * Process is not runnable.
        !          131113:                         */
        !          131114:                        if ( pp1->p_state != PSRUN )
        !          131115:                                continue;
        !          131116: 
        !          131117:                        /*
        !          131118:                         * Calculate disk usage in Kbytes.
        !          131119:                         */
        !          131120:                        s = 0;
        !          131121:                        for ( i = 0; i < NUSEG+1; i++ )
        !          131122:                                if ( (sp = pp1->p_segp[i]) != NULL )
        !          131123:                                        if ( (sp->s_flags & SFCORE) == 0 )
        !          131124:                                                s += sp->s_size / 1024;
        !          131125:                        if ( s == 0 )
        !          131126:                                s = 1;
        !          131127: 
        !          131128:                        /*
        !          131129:                         * Compute importance:
        !          131130:                         *
        !          131131:                         *      swap value + response value
        !          131132:                         *      ---------------------------
        !          131133:                         *        Kbytes to be swapped in
        !          131134:                         */
        !          131135:                        n = (pp1->p_sval + pp1->p_rval) / s;
        !          131136: 
        !          131137:                        /*
        !          131138:                         * More important.
        !          131139:                         */
        !          131140:                        if ( n > m ) {
        !          131141:                                m = n;
        !          131142:                                pp2 = pp1;
        !          131143:                        }
        !          131144:                }
        !          131145:                unlock( pnxgate );
        !          131146: 
        !          131147:                /*
        !          131148:                 * No runnable processes swapped out.
        !          131149:                 */
        !          131150:                if ( pp2 == NULL ) {
        !          131151:                        /*
        !          131152:                         * No processes swapped out, and KILL signal received.
        !          131153:                         */
        !          131154:                        if ( (s == 0) && (SELF->p_ssig & 0x0100) )
        !          131155:                                break;
        !          131156:                        goto con;
        !          131157:                }
        !          131158: 
        !          131159: #ifndef        NOMONITOR
        !          131160:                if (swmflag)
        !          131161:                        printf("Swapin(%p, %d)\n", pp2, pp2->p_pid);
        !          131162: #endif
        !          131163:        xxx:
        !          131164:                /*
        !          131165:                 * Try to swap process into memory.
        !          131166:                 */
        !          131167:                while ( (testcore(pp2) == 0) || (proccore(pp2) != 0) ) {
        !          131168: 
        !          131169:                        /*
        !          131170:                         * Swap process out.
        !          131171:                         */
        !          131172:                        procdisk(pp2);
        !          131173:                        i   = 32767;
        !          131174:                        pp3 = NULL;
        !          131175: 
        !          131176:                        /*
        !          131177:                         * Search for process to swap out.
        !          131178:                         */
        !          131179:                        lock( pnxgate );
        !          131180:                        for (pp1=procq.p_nforw; pp1!=&procq; pp1=pp1->p_nforw){
        !          131181: 
        !          131182:                                if ( pp1->p_flags & (PFSWIO|PFLOCK|PFKERN) )
        !          131183:                                        continue;
        !          131184: 
        !          131185:                                /*
        !          131186:                                 * Process is not totally memory resident.
        !          131187:                                 */
        !          131188:                                if ( (pp1->p_flags&PFCORE) == 0 ) {
        !          131189:                                        /*
        !          131190:                                         * Swap segments out to disk.
        !          131191:                                         */
        !          131192:                                        if ( procdisk(pp1) != 0 ) {
        !          131193:                                                unlock( pnxgate );
        !          131194:                                                goto xxx;
        !          131195:                                        }
        !          131196:                                        continue;
        !          131197:                                }
        !          131198: 
        !          131199:                                /*
        !          131200:                                 * Process too important to swap out.
        !          131201:                                 */
        !          131202:                                if ((pp1->p_ival > -64) && (pp1->p_sval != 0))
        !          131203:                                        continue;
        !          131204: 
        !          131205:                                /*
        !          131206:                                 * Less important.
        !          131207:                                 */
        !          131208:                                if ( pp1->p_ival < i ) {
        !          131209:                                        i = pp1->p_ival;
        !          131210:                                        pp3 = pp1;
        !          131211:                                }
        !          131212:                        }
        !          131213:                        unlock( pnxgate );
        !          131214: 
        !          131215:                        /*
        !          131216:                         * No processes to swap out.
        !          131217:                         */
        !          131218:                        if ( pp3 == NULL ) {
        !          131219: #ifndef NOMONITOR
        !          131220:                                if (swmflag)
        !          131221:                                        printf("No one to swap out\n");
        !          131222: #endif
        !          131223:                                break;
        !          131224:                        }
        !          131225: 
        !          131226:                        /*
        !          131227:                         * Process is too important to swap out.
        !          131228:                         */
        !          131229:                        if ( i > 0 ) {
        !          131230: #ifndef NOMONITOR
        !          131231:                                if (swmflag)
        !          131232:                                        printf("Dispatch(%p, %d)\n",
        !          131233:                                                pp3, pp3->p_pid);
        !          131234: #endif
        !          131235:                                pp3->p_flags |= PFDISP;
        !          131236:                                break;
        !          131237:                        }
        !          131238: #ifndef NOMONITOR
        !          131239:                        if (swmflag)
        !          131240:                                printf("Swapout(%p, %d)\n", pp3, pp3->p_pid);
        !          131241: #endif
        !          131242:                        /*
        !          131243:                         * Swap process out to disk.
        !          131244:                         */
        !          131245:                        procdisk( pp3 );
        !          131246:                }
        !          131247: 
        !          131248: #ifndef NOMONITOR
        !          131249:                if (swmflag)
        !          131250:                        printf("Swapdone\n");
        !          131251: #endif
        !          131252:        con:
        !          131253:                kcall( Ktimeout, &stimer, NSRTICK, Kwakeup, (char *)&stimer );
        !          131254:                sleep( (char *)&stimer, CVSWAP, IVSWAP, SVSWAP );
        !          131255:        }
        !          131256:        sexflag--;
        !          131257:        uexit( 1 );
        !          131258: }
        !          131259: 
        !          131260: /*
        !          131261:  * See if the given process may fit in core.
        !          131262:  */
        !          131263: testcore( pp )
        !          131264: register PROC *pp;
        !          131265: {
        !          131266:        register SEG *sp;
        !          131267:        register fsize_t s;
        !          131268:        register paddr_t s1;
        !          131269:        register paddr_t s2;
        !          131270:        register int i;
        !          131271: 
        !          131272:        /*
        !          131273:         * Find largest segment in process.
        !          131274:         */
        !          131275:        s = 0;
        !          131276:        for ( i = 0; i < NUSEG+1; i++ ) {
        !          131277: 
        !          131278:                if ( (sp = pp->p_segp[i]) == NULL )
        !          131279:                        continue;
        !          131280: 
        !          131281:                /*
        !          131282:                 * Segment is memory resident.
        !          131283:                 */
        !          131284:                if ( (sp->s_flags & SFCORE) != 0 )
        !          131285:                        continue;
        !          131286: 
        !          131287:                /*
        !          131288:                 * Largest segment so far.
        !          131289:                 */
        !          131290:                if ( sp->s_size > s )
        !          131291:                        s = sp->s_size;
        !          131292:        }
        !          131293: 
        !          131294:        /*
        !          131295:         * See if largest segment will fit in memory.
        !          131296:         */
        !          131297:        s1 = corebot;
        !          131298:        sp = &segmq;
        !          131299:        do {
        !          131300:                /*
        !          131301:                 * Advance to next memory segment.
        !          131302:                 */
        !          131303:                sp = sp->s_forw;
        !          131304:                s2 = sp->s_paddr;
        !          131305: 
        !          131306:                /*
        !          131307:                 * It fits!
        !          131308:                 */
        !          131309:                if ( s2 - s1 >= s )
        !          131310:                        return (1);
        !          131311: 
        !          131312:                /*
        !          131313:                 * Compute start of next hole.
        !          131314:                 */
        !          131315:                s1 = sp->s_paddr + sp->s_size;
        !          131316: 
        !          131317:        } while ( sp != &segmq );
        !          131318: 
        !          131319:        return( 0 );
        !          131320: }
        !          131321: 
        !          131322: /*
        !          131323:  * Swap all segments associated with a particular process into core.
        !          131324:  * The number of segments still swapped out is returned.
        !          131325:  */
        !          131326: proccore( pp )
        !          131327: register PROC *pp;
        !          131328: {
        !          131329:        register SEG *sp;
        !          131330:        register int i;
        !          131331:        register int n;
        !          131332:        register int f;
        !          131333: 
        !          131334:        f = pp->p_flags & PFSWAP;
        !          131335: 
        !          131336:        /*
        !          131337:         * Try to swap in all user segments and the auxiliary segment.
        !          131338:         */
        !          131339:        for ( n = 0, i = 0; i < NUSEG+1; i++ ) {
        !          131340: 
        !          131341:                if ( (sp = pp->p_segp[i]) == NULL )
        !          131342:                        continue;
        !          131343: 
        !          131344:                /*
        !          131345:                 * Process was swapped out.
        !          131346:                 */
        !          131347:                if ( f != 0 )
        !          131348:                        sp->s_lrefc++;
        !          131349: 
        !          131350:                /*
        !          131351:                 * Segment is disk resident - try to swap it in.
        !          131352:                 */
        !          131353:                if ( (sp->s_flags & SFCORE) == 0 )
        !          131354:                        if ( segcore(sp) == 0 )
        !          131355:                                n++;
        !          131356:        }
        !          131357: 
        !          131358:        /*
        !          131359:         * No segments left on disk - mark process as being memory resident.
        !          131360:         */
        !          131361:        if ( n == 0 )
        !          131362:                pp->p_flags |= PFCORE;
        !          131363: 
        !          131364:        /*
        !          131365:         * Mark process as no longer being disk resident.
        !          131366:         */
        !          131367:        pp->p_flags &= ~PFSWAP;
        !          131368: 
        !          131369:        return( n );
        !          131370: }
        !          131371: 
        !          131372: /*
        !          131373:  * Swap out all segments associated with a given process.
        !          131374:  */
        !          131375: procdisk( pp )
        !          131376: register PROC *pp;
        !          131377: {
        !          131378:        register SEG *sp;
        !          131379:        register int i;
        !          131380:        register int f;
        !          131381:        int n;
        !          131382: 
        !          131383:        f = pp->p_flags & PFSWAP;
        !          131384: 
        !          131385:        /*
        !          131386:         * Mark process as no longer being memory resident BEFORE swapping.
        !          131387:         */
        !          131388:        pp->p_flags &= ~PFCORE;
        !          131389: 
        !          131390:        /*
        !          131391:         * Try to swap out all user segments and the auxiliary segment.
        !          131392:         */
        !          131393:        for ( n = 0, i = 0; i < NUSEG+1; i++ ) {
        !          131394: 
        !          131395:                if ( (sp = pp->p_segp[i]) == NULL )
        !          131396:                        continue;
        !          131397: 
        !          131398:                /*
        !          131399:                 * Process not already swapped out.
        !          131400:                 */
        !          131401:                if ( f == 0 )
        !          131402:                        sp->s_lrefc--;
        !          131403: 
        !          131404:                /*
        !          131405:                 * Segment already swapped out.
        !          131406:                 */
        !          131407:                if ( (sp->s_flags & SFCORE) == 0 )
        !          131408:                        continue;
        !          131409: 
        !          131410:                /*
        !          131411:                 * Segment no longer referenced by a memory-resident process.
        !          131412:                 */
        !          131413:                if ( (sp->s_lrefc == 0) && (segdisk(sp) != 0) )
        !          131414:                        n++;
        !          131415:        }
        !          131416: 
        !          131417:        /*
        !          131418:         * Mark process as being disk resident.
        !          131419:         */
        !          131420:        pp->p_flags |= PFSWAP;
        !          131421: 
        !          131422:        return( n );
        !          131423: }
        !          131424: 
        !          131425: /*
        !          131426:  * Swap the given segment into core.
        !          131427:  * NOTE: Although swapped out, the segment may have a descriptor table entry,
        !          131428:  *      and therefore have a valid s_faddr field.
        !          131429:  */
        !          131430: segcore( sp1 )
        !          131431: register SEG *sp1;
        !          131432: {
        !          131433:        register SEG *sp2;
        !          131434: 
        !          131435:        /*
        !          131436:         * Lock segmentation.
        !          131437:         */
        !          131438:        lock( seglink );
        !          131439: 
        !          131440:        /*
        !          131441:         * Segment has been moved to memory while we waited to lock.
        !          131442:         */
        !          131443:        if ( (sp1->s_flags & SFCORE) != 0 ) {
        !          131444:                unlock(seglink);
        !          131445:                return( 1 );
        !          131446:        }
        !          131447: 
        !          131448:        /*
        !          131449:         * Allocate a memory segment sp2.
        !          131450:         */
        !          131451:        if ((sp2 = xmalloc( sp1->s_size )) == NULL ) {
        !          131452:                unlock( seglink );
        !          131453:                return( 0 );
        !          131454:        }
        !          131455: 
        !          131456:        /*
        !          131457:         * Copy the disk segment sp1 into the memory segment sp2.
        !          131458:         */
        !          131459:        sp1->s_lrefc++;
        !          131460:        swapio(0, sp2->s_paddr, sp1->s_daddr, sp2->s_size );
        !          131461:        sp1->s_lrefc--;
        !          131462: 
        !          131463:        /*
        !          131464:         * Remove segment sp1 from the disk queue.
        !          131465:         */
        !          131466:        sp1->s_back->s_forw = sp1->s_forw;
        !          131467:        sp1->s_forw->s_back = sp1->s_back;
        !          131468: 
        !          131469:        /*
        !          131470:         * Insert segment sp1 into memory queue replacing segment sp2.
        !          131471:         */
        !          131472:        sp2->s_back->s_forw = sp1;
        !          131473:        sp1->s_back = sp2->s_back;
        !          131474:        sp2->s_forw->s_back = sp1;
        !          131475:        sp1->s_forw = sp2->s_forw;
        !          131476: 
        !          131477:        /*
        !          131478:         * Enable access to memory segment sp1.
        !          131479:         */
        !          131480:        sp1->s_flags |= SFCORE;
        !          131481:        sp1->s_paddr = sp2->s_paddr;
        !          131482:        vremap( sp1 );
        !          131483: 
        !          131484:        /*
        !          131485:         * Unlock segmentation.
        !          131486:         */
        !          131487:        unlock( seglink );
        !          131488: 
        !          131489:        return( 1 );
        !          131490: }
        !          131491: 
        !          131492: /*
        !          131493:  * Swap the given segment out onto disk.
        !          131494:  */
        !          131495: segdisk( sp1 )
        !          131496: register SEG *sp1;
        !          131497: {
        !          131498:        register SEG *sp2;
        !          131499: 
        !          131500:        /*
        !          131501:         * Lock segmentation.
        !          131502:         */
        !          131503:        lock( seglink );
        !          131504: 
        !          131505:        /*
        !          131506:         * Verify segment sp1 did not become busy while we waited to lock.
        !          131507:         * IE: raw disk i/o, or shared code fork.
        !          131508:         */
        !          131509:        if ( sp1->s_lrefc != 0 ) {
        !          131510:                unlock( seglink );
        !          131511:                return( 0 );
        !          131512:        }
        !          131513: 
        !          131514:        /*
        !          131515:         * Segment has been moved to disk while we waited to lock.
        !          131516:         */
        !          131517:        if ( (sp1->s_flags & SFCORE) == 0 ) {
        !          131518:                unlock(seglink);
        !          131519:                return( 1 );
        !          131520:        }
        !          131521: 
        !          131522:        /*
        !          131523:         * Allocate a disk segment sp2.
        !          131524:         */
        !          131525:        if ( (sp2 = xdalloc( sp1->s_size )) == NULL ) {
        !          131526:                unlock( seglink );
        !          131527:                return( 0 );
        !          131528:        }
        !          131529: 
        !          131530:        /*
        !          131531:         * Disable access to memory segment sp1.
        !          131532:         */
        !          131533:        sp1->s_flags &= ~SFCORE;
        !          131534:        sp1->s_daddr = sp2->s_daddr;
        !          131535:        vremap( sp1 );
        !          131536: 
        !          131537:        /*
        !          131538:         * Copy the memory segment sp1 into the disk segment sp2.
        !          131539:         */
        !          131540:        sp1->s_lrefc++;
        !          131541:        swapio( 1, sp1->s_paddr, sp2->s_daddr, sp1->s_size );
        !          131542:        sp1->s_lrefc--;
        !          131543: 
        !          131544:        /*
        !          131545:         * Remove segment sp1 from the memory queue.
        !          131546:         */
        !          131547:        sp1->s_back->s_forw = sp1->s_forw;
        !          131548:        sp1->s_forw->s_back = sp1->s_back;
        !          131549: 
        !          131550:        /*
        !          131551:         * Insert segment sp1 into disk queue replacing segment sp2.
        !          131552:         */
        !          131553:        sp2->s_back->s_forw = sp1;
        !          131554:        sp1->s_back = sp2->s_back;
        !          131555:        sp2->s_forw->s_back = sp1;
        !          131556:        sp1->s_forw = sp2->s_forw;
        !          131557: 
        !          131558:        /*
        !          131559:         * Unlock segmentation.
        !          131560:         */
        !          131561:        unlock( seglink );
        !          131562: 
        !          131563:        return( 1 );
        !          131564: }
        !          131565: 
        !          131566: /*
        !          131567:  * Allocate a segment on disk that is `n' bytes long.
        !          131568:  * The `seglink' gate should be locked before this routine is called.
        !          131569:  * This routine is the same as `sdalloc' except that we can't run out of
        !          131570:  * alloc space to allocate the segment and we allocate in high regions.
        !          131571:  * NOTE: descriptor table entries are not released.
        !          131572:  */
        !          131573: SEG *
        !          131574: xdalloc( s )
        !          131575: fsize_t s;
        !          131576: {
        !          131577:        register SEG *sp1;
        !          131578:        register SEG *sp2;
        !          131579:        register daddr_t d;
        !          131580:        register daddr_t d1;
        !          131581:        register daddr_t d2;
        !          131582: 
        !          131583:        d  = s / BSIZE;
        !          131584:        d2 = swaptop;
        !          131585:        sp1 = &segdq;
        !          131586:        do {
        !          131587:                if ( (sp1 = sp1->s_back) != &segdq )
        !          131588:                        d1 = sp1->s_daddr + (sp1->s_size / BSIZE);
        !          131589:                else
        !          131590:                        d1 = swapbot;
        !          131591: 
        !          131592:                if ( d2 - d1 >= d ) {
        !          131593:                        sp2 = &segswap;
        !          131594:                        kclear( (char *)sp2, sizeof(SEG) );
        !          131595:                        sp1->s_forw->s_back = sp2;
        !          131596:                        sp2->s_forw  = sp1->s_forw;
        !          131597:                        sp1->s_forw  = sp2;
        !          131598:                        sp2->s_back  = sp1;
        !          131599:                        sp2->s_urefc = 1;
        !          131600:                        sp2->s_lrefc = 1;
        !          131601:                        sp2->s_size  = s;
        !          131602:                        sp2->s_daddr = d2 - d;
        !          131603:                        return( sp2 );
        !          131604:                }
        !          131605: 
        !          131606:                d2 = sp1->s_daddr;
        !          131607: 
        !          131608:        } while ( sp1 != &segdq );
        !          131609: 
        !          131610:        return( NULL );
        !          131611: }
        !          131612: 
        !          131613: /*
        !          131614:  * Allocate a segment in memory that is `n' bytes long.
        !          131615:  * The `seglink' gate should be locked before this routine is called.
        !          131616:  * This routine is the same as `smalloc' except that we can't run out of
        !          131617:  * alloc space to allocate the segment.
        !          131618:  * NOTE: Do NOT remap virtual descriptor table entry.
        !          131619:  *      This is a scratch entry, and the s_faddr field is not retained.
        !          131620:  */
        !          131621: SEG *
        !          131622: xmalloc( s )
        !          131623: register fsize_t s;
        !          131624: {
        !          131625:        register SEG *sp1;
        !          131626:        register SEG *sp2;
        !          131627:        register paddr_t s1;
        !          131628:        register paddr_t s2;
        !          131629: 
        !          131630:        s1  = corebot;
        !          131631:        sp1 = &segmq;
        !          131632:        do {
        !          131633:                if ( (sp1 = sp1->s_forw) != &segmq )
        !          131634:                        s2 = sp1->s_paddr;
        !          131635:                else
        !          131636:                        s2 = coretop;
        !          131637: 
        !          131638:                if ( s2 - s1 >= s ) {
        !          131639:                        sp2 = &segswap;
        !          131640:                        kclear( (char *)sp2, sizeof(SEG) );
        !          131641:                        sp1->s_back->s_forw = sp2;
        !          131642:                        sp2->s_back = sp1->s_back;
        !          131643:                        sp1->s_back = sp2;
        !          131644:                        sp2->s_forw = sp1;
        !          131645:                        sp2->s_urefc = 1;
        !          131646:                        sp2->s_lrefc = 1;
        !          131647:                        sp2->s_size  = s;
        !          131648:                        sp2->s_paddr = s1;
        !          131649:                        return( sp2 );
        !          131650:                }
        !          131651: 
        !          131652:                s1 = sp1->s_paddr + sp1->s_size;
        !          131653: 
        !          131654:        } while ( sp1 != &segmq );
        !          131655: 
        !          131656:        return( NULL );
        !          131657: }
        !          131658: @
        !          131659: 
        !          131660: 
        !          131661: 1.1
        !          131662: log
        !          131663: @Initial revision
        !          131664: @
        !          131665: text
        !          131666: @d33 3
        !          131667: a35 3
        !          131668: #include <coherent.h>
        !          131669: #include <proc.h>
        !          131670: #include <sched.h>
        !          131671: @
        !          131672: 0707070064030105051004440000030000030000011777770507310745600005400000001351/newbits/kernel/USRSRC/ldrv/RCS/nonedev.c,vhead     1.2;
        !          131673: branch   ;
        !          131674: access   ;
        !          131675: symbols  ;
        !          131676: locks    bin:1.2; strict;
        !          131677: comment  @ * @;
        !          131678: 
        !          131679: 
        !          131680: 1.2
        !          131681: date     91.06.20.14.35.11;  author bin;  state Exp;
        !          131682: branches ;
        !          131683: next     1.1;
        !          131684: 
        !          131685: 1.1
        !          131686: date     91.06.10.10.43.25;  author bin;  state Exp;
        !          131687: branches ;
        !          131688: next     ;
        !          131689: 
        !          131690: 
        !          131691: desc
        !          131692: @initial version provided by stevesf 
        !          131693: @
        !          131694: 
        !          131695: 
        !          131696: 1.2
        !          131697: log
        !          131698: @update provided by hal
        !          131699: @
        !          131700: text
        !          131701: @/* $Header: /usr/src/sys/ldrv/RCS/nonedev.c,v 1.1 88/03/24 16:30:54 src Exp $ */
        !          131702: 
        !          131703: /*
        !          131704:  * $Log:       /usr/src/sys/ldrv/RCS/nonedev.c,v $
        !          131705:  * Revision 1.1        88/03/24  16:30:54      src
        !          131706:  * Initial revision
        !          131707:  * 
        !          131708:  */
        !          131709: #include <sys/coherent.h>
        !          131710: #include <sys/uproc.h>
        !          131711: #include <errno.h>
        !          131712: 
        !          131713: /*
        !          131714:  * Non existant device.
        !          131715:  */
        !          131716: nonedev()
        !          131717: {
        !          131718:        u.u_error = ENXIO;
        !          131719: }
        !          131720: @
        !          131721: 
        !          131722: 
        !          131723: 1.1
        !          131724: log
        !          131725: @Initial revision
        !          131726: @
        !          131727: text
        !          131728: @d9 1
        !          131729: a9 1
        !          131730: #include <coherent.h>
        !          131731: @
        !          131732: 0707070064030105041004440000030000030000011777770507310745600005400000001150/newbits/kernel/USRSRC/ldrv/RCS/nulldev.c,vhead     1.2;
        !          131733: branch   ;
        !          131734: access   ;
        !          131735: symbols  ;
        !          131736: locks    bin:1.2; strict;
        !          131737: comment  @ * @;
        !          131738: 
        !          131739: 
        !          131740: 1.2
        !          131741: date     91.06.20.14.35.14;  author bin;  state Exp;
        !          131742: branches ;
        !          131743: next     1.1;
        !          131744: 
        !          131745: 1.1
        !          131746: date     91.06.10.10.43.26;  author bin;  state Exp;
        !          131747: branches ;
        !          131748: next     ;
        !          131749: 
        !          131750: 
        !          131751: desc
        !          131752: @initial version provided by stevesf 
        !          131753: @
        !          131754: 
        !          131755: 
        !          131756: 1.2
        !          131757: log
        !          131758: @update provided by hal
        !          131759: @
        !          131760: text
        !          131761: @/* $Header: /usr/src/sys/ldrv/RCS/nulldev.c,v 1.1 88/03/24 16:30:57 src Exp $ */
        !          131762: /*
        !          131763:  * $Log:       /usr/src/sys/ldrv/RCS/nulldev.c,v $
        !          131764:  * Revision 1.1        88/03/24  16:30:57      src
        !          131765:  * Initial revision
        !          131766:  * 
        !          131767:  */
        !          131768: 
        !          131769: /*
        !          131770:  * Null device.
        !          131771:  */
        !          131772: nulldev()
        !          131773: {
        !          131774: }
        !          131775: @
        !          131776: 
        !          131777: 
        !          131778: 1.1
        !          131779: log
        !          131780: @Initial revision
        !          131781: @
        !          131782: text
        !          131783: @@
        !          131784: 0707070064030105171004440000030000030000011777770507310745600005400000005153/newbits/kernel/USRSRC/ldrv/RCS/setivec.c,vhead     1.2;
        !          131785: branch   ;
        !          131786: access   ;
        !          131787: symbols  ;
        !          131788: locks    bin:1.2; strict;
        !          131789: comment  @ * @;
        !          131790: 
        !          131791: 
        !          131792: 1.2
        !          131793: date     91.06.20.14.35.19;  author bin;  state Exp;
        !          131794: branches ;
        !          131795: next     1.1;
        !          131796: 
        !          131797: 1.1
        !          131798: date     91.06.10.10.43.27;  author bin;  state Exp;
        !          131799: branches ;
        !          131800: next     ;
        !          131801: 
        !          131802: 
        !          131803: desc
        !          131804: @initial version provided by stevesf 
        !          131805: @
        !          131806: 
        !          131807: 
        !          131808: 1.2
        !          131809: log
        !          131810: @update provided by hal
        !          131811: @
        !          131812: text
        !          131813: @/* $Header: /usr/src/sys/ldrv/RCS/setivec.c,v 1.1 88/03/24 16:31:02 src Exp $ */
        !          131814: /*
        !          131815:  *     The  information  contained herein  is a trade secret  of INETCO
        !          131816:  *     Systems, and is confidential information.   It is provided under
        !          131817:  *     a license agreement,  and may be copied or disclosed  only under
        !          131818:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          131819:  *     this  material  without  the express  written  authorization  of
        !          131820:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          131821:  *
        !          131822:  *     Copyright (c) 1987
        !          131823:  *     An unpublished work by INETCO Systems, Ltd.
        !          131824:  *     All rights reserved.
        !          131825:  */
        !          131826: 
        !          131827: /*
        !          131828:  * Loadable Driver - Enable/Disable Interrupts.
        !          131829:  *
        !          131830:  * $Log:       /usr/src/sys/ldrv/RCS/setivec.c,v $
        !          131831:  * Revision 1.1        88/03/24  16:31:02      src
        !          131832:  * Initial revision
        !          131833:  * 
        !          131834:  * 87/12/03    Allan Cornish           /usr/src/sys/ldrv/setivec.c
        !          131835:  * Initial version.
        !          131836:  */
        !          131837: #include <sys/coherent.h>
        !          131838: #include <errno.h>
        !          131839: #include <sys/con.h>
        !          131840: #include <sys/uproc.h>
        !          131841: 
        !          131842: /*
        !          131843:  * Interrupt entry points [within kernel] for loadable drivers.
        !          131844:  */
        !          131845: extern void (*ldrvint[16])();
        !          131846: 
        !          131847: /*
        !          131848:  * Interrupt handlers [within driver] for loadable drivers.
        !          131849:  *     ldrvics[n]:     Interrupt handler code segment.
        !          131850:  *     ldrvipc[n]:     Interrupt handler program counter.
        !          131851:  */
        !          131852: extern saddr_t ldrvics[16];
        !          131853: extern void  (*ldrvipc[16])();
        !          131854: 
        !          131855: setivec( level, func )
        !          131856: int level;
        !          131857: void (*func)();
        !          131858: {
        !          131859:        extern void Ksetivec();
        !          131860:        extern saddr_t ucs;
        !          131861: 
        !          131862:        u.u_error = 0;
        !          131863:        level &= 15;
        !          131864: 
        !          131865:        /*
        !          131866:         * Ensure interrupt is not already in use.
        !          131867:         */
        !          131868:        if ( (ldrvics[level] != 0) || (ldrvipc[level] != NULL) ) {
        !          131869:                u.u_error = EDBUSY;
        !          131870:                return;
        !          131871:        }
        !          131872: 
        !          131873:        /*
        !          131874:         * Record interrupt function BEFORE enabling interrupt.
        !          131875:         */
        !          131876:        ldrvipc[level] = func;
        !          131877:        ldrvics[level] = ucs;
        !          131878: 
        !          131879:        /*
        !          131880:         * Attempt to enable interrupt.
        !          131881:         */
        !          131882:        kcall( Ksetivec, level, ldrvint[level] );
        !          131883: 
        !          131884:        /*
        !          131885:         * Interrupt is in use by a resident driver.
        !          131886:         */
        !          131887:        if ( u.u_error ) {
        !          131888:                ldrvipc[level] = NULL;
        !          131889:                ldrvics[level] = 0;
        !          131890:        }
        !          131891: }
        !          131892: 
        !          131893: clrivec( level )
        !          131894: register int level;
        !          131895: {
        !          131896:        extern void Kclrivec();
        !          131897:        extern saddr_t ucs;
        !          131898: 
        !          131899:        level &= 15;
        !          131900: 
        !          131901:        /*
        !          131902:         * Ensure interrupt belongs to our process.
        !          131903:         */
        !          131904:        if ( ldrvics[level] != ucs ) {
        !          131905:                u.u_error = EPERM;
        !          131906:                return;
        !          131907:        }
        !          131908: 
        !          131909:        /*
        !          131910:         * Disable interrupt.
        !          131911:         */
        !          131912:        kcall( Kclrivec, level );
        !          131913: 
        !          131914:        /*
        !          131915:         * Erase interrupt function AFTER disabling interrupt.
        !          131916:         */
        !          131917:        ldrvipc[level] = NULL;
        !          131918:        ldrvics[level] = 0;
        !          131919: }
        !          131920: @
        !          131921: 
        !          131922: 
        !          131923: 1.1
        !          131924: log
        !          131925: @Initial revision
        !          131926: @
        !          131927: text
        !          131928: @d25 1
        !          131929: a25 1
        !          131930: #include <coherent.h>
        !          131931: @
        !          131932: 0707070064030105111004440000030000030000011777770507310745700005400000004264/newbits/kernel/USRSRC/ldrv/RCS/timeout.c,vhead     1.2;
        !          131933: branch   ;
        !          131934: access   ;
        !          131935: symbols  ;
        !          131936: locks    bin:1.2; strict;
        !          131937: comment  @ * @;
        !          131938: 
        !          131939: 
        !          131940: 1.2
        !          131941: date     91.06.20.14.35.45;  author bin;  state Exp;
        !          131942: branches ;
        !          131943: next     1.1;
        !          131944: 
        !          131945: 1.1
        !          131946: date     91.06.10.10.43.28;  author bin;  state Exp;
        !          131947: branches ;
        !          131948: next     ;
        !          131949: 
        !          131950: 
        !          131951: desc
        !          131952: @initial version provided by stevesf 
        !          131953: @
        !          131954: 
        !          131955: 
        !          131956: 1.2
        !          131957: log
        !          131958: @update provided by hal
        !          131959: @
        !          131960: text
        !          131961: @/* $Header: /usr/src/sys/ldrv/RCS/timeout.c,v 1.1 88/03/24 16:31:21 src Exp $ */
        !          131962: /*
        !          131963:  *     The  information  contained herein  is a trade secret  of INETCO
        !          131964:  *     Systems, and is confidential information.   It is provided under
        !          131965:  *     a license agreement,  and may be copied or disclosed  only under
        !          131966:  *     the terms of that agreement.   Any reproduction or disclosure of
        !          131967:  *     this  material  without  the express  written  authorization  of
        !          131968:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !          131969:  *
        !          131970:  *     Copyright (c) 1987
        !          131971:  *     An unpublished work by INETCO Systems, Ltd.
        !          131972:  *     All rights reserved.
        !          131973:  */
        !          131974: 
        !          131975: /*
        !          131976:  * Loadable Driver - Timed functions.
        !          131977:  *
        !          131978:  * $Log:       /usr/src/sys/ldrv/RCS/timeout.c,v $
        !          131979:  * Revision 1.1        88/03/24  16:31:21      src
        !          131980:  * Initial revision
        !          131981:  * 
        !          131982:  * 87/12/08    Allan Cornish   /usr/src/sys/ldrv/timeout.c
        !          131983:  * Timed loadable driver functions now supported.
        !          131984:  */
        !          131985: #include <sys/coherent.h>
        !          131986: 
        !          131987: /*
        !          131988:  * External functions.
        !          131989:  */
        !          131990: extern void Ktimeout();
        !          131991: extern void Kldtimcall();
        !          131992: extern saddr_t getcs();
        !          131993: 
        !          131994: /*
        !          131995:  * Given a pointer to a timeout structure, `tp', call the function `f'
        !          131996:  * with integer argument `a' in `n' ticks of the clock. The list is
        !          131997:  * searched to see if the specified timeout structure is already in a
        !          131998:  * list, and it is removed if already there.
        !          131999:  * This module is specific to loadable drivers.
        !          132000:  */
        !          132001: timeout( tp, n, f, a )
        !          132002: register TIM * tp;
        !          132003: int n;
        !          132004: void (*f)();
        !          132005: int a;
        !          132006: {
        !          132007:        register int s;
        !          132008: 
        !          132009:        /*
        !          132010:         * Cancel existing timer.
        !          132011:         */
        !          132012:        if ( (f == NULL) || (n <= 0) ) {
        !          132013:                kcall( Ktimeout, tp, 0, NULL, 0 );
        !          132014:                return;
        !          132015:        }
        !          132016: 
        !          132017:        /*
        !          132018:         * Define loadable driver interface.
        !          132019:         * Kldtimcall will be invoked when timeout occurs.
        !          132020:         * It will in turn invoke FP_SEL(tp->t_ldrv):4,
        !          132021:         *      passing FP_OFF(tp->t_ldrv) in AX.
        !          132022:         */
        !          132023:        s = sphi();
        !          132024:        FP_SEL(tp->t_ldrv) = getcs();
        !          132025:        FP_OFF(tp->t_ldrv) = f;
        !          132026:        kcall( Ktimeout, tp, n, Kldtimcall, a );
        !          132027:        spl(s);
        !          132028: }
        !          132029: @
        !          132030: 
        !          132031: 
        !          132032: 1.1
        !          132033: log
        !          132034: @Initial revision
        !          132035: @
        !          132036: text
        !          132037: @d25 1
        !          132038: a25 1
        !          132039: #include <coherent.h>
        !          132040: @
        !          132041: 0707070064030105001005550000030000030000011777770507310745700005700000001021/newbits/kernel/USRSRC/ldrv/RCS/mkstub.sh.ob,vhead     1.1;
        !          132042: branch   ;
        !          132043: access   ;
        !          132044: symbols  ;
        !          132045: locks    bin:1.1; strict;
        !          132046: comment  @@;
        !          132047: 
        !          132048: 
        !          132049: 1.1
        !          132050: date     91.06.10.10.43.29;  author bin;  state Exp;
        !          132051: branches ;
        !          132052: next     ;
        !          132053: 
        !          132054: 
        !          132055: desc
        !          132056: @initial version provided by stevesf 
        !          132057: @
        !          132058: 
        !          132059: 
        !          132060: 
        !          132061: 1.1
        !          132062: log
        !          132063: @Initial revision
        !          132064: @
        !          132065: text
        !          132066: @: 'Created by Makefile - do not edit.'; set -e; ENTRY=`basename $1`;( echo ".globl ${ENTRY}_"; echo "${ENTRY}_: mov ax,\$K${ENTRY}_"; echo .byte 0x9A; echo .word xcalled; echo .word 0x0060; echo ret;)>/tmp/$$.s; as -gxo /tmp/$$.o /tmp/$$.s; mv /tmp/$$.o $1.o; rm -f /tmp/$$.s
        !          132067: @
        !          132068: 0707070064030104771005550000030000030000011777770507310745700005400000001024/newbits/kernel/USRSRC/ldrv/RCS/mkstub.sh,vhead     1.1;
        !          132069: branch   ;
        !          132070: access   ;
        !          132071: symbols  ;
        !          132072: locks    bin:1.1; strict;
        !          132073: comment  @# @;
        !          132074: 
        !          132075: 
        !          132076: 1.1
        !          132077: date     91.06.10.10.43.30;  author bin;  state Exp;
        !          132078: branches ;
        !          132079: next     ;
        !          132080: 
        !          132081: 
        !          132082: desc
        !          132083: @initial version provided by stevesf 
        !          132084: @
        !          132085: 
        !          132086: 
        !          132087: 
        !          132088: 1.1
        !          132089: log
        !          132090: @Initial revision
        !          132091: @
        !          132092: text
        !          132093: @set -e
        !          132094: ENTRY=`basename $1`
        !          132095: (                                                      \
        !          132096:        echo ".globl ${ENTRY}_";                        \
        !          132097:        echo "${ENTRY}_: mov ax,\$K${ENTRY}_";          \
        !          132098:        echo .byte 0x9A;                                \
        !          132099:        echo .word xcalled;                             \
        !          132100:        echo .word 0x0060;                              \
        !          132101:        echo ret;                                       \
        !          132102: ) > /tmp/$$.s
        !          132103: as -gxo /tmp/$$.o /tmp/$$.s
        !          132104: mv /tmp/$$.o $1.o
        !          132105: rm -f /tmp/$$.s
        !          132106: @
        !          132107: 0707070064030105211004440000030000030000011777770507310746000005300000002443/newbits/kernel/USRSRC/ldrv/RCS/ldconfig,vhead     1.1;
        !          132108: branch   ;
        !          132109: access   ;
        !          132110: symbols  ;
        !          132111: locks    bin:1.1; strict;
        !          132112: comment  @# @;
        !          132113: 
        !          132114: 
        !          132115: 1.1
        !          132116: date     91.06.20.14.34.20;  author bin;  state Exp;
        !          132117: branches ;
        !          132118: next     ;
        !          132119: 
        !          132120: 
        !          132121: desc
        !          132122: @provided by hal to use relative paths
        !          132123: @
        !          132124: 
        !          132125: 
        !          132126: 
        !          132127: 1.1
        !          132128: log
        !          132129: @Initial revision
        !          132130: @
        !          132131: text
        !          132132: @: '$Header: /usr/src/sys/ldrv/RCS/ldconfig,v 1.1 88/04/04 16:59:20 src Exp $'
        !          132133: :
        !          132134: :      configure a loadable driver
        !          132135: :
        !          132136: : usage: ldconfig [swap] [DRV ...]
        !          132137: :
        !          132138: BUILD=0
        !          132139: DEV=/tmp/dev
        !          132140: PATCH=""
        !          132141: UNDEF=""
        !          132142: LDMOD=""
        !          132143: PASS1=""
        !          132144: 
        !          132145: for ARG in $*
        !          132146: do
        !          132147:        case "${ARG}" in
        !          132148:        DEV\=*)
        !          132149:                DEV=`/bin/echo "${ARG}" | /bin/sed -e 's/^....//'`
        !          132150:                ;;
        !          132151:        *)
        !          132152:                PASS1="${PASS1} ${ARG}"
        !          132153:                ;;
        !          132154:        esac
        !          132155: done
        !          132156: 
        !          132157: for ARG in ${PASS1}
        !          132158: do
        !          132159:        case "$ARG" in
        !          132160: 
        !          132161:        swap)
        !          132162:                /bin/echo "ldrv/swap: "
        !          132163:                ld -r -o ldrv/swap lib/ldrts0.o lib/ldswap.o lib/ldlib.a
        !          132164:                LDMOD=""
        !          132165:                ;;
        !          132166: 
        !          132167:        *\=*)
        !          132168:                LDMOD="${LDMOD} ${ARG}"
        !          132169:                ;;
        !          132170: 
        !          132171:        *)
        !          132172:                case "${ARG}" in
        !          132173:                *[0123][abcdx])
        !          132174:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          132175:                        ;;
        !          132176:                *)
        !          132177:                        FILE="${ARG}"
        !          132178:                        ;;
        !          132179:                esac
        !          132180: 
        !          132181:                /bin/echo "ldrv/${FILE}: "
        !          132182:                if /bin/test -r confdrv/${FILE}
        !          132183:                then
        !          132184:                        UNDEF=""
        !          132185:                        . confdrv/${FILE}
        !          132186:                        /bin/ld -r -o ldrv/${FILE} lib/ldrts0.o \
        !          132187:                                lib/ldmain.o ${UNDEF} \
        !          132188:                                lib/ldlib.a || exit 1
        !          132189:                        case "${LDMOD}" in
        !          132190:                        "")     ;;
        !          132191:                        *)      /conf/patch ldrv/${FILE} ${LDMOD}
        !          132192:                        esac
        !          132193:                else
        !          132194:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          132195:                        exit 1
        !          132196:                fi
        !          132197:                LDMOD=""
        !          132198:                ;;
        !          132199:        esac
        !          132200: done
        !          132201: @
        !          132202: 0707070064030111110407770000000000000000011777770507310746000004400000000000/newbits/kernel/USRSRC/ldrv/objects0707070064030114121006440000030000030000011777770507310746000004600000000176/newbits/kernel/USRSRC/ldrv/mkstub.m4define(sym, substr(basename, -2, ))dnl
        !          132203:        .globl  sym`_'
        !          132204: sym`_':        mov     ax,`$K'sym`_'
        !          132205:        .byte   0x9A
        !          132206:        .word   xcalled
        !          132207:        .word   0x0060
        !          132208:        ret
        !          132209: 0707070064030057020407550000030000030000011777770507310746000002700000000000/newbits/kernel/USRSYS0707070064030110601006440000030000030000011777770507310746000004000000014223/newbits/kernel/USRSYS/Makefile# $Header: /newbits/kernel/USRSYS/RCS/Makefile,v 1.6 91/07/24 08:05:32 bin Exp Locker: bin $
        !          132210: #
        !          132211: # Makefile for ibm specific coherent sources and coherent images.
        !          132212: #
        !          132213: # Requires environment variables
        !          132214: #      USRSYS (e.g. /usr/sys)
        !          132215: #      USRSRC (e.g. /usr/src/sys)
        !          132216: #      KOBJ (e.g. /usr/kobj)
        !          132217: #
        !          132218: # $Log:        Makefile,v $
        !          132219: # Revision 1.6  91/07/24  08:05:32  bin
        !          132220: # update prov by hal
        !          132221: #
        !          132222: # Revision 1.3 89/06/30  16:26:39      src
        !          132223: # Bug: Lack of DMA lock resulted in failed transfers between SCSI drive
        !          132224: #      and floppy disk.
        !          132225: # Fix: Added dma lock routines to insure single DMA transfer. (JHB)
        !          132226: # 
        !          132227: # Revision 1.1 88/03/24  17:33:15      src
        !          132228: # Initial revision
        !          132229: # 
        !          132230: 
        !          132231: # Include directories
        !          132232: USRINC=/usr/include
        !          132233: SYSINC=/usr/include/sys
        !          132234: 
        !          132235: # Source directories
        !          132236: COHSRC=$(USRSRC)/coh
        !          132237: DRVSRC=$(USRSRC)/i8086/drv
        !          132238: I86SRC=$(USRSRC)/i8086/src
        !          132239: IBMATSRC=$(USRSRC)/i8086/ibm_at
        !          132240: KERSRC=$(USRSRC)/ker
        !          132241: TTYSRC=$(USRSRC)/ttydrv
        !          132242: 
        !          132243: # Library directory
        !          132244: DRVLIB=$(USRSYS)/lib
        !          132245: 
        !          132246: # Compiler stuff
        !          132247: CC=exec /bin/cc
        !          132248: CFLAGS=
        !          132249: 
        !          132250: HERE=  $(KOBJ)/md2.o \
        !          132251:        $(KOBJ)/dmac.o \
        !          132252:        $(KOBJ)/pccon.o \
        !          132253:        $(KOBJ)/console.o \
        !          132254:        $(KOBJ)/dmareq.o \
        !          132255:        $(KOBJ)/mmu.o \
        !          132256:        $(KOBJ)/support.o
        !          132257: 
        !          132258: DOTDOT=        $(KOBJ)/alloc.o \
        !          132259:        $(KOBJ)/as1.o \
        !          132260:        $(KOBJ)/bio.o \
        !          132261:        $(KOBJ)/clist.o \
        !          132262:        $(KOBJ)/clock.o \
        !          132263:        $(KOBJ)/ct.o \
        !          132264:        $(KOBJ)/defer.o \
        !          132265:        $(KOBJ)/dmalock.o       \
        !          132266:        $(KOBJ)/exec.o \
        !          132267:        $(KOBJ)/fd.o \
        !          132268:        $(KOBJ)/fs1.o $(KOBJ)/fs2.o $(KOBJ)/fs3.o \
        !          132269:        $(KOBJ)/krunch.o \
        !          132270:        $(KOBJ)/ld.o $(KOBJ)/ldas.o \
        !          132271:        $(KOBJ)/main.o \
        !          132272:        $(KOBJ)/md1.o \
        !          132273:        $(KOBJ)/misc.o \
        !          132274:        $(KOBJ)/mmain.o \
        !          132275:        $(KOBJ)/null.o \
        !          132276:        $(KOBJ)/pipe.o \
        !          132277:        $(KOBJ)/poll.o \
        !          132278:        $(KOBJ)/printf.o \
        !          132279:        $(KOBJ)/proc.o \
        !          132280:        $(KOBJ)/seg.o \
        !          132281:        $(KOBJ)/sig.o \
        !          132282:        $(KOBJ)/sys1.o $(KOBJ)/sys2.o $(KOBJ)/sys3.o \
        !          132283:        $(KOBJ)/tab.o \
        !          132284:        $(KOBJ)/timeout.o \
        !          132285:        $(KOBJ)/trap.o \
        !          132286:        $(KOBJ)/var.o
        !          132287: 
        !          132288: kernel:        $(KOBJ) $(USRSYS)/atkernel.o $(DRVLIB)/support.a $(DRVLIB)/tty.a
        !          132289:        @exec /bin/sync
        !          132290: 
        !          132291: shrink:
        !          132292:        rm -f $(KOBJ)/* $(KOBJ)/* $(KOBJ)/*
        !          132293: 
        !          132294: $(KOBJ)/pccon.o: \
        !          132295:        $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          132296:                                $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          132297:                                $(SYSINC)/fun.h \
        !          132298:        $(SYSINC)/con.h         \
        !          132299:        $(USRINC)/mtype.h       \
        !          132300:        $(SYSINC)/stat.h        \
        !          132301:        $(DRVSRC)/pccon.c
        !          132302:        $(CC) $(CFLAGS) -c -o $@ $(DRVSRC)/pccon.c
        !          132303: 
        !          132304: $(KOBJ)/console.o:     \
        !          132305:        $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          132306:                                $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          132307:                                $(SYSINC)/fun.h \
        !          132308:        $(SYSINC)/con.h         \
        !          132309:        $(SYSINC)/inode.h       \
        !          132310:        $(SYSINC)/io.h          \
        !          132311:        $(SYSINC)/stat.h        \
        !          132312:        $(DRVSRC)/console.c
        !          132313:        $(CC) $(CFLAGS) -c -o $@ $(DRVSRC)/console.c
        !          132314: 
        !          132315: $(KOBJ)/dmareq.o:      \
        !          132316:        $(SYSINC)/buf.h         \
        !          132317:        $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          132318:                                $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          132319:                                $(SYSINC)/fun.h \
        !          132320:        $(SYSINC)/con.h         \
        !          132321:        $(SYSINC)/dmac.h        \
        !          132322:        $(USRINC)/errno.h       \
        !          132323:        $(SYSINC)/io.h          \
        !          132324:        $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          132325:        $(SYSINC)/sched.h       \
        !          132326:        $(SYSINC)/seg.h         \
        !          132327:        $(SYSINC)/stat.h        \
        !          132328:        $(SYSINC)/uproc.h       \
        !          132329:        $(DRVSRC)/dmareq.c
        !          132330:        $(CC) $(CFLAGS) -c -o $@ $(DRVSRC)/dmareq.c
        !          132331: 
        !          132332: $(USRSYS)/atkernel.o: $(KOBJ)/as2.obj $(HERE) $(DOTDOT)
        !          132333:        exec /bin/ld -r -o $@ $<
        !          132334: 
        !          132335: $(KOBJ)/as2.obj: $(IBMATSRC)/as2.s
        !          132336:        exec as -go $@ $<
        !          132337: 
        !          132338: $(KOBJ)/dmac.o: $(IBMATSRC)/dmac.c
        !          132339:        $(CC) $(CFLAGS) -c -o $@ $<
        !          132340: 
        !          132341: $(KOBJ)/dump.o: $(IBMATSRC)/dump.c
        !          132342:        $(CC) $(CFLAGS) -c -o $@ $<
        !          132343: 
        !          132344: $(KOBJ)/md2.o: $(IBMATSRC)/md2.c
        !          132345:        $(CC) $(CFLAGS) -c -o $@ $<
        !          132346: 
        !          132347: # Define REAL_MODE if real mode is also required
        !          132348: $(KOBJ)/mmu.o: $(IBMATSRC)/mmu.c
        !          132349:        $(CC) $(CFLAGS) -DREAL_MODE -c -o $@ $<
        !          132350: 
        !          132351: $(KOBJ)/support.o: $(I86SRC)/support.c
        !          132352:        $(CC) $(CFLAGS) -c -o $@ $<
        !          132353: 
        !          132354: # this stuff was in the /usr/src/sys/i8086 Makefile before 90/08/08
        !          132355: C86FLAGS=-c -DNOMONITOR=1
        !          132356: #
        !          132357: $(KOBJ):
        !          132358:        mkdir $(KOBJ)
        !          132359: 
        !          132360: $(KOBJ)/alloc.o: $(COHSRC)/alloc.c
        !          132361:        $(CC) $(C86FLAGS) -o $@ $<
        !          132362: 
        !          132363: $(KOBJ)/as1.o: $(I86SRC)/as1.s
        !          132364:        $(CC) $(C86FLAGS) -o $@ $<
        !          132365: 
        !          132366: $(KOBJ)/bio.o: $(COHSRC)/bio.c
        !          132367:        $(CC) $(C86FLAGS) -DREADAHEAD=0 -o $@ $<
        !          132368: 
        !          132369: # Clists are assembly source on i8086
        !          132370: $(KOBJ)/clist.o: $(I86SRC)/clist.s $(SYSINC)/const.h
        !          132371:        /lib/cpp -E -Isys -o clist.i $(I86SRC)/clist.s
        !          132372:        as -go $@ clist.i
        !          132373:        rm clist.i
        !          132374: 
        !          132375: $(KOBJ)/clock.o: $(COHSRC)/clock.c
        !          132376:        $(CC) $(C86FLAGS) -o $@ $<
        !          132377: 
        !          132378: $(KOBJ)/ct.o: $(TTYSRC)/ct.c
        !          132379:        $(CC) $(C86FLAGS) -o $@ $<
        !          132380: 
        !          132381: $(KOBJ)/defer.o: $(I86SRC)/defer.s
        !          132382:        $(CC) $(C86FLAGS) -o $@ $<
        !          132383: 
        !          132384: $(KOBJ)/dmalock.o: $(I86SRC)/dmalock.c
        !          132385:        $(CC) $(C86FLAGS) -o $@ $<
        !          132386: 
        !          132387: $(KOBJ)/exec.o: $(I86SRC)/exec.c
        !          132388:        $(CC) $(C86FLAGS) -o $@ $<
        !          132389: 
        !          132390: $(KOBJ)/fd.o: $(COHSRC)/fd.c
        !          132391:        $(CC) $(C86FLAGS) -o $@ $<
        !          132392: 
        !          132393: $(KOBJ)/fs1.o: $(COHSRC)/fs1.c
        !          132394:        $(CC) $(C86FLAGS) -o $@ $<
        !          132395: 
        !          132396: $(KOBJ)/fs2.o: $(COHSRC)/fs2.c
        !          132397:        $(CC) $(C86FLAGS) -o $@ $<
        !          132398: 
        !          132399: $(KOBJ)/fs3.o: $(COHSRC)/fs3.c
        !          132400:        $(CC) $(C86FLAGS) -DTINY=1 -o $@ $<
        !          132401: 
        !          132402: $(KOBJ)/krunch.o: $(I86SRC)/krunch.c
        !          132403:        $(CC) $(C86FLAGS) -o $@ $<
        !          132404: 
        !          132405: $(KOBJ)/ld.o: $(I86SRC)/ld.c
        !          132406:        $(CC) $(C86FLAGS) -o $@ $<
        !          132407: 
        !          132408: $(KOBJ)/ldas.o: $(I86SRC)/ldas.s
        !          132409:        as -gxo $@ $<
        !          132410: 
        !          132411: $(KOBJ)/main.o: $(USRSYS)/version $(COHSRC)/main.c
        !          132412:        $(CC) $(C86FLAGS) `$(USRSYS)/version` -o $@ $(COHSRC)/main.c
        !          132413: 
        !          132414: $(KOBJ)/md1.o: $(I86SRC)/md1.c
        !          132415:        $(CC) $(C86FLAGS) -o $@ $<
        !          132416: 
        !          132417: $(KOBJ)/misc.o: $(COHSRC)/misc.c
        !          132418:        $(CC) $(C86FLAGS) -o $@ $<
        !          132419: 
        !          132420: $(KOBJ)/mmain.o: $(I86SRC)/mmain.c $(SYSINC)/const.h
        !          132421:        $(CC) $(C86FLAGS) -o $@ $(I86SRC)/mmain.c
        !          132422: 
        !          132423: $(KOBJ)/null.o: $(COHSRC)/null.c
        !          132424:        $(CC) $(C86FLAGS) -o $@ $<
        !          132425: 
        !          132426: $(KOBJ)/pipe.o: $(COHSRC)/pipe.c
        !          132427:        $(CC) $(C86FLAGS) -o $@ $<
        !          132428: 
        !          132429: $(KOBJ)/poll.o: $(COHSRC)/poll.c
        !          132430:        $(CC) $(C86FLAGS) -o $@ $<
        !          132431: 
        !          132432: $(KOBJ)/printf.o: $(COHSRC)/printf.c
        !          132433:        $(CC) $(C86FLAGS) -o $@ $<
        !          132434: 
        !          132435: $(KOBJ)/proc.o: $(COHSRC)/proc.c
        !          132436:        $(CC) $(C86FLAGS) -o $@ $<
        !          132437: 
        !          132438: $(KOBJ)/seg.o: $(COHSRC)/seg.c
        !          132439:        $(CC) $(C86FLAGS) -o $@ $<
        !          132440: 
        !          132441: $(KOBJ)/sig.o: $(COHSRC)/sig.c
        !          132442:        $(CC) $(C86FLAGS) -o $@ $<
        !          132443: 
        !          132444: $(KOBJ)/swap.o: $(KERSRC)/swap.c
        !          132445:        $(CC) $(C86FLAGS) -o $@ $<
        !          132446: 
        !          132447: $(KOBJ)/elog.o: $(KERSRC)/elog.c
        !          132448:        $(CC) $(C86FLAGS) -o $@ $<
        !          132449: 
        !          132450: $(KOBJ)/sys1.o: $(COHSRC)/sys1.c
        !          132451:        $(CC) $(C86FLAGS) -o $@ $<
        !          132452: 
        !          132453: $(KOBJ)/sys2.o: $(COHSRC)/sys2.c
        !          132454:        $(CC) $(C86FLAGS) -o $@ $<
        !          132455: 
        !          132456: $(KOBJ)/sys3.o: $(COHSRC)/sys3.c
        !          132457:        $(CC) $(C86FLAGS) -o $@ $<
        !          132458: 
        !          132459: $(KOBJ)/tab.o: $(I86SRC)/tab.c
        !          132460:        $(CC) $(C86FLAGS) -o $@ $<
        !          132461: 
        !          132462: $(KOBJ)/timeout.o: $(COHSRC)/timeout.c
        !          132463:        $(CC) $(C86FLAGS) -o $@ $<
        !          132464: 
        !          132465: $(KOBJ)/trap.o: $(I86SRC)/trap.c
        !          132466:        $(CC) $(C86FLAGS) -o $@ $<
        !          132467: 
        !          132468: $(KOBJ)/var.o: $(COHSRC)/var.c
        !          132469:        $(CC) $(C86FLAGS) -o $@ $<
        !          132470: 
        !          132471: # Additional libraries searched when "config" runs.
        !          132472: 
        !          132473: $(DRVLIB)/support.a:   $(KOBJ)/cs_sel.o $(KOBJ)/clocked.o
        !          132474:        rm -f $@
        !          132475:        ar rc $@ $<
        !          132476: 
        !          132477: $(KOBJ)/cs_sel.o: $(I86SRC)/cs_sel.s
        !          132478:        as -gxo $@ $<
        !          132479: 
        !          132480: $(KOBJ)/clocked.o: $(I86SRC)/clocked.c
        !          132481:        $(CC) $(CFLAGS) -c -o $@ $<
        !          132482: 
        !          132483: $(DRVLIB)/tty.a:       $(KOBJ)/tty.o
        !          132484:        rm -f $@
        !          132485:        ar rc $@ $<
        !          132486: 
        !          132487: $(KOBJ)/tty.o: $(TTYSRC)/tty.c
        !          132488:        $(CC) $(CFLAGS) -c -o $@ $<
        !          132489: 0707070064030112171007550000030000030000011777770507310746200003300000003532/newbits/kernel/USRSYS/bld:
        !          132490: :  Build a Coherent executable with a host adapter driver linked in.
        !          132491: :
        !          132492: if [ $USRSYS ]
        !          132493: then
        !          132494: if [ $USRSRC ]
        !          132495: then
        !          132496: if [ $KOBJ ]
        !          132497: then
        !          132498: if [ $LOBJ ]
        !          132499: then
        !          132500: DRIVERS="rm fl lp mm"
        !          132501: COH_TYPE=fl
        !          132502: HD=""
        !          132503: KB=nkb
        !          132504: for ARG
        !          132505: do
        !          132506:        case $ARG in
        !          132507:        at|aha|ss)
        !          132508:                HD=$ARG
        !          132509:                COH_TYPE=$ARG
        !          132510:                ;;
        !          132511:        kb|nkb|gkb)
        !          132512:                KB=$ARG
        !          132513:                ;;
        !          132514:        *)              echo "Usage: $0 { at | ss | aha } { kb | nkb | gkb }"
        !          132515:                        exit 0
        !          132516:                        ;;
        !          132517:        esac
        !          132518: done
        !          132519: DRIVERS="$KB $HD $DRIVERS"
        !          132520: echo "Kernel:    /coh.$COH_TYPE"
        !          132521: echo "Version:   `version ID`"
        !          132522: echo "Devices:   $DRIVERS"
        !          132523: 
        !          132524: : default root/pipe device
        !          132525: BOOTDEV="fva0"
        !          132526: echo "Default root/pipe device is $BOOTDEV."
        !          132527: 
        !          132528: ( cd $USRSRC/ldrv; make ld_support )                   || exit 1
        !          132529: ( cd $USRSRC/i8086/drv; make -f Mf.mwc install )       || exit 1
        !          132530: ( make kernel )                                                || exit 1
        !          132531: ./config.mwc ibm-at $DRIVERS root=$BOOTDEV                     || exit 1
        !          132532: cp coherent /tmp/coh                                   || exit 1
        !          132533: strip /tmp/coh                                         || exit 1
        !          132534: set `ls -s /tmp/coh`
        !          132535: SIZE=$1
        !          132536: rm /tmp/coh                                            || exit 1
        !          132537: echo "Coherent bootable limit is 138 blocks.  This kernel is $SIZE"
        !          132538: if [ $SIZE -gt 138 ] ;then
        !          132539:        echo 
        !          132540:        echo Your Coherent image exceeds the bootable limit of 138 blocks
        !          132541:        echo by `expr $SIZE - 138` 'block(s).'  You will need to decrease the
        !          132542:        echo size of your kernel in order to make it bootable.
        !          132543:        echo
        !          132544:        echo We suggest removing some of the non critical drivers from the
        !          132545:        echo default list of drivers linked into Coherent.  These additional
        !          132546:        echo drivers may then be linked as loadable drivers using the
        !          132547:        echo ldconfig script located in this directory.
        !          132548: fi
        !          132549: mv coherent /coh.$COH_TYPE
        !          132550: chown sys /coh.$COH_TYPE
        !          132551: chgrp sys /coh.$COH_TYPE
        !          132552: chmod 400 /coh.$COH_TYPE
        !          132553: echo "New kernel in /coh.$COH_TYPE"
        !          132554: ls -l /coh.$COH_TYPE
        !          132555: # the rest is error exits
        !          132556: else
        !          132557: echo "Error - LOBJ not defined - (e.g. /usr/lobj)"
        !          132558: fi
        !          132559: else
        !          132560: echo "Error - KOBJ not defined - (e.g. /usr/kobj)"
        !          132561: fi
        !          132562: else
        !          132563: echo "Error - USRSRC not defined - (e.g. /usr/src/sys)"
        !          132564: fi
        !          132565: else
        !          132566: echo "Error - USRSYS not defined - (e.g. /usr/sys)"
        !          132567: fi
        !          132568: 0707070064030056771005440000030000030000011777770507310746200003600000013733/newbits/kernel/USRSYS/config:
        !          132569: :      configure a Coherent kernel for the AT
        !          132570: :
        !          132571: : usage: config [help]
        !          132572: :       config [stand=fha0]
        !          132573: :       config [stand=fva0]
        !          132574: :       config [stand=fha0] [standard] [root=DRV] [DRV ...]
        !          132575: :       config [stand=fva0] [standard] [root=DRV] [DRV ...]
        !          132576: 
        !          132577: :      initialize variables
        !          132578: :
        !          132579: ATSTANDARD=" fl lp mm "
        !          132580: ATKERNEL=atkernel.o
        !          132581: 
        !          132582: STANDARD="${ATSTANDARD}"
        !          132583: KERNEL="${ATKERNEL}"
        !          132584: LIBS="lib/tty.a lib/support.a"
        !          132585: BUILD=0
        !          132586: DEV=/tmp/dev
        !          132587: PASS1=""
        !          132588: PASS2=""
        !          132589: UNDEF=""
        !          132590: PATCH=""
        !          132591: ROOTDEV=""
        !          132592: INSTALL=""
        !          132593: 
        !          132594: case "$#" in
        !          132595: 0)     /bin/echo
        !          132596:        /bin/echo       "The following can be used as arguments to config:"
        !          132597:        /bin/echo
        !          132598:        /bin/cat doc/*
        !          132599:        exit 0
        !          132600:        ;;
        !          132601: esac
        !          132602: 
        !          132603: for ARG in $*
        !          132604: do
        !          132605:        case "${ARG}" in
        !          132606:        help)
        !          132607:                /bin/echo
        !          132608:                /bin/echo "The following can be used as arguments to config:"
        !          132609:                /bin/echo
        !          132610:                /bin/cat doc/*
        !          132611:                exit 0
        !          132612:                ;;
        !          132613:        ibm-at)
        !          132614:                STANDARD="${ATSTANDARD}"
        !          132615:                KERNEL="${ATKERNEL}"
        !          132616:                ;;
        !          132617:        *)
        !          132618:                PASS1="${PASS1} ${ARG}"
        !          132619:                ;;
        !          132620:        esac
        !          132621: done
        !          132622: 
        !          132623: for ARG in ${PASS1}
        !          132624: do
        !          132625:        case "${ARG}" in
        !          132626:        standard)
        !          132627:                PASS2="${STANDARD} ${PASS2}"
        !          132628:                ;;
        !          132629:        stand\=fha0)
        !          132630:                /etc/umount /dev/fha0 2> /dev/null
        !          132631:                echo -n "Insert 5.25 high capacity floppy into drive 0, press return [y to format]: "
        !          132632:                read x
        !          132633:                case "x$x" in
        !          132634:                xy)     /etc/fdformat -i 6 /dev/fha0 || exit 1 ;;
        !          132635:                esac
        !          132636:                /etc/mkfs  /dev/fha0 2400               || exit 1
        !          132637:                /bin/cp /conf/boot.fha /dev/fha0        || exit 1
        !          132638:                /etc/mount /dev/fha0 /f0                || exit 1
        !          132639:                /bin/mkdir /f0/bin /f0/dev /f0/etc /f0/mnt /f0/tmp || exit 1
        !          132640:                umask 011
        !          132641:                /etc/mknod /f0/dev/null c 0 0           || exit 1
        !          132642:                /bin/ln -f /f0/dev/null /f0/dev/swap    || exit 1
        !          132643:                umask 077
        !          132644:                /etc/mknod /f0/dev/mem  c 0 1           || exit 1
        !          132645:                /etc/mknod /f0/dev/kmem c 0 2           || exit 1
        !          132646:                /bin/chmod 777 /f0/tmp                  || exit 1
        !          132647:                umask 022
        !          132648: 
        !          132649:                /bin/cp /bin/bad /bin/cat /bin/cp /bin/cpdir \
        !          132650:                        /bin/db /bin/dd /bin/df /bin/du \
        !          132651:                        /bin/echo /bin/kill \
        !          132652:                        /bin/ls /bin/mkdir /bin/mv /bin/ncheck \
        !          132653:                        /bin/rm /bin/sh /bin/stty /bin/sync \
        !          132654:                        /bin/time /bin/true /f0/bin || exit 1
        !          132655:                /bin/cp /etc/fsck /etc/init /etc/badscan /etc/clri \
        !          132656:                        /etc/fdisk /etc/mkfs \
        !          132657:                        /etc/mknod /etc/mount /etc/umount /f0/etc || exit 1
        !          132658: 
        !          132659:                DEV=/f0/dev
        !          132660:                :
        !          132661:                : Place a Coherent image out on drive 0.
        !          132662:                : Add a floppy root patched version as a file called 'stand'.
        !          132663:                :
        !          132664:                INSTALL="umask 022; set -e ; /bin/cp coherent /f0 ; \
        !          132665:                        /conf/patch coherent 'rootdev_=makedev(4,14)' ; \
        !          132666:                        /conf/patch coherent 'pipedev_=makedev(4,14)' ; \
        !          132667:                        /bin/cp coherent /f0/stand ; /bin/strip /f0/stand ; \
        !          132668:                        /etc/umount /dev/fha0 ; /bin/df /dev/fha0"
        !          132669: 
        !          132670:                case "$#" in
        !          132671:                1) eval ${INSTALL} ; exit 0 ;;
        !          132672:                esac
        !          132673:                ;;
        !          132674: 
        !          132675:        stand\=fva0)
        !          132676:                /etc/umount /dev/fva0 2> /dev/null
        !          132677:                echo -n "Insert high density 3.5 floppy into drive 0, press return [y to format]: "
        !          132678:                read x
        !          132679:                case "x$x" in
        !          132680:                xy)     /etc/fdformat -i 6 /dev/fva0 || exit 1 ;;
        !          132681:                esac
        !          132682:                /etc/mkfs  /dev/fva0 2880               || exit 1
        !          132683:                /bin/cp /conf/boot.fva /dev/fva0        || exit 1
        !          132684:                /etc/mount /dev/fva0 /f0                || exit 1
        !          132685:                /bin/mkdir /f0/bin /f0/dev /f0/etc /f0/mnt /f0/tmp || exit 1
        !          132686:                umask 011
        !          132687:                /etc/mknod /f0/dev/null c 0 0           || exit 1
        !          132688:                /bin/ln -f /f0/dev/null /f0/dev/swap    || exit 1
        !          132689:                umask 077
        !          132690:                /etc/mknod /f0/dev/mem  c 0 1           || exit 1
        !          132691:                /etc/mknod /f0/dev/kmem c 0 2           || exit 1
        !          132692:                /bin/chmod 777 /f0/tmp                  || exit 1
        !          132693:                umask 022
        !          132694: 
        !          132695:                /bin/cp /bin/bad /bin/cat /bin/cp /bin/cpdir \
        !          132696:                        /bin/db /bin/dd /bin/df /bin/du \
        !          132697:                        /bin/echo /bin/kill \
        !          132698:                        /bin/ls /bin/mkdir /bin/mv /bin/ncheck \
        !          132699:                        /bin/rm /bin/sh /bin/stty /bin/sync \
        !          132700:                        /bin/time /bin/true /f0/bin || exit 1
        !          132701:                /bin/cp /etc/fsck /etc/init /etc/badscan /etc/clri \
        !          132702:                        /etc/fdisk /etc/mkfs \
        !          132703:                        /etc/mknod /etc/mount /etc/umount /f0/etc || exit 1
        !          132704: 
        !          132705:                DEV=/f0/dev
        !          132706:                :
        !          132707:                : Place a Coherent image out on drive 0.
        !          132708:                : Add a floppy root patched version as a file called 'stand'.
        !          132709:                :
        !          132710:                INSTALL="umask 022; set -e ; /bin/cp coherent /f0 ; \
        !          132711:                        /conf/patch coherent 'rootdev_=makedev(4,15)' ; \
        !          132712:                        /conf/patch coherent 'pipedev_=makedev(4,15)' ; \
        !          132713:                        /bin/cp coherent /f0/stand ; /bin/strip /f0/stand ; \
        !          132714:                        /etc/umount /dev/fva0 ; /bin/df /dev/fva0"
        !          132715: 
        !          132716:                case "$#" in
        !          132717:                1) eval ${INSTALL} ; exit 0 ;;
        !          132718:                esac
        !          132719:                ;;
        !          132720: 
        !          132721:        DEV\=*)
        !          132722:                DEV=`/bin/echo "${ARG}" | /bin/sed -e 's/^....//'`
        !          132723:                ;;
        !          132724:        *)
        !          132725:                PASS2="${PASS2} ${ARG}"
        !          132726:                ;;
        !          132727:        esac
        !          132728: done
        !          132729: 
        !          132730: :      get the proper driver information
        !          132731: :
        !          132732: 
        !          132733: for ARG in ${PASS2}
        !          132734: do
        !          132735:        case "$ARG" in
        !          132736: 
        !          132737:        root\=fva0)
        !          132738:                ROOTDEV="makedev(4,15)"
        !          132739:                . confdrv/fl
        !          132740:                ;;
        !          132741:        root\=fha0)
        !          132742:                ROOTDEV="makedev(4,14)"
        !          132743:                . confdrv/fl
        !          132744:                ;;
        !          132745:        root\=*)
        !          132746:                ARG=`/bin/echo "${ARG}" | /bin/sed -e 's/^.....//'`
        !          132747: 
        !          132748:                case "${ARG}" in
        !          132749:                *[0123][abcdx])
        !          132750:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          132751:                        ;;
        !          132752:                *)
        !          132753:                        FILE="${ARG}"
        !          132754:                        ;;
        !          132755:                esac
        !          132756: 
        !          132757:                if /bin/test -r confdrv/${FILE}
        !          132758:                then
        !          132759:                        . confdrv/${FILE}
        !          132760:                        ROOTDEV="${MAKEDEV}"
        !          132761: /bin/echo "'confdrv/${FILE}' executing"
        !          132762:                else
        !          132763:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          132764:                        exit 1
        !          132765:                fi
        !          132766:                ;;
        !          132767: 
        !          132768:        swap)
        !          132769:                ;;
        !          132770: 
        !          132771:        swap\=*)
        !          132772:                ARG=`/bin/echo "${ARG}" | /bin/sed -e 's/^.....//'`
        !          132773: 
        !          132774:                case "${ARG}" in
        !          132775:                *[0123][abcdx])
        !          132776:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          132777:                        if [ -d "${DEV-/dev}" ]
        !          132778:                        then
        !          132779:                                /bin/ln -f ${DEV-/dev}/${ARG} ${DEV-/dev}/swap
        !          132780:                        fi
        !          132781:                        ;;
        !          132782:                *)
        !          132783:                        FILE="${ARG}"
        !          132784:                        ;;
        !          132785:                esac
        !          132786: 
        !          132787:                if /bin/test -r confdrv/${FILE}
        !          132788:                then
        !          132789:                        . confdrv/${FILE}
        !          132790:                        PATCH="${PATCH} swapdev_=${MAKEDEV}"
        !          132791:                        /bin/echo "Swap device will be ${DEV-/dev}/${ARG}"
        !          132792:                        /bin/echo "See documentation before enabling"
        !          132793:                else
        !          132794:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          132795:                        exit 1
        !          132796:                fi
        !          132797:                ;;
        !          132798: 
        !          132799:        *\=*)
        !          132800:                PATCH="${PATCH} ${ARG}"
        !          132801:                ;;
        !          132802: 
        !          132803:        *)
        !          132804:                case "${ARG}" in
        !          132805:                *[0123][abcdx])
        !          132806:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          132807:                        ;;
        !          132808:                *)
        !          132809:                        FILE="${ARG}"
        !          132810:                        ;;
        !          132811:                esac
        !          132812: 
        !          132813:                if /bin/test -r confdrv/${FILE}
        !          132814:                then
        !          132815:                        . confdrv/${FILE}
        !          132816:                        case "${ROOTDEV}" in
        !          132817:                        ?*)     ;;
        !          132818:                        *)      ROOTDEV="${MAKEDEV}" ;;
        !          132819:                        esac
        !          132820:                else
        !          132821:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          132822:                        exit 1
        !          132823:                fi
        !          132824:                ;;
        !          132825:        esac
        !          132826: done
        !          132827: ROOTDEV="${ROOTDEV-makedev(4,14)}"
        !          132828: 
        !          132829: :      include stub drivers
        !          132830: :
        !          132831: UNDEF="${UNDEF} ${LIBS}"
        !          132832: 
        !          132833: :      make the proper root and pipe devices
        !          132834: :
        !          132835: PATCH="${PATCH} rootdev_=${ROOTDEV} pipedev_=${ROOTDEV}"
        !          132836: 
        !          132837: set -ex
        !          132838: :
        !          132839: :      create a kernel with the desired device drivers
        !          132840: :
        !          132841: /bin/ld -i -x -o coherent ${KERNEL} ${UNDEF} -lc
        !          132842: :
        !          132843: :      enable the desired device drivers
        !          132844: :
        !          132845: /conf/patch coherent ALLSIZE_=16384 NBUF_=32 NCLIST_=24 ${PATCH}
        !          132846: /bin/chmod 644 coherent
        !          132847: /bin/chown sys coherent
        !          132848: /bin/chgrp sys coherent
        !          132849: /bin/sync
        !          132850: :
        !          132851: eval ${INSTALL}
        !          132852: 0707070064030056761005440000030000030000011777770507310746400004000000001721/newbits/kernel/USRSYS/ldconfig:
        !          132853: :      configure a loadable driver
        !          132854: :
        !          132855: : usage: ldconfig [swap] [DRV ...]
        !          132856: :
        !          132857: BUILD=0
        !          132858: DEV=/dev
        !          132859: PATCH=""
        !          132860: UNDEF=""
        !          132861: LDMOD=""
        !          132862: PASS1=""
        !          132863: 
        !          132864: for ARG in $*
        !          132865: do
        !          132866:        case "${ARG}" in
        !          132867:        DEV\=*)
        !          132868:                DEV=`/bin/echo "${ARG}" | /bin/sed -e 's/^....//'`
        !          132869:                ;;
        !          132870:        *)
        !          132871:                PASS1="${PASS1} ${ARG}"
        !          132872:                ;;
        !          132873:        esac
        !          132874: done
        !          132875: 
        !          132876: for ARG in ${PASS1}
        !          132877: do
        !          132878:        case "$ARG" in
        !          132879: 
        !          132880:        swap)
        !          132881:                /bin/echo "ldrv/swap: "
        !          132882:                ld -r -o ldrv/swap lib/ldrts0.o lib/ldswap.o lib/ldlib.a
        !          132883:                LDMOD=""
        !          132884:                ;;
        !          132885: 
        !          132886:        *\=*)
        !          132887:                LDMOD="${LDMOD} ${ARG}"
        !          132888:                ;;
        !          132889: 
        !          132890:        *)
        !          132891:                case "${ARG}" in
        !          132892:                *[0123][abcdx])
        !          132893:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          132894:                        ;;
        !          132895:                *)
        !          132896:                        FILE="${ARG}"
        !          132897:                        ;;
        !          132898:                esac
        !          132899: 
        !          132900:                /bin/echo "ldrv/${FILE}: "
        !          132901:                if /bin/test -r confdrv/${FILE}
        !          132902:                then
        !          132903:                        UNDEF=""
        !          132904:                        . confdrv/${FILE}
        !          132905:                        /bin/ld -r -o ldrv/${FILE} lib/ldrts0.o \
        !          132906:                                lib/ldmain.o ${UNDEF} \
        !          132907:                                lib/ldlib.a || exit 1
        !          132908:                        case "${LDMOD}" in
        !          132909:                        "")     ;;
        !          132910:                        *)      /conf/patch ldrv/${FILE} ${LDMOD}
        !          132911:                        esac
        !          132912:                else
        !          132913:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          132914:                        exit 1
        !          132915:                fi
        !          132916:                LDMOD=""
        !          132917:                ;;
        !          132918:        esac
        !          132919: done
        !          132920: 0707070064030110561007550000030000030000011777770507310746400003700000000250/newbits/kernel/USRSYS/versionversion=1
        !          132921: release=2
        !          132922: revision=0.DK
        !          132923: arg=${1-foo}
        !          132924: if [ $arg = "ID" ]
        !          132925: then
        !          132926:        echo "$version.$release.$revision"
        !          132927: else
        !          132928:        echo -n '-DVERSION="'$version.$release.$revision'"'
        !          132929: fi
        !          132930: 0707070064030055230407550000030000030000011777770507310746500003300000000000/newbits/kernel/USRSYS/RCS0707070064030103141004440000030000030000011777770507310746500004600000027602/newbits/kernel/USRSYS/RCS/Makefile,vhead     1.6;
        !          132931: branch   ;
        !          132932: access   ;
        !          132933: symbols  ;
        !          132934: locks    bin:1.6;
        !          132935: comment  @@;
        !          132936: 
        !          132937: 
        !          132938: 1.6
        !          132939: date     91.07.24.08.05.32;  author bin;  state Exp;
        !          132940: branches ;
        !          132941: next     1.5;
        !          132942: 
        !          132943: 1.5
        !          132944: date     91.07.15.14.06.55;  author bin;  state Exp;
        !          132945: branches ;
        !          132946: next     1.4;
        !          132947: 
        !          132948: 1.4
        !          132949: date     91.06.20.14.24.40;  author bin;  state Exp;
        !          132950: branches ;
        !          132951: next     1.3;
        !          132952: 
        !          132953: 1.3
        !          132954: date     91.06.18.07.52.10;  author bin;  state Exp;
        !          132955: branches ;
        !          132956: next     1.2;
        !          132957: 
        !          132958: 1.2
        !          132959: date     91.06.17.12.43.51;  author bin;  state Exp;
        !          132960: branches ;
        !          132961: next     1.1;
        !          132962: 
        !          132963: 1.1
        !          132964: date     91.06.10.14.15.04;  author bin;  state Exp;
        !          132965: branches ;
        !          132966: next     ;
        !          132967: 
        !          132968: 
        !          132969: desc
        !          132970: @initial version prov by hal
        !          132971: @
        !          132972: 
        !          132973: 
        !          132974: 1.6
        !          132975: log
        !          132976: @update prov by hal
        !          132977: @
        !          132978: text
        !          132979: @# $Header: /usr/src/sys/i8086/ibm_at/RCS/Makefile,v 1.3 89/06/30 16:26:39 src Exp $
        !          132980: #
        !          132981: # Makefile for ibm specific coherent sources and coherent images.
        !          132982: #
        !          132983: # Requires environment variables
        !          132984: #      USRSYS (e.g. /usr/sys)
        !          132985: #      USRSRC (e.g. /usr/src/sys)
        !          132986: #      KOBJ (e.g. /usr/kobj)
        !          132987: #
        !          132988: # $Log:        /usr/src/sys/i8086/ibm_at/RCS/Makefile,v $
        !          132989: # Revision 1.3 89/06/30  16:26:39      src
        !          132990: # Bug: Lack of DMA lock resulted in failed transfers between SCSI drive
        !          132991: #      and floppy disk.
        !          132992: # Fix: Added dma lock routines to insure single DMA transfer. (JHB)
        !          132993: # 
        !          132994: # Revision 1.1 88/03/24  17:33:15      src
        !          132995: # Initial revision
        !          132996: # 
        !          132997: 
        !          132998: # Include directories
        !          132999: USRINC=/usr/include
        !          133000: SYSINC=/usr/include/sys
        !          133001: 
        !          133002: # Source directories
        !          133003: COHSRC=$(USRSRC)/coh
        !          133004: DRVSRC=$(USRSRC)/i8086/drv
        !          133005: I86SRC=$(USRSRC)/i8086/src
        !          133006: IBMATSRC=$(USRSRC)/i8086/ibm_at
        !          133007: KERSRC=$(USRSRC)/ker
        !          133008: TTYSRC=$(USRSRC)/ttydrv
        !          133009: 
        !          133010: # Library directory
        !          133011: DRVLIB=$(USRSYS)/lib
        !          133012: 
        !          133013: # Compiler stuff
        !          133014: CC=exec /bin/cc
        !          133015: CFLAGS=
        !          133016: 
        !          133017: HERE=  $(KOBJ)/md2.o \
        !          133018:        $(KOBJ)/dmac.o \
        !          133019:        $(KOBJ)/pccon.o \
        !          133020:        $(KOBJ)/console.o \
        !          133021:        $(KOBJ)/dmareq.o \
        !          133022:        $(KOBJ)/mmu.o \
        !          133023:        $(KOBJ)/support.o
        !          133024: 
        !          133025: DOTDOT=        $(KOBJ)/alloc.o \
        !          133026:        $(KOBJ)/as1.o \
        !          133027:        $(KOBJ)/bio.o \
        !          133028:        $(KOBJ)/clist.o \
        !          133029:        $(KOBJ)/clock.o \
        !          133030:        $(KOBJ)/ct.o \
        !          133031:        $(KOBJ)/defer.o \
        !          133032:        $(KOBJ)/dmalock.o       \
        !          133033:        $(KOBJ)/exec.o \
        !          133034:        $(KOBJ)/fd.o \
        !          133035:        $(KOBJ)/fs1.o $(KOBJ)/fs2.o $(KOBJ)/fs3.o \
        !          133036:        $(KOBJ)/krunch.o \
        !          133037:        $(KOBJ)/ld.o $(KOBJ)/ldas.o \
        !          133038:        $(KOBJ)/main.o \
        !          133039:        $(KOBJ)/md1.o \
        !          133040:        $(KOBJ)/misc.o \
        !          133041:        $(KOBJ)/mmain.o \
        !          133042:        $(KOBJ)/null.o \
        !          133043:        $(KOBJ)/pipe.o \
        !          133044:        $(KOBJ)/poll.o \
        !          133045:        $(KOBJ)/printf.o \
        !          133046:        $(KOBJ)/proc.o \
        !          133047:        $(KOBJ)/seg.o \
        !          133048:        $(KOBJ)/sig.o \
        !          133049:        $(KOBJ)/sys1.o $(KOBJ)/sys2.o $(KOBJ)/sys3.o \
        !          133050:        $(KOBJ)/tab.o \
        !          133051:        $(KOBJ)/timeout.o \
        !          133052:        $(KOBJ)/trap.o \
        !          133053:        $(KOBJ)/var.o
        !          133054: 
        !          133055: kernel:        $(KOBJ) $(USRSYS)/atkernel.o $(DRVLIB)/support.a $(DRVLIB)/tty.a
        !          133056:        @@exec /bin/sync
        !          133057: 
        !          133058: shrink:
        !          133059:        rm -f $(KOBJ)/* $(KOBJ)/* $(KOBJ)/*
        !          133060: 
        !          133061: $(KOBJ)/pccon.o: \
        !          133062:        $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          133063:                                $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          133064:                                $(SYSINC)/fun.h \
        !          133065:        $(SYSINC)/con.h         \
        !          133066:        $(USRINC)/mtype.h       \
        !          133067:        $(SYSINC)/stat.h        \
        !          133068:        $(DRVSRC)/pccon.c
        !          133069:        $(CC) $(CFLAGS) -c -o $@@ $(DRVSRC)/pccon.c
        !          133070: 
        !          133071: $(KOBJ)/console.o:     \
        !          133072:        $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          133073:                                $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          133074:                                $(SYSINC)/fun.h \
        !          133075:        $(SYSINC)/con.h         \
        !          133076:        $(SYSINC)/inode.h       \
        !          133077:        $(SYSINC)/io.h          \
        !          133078:        $(SYSINC)/stat.h        \
        !          133079:        $(DRVSRC)/console.c
        !          133080:        $(CC) $(CFLAGS) -c -o $@@ $(DRVSRC)/console.c
        !          133081: 
        !          133082: $(KOBJ)/dmareq.o:      \
        !          133083:        $(SYSINC)/buf.h         \
        !          133084:        $(SYSINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          133085:                                $(SYSINC)/machine.h $(SYSINC)/param.h \
        !          133086:                                $(SYSINC)/fun.h \
        !          133087:        $(SYSINC)/con.h         \
        !          133088:        $(SYSINC)/dmac.h        \
        !          133089:        $(USRINC)/errno.h       \
        !          133090:        $(SYSINC)/io.h          \
        !          133091:        $(SYSINC)/proc.h        $(SYSINC)/types.h $(SYSINC)/poll.h \
        !          133092:        $(SYSINC)/sched.h       \
        !          133093:        $(SYSINC)/seg.h         \
        !          133094:        $(SYSINC)/stat.h        \
        !          133095:        $(SYSINC)/uproc.h       \
        !          133096:        $(DRVSRC)/dmareq.c
        !          133097:        $(CC) $(CFLAGS) -c -o $@@ $(DRVSRC)/dmareq.c
        !          133098: 
        !          133099: $(USRSYS)/atkernel.o: $(KOBJ)/as2.obj $(HERE) $(DOTDOT)
        !          133100:        exec /bin/ld -r -o $@@ $<
        !          133101: 
        !          133102: $(KOBJ)/as2.obj: $(IBMATSRC)/as2.s
        !          133103:        exec as -go $@@ $<
        !          133104: 
        !          133105: $(KOBJ)/dmac.o: $(IBMATSRC)/dmac.c
        !          133106:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          133107: 
        !          133108: $(KOBJ)/dump.o: $(IBMATSRC)/dump.c
        !          133109:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          133110: 
        !          133111: $(KOBJ)/md2.o: $(IBMATSRC)/md2.c
        !          133112:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          133113: 
        !          133114: # Define REAL_MODE if real mode is also required
        !          133115: $(KOBJ)/mmu.o: $(IBMATSRC)/mmu.c
        !          133116:        $(CC) $(CFLAGS) -DREAL_MODE -c -o $@@ $<
        !          133117: 
        !          133118: $(KOBJ)/support.o: $(I86SRC)/support.c
        !          133119:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          133120: 
        !          133121: # this stuff was in the /usr/src/sys/i8086 Makefile before 90/08/08
        !          133122: C86FLAGS=-c -DNOMONITOR=1
        !          133123: #
        !          133124: $(KOBJ):
        !          133125:        mkdir $(KOBJ)
        !          133126: 
        !          133127: $(KOBJ)/alloc.o: $(COHSRC)/alloc.c
        !          133128:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133129: 
        !          133130: $(KOBJ)/as1.o: $(I86SRC)/as1.s
        !          133131:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133132: 
        !          133133: $(KOBJ)/bio.o: $(COHSRC)/bio.c
        !          133134:        $(CC) $(C86FLAGS) -DREADAHEAD=0 -o $@@ $<
        !          133135: 
        !          133136: # Clists are assembly source on i8086
        !          133137: $(KOBJ)/clist.o: $(I86SRC)/clist.s $(SYSINC)/const.h
        !          133138:        /lib/cpp -E -Isys -o clist.i $(I86SRC)/clist.s
        !          133139:        as -go $@@ clist.i
        !          133140:        rm clist.i
        !          133141: 
        !          133142: $(KOBJ)/clock.o: $(COHSRC)/clock.c
        !          133143:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133144: 
        !          133145: $(KOBJ)/ct.o: $(TTYSRC)/ct.c
        !          133146:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133147: 
        !          133148: $(KOBJ)/defer.o: $(I86SRC)/defer.s
        !          133149:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133150: 
        !          133151: $(KOBJ)/dmalock.o: $(I86SRC)/dmalock.c
        !          133152:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133153: 
        !          133154: $(KOBJ)/exec.o: $(I86SRC)/exec.c
        !          133155:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133156: 
        !          133157: $(KOBJ)/fd.o: $(COHSRC)/fd.c
        !          133158:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133159: 
        !          133160: $(KOBJ)/fs1.o: $(COHSRC)/fs1.c
        !          133161:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133162: 
        !          133163: $(KOBJ)/fs2.o: $(COHSRC)/fs2.c
        !          133164:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133165: 
        !          133166: $(KOBJ)/fs3.o: $(COHSRC)/fs3.c
        !          133167:        $(CC) $(C86FLAGS) -DTINY=1 -o $@@ $<
        !          133168: 
        !          133169: $(KOBJ)/krunch.o: $(I86SRC)/krunch.c
        !          133170:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133171: 
        !          133172: $(KOBJ)/ld.o: $(I86SRC)/ld.c
        !          133173:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133174: 
        !          133175: $(KOBJ)/ldas.o: $(I86SRC)/ldas.s
        !          133176:        as -gxo $@@ $<
        !          133177: 
        !          133178: $(KOBJ)/main.o: $(USRSYS)/version $(COHSRC)/main.c
        !          133179:        $(CC) $(C86FLAGS) `$(USRSYS)/version` -o $@@ $(COHSRC)/main.c
        !          133180: 
        !          133181: $(KOBJ)/md1.o: $(I86SRC)/md1.c
        !          133182:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133183: 
        !          133184: $(KOBJ)/misc.o: $(COHSRC)/misc.c
        !          133185:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133186: 
        !          133187: $(KOBJ)/mmain.o: $(I86SRC)/mmain.c $(SYSINC)/const.h
        !          133188:        $(CC) $(C86FLAGS) -o $@@ $(I86SRC)/mmain.c
        !          133189: 
        !          133190: $(KOBJ)/null.o: $(COHSRC)/null.c
        !          133191:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133192: 
        !          133193: $(KOBJ)/pipe.o: $(COHSRC)/pipe.c
        !          133194:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133195: 
        !          133196: $(KOBJ)/poll.o: $(COHSRC)/poll.c
        !          133197:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133198: 
        !          133199: $(KOBJ)/printf.o: $(COHSRC)/printf.c
        !          133200:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133201: 
        !          133202: $(KOBJ)/proc.o: $(COHSRC)/proc.c
        !          133203:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133204: 
        !          133205: $(KOBJ)/seg.o: $(COHSRC)/seg.c
        !          133206:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133207: 
        !          133208: $(KOBJ)/sig.o: $(COHSRC)/sig.c
        !          133209:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133210: 
        !          133211: $(KOBJ)/swap.o: $(KERSRC)/swap.c
        !          133212:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133213: 
        !          133214: $(KOBJ)/elog.o: $(KERSRC)/elog.c
        !          133215:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133216: 
        !          133217: $(KOBJ)/sys1.o: $(COHSRC)/sys1.c
        !          133218:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133219: 
        !          133220: $(KOBJ)/sys2.o: $(COHSRC)/sys2.c
        !          133221:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133222: 
        !          133223: $(KOBJ)/sys3.o: $(COHSRC)/sys3.c
        !          133224:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133225: 
        !          133226: $(KOBJ)/tab.o: $(I86SRC)/tab.c
        !          133227:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133228: 
        !          133229: $(KOBJ)/timeout.o: $(COHSRC)/timeout.c
        !          133230:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133231: 
        !          133232: $(KOBJ)/trap.o: $(I86SRC)/trap.c
        !          133233:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133234: 
        !          133235: $(KOBJ)/var.o: $(COHSRC)/var.c
        !          133236:        $(CC) $(C86FLAGS) -o $@@ $<
        !          133237: 
        !          133238: # Additional libraries searched when "config" runs.
        !          133239: 
        !          133240: $(DRVLIB)/support.a:   $(KOBJ)/cs_sel.o $(KOBJ)/clocked.o
        !          133241:        rm -f $@@
        !          133242:        ar rc $@@ $<
        !          133243: 
        !          133244: $(KOBJ)/cs_sel.o: $(I86SRC)/cs_sel.s
        !          133245:        as -gxo $@@ $<
        !          133246: 
        !          133247: $(KOBJ)/clocked.o: $(I86SRC)/clocked.c
        !          133248:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          133249: 
        !          133250: $(DRVLIB)/tty.a:       $(KOBJ)/tty.o
        !          133251:        rm -f $@@
        !          133252:        ar rc $@@ $<
        !          133253: 
        !          133254: $(KOBJ)/tty.o: $(TTYSRC)/tty.c
        !          133255:        $(CC) $(CFLAGS) -c -o $@@ $<
        !          133256: @
        !          133257: 
        !          133258: 
        !          133259: 1.5
        !          133260: log
        !          133261: @update prov. by hal (moves objects to relocatable directories)
        !          133262: @
        !          133263: text
        !          133264: @d8 1
        !          133265: a8 1
        !          133266: #      KOBJ (e.g. /tmp/kobj)
        !          133267: @
        !          133268: 
        !          133269: 
        !          133270: 1.4
        !          133271: log
        !          133272: @another hal update
        !          133273: @
        !          133274: text
        !          133275: @d5 5
        !          133276: a31 6
        !          133277: # Object directories
        !          133278: I86OBJ=$(USRSRC)/i8086/objects
        !          133279: DRVOBJ=$(USRSRC)/i8086/drv/objects
        !          133280: SRCOBJ=$(USRSRC)/i8086/src/objects
        !          133281: IBMATOBJ=$(USRSRC)/i8086/ibm_at/objects
        !          133282: 
        !          133283: d39 7
        !          133284: a45 7
        !          133285: HERE=  $(IBMATOBJ)/md2.o \
        !          133286:        $(IBMATOBJ)/dmac.o \
        !          133287:        $(DRVOBJ)/pccon.o \
        !          133288:        $(DRVOBJ)/console.o \
        !          133289:        $(DRVOBJ)/dmareq.o \
        !          133290:        $(IBMATOBJ)/mmu.o \
        !          133291:        $(SRCOBJ)/support.o
        !          133292: d47 29
        !          133293: a75 29
        !          133294: DOTDOT=        $(I86OBJ)/alloc.o \
        !          133295:        $(I86OBJ)/as1.o \
        !          133296:        $(I86OBJ)/bio.o \
        !          133297:        $(I86OBJ)/clist.o \
        !          133298:        $(I86OBJ)/clock.o \
        !          133299:        $(I86OBJ)/ct.o \
        !          133300:        $(I86OBJ)/defer.o \
        !          133301:        $(I86OBJ)/dmalock.o     \
        !          133302:        $(I86OBJ)/exec.o \
        !          133303:        $(I86OBJ)/fd.o \
        !          133304:        $(I86OBJ)/fs1.o $(I86OBJ)/fs2.o $(I86OBJ)/fs3.o \
        !          133305:        $(I86OBJ)/krunch.o \
        !          133306:        $(I86OBJ)/ld.o $(I86OBJ)/ldas.o \
        !          133307:        $(I86OBJ)/main.o \
        !          133308:        $(I86OBJ)/md1.o \
        !          133309:        $(I86OBJ)/misc.o \
        !          133310:        $(I86OBJ)/mmain.o \
        !          133311:        $(I86OBJ)/null.o \
        !          133312:        $(I86OBJ)/pipe.o \
        !          133313:        $(I86OBJ)/poll.o \
        !          133314:        $(I86OBJ)/printf.o \
        !          133315:        $(I86OBJ)/proc.o \
        !          133316:        $(I86OBJ)/seg.o \
        !          133317:        $(I86OBJ)/sig.o \
        !          133318:        $(I86OBJ)/sys1.o $(I86OBJ)/sys2.o $(I86OBJ)/sys3.o \
        !          133319:        $(I86OBJ)/tab.o \
        !          133320:        $(I86OBJ)/timeout.o \
        !          133321:        $(I86OBJ)/trap.o \
        !          133322:        $(I86OBJ)/var.o
        !          133323: d77 1
        !          133324: a77 1
        !          133325: kernel:        $(IBMATOBJ) $(USRSYS)/atkernel.o $(DRVLIB)/support.a $(DRVLIB)/tty.a
        !          133326: d81 1
        !          133327: a81 1
        !          133328:        rm -f $(IBMATOBJ)/* $(I86OBJ)/* $(DRVOBJ)/*
        !          133329: d83 1
        !          133330: a83 4
        !          133331: $(IBMATOBJ):
        !          133332:        mkdir $(IBMATOBJ)
        !          133333: 
        !          133334: $(DRVOBJ)/pccon.o: \
        !          133335: d93 1
        !          133336: a93 1
        !          133337: $(DRVOBJ)/console.o:   \
        !          133338: d104 1
        !          133339: a104 1
        !          133340: $(DRVOBJ)/dmareq.o:    \
        !          133341: d121 1
        !          133342: a121 1
        !          133343: $(USRSYS)/atkernel.o: $(IBMATOBJ)/as2.obj $(HERE) $(DOTDOT)
        !          133344: d124 1
        !          133345: a124 1
        !          133346: $(IBMATOBJ)/as2.obj: $(IBMATSRC)/as2.s
        !          133347: d127 1
        !          133348: a127 1
        !          133349: $(IBMATOBJ)/dmac.o: $(IBMATSRC)/dmac.c
        !          133350: d130 1
        !          133351: a130 1
        !          133352: $(IBMATOBJ)/dump.o: $(IBMATSRC)/dump.c
        !          133353: d133 1
        !          133354: a133 1
        !          133355: $(IBMATOBJ)/md2.o: $(IBMATSRC)/md2.c
        !          133356: d137 1
        !          133357: a137 1
        !          133358: $(IBMATOBJ)/mmu.o: $(IBMATSRC)/mmu.c
        !          133359: d140 1
        !          133360: a140 1
        !          133361: $(SRCOBJ)/support.o: $(I86SRC)/support.c
        !          133362: d146 2
        !          133363: a147 2
        !          133364: $(I86OBJ):
        !          133365:        mkdir $(I86OBJ)
        !          133366: d149 1
        !          133367: a149 1
        !          133368: $(I86OBJ)/alloc.o: $(COHSRC)/alloc.c
        !          133369: d152 1
        !          133370: a152 1
        !          133371: $(I86OBJ)/as1.o: $(I86SRC)/as1.s
        !          133372: d155 1
        !          133373: a155 1
        !          133374: $(I86OBJ)/bio.o: $(COHSRC)/bio.c
        !          133375: d159 1
        !          133376: a159 1
        !          133377: $(I86OBJ)/clist.o: $(I86SRC)/clist.s $(SYSINC)/const.h
        !          133378: d164 1
        !          133379: a164 1
        !          133380: $(I86OBJ)/clock.o: $(COHSRC)/clock.c
        !          133381: d167 1
        !          133382: a167 1
        !          133383: $(I86OBJ)/ct.o: $(TTYSRC)/ct.c
        !          133384: d170 1
        !          133385: a170 1
        !          133386: $(I86OBJ)/defer.o: $(I86SRC)/defer.s
        !          133387: d173 1
        !          133388: a173 1
        !          133389: $(I86OBJ)/dmalock.o: $(I86SRC)/dmalock.c
        !          133390: d176 1
        !          133391: a176 1
        !          133392: $(I86OBJ)/exec.o: $(I86SRC)/exec.c
        !          133393: d179 1
        !          133394: a179 1
        !          133395: $(I86OBJ)/fd.o: $(COHSRC)/fd.c
        !          133396: d182 1
        !          133397: a182 1
        !          133398: $(I86OBJ)/fs1.o: $(COHSRC)/fs1.c
        !          133399: d185 1
        !          133400: a185 1
        !          133401: $(I86OBJ)/fs2.o: $(COHSRC)/fs2.c
        !          133402: d188 1
        !          133403: a188 1
        !          133404: $(I86OBJ)/fs3.o: $(COHSRC)/fs3.c
        !          133405: d191 1
        !          133406: a191 1
        !          133407: $(I86OBJ)/krunch.o: $(I86SRC)/krunch.c
        !          133408: d194 1
        !          133409: a194 1
        !          133410: $(I86OBJ)/ld.o: $(I86SRC)/ld.c
        !          133411: d197 1
        !          133412: a197 1
        !          133413: $(I86OBJ)/ldas.o: $(I86SRC)/ldas.s
        !          133414: d200 1
        !          133415: a200 1
        !          133416: $(I86OBJ)/main.o: $(USRSYS)/version $(COHSRC)/main.c
        !          133417: d203 1
        !          133418: a203 1
        !          133419: $(I86OBJ)/md1.o: $(I86SRC)/md1.c
        !          133420: d206 1
        !          133421: a206 1
        !          133422: $(I86OBJ)/misc.o: $(COHSRC)/misc.c
        !          133423: d209 1
        !          133424: a209 1
        !          133425: $(I86OBJ)/mmain.o: $(I86SRC)/mmain.c $(SYSINC)/const.h
        !          133426: d212 1
        !          133427: a212 1
        !          133428: $(I86OBJ)/null.o: $(COHSRC)/null.c
        !          133429: d215 1
        !          133430: a215 1
        !          133431: $(I86OBJ)/pipe.o: $(COHSRC)/pipe.c
        !          133432: d218 1
        !          133433: a218 1
        !          133434: $(I86OBJ)/poll.o: $(COHSRC)/poll.c
        !          133435: d221 1
        !          133436: a221 1
        !          133437: $(I86OBJ)/printf.o: $(COHSRC)/printf.c
        !          133438: d224 1
        !          133439: a224 1
        !          133440: $(I86OBJ)/proc.o: $(COHSRC)/proc.c
        !          133441: d227 1
        !          133442: a227 1
        !          133443: $(I86OBJ)/seg.o: $(COHSRC)/seg.c
        !          133444: d230 1
        !          133445: a230 1
        !          133446: $(I86OBJ)/sig.o: $(COHSRC)/sig.c
        !          133447: d233 1
        !          133448: a233 1
        !          133449: $(I86OBJ)/swap.o: $(KERSRC)/swap.c
        !          133450: d236 1
        !          133451: a236 1
        !          133452: $(I86OBJ)/elog.o: $(KERSRC)/elog.c
        !          133453: d239 1
        !          133454: a239 1
        !          133455: $(I86OBJ)/sys1.o: $(COHSRC)/sys1.c
        !          133456: d242 1
        !          133457: a242 1
        !          133458: $(I86OBJ)/sys2.o: $(COHSRC)/sys2.c
        !          133459: d245 1
        !          133460: a245 1
        !          133461: $(I86OBJ)/sys3.o: $(COHSRC)/sys3.c
        !          133462: d248 1
        !          133463: a248 1
        !          133464: $(I86OBJ)/tab.o: $(I86SRC)/tab.c
        !          133465: d251 1
        !          133466: a251 1
        !          133467: $(I86OBJ)/timeout.o: $(COHSRC)/timeout.c
        !          133468: d254 1
        !          133469: a254 1
        !          133470: $(I86OBJ)/trap.o: $(I86SRC)/trap.c
        !          133471: d257 1
        !          133472: a257 1
        !          133473: $(I86OBJ)/var.o: $(COHSRC)/var.c
        !          133474: d262 1
        !          133475: a262 1
        !          133476: $(DRVLIB)/support.a:   $(SRCOBJ)/cs_sel.o $(SRCOBJ)/clocked.o
        !          133477: d266 1
        !          133478: a266 1
        !          133479: $(SRCOBJ)/cs_sel.o: $(I86SRC)/cs_sel.s
        !          133480: d269 1
        !          133481: a269 1
        !          133482: $(SRCOBJ)/clocked.o: $(I86SRC)/clocked.c
        !          133483: d272 1
        !          133484: a272 1
        !          133485: $(DRVLIB)/tty.a:       $(DRVOBJ)/tty.o
        !          133486: d276 1
        !          133487: a276 1
        !          133488: $(DRVOBJ)/tty.o: $(TTYSRC)/tty.c
        !          133489: @
        !          133490: 
        !          133491: 
        !          133492: 1.3
        !          133493: log
        !          133494: @provided by hal
        !          133495: @
        !          133496: text
        !          133497: @a17 2
        !          133498: KERINC=/usr/src/sys/sys
        !          133499: DRVINC=/usr/src/sys/i8086/sys
        !          133500: d38 1
        !          133501: a38 1
        !          133502: CFLAGS= -I$(DRVINC) -I$(KERINC) -I$(SYSINC)
        !          133503: d88 1
        !          133504: a88 1
        !          133505:        $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          133506: d98 1
        !          133507: a98 1
        !          133508:        $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          133509: d110 1
        !          133510: a110 1
        !          133511:        $(KERINC)/coherent.h    $(SYSINC)/types.h $(SYSINC)/timeout.h \
        !          133512: d114 1
        !          133513: a114 1
        !          133514:        $(DRVINC)/dmac.h        \
        !          133515: d148 1
        !          133516: a148 1
        !          133517: C86FLAGS=-c -DNOMONITOR=1 -I$(DRVINC) -I$(KERINC) -I$(SYSINC)
        !          133518: @
        !          133519: 
        !          133520: 
        !          133521: 1.2
        !          133522: log
        !          133523: @new version provided by hal to handle environmental variable
        !          133524: for src box and to allow generic copies of this source to be distributed
        !          133525: with relative paths.
        !          133526: @
        !          133527: text
        !          133528: @@
        !          133529: 
        !          133530: 
        !          133531: 1.1
        !          133532: log
        !          133533: @Initial revision
        !          133534: @
        !          133535: text
        !          133536: @a14 2
        !          133537: USRSYS=/usr/sys
        !          133538: 
        !          133539: a19 1
        !          133540: USSINC=/usr/src/sys
        !          133541: d22 6
        !          133542: a27 6
        !          133543: COHSRC=/usr/src/sys/coh
        !          133544: DRVSRC=/usr/src/sys/i8086/drv
        !          133545: I86SRC=/usr/src/sys/i8086/src
        !          133546: IBMATSRC=/usr/src/sys/i8086/ibm_at
        !          133547: KERSRC=/usr/src/sys/ker
        !          133548: TTYSRC=/usr/src/sys/ttydrv
        !          133549: d30 4
        !          133550: a33 4
        !          133551: I86OBJ=/usr/src/sys/i8086/objects
        !          133552: DRVOBJ=/usr/src/sys/i8086/drv/objects
        !          133553: SRCOBJ=/usr/src/sys/i8086/src/objects
        !          133554: IBMATOBJ=/usr/src/sys/i8086/ibm_at/objects
        !          133555: d36 1
        !          133556: a36 1
        !          133557: DRVLIB=/usr/sys/lib
        !          133558: d150 1
        !          133559: a150 1
        !          133560: C86FLAGS=-c -DNOMONITOR=1 -I$(DRVINC) -I$(KERINC) -I$(SYSINC) -I$(USSINC)
        !          133561: @
        !          133562: 0707070064030054761005550000030000030000011777770507310746700004100000000422/newbits/kernel/USRSYS/RCS/RCS,vhead     1.1;
        !          133563: access   ;
        !          133564: symbols  ;
        !          133565: locks    bin:1.1;
        !          133566: comment  @@;
        !          133567: 
        !          133568: 
        !          133569: 1.1
        !          133570: date     91.06.10.14.15.08;  author bin;  state Exp;
        !          133571: branches ;
        !          133572: next   ;
        !          133573: 
        !          133574: 
        !          133575: desc
        !          133576: @
        !          133577: @
        !          133578: 
        !          133579: 
        !          133580: 
        !          133581: 1.1
        !          133582: log
        !          133583: @Initial revision
        !          133584: @
        !          133585: text
        !          133586: @ .&..#,RCS,-,RCSnew00318cGMakefile,v@
        !          133587: 0707070064030106221005550000030000030000011777770507310747000004100000010404/newbits/kernel/USRSYS/RCS/bld,vhead     1.6;
        !          133588: branch   ;
        !          133589: access   ;
        !          133590: symbols  ;
        !          133591: locks    bin:1.6;
        !          133592: comment  @@;
        !          133593: 
        !          133594: 
        !          133595: 1.6
        !          133596: date     91.07.24.08.05.48;  author bin;  state Exp;
        !          133597: branches ;
        !          133598: next     1.5;
        !          133599: 
        !          133600: 1.5
        !          133601: date     91.07.15.14.07.50;  author bin;  state Exp;
        !          133602: branches ;
        !          133603: next     1.4;
        !          133604: 
        !          133605: 1.4
        !          133606: date     91.07.03.13.16.54;  author bin;  state Exp;
        !          133607: branches ;
        !          133608: next     1.3;
        !          133609: 
        !          133610: 1.3
        !          133611: date     91.06.20.14.24.52;  author bin;  state Exp;
        !          133612: branches ;
        !          133613: next     1.2;
        !          133614: 
        !          133615: 1.2
        !          133616: date     91.06.17.12.44.48;  author bin;  state Exp;
        !          133617: branches ;
        !          133618: next     1.1;
        !          133619: 
        !          133620: 1.1
        !          133621: date     91.06.10.14.15.11;  author bin;  state Exp;
        !          133622: branches ;
        !          133623: next     ;
        !          133624: 
        !          133625: 
        !          133626: desc
        !          133627: @initial version prov by hal
        !          133628: @
        !          133629: 
        !          133630: 
        !          133631: 1.6
        !          133632: log
        !          133633: @update prov by hal
        !          133634: @
        !          133635: text
        !          133636: @:
        !          133637: :  Build a Coherent executable with a host adapter driver linked in.
        !          133638: :
        !          133639: if [ $USRSYS ]
        !          133640: then
        !          133641: if [ $USRSRC ]
        !          133642: then
        !          133643: if [ $KOBJ ]
        !          133644: then
        !          133645: if [ $LOBJ ]
        !          133646: then
        !          133647: DRIVERS="rm fl lp mm"
        !          133648: COH_TYPE=fl
        !          133649: HD=""
        !          133650: KB=nkb
        !          133651: for ARG
        !          133652: do
        !          133653:        case $ARG in
        !          133654:        at|aha|ss)
        !          133655:                HD=$ARG
        !          133656:                COH_TYPE=$ARG
        !          133657:                ;;
        !          133658:        kb|nkb|gkb)
        !          133659:                KB=$ARG
        !          133660:                ;;
        !          133661:        *)              echo "Usage: $0 { at | ss | aha } { kb | nkb | gkb }"
        !          133662:                        exit 0
        !          133663:                        ;;
        !          133664:        esac
        !          133665: done
        !          133666: DRIVERS="$KB $HD $DRIVERS"
        !          133667: echo "Kernel:    /coh.$COH_TYPE"
        !          133668: echo "Version:   `version ID`"
        !          133669: echo "Devices:   $DRIVERS"
        !          133670: 
        !          133671: : default root/pipe device
        !          133672: BOOTDEV="fva0"
        !          133673: echo "Default root/pipe device is $BOOTDEV."
        !          133674: 
        !          133675: ( cd $USRSRC/ldrv; make ld_support )                   || exit 1
        !          133676: ( cd $USRSRC/i8086/drv; make -f Mf.mwc install )       || exit 1
        !          133677: ( make kernel )                                                || exit 1
        !          133678: ./config.mwc ibm-at $DRIVERS root=$BOOTDEV                     || exit 1
        !          133679: cp coherent /tmp/coh                                   || exit 1
        !          133680: strip /tmp/coh                                         || exit 1
        !          133681: set `ls -s /tmp/coh`
        !          133682: SIZE=$1
        !          133683: rm /tmp/coh                                            || exit 1
        !          133684: echo "Coherent bootable limit is 138 blocks.  This kernel is $SIZE"
        !          133685: if [ $SIZE -gt 138 ] ;then
        !          133686:        echo 
        !          133687:        echo Your Coherent image exceeds the bootable limit of 138 blocks
        !          133688:        echo by `expr $SIZE - 138` 'block(s).'  You will need to decrease the
        !          133689:        echo size of your kernel in order to make it bootable.
        !          133690:        echo
        !          133691:        echo We suggest removing some of the non critical drivers from the
        !          133692:        echo default list of drivers linked into Coherent.  These additional
        !          133693:        echo drivers may then be linked as loadable drivers using the
        !          133694:        echo ldconfig script located in this directory.
        !          133695: fi
        !          133696: mv coherent /coh.$COH_TYPE
        !          133697: chown sys /coh.$COH_TYPE
        !          133698: chgrp sys /coh.$COH_TYPE
        !          133699: chmod 400 /coh.$COH_TYPE
        !          133700: echo "New kernel in /coh.$COH_TYPE"
        !          133701: ls -l /coh.$COH_TYPE
        !          133702: # the rest is error exits
        !          133703: else
        !          133704: echo "Error - LOBJ not defined - (e.g. /usr/lobj)"
        !          133705: fi
        !          133706: else
        !          133707: echo "Error - KOBJ not defined - (e.g. /usr/kobj)"
        !          133708: fi
        !          133709: else
        !          133710: echo "Error - USRSRC not defined - (e.g. /usr/src/sys)"
        !          133711: fi
        !          133712: else
        !          133713: echo "Error - USRSYS not defined - (e.g. /usr/sys)"
        !          133714: fi
        !          133715: @
        !          133716: 
        !          133717: 
        !          133718: 1.5
        !          133719: log
        !          133720: @update prov. by hal (moves objects to relocatable directories)
        !          133721: @
        !          133722: text
        !          133723: @d12 23
        !          133724: a34 17
        !          133725: HDDR=${1-"at"}
        !          133726: case $HDDR in
        !          133727: at)
        !          133728:        DRIVERS="at rm fl lp mm"
        !          133729:        ;;
        !          133730: ss)
        !          133731:        DRIVERS="ss rm fl lp mm"
        !          133732:        ;;
        !          133733: aha)
        !          133734:        DRIVERS="aha154x rm fl lp mm"
        !          133735:        ;;
        !          133736: *)
        !          133737:        echo "Usage: $0 { at | ss | aha }"
        !          133738:        exit 0
        !          133739:        ;;
        !          133740: esac
        !          133741: echo "Building kernel /coh.$HDDR Version `version ID` with drivers ($DRIVERS)."
        !          133742: d40 9
        !          133743: a48 10
        !          133744: ( cd $USRSRC/ldrv; make ld_support )                           || exit 1
        !          133745: ( cd $USRSRC/i8086/drv; make install )                         || exit 1
        !          133746: ( make kernel )                                                        || exit 1
        !          133747: ./config ibm-at $DRIVERS root=$BOOTDEV                         || exit 1
        !          133748: cp coherent /tmp/coh                                           || exit 1
        !          133749: strip /tmp/coh                                                 || exit 1
        !          133750: : the SIZE expression needs fewer backslashes since Steve fixed sh
        !          133751: :SIZE=`ls -s /tmp/coh | sed -n -e 's/^\\\(....\\\).*$/\\\1/p'`
        !          133752: SIZE=`ls -s /tmp/coh | sed -n -e 's/^\(....\).*$/\1/p'`
        !          133753: rm /tmp/coh                                                    || exit 1
        !          133754: d61 6
        !          133755: a66 6
        !          133756: mv coherent /coh.$HDDR
        !          133757: chown sys /coh.$HDDR
        !          133758: chgrp sys /coh.$HDDR
        !          133759: chmod 400 /coh.$HDDR
        !          133760: echo "New kernel in /coh.$HDDR"
        !          133761: ls -l /coh.$HDDR
        !          133762: d69 1
        !          133763: a69 1
        !          133764: echo "Error - LOBJ not defined - (e.g. /tmp/lobj)"
        !          133765: d72 1
        !          133766: a72 1
        !          133767: echo "Error - KOBJ not defined - (e.g. /tmp/kobj)"
        !          133768: @
        !          133769: 
        !          133770: 
        !          133771: 1.4
        !          133772: log
        !          133773: @updates provided by hal
        !          133774: @
        !          133775: text
        !          133776: @d8 4
        !          133777: d64 1
        !          133778: a64 1
        !          133779: echo "Error - USRSRC not defined - (was /usr/src/sys)"
        !          133780: d67 1
        !          133781: a67 1
        !          133782: echo "Error - USRSYS not defined - (was /usr/sys)"
        !          133783: d69 6
        !          133784: @
        !          133785: 
        !          133786: 
        !          133787: 1.3
        !          133788: log
        !          133789: @another hal update
        !          133790: @
        !          133791: text
        !          133792: @d24 1
        !          133793: a24 1
        !          133794: echo "Building kernel /coh.$HDDR with drivers ($DRIVERS)."
        !          133795: d30 1
        !          133796: a31 1
        !          133797: ( cd $USRSRC/ldrv; make ld_support )                           || exit 1
        !          133798: @
        !          133799: 
        !          133800: 
        !          133801: 1.2
        !          133802: log
        !          133803: @new version provided by hal to handle environmental variable
        !          133804: for src box and to allow generic copies of this source to be distributed
        !          133805: with relative paths.
        !          133806: @
        !          133807: text
        !          133808: @d31 1
        !          133809: @
        !          133810: 
        !          133811: 
        !          133812: 1.1
        !          133813: log
        !          133814: @Initial revision
        !          133815: @
        !          133816: text
        !          133817: @d2 1
        !          133818: a2 1
        !          133819: :      Build a Coherent executable
        !          133820: d4 4
        !          133821: d30 1
        !          133822: a30 1
        !          133823: ( cd /usr/src/sys/i8086/drv; make install )                    || exit 1
        !          133824: d57 7
        !          133825: @
        !          133826: 0707070064030054621005550000030000030000011777770507310747100004500000001355/newbits/kernel/USRSYS/RCS/confdrv,vhead     1.1;
        !          133827: access   ;
        !          133828: symbols  ;
        !          133829: locks    bin:1.1;
        !          133830: comment  @@;
        !          133831: 
        !          133832: 
        !          133833: 1.1
        !          133834: date     91.06.10.14.15.13;  author bin;  state Exp;
        !          133835: branches ;
        !          133836: next   ;
        !          133837: 
        !          133838: 
        !          133839: desc
        !          133840: @initial version prov by hal
        !          133841: @
        !          133842: 
        !          133843: 
        !          133844: 
        !          133845: 1.1
        !          133846: log
        !          133847: @Initial revision
        !          133848: @
        !          133849: text
        !          133850: @�.&..|aha154xzal0yal1xatwativdgufltgmsgrrhsqlppmmomsnmsgmqqlrmkrpjrs0irs1hsdgsemfshmesscss.cp340bss.futass.real`ss.short_st^tn�RCS,RCSt300307^@
        !          133851: 0707070064030053241005440000030000030000011777770507310747100004400000014270/newbits/kernel/USRSYS/RCS/config,vhead     1.1;
        !          133852: access   ;
        !          133853: symbols  ;
        !          133854: locks    bin:1.1;
        !          133855: comment  @@;
        !          133856: 
        !          133857: 
        !          133858: 1.1
        !          133859: date     91.06.10.14.15.15;  author bin;  state Exp;
        !          133860: branches ;
        !          133861: next   ;
        !          133862: 
        !          133863: 
        !          133864: desc
        !          133865: @initial version prov by hal
        !          133866: @
        !          133867: 
        !          133868: 
        !          133869: 
        !          133870: 1.1
        !          133871: log
        !          133872: @Initial revision
        !          133873: @
        !          133874: text
        !          133875: @:
        !          133876: :      configure a Coherent kernel for the AT
        !          133877: :
        !          133878: : usage: config [help]
        !          133879: :       config [stand=fha0]
        !          133880: :       config [stand=fva0]
        !          133881: :       config [stand=fha0] [standard] [root=DRV] [DRV ...]
        !          133882: :       config [stand=fva0] [standard] [root=DRV] [DRV ...]
        !          133883: 
        !          133884: :      initialize variables
        !          133885: :
        !          133886: ATSTANDARD=" fl lp mm "
        !          133887: ATKERNEL=atkernel.o
        !          133888: 
        !          133889: STANDARD="${ATSTANDARD}"
        !          133890: KERNEL="${ATKERNEL}"
        !          133891: LIBS="lib/tty.a lib/support.a"
        !          133892: BUILD=0
        !          133893: DEV=/tmp/dev
        !          133894: PASS1=""
        !          133895: PASS2=""
        !          133896: UNDEF=""
        !          133897: PATCH=""
        !          133898: ROOTDEV=""
        !          133899: INSTALL=""
        !          133900: 
        !          133901: case "$#" in
        !          133902: 0)     /bin/echo
        !          133903:        /bin/echo       "The following can be used as arguments to config:"
        !          133904:        /bin/echo
        !          133905:        /bin/cat doc/*
        !          133906:        exit 0
        !          133907:        ;;
        !          133908: esac
        !          133909: 
        !          133910: for ARG in $*
        !          133911: do
        !          133912:        case "${ARG}" in
        !          133913:        help)
        !          133914:                /bin/echo
        !          133915:                /bin/echo "The following can be used as arguments to config:"
        !          133916:                /bin/echo
        !          133917:                /bin/cat doc/*
        !          133918:                exit 0
        !          133919:                ;;
        !          133920:        ibm-at)
        !          133921:                STANDARD="${ATSTANDARD}"
        !          133922:                KERNEL="${ATKERNEL}"
        !          133923:                ;;
        !          133924:        *)
        !          133925:                PASS1="${PASS1} ${ARG}"
        !          133926:                ;;
        !          133927:        esac
        !          133928: done
        !          133929: 
        !          133930: for ARG in ${PASS1}
        !          133931: do
        !          133932:        case "${ARG}" in
        !          133933:        standard)
        !          133934:                PASS2="${STANDARD} ${PASS2}"
        !          133935:                ;;
        !          133936:        stand\=fha0)
        !          133937:                /etc/umount /dev/fha0 2> /dev/null
        !          133938:                echo -n "Insert 5.25 high capacity floppy into drive 0, press return [y to format]: "
        !          133939:                read x
        !          133940:                case "x$x" in
        !          133941:                xy)     /etc/fdformat -i 6 /dev/fha0 || exit 1 ;;
        !          133942:                esac
        !          133943:                /etc/mkfs  /dev/fha0 2400               || exit 1
        !          133944:                /bin/cp /conf/boot.fha /dev/fha0        || exit 1
        !          133945:                /etc/mount /dev/fha0 /f0                || exit 1
        !          133946:                /bin/mkdir /f0/bin /f0/dev /f0/etc /f0/mnt /f0/tmp || exit 1
        !          133947:                umask 011
        !          133948:                /etc/mknod /f0/dev/null c 0 0           || exit 1
        !          133949:                /bin/ln -f /f0/dev/null /f0/dev/swap    || exit 1
        !          133950:                umask 077
        !          133951:                /etc/mknod /f0/dev/mem  c 0 1           || exit 1
        !          133952:                /etc/mknod /f0/dev/kmem c 0 2           || exit 1
        !          133953:                /bin/chmod 777 /f0/tmp                  || exit 1
        !          133954:                umask 022
        !          133955: 
        !          133956:                /bin/cp /bin/bad /bin/cat /bin/cp /bin/cpdir \
        !          133957:                        /bin/db /bin/dd /bin/df /bin/du \
        !          133958:                        /bin/echo /bin/kill \
        !          133959:                        /bin/ls /bin/mkdir /bin/mv /bin/ncheck \
        !          133960:                        /bin/rm /bin/sh /bin/stty /bin/sync \
        !          133961:                        /bin/time /bin/true /f0/bin || exit 1
        !          133962:                /bin/cp /etc/fsck /etc/init /etc/badscan /etc/clri \
        !          133963:                        /etc/fdisk /etc/mkfs \
        !          133964:                        /etc/mknod /etc/mount /etc/umount /f0/etc || exit 1
        !          133965: 
        !          133966:                DEV=/f0/dev
        !          133967:                :
        !          133968:                : Place a Coherent image out on drive 0.
        !          133969:                : Add a floppy root patched version as a file called 'stand'.
        !          133970:                :
        !          133971:                INSTALL="umask 022; set -e ; /bin/cp coherent /f0 ; \
        !          133972:                        /conf/patch coherent 'rootdev_=makedev(4,14)' ; \
        !          133973:                        /conf/patch coherent 'pipedev_=makedev(4,14)' ; \
        !          133974:                        /bin/cp coherent /f0/stand ; /bin/strip /f0/stand ; \
        !          133975:                        /etc/umount /dev/fha0 ; /bin/df /dev/fha0"
        !          133976: 
        !          133977:                case "$#" in
        !          133978:                1) eval ${INSTALL} ; exit 0 ;;
        !          133979:                esac
        !          133980:                ;;
        !          133981: 
        !          133982:        stand\=fva0)
        !          133983:                /etc/umount /dev/fva0 2> /dev/null
        !          133984:                echo -n "Insert high density 3.5 floppy into drive 0, press return [y to format]: "
        !          133985:                read x
        !          133986:                case "x$x" in
        !          133987:                xy)     /etc/fdformat -i 6 /dev/fva0 || exit 1 ;;
        !          133988:                esac
        !          133989:                /etc/mkfs  /dev/fva0 2880               || exit 1
        !          133990:                /bin/cp /conf/boot.fva /dev/fva0        || exit 1
        !          133991:                /etc/mount /dev/fva0 /f0                || exit 1
        !          133992:                /bin/mkdir /f0/bin /f0/dev /f0/etc /f0/mnt /f0/tmp || exit 1
        !          133993:                umask 011
        !          133994:                /etc/mknod /f0/dev/null c 0 0           || exit 1
        !          133995:                /bin/ln -f /f0/dev/null /f0/dev/swap    || exit 1
        !          133996:                umask 077
        !          133997:                /etc/mknod /f0/dev/mem  c 0 1           || exit 1
        !          133998:                /etc/mknod /f0/dev/kmem c 0 2           || exit 1
        !          133999:                /bin/chmod 777 /f0/tmp                  || exit 1
        !          134000:                umask 022
        !          134001: 
        !          134002:                /bin/cp /bin/bad /bin/cat /bin/cp /bin/cpdir \
        !          134003:                        /bin/db /bin/dd /bin/df /bin/du \
        !          134004:                        /bin/echo /bin/kill \
        !          134005:                        /bin/ls /bin/mkdir /bin/mv /bin/ncheck \
        !          134006:                        /bin/rm /bin/sh /bin/stty /bin/sync \
        !          134007:                        /bin/time /bin/true /f0/bin || exit 1
        !          134008:                /bin/cp /etc/fsck /etc/init /etc/badscan /etc/clri \
        !          134009:                        /etc/fdisk /etc/mkfs \
        !          134010:                        /etc/mknod /etc/mount /etc/umount /f0/etc || exit 1
        !          134011: 
        !          134012:                DEV=/f0/dev
        !          134013:                :
        !          134014:                : Place a Coherent image out on drive 0.
        !          134015:                : Add a floppy root patched version as a file called 'stand'.
        !          134016:                :
        !          134017:                INSTALL="umask 022; set -e ; /bin/cp coherent /f0 ; \
        !          134018:                        /conf/patch coherent 'rootdev_=makedev(4,15)' ; \
        !          134019:                        /conf/patch coherent 'pipedev_=makedev(4,15)' ; \
        !          134020:                        /bin/cp coherent /f0/stand ; /bin/strip /f0/stand ; \
        !          134021:                        /etc/umount /dev/fva0 ; /bin/df /dev/fva0"
        !          134022: 
        !          134023:                case "$#" in
        !          134024:                1) eval ${INSTALL} ; exit 0 ;;
        !          134025:                esac
        !          134026:                ;;
        !          134027: 
        !          134028:        DEV\=*)
        !          134029:                DEV=`/bin/echo "${ARG}" | /bin/sed -e 's/^....//'`
        !          134030:                ;;
        !          134031:        *)
        !          134032:                PASS2="${PASS2} ${ARG}"
        !          134033:                ;;
        !          134034:        esac
        !          134035: done
        !          134036: 
        !          134037: :      get the proper driver information
        !          134038: :
        !          134039: 
        !          134040: for ARG in ${PASS2}
        !          134041: do
        !          134042:        case "$ARG" in
        !          134043: 
        !          134044:        root\=fva0)
        !          134045:                ROOTDEV="makedev(4,15)"
        !          134046:                . confdrv/fl
        !          134047:                ;;
        !          134048:        root\=fha0)
        !          134049:                ROOTDEV="makedev(4,14)"
        !          134050:                . confdrv/fl
        !          134051:                ;;
        !          134052:        root\=*)
        !          134053:                ARG=`/bin/echo "${ARG}" | /bin/sed -e 's/^.....//'`
        !          134054: 
        !          134055:                case "${ARG}" in
        !          134056:                *[0123][abcdx])
        !          134057:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          134058:                        ;;
        !          134059:                *)
        !          134060:                        FILE="${ARG}"
        !          134061:                        ;;
        !          134062:                esac
        !          134063: 
        !          134064:                if /bin/test -r confdrv/${FILE}
        !          134065:                then
        !          134066:                        . confdrv/${FILE}
        !          134067:                        ROOTDEV="${MAKEDEV}"
        !          134068: /bin/echo "'confdrv/${FILE}' executing"
        !          134069:                else
        !          134070:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          134071:                        exit 1
        !          134072:                fi
        !          134073:                ;;
        !          134074: 
        !          134075:        swap)
        !          134076:                ;;
        !          134077: 
        !          134078:        swap\=*)
        !          134079:                ARG=`/bin/echo "${ARG}" | /bin/sed -e 's/^.....//'`
        !          134080: 
        !          134081:                case "${ARG}" in
        !          134082:                *[0123][abcdx])
        !          134083:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          134084:                        if [ -d "${DEV-/dev}" ]
        !          134085:                        then
        !          134086:                                /bin/ln -f ${DEV-/dev}/${ARG} ${DEV-/dev}/swap
        !          134087:                        fi
        !          134088:                        ;;
        !          134089:                *)
        !          134090:                        FILE="${ARG}"
        !          134091:                        ;;
        !          134092:                esac
        !          134093: 
        !          134094:                if /bin/test -r confdrv/${FILE}
        !          134095:                then
        !          134096:                        . confdrv/${FILE}
        !          134097:                        PATCH="${PATCH} swapdev_=${MAKEDEV}"
        !          134098:                        /bin/echo "Swap device will be ${DEV-/dev}/${ARG}"
        !          134099:                        /bin/echo "See documentation before enabling"
        !          134100:                else
        !          134101:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          134102:                        exit 1
        !          134103:                fi
        !          134104:                ;;
        !          134105: 
        !          134106:        *\=*)
        !          134107:                PATCH="${PATCH} ${ARG}"
        !          134108:                ;;
        !          134109: 
        !          134110:        *)
        !          134111:                case "${ARG}" in
        !          134112:                *[0123][abcdx])
        !          134113:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          134114:                        ;;
        !          134115:                *)
        !          134116:                        FILE="${ARG}"
        !          134117:                        ;;
        !          134118:                esac
        !          134119: 
        !          134120:                if /bin/test -r confdrv/${FILE}
        !          134121:                then
        !          134122:                        . confdrv/${FILE}
        !          134123:                        case "${ROOTDEV}" in
        !          134124:                        ?*)     ;;
        !          134125:                        *)      ROOTDEV="${MAKEDEV}" ;;
        !          134126:                        esac
        !          134127:                else
        !          134128:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          134129:                        exit 1
        !          134130:                fi
        !          134131:                ;;
        !          134132:        esac
        !          134133: done
        !          134134: ROOTDEV="${ROOTDEV-makedev(4,14)}"
        !          134135: 
        !          134136: :      include stub drivers
        !          134137: :
        !          134138: UNDEF="${UNDEF} ${LIBS}"
        !          134139: 
        !          134140: :      make the proper root and pipe devices
        !          134141: :
        !          134142: PATCH="${PATCH} rootdev_=${ROOTDEV} pipedev_=${ROOTDEV}"
        !          134143: 
        !          134144: set -ex
        !          134145: :
        !          134146: :      create a kernel with the desired device drivers
        !          134147: :
        !          134148: /bin/ld -i -x -o coherent ${KERNEL} ${UNDEF} -lc
        !          134149: :
        !          134150: :      enable the desired device drivers
        !          134151: :
        !          134152: /conf/patch coherent ALLSIZE_=16384 NBUF_=32 NCLIST_=24 ${PATCH}
        !          134153: /bin/chmod 644 coherent
        !          134154: /bin/chown sys coherent
        !          134155: /bin/chgrp sys coherent
        !          134156: /bin/sync
        !          134157: :
        !          134158: eval ${INSTALL}
        !          134159: @
        !          134160: 0707070064030053231005550000030000030000011777770507310747300004100000001135/newbits/kernel/USRSYS/RCS/doc,vhead     1.1;
        !          134161: access   ;
        !          134162: symbols  ;
        !          134163: locks    bin:1.1;
        !          134164: comment  @@;
        !          134165: 
        !          134166: 
        !          134167: 1.1
        !          134168: date     91.06.10.14.15.18;  author bin;  state Exp;
        !          134169: branches ;
        !          134170: next   ;
        !          134171: 
        !          134172: 
        !          134173: desc
        !          134174: @initial version prov by hal
        !          134175: @
        !          134176: 
        !          134177: 
        !          134178: 
        !          134179: 1.1
        !          134180: log
        !          134181: @Initial revision
        !          134182: @
        !          134183: text
        !          134184: @[.&..[aha154xZalYatXatiWflVgmUgrThsSlpRmmQmsPmsgOrmNrpMrsLsemKshmJstIswapHtnRCS,RCSt300314L@
        !          134185: 0707070064030053221004440000030000030000011777770507310747300004500000000446/newbits/kernel/USRSYS/RCS/ker.inc,vhead     1.1;
        !          134186: access   ;
        !          134187: symbols  ;
        !          134188: locks    bin:1.1;
        !          134189: comment  @ * @;
        !          134190: 
        !          134191: 
        !          134192: 1.1
        !          134193: date     91.06.10.14.15.19;  author bin;  state Exp;
        !          134194: branches ;
        !          134195: next   ;
        !          134196: 
        !          134197: 
        !          134198: desc
        !          134199: @initial version prov by hal
        !          134200: @
        !          134201: 
        !          134202: 
        !          134203: 
        !          134204: 1.1
        !          134205: log
        !          134206: @Initial revision
        !          134207: @
        !          134208: text
        !          134209: @/usr/include
        !          134210: /usr/include/sys
        !          134211: /usr/src/sys/sys
        !          134212: /usr/src/sys/i8086/sys
        !          134213: @
        !          134214: 0707070064030053211004440000030000030000011777770507310747300004500000000601/newbits/kernel/USRSYS/RCS/ker.src,vhead     1.1;
        !          134215: access   ;
        !          134216: symbols  ;
        !          134217: locks    bin:1.1;
        !          134218: comment  @ * @;
        !          134219: 
        !          134220: 
        !          134221: 1.1
        !          134222: date     91.06.10.14.15.20;  author bin;  state Exp;
        !          134223: branches ;
        !          134224: next   ;
        !          134225: 
        !          134226: 
        !          134227: desc
        !          134228: @initial version prov by hal
        !          134229: @
        !          134230: 
        !          134231: 
        !          134232: 
        !          134233: 1.1
        !          134234: log
        !          134235: @Initial revision
        !          134236: @
        !          134237: text
        !          134238: @/usr/src/sys/coh
        !          134239: /usr/src/sys/i8086/drv
        !          134240: /usr/src/sys/i8086/src
        !          134241: /usr/src/sys/i8086/ibm_at
        !          134242: /usr/src/sys/ker
        !          134243: /usr/src/sys/ttydrv
        !          134244: /usr/src/sys/ldrv
        !          134245: /usr/src/cmd/etc
        !          134246: @
        !          134247: 0707070064030053201005440000030000030000011777770507310747300004600000002256/newbits/kernel/USRSYS/RCS/ldconfig,vhead     1.1;
        !          134248: access   ;
        !          134249: symbols  ;
        !          134250: locks    bin:1.1;
        !          134251: comment  @@;
        !          134252: 
        !          134253: 
        !          134254: 1.1
        !          134255: date     91.06.10.14.15.20;  author bin;  state Exp;
        !          134256: branches ;
        !          134257: next   ;
        !          134258: 
        !          134259: 
        !          134260: desc
        !          134261: @initial version prov by hal
        !          134262: @
        !          134263: 
        !          134264: 
        !          134265: 
        !          134266: 1.1
        !          134267: log
        !          134268: @Initial revision
        !          134269: @
        !          134270: text
        !          134271: @:
        !          134272: :      configure a loadable driver
        !          134273: :
        !          134274: : usage: ldconfig [swap] [DRV ...]
        !          134275: :
        !          134276: BUILD=0
        !          134277: DEV=/dev
        !          134278: PATCH=""
        !          134279: UNDEF=""
        !          134280: LDMOD=""
        !          134281: PASS1=""
        !          134282: 
        !          134283: for ARG in $*
        !          134284: do
        !          134285:        case "${ARG}" in
        !          134286:        DEV\=*)
        !          134287:                DEV=`/bin/echo "${ARG}" | /bin/sed -e 's/^....//'`
        !          134288:                ;;
        !          134289:        *)
        !          134290:                PASS1="${PASS1} ${ARG}"
        !          134291:                ;;
        !          134292:        esac
        !          134293: done
        !          134294: 
        !          134295: for ARG in ${PASS1}
        !          134296: do
        !          134297:        case "$ARG" in
        !          134298: 
        !          134299:        swap)
        !          134300:                /bin/echo "ldrv/swap: "
        !          134301:                ld -r -o ldrv/swap lib/ldrts0.o lib/ldswap.o lib/ldlib.a
        !          134302:                LDMOD=""
        !          134303:                ;;
        !          134304: 
        !          134305:        *\=*)
        !          134306:                LDMOD="${LDMOD} ${ARG}"
        !          134307:                ;;
        !          134308: 
        !          134309:        *)
        !          134310:                case "${ARG}" in
        !          134311:                *[0123][abcdx])
        !          134312:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          134313:                        ;;
        !          134314:                *)
        !          134315:                        FILE="${ARG}"
        !          134316:                        ;;
        !          134317:                esac
        !          134318: 
        !          134319:                /bin/echo "ldrv/${FILE}: "
        !          134320:                if /bin/test -r confdrv/${FILE}
        !          134321:                then
        !          134322:                        UNDEF=""
        !          134323:                        . confdrv/${FILE}
        !          134324:                        /bin/ld -r -o ldrv/${FILE} lib/ldrts0.o \
        !          134325:                                lib/ldmain.o ${UNDEF} \
        !          134326:                                lib/ldlib.a || exit 1
        !          134327:                        case "${LDMOD}" in
        !          134328:                        "")     ;;
        !          134329:                        *)      /conf/patch ldrv/${FILE} ${LDMOD}
        !          134330:                        esac
        !          134331:                else
        !          134332:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          134333:                        exit 1
        !          134334:                fi
        !          134335:                LDMOD=""
        !          134336:                ;;
        !          134337:        esac
        !          134338: done
        !          134339: @
        !          134340: 0707070064030053171004440000030000030000011777770507310747300004600000000337/newbits/kernel/USRSYS/RCS/makedisk,vhead     1.1;
        !          134341: access   ;
        !          134342: symbols  ;
        !          134343: locks    bin:1.1;
        !          134344: comment  @@;
        !          134345: 
        !          134346: 
        !          134347: 1.1
        !          134348: date     91.06.10.14.15.21;  author bin;  state Exp;
        !          134349: branches ;
        !          134350: next   ;
        !          134351: 
        !          134352: 
        !          134353: desc
        !          134354: @initial version prov by hal
        !          134355: @
        !          134356: 
        !          134357: 
        !          134358: 
        !          134359: 1.1
        !          134360: log
        !          134361: @Initial revision
        !          134362: @
        !          134363: text
        !          134364: @c
        !          134365: @
        !          134366: 0707070064030053161005550000030000030000011777770507310747400004600000000600/newbits/kernel/USRSYS/RCS/makefind,vhead     1.1;
        !          134367: access   ;
        !          134368: symbols  ;
        !          134369: locks    bin:1.1;
        !          134370: comment  @@;
        !          134371: 
        !          134372: 
        !          134373: 1.1
        !          134374: date     91.06.10.14.15.22;  author bin;  state Exp;
        !          134375: branches ;
        !          134376: next   ;
        !          134377: 
        !          134378: 
        !          134379: desc
        !          134380: @initial version prov by hal
        !          134381: @
        !          134382: 
        !          134383: 
        !          134384: 
        !          134385: 1.1
        !          134386: log
        !          134387: @Initial revision
        !          134388: @
        !          134389: text
        !          134390: @# makefind - search kernel and driver Makefiles for a pattern
        !          134391: for f in `cat /usr/sys/ker.src`
        !          134392: do
        !          134393:   if grep -n $1 $f/M* 2> /dev/null
        !          134394:   then
        !          134395:        echo $f/M*
        !          134396:   fi
        !          134397: done
        !          134398: @
        !          134399: 0707070064030110631005550000030000030000011777770507310747400004500000002046/newbits/kernel/USRSYS/RCS/version,vhead     1.5;
        !          134400: branch   ;
        !          134401: access   ;
        !          134402: symbols  ;
        !          134403: locks    bin:1.5;
        !          134404: comment  @@;
        !          134405: 
        !          134406: 
        !          134407: 1.5
        !          134408: date     91.07.24.08.06.21;  author bin;  state Exp;
        !          134409: branches ;
        !          134410: next     1.4;
        !          134411: 
        !          134412: 1.4
        !          134413: date     91.07.15.14.08.36;  author bin;  state Exp;
        !          134414: branches ;
        !          134415: next     1.3;
        !          134416: 
        !          134417: 1.3
        !          134418: date     91.07.03.13.17.03;  author bin;  state Exp;
        !          134419: branches ;
        !          134420: next     1.2;
        !          134421: 
        !          134422: 1.2
        !          134423: date     91.06.20.14.25.05;  author bin;  state Exp;
        !          134424: branches ;
        !          134425: next     1.1;
        !          134426: 
        !          134427: 1.1
        !          134428: date     91.06.10.14.15.23;  author bin;  state Exp;
        !          134429: branches ;
        !          134430: next     ;
        !          134431: 
        !          134432: 
        !          134433: desc
        !          134434: @initial version prov by hal
        !          134435: @
        !          134436: 
        !          134437: 
        !          134438: 1.5
        !          134439: log
        !          134440: @update prov by hal
        !          134441: @
        !          134442: text
        !          134443: @version=1
        !          134444: release=2
        !          134445: revision=0.DK
        !          134446: arg=${1-foo}
        !          134447: if [ $arg = "ID" ]
        !          134448: then
        !          134449:        echo "$version.$release.$revision"
        !          134450: else
        !          134451:        echo -n '-DVERSION="'$version.$release.$revision'"'
        !          134452: fi
        !          134453: @
        !          134454: 
        !          134455: 
        !          134456: 1.4
        !          134457: log
        !          134458: @changes by hal
        !          134459: @
        !          134460: text
        !          134461: @d1 1
        !          134462: a1 1
        !          134463: version=3
        !          134464: d3 1
        !          134465: a3 1
        !          134466: revision=0.G
        !          134467: @
        !          134468: 
        !          134469: 
        !          134470: 1.3
        !          134471: log
        !          134472: @updates provided by hal
        !          134473: @
        !          134474: text
        !          134475: @d3 1
        !          134476: a3 1
        !          134477: revision=0xx
        !          134478: @
        !          134479: 
        !          134480: 
        !          134481: 1.2
        !          134482: log
        !          134483: @another hal update
        !          134484: @
        !          134485: text
        !          134486: @d3 8
        !          134487: a10 2
        !          134488: revision=0
        !          134489: echo -n '-DVERSION="'$version.$release.$revision'"'
        !          134490: @
        !          134491: 
        !          134492: 
        !          134493: 1.1
        !          134494: log
        !          134495: @Initial revision
        !          134496: @
        !          134497: text
        !          134498: @d3 1
        !          134499: a3 1
        !          134500: revision=0_beta
        !          134501: @
        !          134502: 0707070064030112211005550000030000030000011777770507310747400004400000001153/newbits/kernel/USRSYS/RCS/usrsrc,vhead     1.1;
        !          134503: branch   ;
        !          134504: access   ;
        !          134505: symbols  ;
        !          134506: locks    bin:1.1; strict;
        !          134507: comment  @# @;
        !          134508: 
        !          134509: 
        !          134510: 1.1
        !          134511: date     91.07.15.14.08.20;  author bin;  state Exp;
        !          134512: branches ;
        !          134513: next     ;
        !          134514: 
        !          134515: 
        !          134516: desc
        !          134517: @init ver prov by hal
        !          134518: @
        !          134519: 
        !          134520: 
        !          134521: 
        !          134522: 1.1
        !          134523: log
        !          134524: @Initial revision
        !          134525: @
        !          134526: text
        !          134527: @# back up USRSRC directories
        !          134528: TMPFILE=/tmp/usrsrc.$$
        !          134529: rm -f $TMPFILE
        !          134530: cd $USRSRC
        !          134531: for DIR in i8086/drv i8086/drv/tools i8086/ibm_at i8086/src coh ttydrv ker ldrv
        !          134532: do
        !          134533:        for FILE in `ls $USRSRC/$DIR`
        !          134534:        do
        !          134535:                echo $DIR/$FILE >> $TMPFILE
        !          134536:        done
        !          134537: done
        !          134538: echo "$TMPFILE created"
        !          134539: echo -n "Insert 3-1/2\" formatted diskette and press <Enter> "
        !          134540: read JUNK
        !          134541: cpio -ocv < $TMPFILE > /dev/rfva1
        !          134542: rm $TMPFILE
        !          134543: @
        !          134544: 0707070064030112221005550000030000030000011777770507310747400004400000001075/newbits/kernel/USRSYS/RCS/usrsys,vhead     1.1;
        !          134545: branch   ;
        !          134546: access   ;
        !          134547: symbols  ;
        !          134548: locks    bin:1.1; strict;
        !          134549: comment  @# @;
        !          134550: 
        !          134551: 
        !          134552: 1.1
        !          134553: date     91.07.15.14.08.31;  author bin;  state Exp;
        !          134554: branches ;
        !          134555: next     ;
        !          134556: 
        !          134557: 
        !          134558: desc
        !          134559: @init ver prov by hal
        !          134560: @
        !          134561: 
        !          134562: 
        !          134563: 
        !          134564: 1.1
        !          134565: log
        !          134566: @Initial revision
        !          134567: @
        !          134568: text
        !          134569: @# back up USRSYS directories
        !          134570: TMPFILE=/tmp/usrsys.$$
        !          134571: rm -f $TMPFILE
        !          134572: cd $USRSYS
        !          134573: for DIR in . ldrv doc confdrv lib
        !          134574: do
        !          134575:        for FILE in `ls $USRSYS/$DIR`
        !          134576:        do
        !          134577:                echo $DIR/$FILE >> $TMPFILE
        !          134578:        done
        !          134579: done
        !          134580: echo "$TMPFILE created"
        !          134581: echo -n "Insert 3-1/2\" formatted diskette and press <Enter> "
        !          134582: read JUNK
        !          134583: cpio -ocv < $TMPFILE > /dev/rfva1
        !          134584: rm $TMPFILE
        !          134585: @
        !          134586: 0707070064030110621005550000030000030000011777770507310747400004300000003204/newbits/kernel/USRSYS/RCS/Build,vhead     1.1;
        !          134587: branch   ;
        !          134588: access   ;
        !          134589: symbols  ;
        !          134590: locks    bin:1.1; strict;
        !          134591: comment  @# @;
        !          134592: 
        !          134593: 
        !          134594: 1.1
        !          134595: date     91.07.24.08.05.17;  author bin;  state Exp;
        !          134596: branches ;
        !          134597: next     ;
        !          134598: 
        !          134599: 
        !          134600: desc
        !          134601: @build script for scsi kernels
        !          134602: @
        !          134603: 
        !          134604: 
        !          134605: 
        !          134606: 1.1
        !          134607: log
        !          134608: @Initial revision
        !          134609: @
        !          134610: text
        !          134611: @:
        !          134612: :  Build a Coherent executable with a host adapter driver linked in.
        !          134613: :
        !          134614: DRIVERS="rm fl lp mm"
        !          134615: COH_TYPE=fl
        !          134616: HD=""
        !          134617: KB=nkb
        !          134618: for ARG
        !          134619: do
        !          134620:        case $ARG in
        !          134621:        at|aha|ss)
        !          134622:                HD=$ARG
        !          134623:                COH_TYPE=$ARG
        !          134624:                ;;
        !          134625:        kb|nkb)
        !          134626:                KB=$ARG
        !          134627:                ;;
        !          134628:        *)              echo "Usage: $0 { at | ss | aha } { kb | nkb }"
        !          134629:                        exit 0
        !          134630:                        ;;
        !          134631:        esac
        !          134632: done
        !          134633: DRIVERS="$KB $HD $DRIVERS"
        !          134634: echo "Kernel:    /coh.$COH_TYPE"
        !          134635: echo "Devices:   $DRIVERS"
        !          134636: 
        !          134637: : default root/pipe device
        !          134638: BOOTDEV="fva0"
        !          134639: echo "Default root/pipe device is $BOOTDEV."
        !          134640: 
        !          134641: ( cd /usr/src/sys/i8086/drv; make -f Makefile install )        || exit 1
        !          134642: ./config ibm-at $DRIVERS root=$BOOTDEV                 || exit 1
        !          134643: cp coherent /tmp/coh                                   || exit 1
        !          134644: strip /tmp/coh                                         || exit 1
        !          134645: set `ls -s /tmp/coh`
        !          134646: SIZE=$1
        !          134647: rm /tmp/coh                                            || exit 1
        !          134648: echo "Coherent bootable limit is 138 blocks.  This kernel is $SIZE"
        !          134649: if [ $SIZE -gt 138 ] ;then
        !          134650:        echo 
        !          134651:        echo Your Coherent image exceeds the bootable limit of 138 blocks
        !          134652:        echo by `expr $SIZE - 138` 'block(s).'  You will need to decrease the
        !          134653:        echo size of your kernel in order to make it bootable.
        !          134654:        echo
        !          134655:        echo We suggest removing some of the non critical drivers from the
        !          134656:        echo default list of drivers linked into Coherent.  These additional
        !          134657:        echo drivers may then be linked as loadable drivers using the
        !          134658:        echo ldconfig script located in this directory.
        !          134659: fi
        !          134660: mv coherent /coh.$COH_TYPE
        !          134661: chown sys /coh.$COH_TYPE
        !          134662: chgrp sys /coh.$COH_TYPE
        !          134663: chmod 400 /coh.$COH_TYPE
        !          134664: echo "New kernel in /coh.$COH_TYPE"
        !          134665: ls -l /coh.$COH_TYPE
        !          134666: @
        !          134667: 0707070064030053131005440000030000030000011777770507310747500005000000014263/newbits/kernel/USRSYS/RCS/config.mwc,vhead     1.1;
        !          134668: branch   ;
        !          134669: access   ;
        !          134670: symbols  ;
        !          134671: locks    bin:1.1; strict;
        !          134672: comment  @@;
        !          134673: 
        !          134674: 
        !          134675: 1.1
        !          134676: date     91.07.24.08.06.00;  author bin;  state Exp;
        !          134677: branches ;
        !          134678: next     ;
        !          134679: 
        !          134680: 
        !          134681: desc
        !          134682: @@
        !          134683: 
        !          134684: 
        !          134685: 
        !          134686: 1.1
        !          134687: log
        !          134688: @Initial revision
        !          134689: @
        !          134690: text
        !          134691: @:
        !          134692: :      configure a Coherent kernel for the AT
        !          134693: :
        !          134694: : usage: config [help]
        !          134695: :       config [stand=fha0]
        !          134696: :       config [stand=fva0]
        !          134697: :       config [stand=fha0] [standard] [root=DRV] [DRV ...]
        !          134698: :       config [stand=fva0] [standard] [root=DRV] [DRV ...]
        !          134699: 
        !          134700: :      initialize variables
        !          134701: :
        !          134702: ATSTANDARD=" fl lp mm "
        !          134703: ATKERNEL=atkernel.o
        !          134704: 
        !          134705: STANDARD="${ATSTANDARD}"
        !          134706: KERNEL="${ATKERNEL}"
        !          134707: LIBS="lib/tty.a lib/support.a"
        !          134708: BUILD=0
        !          134709: DEV=/tmp/dev
        !          134710: PASS1=""
        !          134711: PASS2=""
        !          134712: UNDEF=""
        !          134713: PATCH=""
        !          134714: ROOTDEV=""
        !          134715: INSTALL=""
        !          134716: 
        !          134717: case "$#" in
        !          134718: 0)     /bin/echo
        !          134719:        /bin/echo       "The following can be used as arguments to config:"
        !          134720:        /bin/echo
        !          134721:        /bin/cat doc/*
        !          134722:        exit 0
        !          134723:        ;;
        !          134724: esac
        !          134725: 
        !          134726: for ARG in $*
        !          134727: do
        !          134728:        case "${ARG}" in
        !          134729:        help)
        !          134730:                /bin/echo
        !          134731:                /bin/echo "The following can be used as arguments to config:"
        !          134732:                /bin/echo
        !          134733:                /bin/cat doc/*
        !          134734:                exit 0
        !          134735:                ;;
        !          134736:        ibm-at)
        !          134737:                STANDARD="${ATSTANDARD}"
        !          134738:                KERNEL="${ATKERNEL}"
        !          134739:                ;;
        !          134740:        *)
        !          134741:                PASS1="${PASS1} ${ARG}"
        !          134742:                ;;
        !          134743:        esac
        !          134744: done
        !          134745: 
        !          134746: for ARG in ${PASS1}
        !          134747: do
        !          134748:        case "${ARG}" in
        !          134749:        standard)
        !          134750:                PASS2="${STANDARD} ${PASS2}"
        !          134751:                ;;
        !          134752:        stand\=fha0)
        !          134753:                /etc/umount /dev/fha0 2> /dev/null
        !          134754:                echo -n "Insert 5.25 high capacity floppy into drive 0, press return [y to format]: "
        !          134755:                read x
        !          134756:                case "x$x" in
        !          134757:                xy)     /etc/fdformat -i 6 /dev/fha0 || exit 1 ;;
        !          134758:                esac
        !          134759:                /etc/mkfs  /dev/fha0 2400               || exit 1
        !          134760:                /bin/cp /conf/boot.fha /dev/fha0        || exit 1
        !          134761:                /etc/mount /dev/fha0 /f0                || exit 1
        !          134762:                /bin/mkdir /f0/bin /f0/dev /f0/etc /f0/mnt /f0/tmp || exit 1
        !          134763:                umask 011
        !          134764:                /etc/mknod /f0/dev/null c 0 0           || exit 1
        !          134765:                /bin/ln -f /f0/dev/null /f0/dev/swap    || exit 1
        !          134766:                umask 077
        !          134767:                /etc/mknod /f0/dev/mem  c 0 1           || exit 1
        !          134768:                /etc/mknod /f0/dev/kmem c 0 2           || exit 1
        !          134769:                /bin/chmod 777 /f0/tmp                  || exit 1
        !          134770:                umask 022
        !          134771: 
        !          134772:                /bin/cp /bin/bad /bin/cat /bin/cp /bin/cpdir \
        !          134773:                        /bin/db /bin/dd /bin/df /bin/du \
        !          134774:                        /bin/echo /bin/kill \
        !          134775:                        /bin/ls /bin/mkdir /bin/mv /bin/ncheck \
        !          134776:                        /bin/rm /bin/sh /bin/stty /bin/sync \
        !          134777:                        /bin/time /bin/true /f0/bin || exit 1
        !          134778:                /bin/cp /etc/fsck /etc/init /etc/badscan /etc/clri \
        !          134779:                        /etc/fdisk /etc/mkfs \
        !          134780:                        /etc/mknod /etc/mount /etc/umount /f0/etc || exit 1
        !          134781: 
        !          134782:                DEV=/f0/dev
        !          134783:                :
        !          134784:                : Place a Coherent image out on drive 0.
        !          134785:                : Add a floppy root patched version as a file called 'stand'.
        !          134786:                :
        !          134787:                INSTALL="umask 022; set -e ; /bin/cp coherent /f0 ; \
        !          134788:                        /conf/patch coherent 'rootdev_=makedev(4,14)' ; \
        !          134789:                        /conf/patch coherent 'pipedev_=makedev(4,14)' ; \
        !          134790:                        /bin/cp coherent /f0/stand ; /bin/strip /f0/stand ; \
        !          134791:                        /etc/umount /dev/fha0 ; /bin/df /dev/fha0"
        !          134792: 
        !          134793:                case "$#" in
        !          134794:                1) eval ${INSTALL} ; exit 0 ;;
        !          134795:                esac
        !          134796:                ;;
        !          134797: 
        !          134798:        stand\=fva0)
        !          134799:                /etc/umount /dev/fva0 2> /dev/null
        !          134800:                echo -n "Insert high density 3.5 floppy into drive 0, press return [y to format]: "
        !          134801:                read x
        !          134802:                case "x$x" in
        !          134803:                xy)     /etc/fdformat -i 6 /dev/fva0 || exit 1 ;;
        !          134804:                esac
        !          134805:                /etc/mkfs  /dev/fva0 2880               || exit 1
        !          134806:                /bin/cp /conf/boot.fva /dev/fva0        || exit 1
        !          134807:                /etc/mount /dev/fva0 /f0                || exit 1
        !          134808:                /bin/mkdir /f0/bin /f0/dev /f0/etc /f0/mnt /f0/tmp || exit 1
        !          134809:                umask 011
        !          134810:                /etc/mknod /f0/dev/null c 0 0           || exit 1
        !          134811:                /bin/ln -f /f0/dev/null /f0/dev/swap    || exit 1
        !          134812:                umask 077
        !          134813:                /etc/mknod /f0/dev/mem  c 0 1           || exit 1
        !          134814:                /etc/mknod /f0/dev/kmem c 0 2           || exit 1
        !          134815:                /bin/chmod 777 /f0/tmp                  || exit 1
        !          134816:                umask 022
        !          134817: 
        !          134818:                /bin/cp /bin/bad /bin/cat /bin/cp /bin/cpdir \
        !          134819:                        /bin/db /bin/dd /bin/df /bin/du \
        !          134820:                        /bin/echo /bin/kill \
        !          134821:                        /bin/ls /bin/mkdir /bin/mv /bin/ncheck \
        !          134822:                        /bin/rm /bin/sh /bin/stty /bin/sync \
        !          134823:                        /bin/time /bin/true /f0/bin || exit 1
        !          134824:                /bin/cp /etc/fsck /etc/init /etc/badscan /etc/clri \
        !          134825:                        /etc/fdisk /etc/mkfs \
        !          134826:                        /etc/mknod /etc/mount /etc/umount /f0/etc || exit 1
        !          134827: 
        !          134828:                DEV=/f0/dev
        !          134829:                :
        !          134830:                : Place a Coherent image out on drive 0.
        !          134831:                : Add a floppy root patched version as a file called 'stand'.
        !          134832:                :
        !          134833:                INSTALL="umask 022; set -e ; /bin/cp coherent /f0 ; \
        !          134834:                        /conf/patch coherent 'rootdev_=makedev(4,15)' ; \
        !          134835:                        /conf/patch coherent 'pipedev_=makedev(4,15)' ; \
        !          134836:                        /bin/cp coherent /f0/stand ; /bin/strip /f0/stand ; \
        !          134837:                        /etc/umount /dev/fva0 ; /bin/df /dev/fva0"
        !          134838: 
        !          134839:                case "$#" in
        !          134840:                1) eval ${INSTALL} ; exit 0 ;;
        !          134841:                esac
        !          134842:                ;;
        !          134843: 
        !          134844:        DEV\=*)
        !          134845:                DEV=`/bin/echo "${ARG}" | /bin/sed -e 's/^....//'`
        !          134846:                ;;
        !          134847:        *)
        !          134848:                PASS2="${PASS2} ${ARG}"
        !          134849:                ;;
        !          134850:        esac
        !          134851: done
        !          134852: 
        !          134853: :      get the proper driver information
        !          134854: :
        !          134855: 
        !          134856: for ARG in ${PASS2}
        !          134857: do
        !          134858:        case "$ARG" in
        !          134859: 
        !          134860:        root\=fva0)
        !          134861:                ROOTDEV="makedev(4,15)"
        !          134862:                . confdrv/fl
        !          134863:                ;;
        !          134864:        root\=fha0)
        !          134865:                ROOTDEV="makedev(4,14)"
        !          134866:                . confdrv/fl
        !          134867:                ;;
        !          134868:        root\=*)
        !          134869:                ARG=`/bin/echo "${ARG}" | /bin/sed -e 's/^.....//'`
        !          134870: 
        !          134871:                case "${ARG}" in
        !          134872:                *[0123][abcdx])
        !          134873:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          134874:                        ;;
        !          134875:                *)
        !          134876:                        FILE="${ARG}"
        !          134877:                        ;;
        !          134878:                esac
        !          134879: 
        !          134880:                if /bin/test -r confdrv/${FILE}
        !          134881:                then
        !          134882:                        . confdrv/${FILE}
        !          134883:                        ROOTDEV="${MAKEDEV}"
        !          134884: /bin/echo "'confdrv/${FILE}' executing"
        !          134885:                else
        !          134886:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          134887:                        exit 1
        !          134888:                fi
        !          134889:                ;;
        !          134890: 
        !          134891:        swap)
        !          134892:                ;;
        !          134893: 
        !          134894:        swap\=*)
        !          134895:                ARG=`/bin/echo "${ARG}" | /bin/sed -e 's/^.....//'`
        !          134896: 
        !          134897:                case "${ARG}" in
        !          134898:                *[0123][abcdx])
        !          134899:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          134900:                        if [ -d "${DEV-/dev}" ]
        !          134901:                        then
        !          134902:                                /bin/ln -f ${DEV-/dev}/${ARG} ${DEV-/dev}/swap
        !          134903:                        fi
        !          134904:                        ;;
        !          134905:                *)
        !          134906:                        FILE="${ARG}"
        !          134907:                        ;;
        !          134908:                esac
        !          134909: 
        !          134910:                if /bin/test -r confdrv/${FILE}
        !          134911:                then
        !          134912:                        . confdrv/${FILE}
        !          134913:                        PATCH="${PATCH} swapdev_=${MAKEDEV}"
        !          134914:                        /bin/echo "Swap device will be ${DEV-/dev}/${ARG}"
        !          134915:                        /bin/echo "See documentation before enabling"
        !          134916:                else
        !          134917:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          134918:                        exit 1
        !          134919:                fi
        !          134920:                ;;
        !          134921: 
        !          134922:        *\=*)
        !          134923:                PATCH="${PATCH} ${ARG}"
        !          134924:                ;;
        !          134925: 
        !          134926:        *)
        !          134927:                case "${ARG}" in
        !          134928:                *[0123][abcdx])
        !          134929:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          134930:                        ;;
        !          134931:                *)
        !          134932:                        FILE="${ARG}"
        !          134933:                        ;;
        !          134934:                esac
        !          134935: 
        !          134936:                if /bin/test -r confdrv/${FILE}
        !          134937:                then
        !          134938:                        . confdrv/${FILE}
        !          134939:                        case "${ROOTDEV}" in
        !          134940:                        ?*)     ;;
        !          134941:                        *)      ROOTDEV="${MAKEDEV}" ;;
        !          134942:                        esac
        !          134943:                else
        !          134944:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          134945:                        exit 1
        !          134946:                fi
        !          134947:                ;;
        !          134948:        esac
        !          134949: done
        !          134950: ROOTDEV="${ROOTDEV-makedev(4,14)}"
        !          134951: 
        !          134952: :      include stub drivers
        !          134953: :
        !          134954: UNDEF="${UNDEF} ${LIBS}"
        !          134955: 
        !          134956: :      make the proper root and pipe devices
        !          134957: :
        !          134958: PATCH="${PATCH} rootdev_=${ROOTDEV} pipedev_=${ROOTDEV}"
        !          134959: 
        !          134960: set -ex
        !          134961: :
        !          134962: :      create a kernel with the desired device drivers
        !          134963: :
        !          134964: /bin/ld -i -x -o coherent ${KERNEL} ${UNDEF} -lc
        !          134965: :
        !          134966: :      enable the desired device drivers
        !          134967: :
        !          134968: /conf/patch coherent ALLSIZE_=16384 NBUF_=32 NCLIST_=24 ${PATCH}
        !          134969: /bin/chmod 644 coherent
        !          134970: /bin/chown sys coherent
        !          134971: /bin/chgrp sys coherent
        !          134972: /bin/sync
        !          134973: :
        !          134974: eval ${INSTALL}
        !          134975: @
        !          134976: 0707070064030115001005550000030000030000011777770507310747600004500000001517/newbits/kernel/USRSYS/RCS/newkers,vhead     1.1;
        !          134977: branch   ;
        !          134978: access   ;
        !          134979: symbols  ;
        !          134980: locks    bin:1.1; strict;
        !          134981: comment  @# @;
        !          134982: 
        !          134983: 
        !          134984: 1.1
        !          134985: date     91.07.24.08.06.10;  author bin;  state Exp;
        !          134986: branches ;
        !          134987: next     ;
        !          134988: 
        !          134989: 
        !          134990: desc
        !          134991: @@
        !          134992: 
        !          134993: 
        !          134994: 
        !          134995: 1.1
        !          134996: log
        !          134997: @Initial revision
        !          134998: @
        !          134999: text
        !          135000: @# newkers - copy kernels to floppy
        !          135001: VOL=${1-foo}
        !          135002: case $VOL in
        !          135003: f0 | 5)
        !          135004:        VOL=f0
        !          135005:        PATCH="rootdev_=0x40E"
        !          135006:        ;;
        !          135007: f1 | 3)
        !          135008:        PATCH="rootdev_=0x40F"
        !          135009:        VOL=f1
        !          135010:        ;;
        !          135011: *)
        !          135012:        echo "Usage: $0 { f0 | 5 | f1 | 3 }"
        !          135013:        exit 0
        !          135014: esac
        !          135015: echo -n "Place boot diskette in $1 drive and press <Enter> "
        !          135016: read JUNK
        !          135017: mount $VOL || exit 1
        !          135018: cp /coh.at /$VOL/begin
        !          135019: ln -f /$VOL/begin /$VOL/coherent
        !          135020: chmog 400 sys sys /$VOL/coherent       
        !          135021: /conf/patch /$VOL/coherent $PATCH pipedev_=0x883 ronflag_=1 || exit 1
        !          135022: cp /coh.ss /$VOL/coherent.ss
        !          135023: chmog 400 sys sys /$VOL/coherent.ss
        !          135024: cp /coh.aha /$VOL/coherent.aha
        !          135025: chmog 400 sys sys /$VOL/coherent.aha
        !          135026: ls -l /$VOL/begin /$VOL/coh*
        !          135027: umount $VOL
        !          135028: @
        !          135029: 0707070064030107700407550000030000030000011777770507310747700003300000000000/newbits/kernel/USRSYS/lib0707070064030107671006440000000000000000011777770507310747700004500000016423/newbits/kernel/USRSYS/lib/aha154x.a]�scsi.o�(l��&&��p��&VWU����h��6��6�j������}��_^�VWU��>�~
�6�h������6�����+��� }���烽jt������j����F���_^�VW��F%���%�F�~���jP�6�h�����j�~��狅j�F�j%�6�L����F��~�t�~��烽juh�.����#+��&jP�~�����j�����F�F��F��F��F��6�v�������F��V����F�%�F�+�;v�}��~��F���F�P������F�P�����^��G&*�Ȋ*�������+҉F�V���������F�V�^��G*�ȊG*�������+�  F�      V�~��E*�ȊE*�����F�S�L����F�V�~�EL�UN���~�����j�~����F��%����
�P�����_^�VW��v�ƀt#��t�h"V�������������%���%�F���%���^��ヿjuV�)����u��n�^��㋇j�F��^��GL�WN�F�V�����^��G�W�F��V�����^��G�W
        !          135030: F�V�;V�wr;F�v�%�����^��GGt�Y���_^�VWU�������_^�VWU��h@�j&�v�v
        !          135031: h��
���
        !          135032: �_^�VWU��h@�j�v�v
        !          135033: h������
        !          135034: �_^�VW��v�F���%���%�F��F
        !          135035: �J�CC.;��t�&.�g&&HHT���d��~��烽ju �F�&V������~��烽ju����~��狅j�F졺�.����ǙRP�~��uN�uL�J����F�F����F��F�j�v�F�P�)����~�t�~�����j�����~���Džj+��l�~��狅j�F�j�F�P�v������F�*䣺�F�*䣼���RP���RP�����RP�F�RP�����~�EL�UN��v�v
        !          135036: ����������_^�VW��v�D%�F��D%���%�F��D�t�F��D�D�^��㋇j�F��^��ヿjt��~�t��D
        !          135037: Dt���|t��j
�6�������uhK�
        !          135038: �����u�F��E
        !          135039: �E�~�t�^���^��D
        !          135040: �TGW
        !          135041: ��D
        !          135042: �T�E�U�E&����F��>�u�>�����?�>��v��������>h.덋^���^��D��    �ȋ�+�D
        !          135043: T;Ww
s�O�;Gw�G��LV�d����_^�VWU���U�����N�����_^�@ 0
�&�n���+aha154x: sdunload() athough %d active
        !          135044: aha154x: out of kernel memory
        !          135045: No tape yetaha154x: no partition table
        !          135046: aha154x: out of kernel memory
        !          135047: free_aha_ioctl_sdgetpartitions_uaha_command_aha_load_sdclose_�SD_SPT_�sdwatch_�kclear_SDBASE_�sphi_u_aha_start_drvl_nulldev_SDIRQ_�aha_completed_devmsg_bdone_vtop_sds_alloc_vrdivaha_unload_lrmulspl_fdisk_printf_allkp_SD_HDS_�sdcon_�ukcopy_kucopy_ioreq_ � � � � � �'� � � �%%$$7'$%2%9$<7?$F7I%[%f7i'�7�%�%�'�7�%�$�7�'�0�%�7�'&7
&'&
7<&7F&7�&'�&
%�&7�&'$70'
%"0%%C0J'U%a'�0�'�'�
%�%�7�!%7! 70F X Z \ ^ ` b%k0w%�'�0�%�$�$�7�$�$�7� %�7�%�%7$$'$*$0767D7[&'d%�%�0�0�0�0�'�7�$�7�0�77
        !          135048: %>%E%K%Q7W7]$b0�0�7�7�7�aha.o�(l��&&> p&&X�VWU��Y �_^�VWU��ht     ������_^�VWU��6�
        !          135049: �F��
        !          135050: ���_^�VWU�졲
        !          135051: �_^�VW��~�u;�^�;u
        !          135052: ��v���o�|�^�u�tD�L�^�u/�u)�y��F���
        !          135053: �?t�_�7��
        !          135054: �w�v��[������#�M��EW�C���V�<����v�3����_^�VWU���6�
        !          135055: � ���%���t��&u��
        !          135056: @@P��������tӸ����v��
        !          135057: @P�����+��_^�VWU���6�
        !          135058: �����%���u��&u��
        !          135059: @@P��������tӸ�����
        !          135060: @P����%��_^�VW��F        �H     �F��V��n�&�^��F��V��x"u�t�6�
        !          135061: �f���������t��v�'��h�     �K����_^�VWU��J       ��O~��
        !          135062: @@P�.����ȋ���t��u h�      �����6�
        !          135063: �
�����j �6�
        !          135064: ��������_^�VWU���N
        !          135065: |
�~�F��������_^�VW��6�
        !          135066: �����=�u�����B    �D     �F��V��n�&�^��F��V��xu�t�6�
        !          135067: �������ǀu֋F�F�u����G�6�
        !          135068: �r�������@t����0�6�
        !          135069: �[������� t�&��6�
        !          135070: �D�������t+������_^�VWU��N|)��~�F�V
        !          135071: %�+҈��F�V
        !          135072: �������F�V
        !          135073: ���_^�VW��~�*䙉F��V���������F��V��v�D*�ȊD&*�������+�    F�      V���
        !          135074: ��
        !          135075: )F�V��F��_^�VWU��j
        !          135076: �����jh�
        !          135077: ����+���}���
        !          135078: t���
        !          135079: �PVh�  �l���F��h�     �`����_^�VWU��>�
        !          135080: t �>�
        !          135081: t�6�
        !          135082: �?�����
        !          135083: �v�0����_^�VW��v�;����>�
        !          135084: u0�>  ����P�6������
        !          135085: �u    ��������>     ���
        !          135086: ��
        !          135087: +�;6>  }�����
        !          135088: ����>�
        !          135089: +��*�F���6j������
        !          135090: ��
        !          135091: �F�P�6�6�
        !          135092: ����RP�f����>       �F�h��v
        !          135093: ����h�h��v���j&h��k���h��6�
        !          135094: �^������}h�        �N����6�
        !          135095: h
        !          135096: �A����E�j&����+���}����E�*�P�����F��F��
        !          135097: ��
        !          135098: �>     �_^�VW��v�D�F���T�F��V�j>�6������F��~�u      �������v&�^��G;��D�%���G&�D�%G&�D
��^��G*�=*u�O&��^��O&�^��G�F��G�V���������^��G�F��V���������^��G�F��G�G�F��.�>< �G�F��G�G�G
        !          135099: �G�F�P�D
        !          135100: �RP������F�P�t�t�������
        !          135101: @P�6�v������RP�������
        !          135102: �&j�����^��?ujh�h�S�������^��uO�tI�D�%P�D���Ph 
        !          135103: ����+��^��G�;�~�߃�
        !          135104: ^��G*�PhE
        !          135105: ����G��hI
        !          135106: �w����^��G��ȊG����S�_������_^�VWU��vj>�6�E������u;��D
        !          135107: �%���E&�D
        !          135108: �%E&�\�&u
        !          135109: �M&�E(��M&�E*�E�D�T��������E�D�T��������E�D�E�E�\�G+ҹ�������E�\�G��       �E�E�E
        !          135110: �E�EP�G+�RP�n����EP�\�w�w����RP�S������_^�VW��F��j����>�t
        !          135111: W�]������W�O�����
        !          135112: ��F��u��&;6>     |������
        !          135113: �?uq�F��v�������F������
        !          135114: @P�6�v������RP����������
        !          135115: �&j��������F��^����
        !          135116: ��F��~�u�G�v������~�tF�t�;6> t�X����F��_^�VWU��+�+�;6>    }9�����
        !          135117: �?t(�����
        !          135118: @P�x���Ph?�d��������
        !          135119: �GF�����_^�VWU�졲
        !          135120: @@P�=��������ǀu
        !          135121: VhK
        !          135122: �)�����%H=w+����.���    �                                        jh��������Y��       hg
        !          135123: �����j �6�
        !          135124: ������_^�VWU��h�
        !          135125: ������_^�N       &&no messageerror messages not verboseaha154x: out of kernel memory
        !          135126: aha154x: timeout sending cmd byte
        !          135127: aha154x: aha_poll timed out
        !          135128: [%d] %x 
        !          135129: aha154x: initialization error or host adaptor not found at 0x%x
        !          135130: aha: SCSI ID %d LUN %d. SCSI sense = %x
        !          135131: aha: spurious interrupt %x
        !          135132: aha: multiple interrupts not yet handled
        !          135133: aha_ioctl: Not implemented
        !          135134: free_aha_ioctl_)      drive_info_ aha_command_�clrivec_aha_load_�setivec_sphi_aha_start_�buildccb_�inb_outb_aha_get_base_3aha_device_info_adefer_aha_completed_gaha_intr_�bdone_aha_process_?vtop_sds_alloc_aha_unload_�wakeup_spl_aha_set_base_MAX_MAILBOX_>     printf_allkp_sleep_$@  $$7%%%+%97Z7�%�%�7�0�7�7�7�%�7�
        !          135135: %�7�
        !          135136: %&7&%&&7)&
        !          135137: %>&7D&
        !          135138: %W&7\&
        !          135139: $o&$s&%�&7�&
        !          135140: 0�&$�&7�&$�&%�&7�&
        !          135141: $�&7�&%�&7�&
        !          135142: %�&7�&00"%073
        !          135143: 0A$D$H%j7m
        !          135144: %�7�
        !          135145: %�7�
        !          135146: %�7�
        !          135147: %N%R0i%q0t%�%�$�7�$�7�%�%�%�7�%�7�0�%�$�'�7�%&00$%%$!%,%5'D7I%O%S'[%_7b0j$p v7|7�7�%�7�0�$�7�%�$�7�0�0�0�%�%�$�'70(0. �0�0�%�'�7�0%07-$T7W$x7{$�7�7�'�7�0b7u0}7�%�7�0�%�7�%�0�$�0�%�0�%�'�70%07"%.7D0Q$U0Z%^$r%}%�0� �7�%�%�7�
        !          135148: $�7� � � � � � � � � � & 7      0    $      7      %    7       $/    72      fdisk.o�(m��&�&&��(VW��v
        !          135149: �F�����F�j&j�v������>uej&jj�v������F��tF�^�����&U�u/�F��~�}j�F�����&P�ƃ�P�����F����F�&�v������v�v����v��m����F��_^�sphi_u_dclose_blkmvbread_brelease_spl_fdisk_dopen_77'#&727l77�7�0707070064030107631006440000000000000000011777770507310750100004000000021464/newbits/kernel/USRSYS/lib/al.a]�com1.o�(�i�&�& ��&VW��>:t�&i2^P�6������6�u�&k2P�6������4�u�x&i2^P�66����k2P�64���������:�.�>6�E��E�4�E�6��>4���E�>2&~0�0�>6��y���x�4��r�6^��>4�E��E�F��F�;2|��iF�^��>6�E��F�iF�^��>6�}��F�j@P������F�@P������uXj�F�P�����h��F�P������~������v������~��狅��P�F�@P����j�F�P����iF�^��>6�EiF�^��>6�EiF�^��>6�_���\�F��&�hj�M���V�F����_^�VW��F��F�;2}[iF�^��>6�}��F�j@P����j�F�P����jjj��jiF�^6H&P��P�����������F��j������66������64�����_^�VWU��F%?;2s:���~��?i�^6P����h8�~��?i�^6P�v
        !          135150: �v�j������_^�VWU��N��?i�^��>6�Mu(�>����~��?i�^6P�v
        !          135151: �v�#���V�����_^�VWU���v
        !          135152: �~��?i�^6P������_^�VWU��v
        !          135153: �<tV�N��?i�^6P������|V��������|o�^��?i�^��6�_�P�������� t؋^��?i�^��6�_�P�{������� t�W�N��?i�^��6�_�7�V�����_^�VWU��~��?i�^6P�v�v
        !          135154: �v�,����_^�VWU���v�v
        !          135155: �~��?i�^6P�����_^�VWU���68������_^�
        !          135156: P��
��&�free_alxtimer_clrivec_albaud_kclear_setivec_alxstart_sphi_u_alxopen_cs_sel_inb_outb_nulldev_iogetc_blkmvalxintr_ttread_timeout_tp_table_alloc_spl_C1BAUD_.a0con_C3BAUD_0ttwrite_allkp_alxcycle_alxparam_A0CNT_2alxclose_ttpoll_alxioctl_  '
    "'$
'&& ( * ,%0$'7%"0)$-'376%<0C$G%N7Q$X%^7a7g%m$p%t%~%�'�%�$�$�%�%�%�'�%�$�0�%�%�7&7&7%&75&'A&7G&'S&7_&7n&%|&'�&%�&'�&%�&7�&
        !          135157: 0�& �&7�&7�&$�&%�&7�&7�&%7 7&73%:7=%D7G$]0b%q7u%{%�7�     '�%�7�%�7�7�%7%(7,75%O7[%w7�%�7�%�7� %�7�%7
        !          135158: com2.o�(�i�&�& ��&VW��>:t�&i2^P�6������6�u�&k2P�6������4�u�x&i2^P�66����k2P�64���������:�.�>6�E��E�4�E�6��>4���E&�>2&~0�0�>6��y���x�4��r�6^��>4�E��E�F��F�;2|��iF�^��>6�E��F�iF�^��>6�}��F�j@P������F�@P������uXj�F�P�����h��F�P������~������v������~��狅��P�F�@P����j�F�P����iF�^��>6�EiF�^��>6�EiF�^��>6�_���\�F��&�hj�M���V�F����_^�VW��F��F�;2}[iF�^��>6�}��F�j@P����j�F�P����jjj��jiF�^6H&P��P�����������F��j������66������64�����_^�VWU��F%?;2s:���~��?i�^6P����h8�~��?i�^6P�v
        !          135159: �v�j������_^�VWU��N��?i�^��>6�Mu(�>����~��?i�^6P�v
        !          135160: �v�#���V�����_^�VWU���v
        !          135161: �~��?i�^6P������_^�VWU��v
        !          135162: �<tV�N��?i�^6P������|V��������|o�^��?i�^��6�_�P�������� t؋^��?i�^��6�_�P�{������� t�W�N��?i�^��6�_�7�V�����_^�VWU��~��?i�^6P�v�v
        !          135163: �v�,����_^�VWU���v�v
        !          135164: �~��?i�^6P�����_^�VWU���68������_^�
        !          135165: P��
��&�free_alxtimer_clrivec_albaud_kclear_setivec_alxstart_sphi_u_alxopen_cs_sel_inb_outb_nulldev_iogetc_blkmvalxintr_ttread_timeout_tp_table_alloc_spl_C2BAUD_.a1con_ttwrite_C4BAUD_0allkp_alxcycle_alxparam_A1CNT_2alxclose_ttpoll_alxioctl_  '
    "'$
'&& ( * ,%0$'7%"0)$-'376%<0C$G%N7Q$X%^7a7g%m$p%t%~%�'�%�$�$�%�%�%�'�%�$�0�%�%�7&7&7%&75&'A&7G&'S&7_&7n&%|&'�&%�&'�&%�&7�&
        !          135166: 0�& �&7�&7�&$�&%�&7�&7�&%7 7&73%:7=%D7G$]0b%q7u%{%�7�     '�%�7�%�7�7�%7%(7,75%O7[%w7�%�7�%�7� %�7�%7
        !          135167: alx.o�(�i�&�&�
        !          135168: TH�VW��v�~�F%��F��\��F�@P�����������t��&�D�t
        !          135169: ����u��F���ȁ��k�
        !          135170: ��t�'��&�F@t���u��F@u�&�\�G����㋇=&t˃|t�&�\�tjjh&�DP�L������D��F��F@tj��\�G����㋇�j�F�P����j�F�@P�����F��t��L $�F�P������F��F�*�\G�F��u`jjh&�DP�������G$G&t����t��F�P����%P�F�P����j�F�@P������v��������d���F�t�d����d���LV�Y�����
        !          135171:        �,&��
        !          135172: ��!�,&V����v��9����D�vV�,����F@t�\�G�����LJ�_�g�\�G�����LJ&�T�\�G����㋇=u�>��\�G��؁��㋇=&t�X�� ��F��u �Du��
        !          135173: �Du�t���_^�VW��^�w�_�G&�v�����^�G�F��^��?�F��~�tU�^�GPhj
        !          135174: �GP�S���jjh&�^�GP�<����^��[*�F���Z*�:F�u��~�t��N���� uj��@P������^�G$��@tQ��P�����%P��P������F��%��F�k^�
        !          135175: LJ&jjh&kF�
        !          135176: P����k^�
        !          135177: LJ��P����%��P��P�����^�_�G�����LJ���^�_�G�^�GP�Z����_^�VWU��v�����k�
        !          135178: ������=~�~�����k�
        !          135179: P�����_^�VW��v�����\��F�@P������F��F�P������F��F�P������F��F
        !          135180: �A�   CC.;��t��.�g��������&����g~����F�
@P�F�P������F�%����F�
&P�F��ߋF�%����F�
��F�%���ߋF�
�P�F�P�B����v�v��6����F��P�F�@P�$����v�늋N���F�%����w��F�P�����F��F�*�\G�F�*����F�j�v�F�P����
        !          135181: �v�v
        !          135182: V������F�*�P�F�@P����W�����_^�VW��^�G�F��^��7�^��)&��F���(&�:F�t����^��(&����㋇�
        !          135183: ���u+�^�Gt!�g����P�N���%P��P�>����t}�4��F���@P�*����F�h���P����WV��������P��@P�����^��,&%�=&t  =tj�j�j
        !          135184: ��P������F�*�P��@P������v�������_^�VW��v�Du����F��\�P�����F��F�*�\G�v��w����\�Gt>�g��|u  �DP�Z��(�F��u%�O��F���X&*䈄Y&ƄY�v��7���V�0����\�G&t�g��F�t�d����L ��Y*�=�w"�\�P�����
P�\�P������Dt�Du=��Yt6��Y&*�ȋ�ي�Z&*�PV������Y&*�=�s��Y&�ƄY&��Y���F����Z*�Ȋ�[*�+�&F��F��.�>�
        !          135185: �V��N�|7V�i������|*��Z*�ȋ�ًLj�\��Z*�=�rƄZ����Z��V�2���VhMj
        !          135186: ��H&P�!����_^�VW��v���F��\�P���������t
        !          135187: Vhg������� t>��Z*�:�[t2��[*�ȋ�ي�\*�P�\�7������[��[*�=&rƄ[�v������_^�VWU��j�v�����_^�VW��v�\��F��F�@@P�k���=v�`&����.���� 
        !          135188: �      
        !          135189: �
        !          135190: ��F�P�?�������t�Vhg�-�����v��"������|t���,&@u-�ρ���1&�;�u�L 녋ρ���0&�;�u�d���n���Y*�=�s,��X&*�ȋ�ًLj�Z&��X&*�=�s��X&�ƄX&��Y�Du�-���Y*�=�w���F�P����%��P�F�P�x��H���Z*�:�[u����D t�����[*�ȋ�ي�\*�P�v��C�����[��[*�=&rƄ[��[*�:�Zt��VhM����F�P�����\G���_^�VW��F��~�}"�~��狅=u�~������L����F����B�B;@|�B�B�_^�VW����t��F��F��~�}:�~��狅=u'�~��狽��(&����狅�F��F�;F�}�F��F��F����F�;t.��.�>�
        !          135191: �@�<��&���~�t�&h
        !          135192: �6� ����_^�&d     Y@�&�`@:0 dddddddd�,&�&�&X �@ttsignal_alxtimer_�al_sg_clr_�
        !          135193: albaud_�
        !          135194: super_altclk_in_al_sg_set_�
        !          135195: altclk_out_nondsig_alxstart_�com_usage_sphi_tthup_u_alxopen_drvl_inb_outb_ttsetgrp_ttclose_ttin_ttout_poll_owner_poll_rate_alxintr_{ttioctl_defer_timeout_cprocp_alp_rate_alxbreak_gtp_table_wakeup_spl_alxcycle_Mttstart_alxparam_Ssleep_ttopen_kucopy_alxclose__alxioctl_�7 '/
037=0D'W'^
0b'm0{'�
        !          135196: 0�7�%7�'�7�7�0�7&73&%':&7E&7S&7d&7q&'x&
7&!0�&7�&&$�&$�&0�&7�&!7�&'�&
        !          135197: 0�&'&
        !          135198: '
        !          135199: 0'/
        !          135200: 070:0T'X
7v'� 7�7�%7�77"'9'I7M%'X7c7s'�
        !          135201: 0�7� '�'�'�7� 7�777" .0= U W Y [ ] _ a c e7v0|7�7�7�0�7�7&'727C7J!'~
0�$�7�7�7�7�7�7�7�7(787A!0G0^7a7p7�!7� 7�7�!7�777I �7�7�# �7�7�7� 77A7^!7r7�0� � � � � � � � �7� �7�7�0   0]      0k      7u      7�    0�    0�      0�      7�      0�     �      0�      7�      0�    '
        !          135202: 
        !          135203: '*
        !          135204: 0-
        !          135205: %9
        !          135206: %<
        !          135207: %@
        !          135208: %F
        !          135209: %K
        !          135210: 'Y
        !          135211: 0`
        !          135212: 'y
        !          135213: 
        !          135214: '�
        !          135215: $�
        !          135216: '�
        !          135217: '�
        !          135218:  �
        !          135219: %�
        !          135220: 7�
        !          135221: '�
        !          135222: '�
        !          135223:  �
        !          135224: '�
        !          135225: 7�
        !          135226: 0707070064030107601006440000000000000000011777770507310750300004000000014722/newbits/kernel/USRSYS/lib/at.a]�at.o�(ҳ�&�&��&��ZVW�jjp�����jq������������z��%�{j�F�Pjh&�����+�����|��=u,jW�F�+҉F��V��F�+ҹ������F�V�RP�����@��zuƄz&�}u�E�E*�P�u�E*�P�E*�P�u�E*�P�5Vh*
�J���j�F�Pjh&�9�����F�o�+�����}I��zu��F������F��E*�RP�E*�RP�����RP�+�RP������^���������Ph�j�������h�6���������h�6�����������_^�VWU��j�����_^�VWU��jh��|����dNu��
*�%Ph��d���j���h�&�S���=&t   hk
�E���+�����|���zu��F��V��
        !          135227: ���E*�Ph������E��Ph�&�����E*�Ph�&�����j&h�&�������Ph�&���������Ph�&������E*�ȋ�����Ph�&����h�h�&����V�U
        !          135228: ��jh�&����V�C
        !          135229: ���Z��_^�VW�
        !          135230: �v��%�F��ƀt
��%&���F��
        !          135231: ��%�������}��zu���ƀt��^��������u#�����P�ρ������%����P�  ����߃����������F��V��^����������F��V��^���������F�V�;V�wr;F�v�%��^��������u��_^�VWU��h@�j&�v�v
        !          135232: h�����
        !          135233: �_^�VWU��h@�j�v�v
        !          135234: h��i���
        !          135235: �_^�VW��v�ƀt��%&���%����F��F
        !          135236: =&Ht=Ht"�����j�v�F����P�����nj�F����P�v�����~�ƅz&�F����F�����
*�RP�~�����
*�RP�����RP�~������+�RP�����~���������+��_^�VWU��6b�����tH�6t�6r�t�t
        !          135237: �D�tjx�
        !          135238: �x%aP�6ph�
�]����p���r���t�����oW�>����_^�VW��v�D%�F��D�D�D�t�F��F�������|&u�D
        !          135239: �T;Uu;Eu   V������^�D��  �ȋ�+�D
        !          135240: T;Urw;Ew
�D�&u�|u�L����>bu�6b��d�7�6d�>}u
        !          135241: ��t�&�_^�VW��~�|�b���u+��&�D%�x�D�t
�x�D%&�       �D%����p�p����
*�F��x������D
        !          135242: �TEU
        !          135243: �j�l�D��   �n�D�T�f�h�|uE�>n&v
������        &�j�l;�u   ;�u���j�l;�t��;�t���ǃ>n&t���*�;pu:�j�l;�u-;�u'h�t�t�6��z�����b�DV�i��������*�;pu"�j�l;�u;�uh�t�t�6�빃<uW�F�+�RP�6l�6j�����F��V��N������+�+F�V��~�~*�=r
        !          135244: �~����>~t�~*�&n���&�_^�VW��p������D*�RP�D*�RP�6l�6j����RP�����t�D*�RP�D*�RP�6l�6j�~���RP�v����r�D*�RP�6l�6j�]���&���v�p;�u]�t;�uT�r;�uK�b�F��6t�6r�~��u�u
        !          135245: �E�tjx�
        !          135246: �x%aP�6ph�
�����~��MW�y�����6p����D*�Ph�������D��Ph�&������6nh�&�����6vh�&�����6th�&�����t��Ph�&�����p��r�Ph�&�w����>b�}u3j0h�&�b����\��u�6ph 
�N����6h�6f�A����}�j h�&�/����}�t�_^�VWU��jh������_^�VWU��6b�}*�H=v�&����.��            #       �       �
��&�&&�t�}������u
�6ph 
�����~*�;nu�6�>n����������6h�6f������u��~*�;nu*�>n������j�l�������p�>n��~�~��f�l�|�j&�l�nuWV����N�O�t�K��f�l�|�j&�l�nt�����u�6ph 
��������6h�6f������_^�VW�
        !          135247: �6bh�&������ȋ���!u�G&h�&�����F��}*�=u�~*�;nu�|d�3&�F��u�&�|d�p���r���t���6t�6r�n+҉F��V��~*䙉F��V��D��     �ȋ�+�D
        !          135248: TF�V�+F�V�RP�D�tjx�
        !          135249: �x%aP�6ph�
������@u   h������ t  h-�����F�&t h<�����F�t hQ�����F�t hf�����F�@t hv����F�t h�����F��t h�����|*�=s      h����h��w���+���|�|*�=r����&�_^�VW��6b�p�t�F��|*�H=w9����.��������N�}'�F��!�p���F��F�;��r�n����F��|*�=sP��u����t�v�h�&�����F���Ph�&�����p���Ph�&���Wh�&����}&�!�}*�=u�~*�;nt�LV����_^�VWU��v�t�}��bV�\������t�|��_^�VWU��6
�~�;���t���N���vh 
�%��+��_^�|�d��bf&2at%d: TO
        !          135250: at%d: ncyl=%d nhead=%d wpcc=%d eccl=%d ctrl=%d landc=%d nspt=%d
        !          135251: at: AT disk controller not present (reset)
        !          135252: at%d%c: bno=%U head=%u cyl=%u <Watchdog Timeout>
        !          135253: at%d%c: bno=%U head=%u cyl=%u <Track Flagged Bad>
        !          135254: at%d%c: bno=%U head=%u cyl=%u <Drive Not Ready> <Write Fault> <No Data Addr Mark> <Track 0 Not Found> <ID Not Found> <Bad Data Checksum> <Command Aborted> <Block Flagged Bad> retrying...
        !          135255: clrivec_setivec_sphi_u_drvl_inb_outb_nulldev_atsend_myatbsyw_�atrecv_atparm_�defer_bdone_sds_alloc_vrdivvrremspl_fdisk_atdrqw_printf_allkp_atcon_�kpcopy_pkcopy_vrmulatbsyw_ATBSYW_
ukcopy_kucopy_ioreq_ �'� � � � �'� � � �77% %(76$>0F7r%{%�$�7�7�0�$�%�7&7&%&% &0%& (&7-&&%4&'<&7?&%E&%I&'Q&7T&%Z&%^&7n&7�&$�&7�&0�&7�&$�&7�&$�&0�&%�&0�&7�&7�&777 707K7W0^7i0p0v%�'�0�0�%�%�%�7�%%%%%,%0'F%S%W']%u7x%�7�'�0�$�7�$�7�%$$+73$B7I%S%W0Z%i7l'r%x%|%�%�$�7�%�%�%�%�%�%�0�0�7�%�7
%N%U%[%a%e0k0r%�%�%�0�%�%�%�%�$�%�%�%�%�%�%�%&%%%0%%"%&%,01%4%8%<0A%E0J%P0V%Y%_%d%h%l%r%�7�%�7�
0�%�%�%�%�%�%�%�%�%�7�%�%�%       %%%%%#%4$:%P%T7W7_%e%y%}7�7�%�%�%�7�%�%�%�%�%�%�%�%�%�%�%�%�$�7�0
0%07)79%@7F%M7S%Z7`%f7p%v%}7�%�7�7�%�$�7�%�%�7�%�7�%�'� �7�%�%&    0                                  0      0!      0$      0+      0.      71      %9    $<      7?      %E    %K      'Q      %U    %^      %d      %h      7k      
        !          135256: 0q    %x      %~      %�      %�      %�      %�      %�      %�      %�      %�      %�      %�      %�      %�      %�      %�      0�      0�      0�      %�      %�      %�      %�      %�      7
        !          135257: %
        !          135258: $
        !          135259: 7
        !          135260: %
        !          135261: %
        !          135262: 7
        !          135263: %/
        !          135264: 75
        !          135265: 0E
        !          135266: 7K
        !          135267: %T
        !          135268: %^
        !          135269: %d
        !          135270: %j
        !          135271: 0n
        !          135272: 0x
        !          135273: %|
        !          135274: %�
        !          135275: %�
        !          135276: %�
        !          135277: %�
        !          135278: %�
        !          135279: %�
        !          135280: %�
        !          135281: %�
        !          135282: %�
        !          135283: %�
        !          135284: %�
        !          135285: %�
        !          135286: $�
        !          135287: 7�
        !          135288: $�
        !          135289: 7�
        !          135290: $7$7$(7+$87;$H7K$X7[$h7k%q${7~$�7�%�%�0�%�%�%� � � � � � � �%�$�%
        !          135291: '!7*7:%@7M7W%^%d%n%t0'�%�%�7�
0�0�$�7�$�7�atas.o�(ӳ�&&&V�VU���v�&��&��o]^�WU���~�&��&��m]_ú�&����쨀��tKu��ú�&�������uKu���atsend_atrecv_CSR_REG       �&DRQ_ST     atdrqw_@BSY_ST �atbsyw_*fdisk.o�(ӳ�&�&&��(VW��v
        !          135292: �F�����F�j&j�v������>uej&jj�v������F��tF�^�����&U�u/�F��~�}j�F�����&P�ƃ�P�����F����F�&�v������v�v����v��m����F��_^�sphi_u_dclose_blkmvbread_brelease_spl_fdisk_dopen_77'#&727l77�7�0707070064030107541006440000000000000000011777770507310750500004100000021556/newbits/kernel/USRSYS/lib/ati.a]�mm.o�(���&�&�&�&�VW��v�D u2V������F��|$�F��F�&�F��F��F��F�Ph�����ǃ>�&u��&Vh`j
        !          135293: h�����_^�VWU�������>}2�h�jC����h�jB�w���j
        !          135294: jB�m���ja�e���
��>~�uja�K���%��Pja�?����>t��P�-����V�!����v�����vh`j
        !          135295: h�����_^�VWU��>�&~�>�&~        ��&u����_^�VW��v
        !          135296: �D�F��<uV������u����Dup� t'���F��&jjh&h�����v������ы>�E$E&t&�w��t�p��F�;Du��6V�]����t+��V�P����|u��� t��V�2����u��_^�&�ismmfunc_mmtim_mmbeeps_&mm_voff_mmcrtsav_�&mmgo_mmwatch_&nondsig_sphi_u_inb_outb_istty_kbunscroll_ttout_mmwrite_ &cprocp_timeout_mmstart_mmtime_`spl_mmvcnt_�&mmesc_&ttstart_sleep_70;%D%K O'T&7W7f'l's7|7�7�7�
        !          135297: '�'�7�
        !          135298: 7�'�'�7�'�7�7� �'�&7�$&$&$&7&76&0@&'M&7T&'[&'g&7j&7s&'|&7�&7�&
'�&        7�&7�&'�&'�&     7�&ati.o�(���&X&�Xt       ~8(-
        !          135299: qPZ
        !          135300: aPR
���
        !          135301: ���
VWU����^�w�O�?t��
�V���t���F�v�V�F�~+ۊf
        !          135302: �f[�f
        !          135303: �^�v�V�~�V��^���B���J��B���V���F��,&��^���O+O&O]_^�6�c�FP�F!�F��������$0<0u�F �F��F��F�Q+���6�FF����
r�V��B*��J�
�B*��V��*���F��f
        !          135304: �v�v
�^�^+��F��V���F�~��V���.�&B�JK}�Á~�u�F(�F �F��������n��~�u�FP�F!�F�������M��FP�F �F!�������3��~�u�F0�F��F!�l��������F��F!�F@�R��������6��p6���h*���:vvK�vVQ�^�^
��6���6�������6���Q+����� _�N�Y^����.�������6���     ������.���*�����6���<I�����.������:Vs
�'I�����.���*���:v
�I�����.����v�f�����I�����.���*Ҋ���6�����I�����.�������&s�V����:v
}*Ҋv
����6����I�����.����[���I��~�~����s�b�.����@���I�<;t!�؀�0��       w9�f�F����FÈF������I��؀�0��    w�f�F����FÈF�ފ���.���  �����I��؀�0��  w�f�F����FÈF�ފ���.���
        !          135305: ���€�s*����~
u6�&���~
u6����V
        !          135306: �t��:Vr�V���r�Q+Ɋʀ���*�Ѱ �Y:Vr*V��:vv�v���[�*���:v
s�v
�^&�5���:vv�v�(���:Vr*V��:vv�v�V�����v
        !          135307: �t��v
:vr�v�V
        !          135308: �t��:Vr�V�������:v
}�v
���VQ�^����6���6����^��6���+�~���6����N� �*Ҋ���6���Y^����6�&���F<u�^�~<&u�^
�]*Ҋv
����6����^*��8�F<u�^�T<&u*��4*Ҋv
+��^��F��<t7<&t��6���*�*�Q� �N���}�Y��Q����6���+�|� ���Y���Q��6���+�|� ���Y���6����VQ�^�^��6����΃�6���������6+��~����6����N� ��*Ҋ���6���Y^�����V
        !          135309: �t��:Vr�V���v��F
        !          135310: �u���:Vr�V���^��v
        !          135311: �t��:vv�v�V
        !          135312: �t��:Vr�V���7���:v�-��v����V�v�2��V�v����:v
}�v
�.����Nt
        !          135313: 
�F�
        !          135314: ��F�����F<u����<&u����<u�~�t�䈀�&��<u�̀��<u�p�~�u��$w����������
        !          135315: �븁~�u�,|<<�؀��.
        !          135316: ���,,
        !          135317: |(<�؀�.
        !          135318: ���,
        !          135319: |<��.���R�V���Z�g��F��}*�:Fw�^��}*�:^w:�w
        !          135320: �F
�^��*��&��v��*�:vv�v���F
        !          135321: �u���:vr�v����������.6S���&�&��������&���6�����������������������������������������������������������������������������������������������������������������������������������������������������������cl����((�����S6�������u�������������Q������������������������((����������������������������������������������������������������������������Ub6C~0P������Su��������������dx,~����������7���������������������������������������������������������������������������������������������������������������������������������������������
        !          135322:  "$&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~����������������������������������������������������������������&&&&&@ `P0p� 
���8
�Ë 
���8
��,&��@&�&� �`�@�� �`   
        !          135323: �
        !          135324: @�� 
�
`�@�� �`�@�� �`�@����P!mm_vpadZERO   bcolor�mm_scr�mm_cup~mreg132@AZERO     0csival�mm_ed0MM_INVIS     mm_newcmm_hprMM_SROW     fcolor�mm_sgr�mmspec(creg40mm_cuu�mm_hvp,scrolldown�mmbeeps_mm_voff_�mm_dl�creg80mm_elPreinit &mmcrtsav_int11_CLOWER cmm_il�mm_e0�mm_cr�mminit�mm_e1xmm_132�&rowend
rowtab�mmgo_Pmm_e2hmm_vprxmm_ssr7IOUSR     &IO_BASE     IO_IOC     newcrtq&mreg80 MM_DATA     NCB     mm_riuMM_BASE mm_si�&mmputc�IO_SEG     INTENSE     MM_COL     IOSYS     NHB     �ewait�mm_so�&REVERSE     pMM_MODE     COL     
        !          135325: NRB      �NCR     &islock_mm_chaMM_NCOL     MM_FUNC     eval�repos�MM_SCOL     mm_von_�mm_cgh�uds_MM_POS SPACE      asctab�mm_cgl�BLINK     �SEMIC     ;MM_ROW     mm_hpa�mm_cbt�esctab�POS mm_dmi�mm_cubMM_BROW     
mm_indSmm_emi�csgtab�
        !          135326: mm_esc6scrollupBmmesc_mmvcnt_mmdata
MM_ATTR   
        !          135327: mm_cudUcoltab�csitab�   mm_cnl6MM_EROW    mm_cufbcreg1320mm_oldlmm_cplCmm_chtMM_N1 ROW     csi_gt�mmbell.MM_N2     exit�ATTR MM_IBROW     csi_n1QMM_LROW csi_n2zMM_PORT mm_eaMM_IEROW  
 6
'hI$k'�^'�] �7& &0&##&0o& �&0�&0�& �&0�&0�& �&0�&0�& �&00 00&'*]'1#P#U#^ z#�0� �#� � � �0�0� �#� #$ 1040G L0O0x �0� �0�'�0�'�000>0A0P0S0`0|0�0�#�#�#�#�#�0�0�'�@00#'#b0v#�0�#�0�'�@0�#�#�#�#�#�0�0�00*0Q0[0a0j0s0�0�0�0�0�   )050b0v0� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �      
        !          135328:              " $ & ( * , . 0 2 4 6 8 : < > @ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z | ~ � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �                                    
        !          135329:                                                                                       "       $       &       (       *       ,       .       0       2       4       6       8       :       <       >       @       B       D       F       H       J       L       N       P       R       T       V       X       Z       \       ^       `       b       d       f       h       j       l       n       p       r       t       v       x       z       |       ~       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       
        !          135330:  
        !          135331:  
        !          135332:  
        !          135333:  
        !          135334:  
        !          135335: 
        !          135336:  
        !          135337:  
        !          135338:  
        !          135339:  
        !          135340:  
        !          135341:  
        !          135342:  
        !          135343:  
        !          135344:  
        !          135345:  
        !          135346:   
        !          135347:  "
        !          135348:  $
        !          135349:  &
        !          135350:  (
        !          135351:  *
        !          135352:  ,
        !          135353:  .
        !          135354:  0
        !          135355:  2
        !          135356:  4
        !          135357:  6
        !          135358:  8
        !          135359:  :
        !          135360:  <
        !          135361:  >
        !          135362:  @
        !          135363:  B
        !          135364:  D
        !          135365:  F
        !          135366:  H
        !          135367:  J
        !          135368:  L
        !          135369:  N
        !          135370:  P
        !          135371:  R
        !          135372:  T
        !          135373:  V
        !          135374:  X
        !          135375:  Z
        !          135376:  \
        !          135377:  ^
        !          135378:  `
        !          135379:  b
        !          135380:  d
        !          135381:  f
        !          135382:  h
        !          135383:  j
        !          135384:  l
        !          135385:  n
        !          135386:  p
        !          135387:  r
        !          135388:  t
        !          135389:  v
        !          135390:  x
        !          135391:  z
        !          135392:  |
        !          135393:  ~
        !          135394:  �
        !          135395:  �
        !          135396:  �
        !          135397:  �
        !          135398:  �
        !          135399:  �
        !          135400:  �
        !          135401:  �
        !          135402:  �
        !          135403:  �
        !          135404:  �
        !          135405:  �
        !          135406:  �
        !          135407:  �
        !          135408:  �
        !          135409:  �
        !          135410:  �
        !          135411:  �
        !          135412:  �
        !          135413:  �
        !          135414:  �
        !          135415:  �
        !          135416:  �
        !          135417:  �
        !          135418:  �
        !          135419:  �
        !          135420:  �
        !          135421:  �
        !          135422:  �
        !          135423:  �
        !          135424:  �
        !          135425:  �
        !          135426:  �
        !          135427:  �
        !          135428:  �
        !          135429:  �
        !          135430:  �
        !          135431:  �
        !          135432:  �
        !          135433:  �
        !          135434:  �
        !          135435:  �
        !          135436:  �
        !          135437:  �
        !          135438:  �
        !          135439:  �
        !          135440:  �
        !          135441:  �
        !          135442:  �
        !          135443:  �
        !          135444:  �
        !          135445:  �
        !          135446:  �
        !          135447:  �
        !          135448:  �
        !          135449:  �
        !          135450:  �
        !          135451:  �
        !          135452:  �
        !          135453:  �
        !          135454:  �
        !          135455:  �
        !          135456:  �
        !          135457:  �
        !          135458:       
        !          135459:              " $ & ( * , . 0 2 4 6 8 : < > @ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z | ~ � � � � � � �$�$�$�$�'�^0707070064030107521006440000000000000000011777770507310750700004000000012502/newbits/kernel/USRSYS/lib/fl.a]�fl.o�(��&$&v�&�X.VWU��j�����jjp�����jq��������ƈu7�v
�x������
��%��
��
&���t,��
��t"��
�������
��&t����%@��
�>�
tt�|���jh��r���h�j�g���jh��\���jh��Q�����
�=t��
�Ph��:���j�!       ���v��zP�        ���x��P�     ��W�����_^�VWU��>�
tj�����jjjh�
������.jh�������_^�VWU�젔
����F%���;�s�v�������~��������u��_^�VWU��j&�v�v
        !          135460: h�
�}����_^�VWU��j�v�v
        !          135461: h�
�c����_^�VW��~
        !          135462: @t���F%������v�4����F��F@P�&����F��~�&wʋF�;Es��Ft�E�f�F��     �E�f�F������e����+ҹ �����������F���E����j@�vh�h�
�����_^�VW��v�D��        �ȋ�+�D
        !          135463: T-&���F��\�����D
        !          135464: ;��v�LV�v��c�|@t"�\�����F�;��r�D�D�D@t����D�&t�|@u���8����>r
u�6r
��t
�7�6t
�>�
u�W�����_^�VW��6r
��
�=v�����.��#<�#a�.&�u��j�D%���Ph~
�����D%�����
�D%��
��
��ظ���࢖
�D�T�v
�x
�D
        !          135465: �|
��
���Ƈ�
�D��    �z
�u�z
&��
��
��F��t����F�;F�t��
�Ph��:�����
��Ƞ�
�#�uG��
��
��
��Ƞ�
��
Ph������;j&h jdh�
�������
���Ƈ�
��
����
���Ƈ�
��
��Ƞ�
��
Ph����������
��؀��
u%��
������
j�����
�P�����
&��|
��>�
B��
�>�
t!�|
��>�
��
��>�
��
��
��>�
��
��|
��>�
��
��>�
��
��
��>�
��
j�����
��ȡ�
���P�
        !          135466: ���>�
Pt"��
��؀��
u��
��P���
��؀��
t��6�
������
��&�|&tjh jh�
����������
���Ƈ�
���
jh�h�
�����t�&��
���Ƈ�
�f��
�|&t�|uP��
&�E�6�
h�6x
�6v
j�b���
        !          135467: �u>�6x
�6v
h�t�J���h�
�A����LV�N���+���
&�M�6�
�t�j����W�����
��ȡ�
���P�����|@u%��
�P�����6�
������
�P����h��H�6�
����6�
����6�
�����
�P����6�
�����
��؊��
�P�{��h��r����
���
���Ƈ�
j�h���h�
�_�����
������t+��
��
�=}
��
���Ƈ�
�-�X�LV�C���!�z
u�D���|
�v
�x
��
&�>�
u�����
�Ph j��h5������_^�VW�����F���
�=u    �F��
���v������_^�VWU��v���%����؀��
uO�ށ������=u O���%����؀��
u��%=u+����_^�VW��W��F�+����}H��
�#�uF����
|����
���
�=|���� �
��
�;�uր>�
t��?�>�
u��������
��Ƞ�
��
Ph�������>�
u�.�v�������_^�VWU��j�����h�
����jh�����jh�������
�=t��
�Ph�����j�v&���v��zP�e&���x��P�Y&��+���
���
���
���
�r
���t+��
�Ph9�B����|�LV�L���r
���t;|t�jh jh�
������
�_^�VWU���&����2�>�
t���V������_^�VWU��v��r
��
V������_^�VW��F����F�+�h������ȋ����u�N�u�hL������@th���������sɋ�G�ƈ��
뾉>�
jh��i���+�h��^����ȋ����u�N�u�h]�F�����@th��7�������sɋ�G�ƈ��
뾉>�
�v������_^�VWU��+�h�����%�=�tNu�ho�������vh�������_^�VWU���6�
�6�
��
�%Ph������>�
&|*��
�����t        h�������
�����t    h������>�
|~��
�����&t     h��s�����
�����t    h��^�����
�����t    h��I�����
�����t    h��4�����
����� t    h�������
����ǀt    h
�
        !          135468: ����>�
|i��
�����&t h
������
�����t    h.
������
�����t    h>
������
����� t    hP
�����
�����@t    h`
���hp
����_^�&1&Jp&�&�&��@&&(#*P�(#*PP#*Ph&&(  #*P�( #*P�P #*P`        PT@PTfd: DMA page straddle at %x:%xfdsfd%d: <Door Open>
        !          135469: flintr: timeout
        !          135470: flsense: timeout
        !          135471: flput: timeout
        !          135472: fd%d: head=%u cyl=%u <Not Ready> <Equipment Check> <Missing Address Mark> <Write Protected> <No Data> <Overrun> <Data Error> <End of Cyl> <Missing Data Address Mark> <Bad Cylinder> <Wrong Cylinder> <Bad Data CRC> <Data Deleted>
        !          135473: clrivec_int11_dmaoff_flrecov_1setivec_sphi_u_fldone_       drvl_inb_fl_hlt_xdmareq_outb_nulldev_getubd_blkmvdmaunlock_fl_hut_zdevmsg_timeout_dmago_bdone_fl_srt_vpanic_dmaon_spl_flcon_|printf_flunload_�dmalock_ �'�
 � � � �'�
 � � �777 $)$/%9%A%E%P%Z7_&%e%x%|7�7� �7�7�7�%�%�7�0�$�$�0�$�0�7�%&7&%&7&'&7(&%7&0M&$b&'i&%~&7�&%�&7�&'�&0�&$�&7�&7�&' '$'*'3';%>7A$}7�$�7�%�%�%�%�%�0�7�%�%&0
        !          135474:         !'%0.$<%@7C%R%[%^%k%t%x%~%�%�%�%�%�%�0�%�7�%�%�%�%�%�%�7�0� �%7%%%0%%&%*%07=0C%F%M%S%Z0_%e0j%q0u%x%}%�%�%�%�%�%�%�%�%�%�%�%�%�%�%�%�%�%�0�%�%�0�%�%�%�%�%%%0%0! ,%1740:%=%D%I O%R7U0_%b%i%q%�%�%�%�7�%�%�$�7�%�7�0�0�%�%�7�0�%�%�0%0%0%#0(%407%>0A%H0K%Q0V%]0`%f%m0r0{%�0�%�%�7�%�7�%�%�%�%�%�0�0�%�%�%�%�%�%�0% 0$77'%-%90<7B%b$s%�7�%�%�%�%�%�%�%�0�%�0�%�%7%' 7(79%?7B7M7X%^%g7o0w$}$�0�$�0�%�%�%�%�%�%�$�7�0�%� �%�7�%�7�0 %      0      7      %$    %(      7-      7B    7M            $b     7e      7t            %�     %�      7�      7�            $�     7�      7�            %�     %�      7�      7�            $
        !          135475: 7
        !          135476: 7
        !          135477: %,
        !          135478: %0
        !          135479: %3
        !          135480: $;
        !          135481: 7>
        !          135482: %E
        !          135483: %K
        !          135484: $W
        !          135485: 7Z
        !          135486: %`
        !          135487: $l
        !          135488: 7o
        !          135489: %v
        !          135490: %|
        !          135491: $�
        !          135492: 7�
        !          135493: %�
        !          135494: $�
        !          135495: 7�
        !          135496: %�
        !          135497: $�
        !          135498: 7�
        !          135499: %�
        !          135500: $�
        !          135501: 7�
        !          135502: %�
        !          135503: $�
        !          135504: 7�
        !          135505: %�
        !          135506: $�
        !          135507: 7�
        !          135508: %�
        !          135509: %&$
7%$"7%%+$77:%@$L7O%U$a7d$j7m0707070064030066661006440000000000000000011777770507310751000004000000040012/newbits/kernel/USRSYS/lib/gr.a]�mm.o�(���&�&�&�&�VW��v�D u2V������F��|$�F��F�&�F��F��F��F�Ph�����ǃ>�&u��&Vh`j
        !          135510: h�����_^�VWU�������>}2�h�jC����h�jB�w���j
        !          135511: jB�m���ja�e���
��>~�uja�K���%��Pja�?����>t��P�-����V�!����v�����vh`j
        !          135512: h�����_^�VWU��>�&~�>�&~        ��&u����_^�VW��v
        !          135513: �D�F��<uV������u����Dup� t'���F��&jjh&h�����v������ы>�E$E&t&�w��t�p��F�;Du��6V�]����t+��V�P����|u��� t��V�2����u��_^�&�ismmfunc_mmtim_mmbeeps_&mm_voff_mmcrtsav_�&mmgo_mmwatch_&nondsig_sphi_u_inb_outb_istty_kbunscroll_ttout_mmwrite_ &cprocp_timeout_mmstart_mmtime_`spl_mmvcnt_�&mmesc_&ttstart_sleep_70;%D%K O'T&7W7f'l's7|7�7�7�
        !          135514: '�'�7�
        !          135515: 7�'�'�7�'�7�7� �'�&7�$&$&$&7&76&0@&'M&7T&'[&'g&7j&7s&'|&7�&7�&
'�&        7�&7�&'�&'�&     7�&gr.o�(���&�&d2nonedev_grread_nulldev_grwrite_grcon_''''
        !          135516: &''''''gras.o�(���&�&T
 (
        !          135517: �8(+dp& VWU����^�w�O�?t��۽T
�v�V�F�~�F#F&1��&1�� +��f����.����ڀ~(u����F#F&1��&1�� [�^�v�V�~������&��^���O+O&O]_^�6�c����Q��V���B.���JK}�Y��������$t������F���F���F�F�F��F&�FP*Ҋv�v
�^�^+��F�6���y6��s*���:v~U�vVQ�^�^
��.���.�������.���Q+���VWQ�Y_^�� �� �F#F_W���_�� ���Y^�D&����.����ڀ~(u����I�����.�������I�����.����~(t�V*������������Ȏػ��3F#F�W�3F#F&�&��N�3F#F��3F#F&�&��N�3F#F��3F#F&�&��N�3F#F��F3F#F&�&_^+���:V}
�I�����.���*���:v�3��v����oV*�������n�����ػ��3F�W&�!��O�3F�&�!��O�3F�&�!��O�
        !          135518: f3F�&�!_^+���:V}
�I�����.���*���:v����v�j�����I�����.���*Ҋ���.�����I�����.�����}�V����:v
}*Ҋv
�|��H���I��~�~����.���      �2���I�<;t!�؀�0��      w9�f�F����FÈF��� ���I��؀�0��    w�f�F����FÈF�ފ���.���
        !          135519: �����I��؀�0�� w�f�F����FÈF��<htL<ltX�������I��؀�0�� w�f�F����FÈF��<hu��<lu�������€�*����~
u6�&���~
u6����V��}*�:Vr�V���d�� QV+Ɋʀ���*�ыv�~Pu���A��F#ƫ&�A�&�EN&�AN&���&���&���F#�&�����+�^Y:V|*V��:v~�v�����*���:v
s�v
�����~u�F&����~u�F�����:vv�v�����:Vr*V��:vv�v�V�����v��*�v
:vr�v�V��*�:Vr�V���{���:v
}�v
�n�VQ�^����.���.����^��.���+�~1��VWQ�Y_^�� �� �.���W���F#F�_�� ���*�Y^��6�&� ��F<u�^�&<&u�^
�r*Ҋv
����.����^*��<�F<u�^��<&u*��H*Ҋv
+��^��F��<u�<&t,��.���*�*�Q�F#F��������� ��}�Y��RQW�F#F��.�������.���+�~��WQ�Y_�� �Y����.���+�~x�׋���P������P������P������������P������P������P�����+�YZ���RQW�F#F��.�������.���+�~��WQ�Y_�� �_+ɊN*ʀ~(u��׋���P������P������P������������P������P������P�����+�YZ�t�6���VQ�^�^��.����΃�.���������.+��~3��VWQ��Y_^�� �� �.���W���F#F��_�� ���*�Y^�   ��V��*�:Vr�V������F
        !          135520: �u���:Vr�V������v��*�:vv�v�V��*�:Vr�V������:v���v�R��V�v���V�v����:v
}�v
�����Nt
        !          135521: 
�F�����F���F<u�F���F�F�!<&u�F���<u�F���<u�F����D��~Pu�F(�����F�����~(u�FP���F����F��}*�:Fw�^��}*�:^w:�w
        !          135522: �F
�^��*�����v��*�:vv�v����F
        !          135523: �u���:vr�v���&�&�&�&�&�&�&&�#&��&�Rh�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&���&�&�&�&&&�&�&�&�&�&�#&�&�&�&�&�&�&�&��&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&l�&
��&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&&&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&u�&�&���#&�����&v�&�&�&���&�&�&�&�&��&�&�&�&�&x��&�&�����&�&�&�&�&�&�&�&�&|�&�&�&��&�&�&�&�&�&�&�&�&@&��@��
        !          135524: @��
@��@��@��@� �!#@$�%�&(@)�*�+-@.�/�02@3�4�57@8�9�:<@=�>�?VWU��n
        !          135525: �~t����~���؋FF=@wW�F+ҹP������������&u�P+�;N~�N�-)N&NV�^�� �P+�;N~�N�)N&N�� +���]_^�VWU��n
        !          135526: �~t��؋v�����FF=@wҋF+ҹP�������������&u�P+�;N~�N�)N&NW�_�� �P+�;N~�N�)N&N�� +��ĺ���ú���6��&ä�����P&mm_vpa�ZERO       mm_scr�mm_cup�AZERO     0csivalimm_ed�mm_new�mm_hpr�MM_SROW     mm_sgrmmspec&mm_cuumm_hvp�scrolldownmmbeeps_mm_voff_?
mm_dlBANKSZ      mm_el�ewait0�&XMSR     �ewait1Tmmcrtsav_CLOWER     cread1~fontw_page1
read2�mm_ilmm_e0�mm_cr�mminit�page2
mm_e1�csi_q�rowtab�mmgo_mm_e2�mm_vpr�mm_ssr|HLOWER     hIO_BASE     IO_IOC     mm_ri�MM_BASE NRB2     @&grread_;mm_sihNCR2     mmputc�&IO_SEG NRB4     �MM_COL     IOSYS     NCR4     NHB     Pewait�mm_soRCOL     
        !          135527: IO_SEEK      NRB     �putc16�&crtdataNCR     grwrite_�islock_MM_FLIP     mm_chaMM_NCOL MM_MASK     MM_FUNC     done�eval�&CSR     �repos�&MM_SCOL mm_von_F
mm_cgh�uds_MM_VIS MM_POS     asctab�mm_cgl�SEMIC     ;MM_ROW     mm_hpaxmm_cbt�esctab�  MSR        �POS     mm_dmilmm_cub�MM_WRAP     MM_BROW     
mm_ind�mm_emi
mm_escputc8Vscrollup/&mmesc_mmvcnt_mmdataT
MM_ATTR     
        !          135528: mm_cud�mm_cqh�VSEG      �csitab�
        !          135529: mm_cnl#&MM_ULINE   MM_EROW     mm_cuf�mm_old�mm_cpl�mm_chtMM_N1     ROW     mm_cql�csi_gtummbell&MM_N2 exitPMM_CURSE MM_IBROW     csi_n1MM_LROW csi_n2GMM_PORT mm_eavMM_IEROW  T
'(O$- W'�e'�d �0&'&'&d =& B& K&0& �& �&0�& �&0�&'�& @0L0R �0�0�0� � � �00 00E p0s0�0�0�0�0�0�'�0�'000�0�0�0�0�0�0�0�00   % / L0j'oB0t0�0� �0�0� �0� 
  20� � �0'B0 % / ; W0v0�0�0�0�0�0�0�0�0�000P0f0z0�0�0� � � � � � � � � � � � � � � � � � � � � � � � &                                                  
                                                                      !       #       %       '       )       +       -       /       1       3       5       7       9       ;       =       ?       A       C       E       G       I       K       M       O       Q       S       U       W       Y       [       ]       _       a       c       e       g       i       k       m       o       q       s       u       w       y       {       }              �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       &
        !          135530:  
        !          135531:  
        !          135532:  
        !          135533:        
        !          135534:  
        !          135535:  
        !          135536:  
        !          135537:  
        !          135538:  
        !          135539:  
        !          135540:  
        !          135541:  
        !          135542:  
        !          135543:  
        !          135544:  
        !          135545:  !
        !          135546:  #
        !          135547:  %
        !          135548:  '
        !          135549:  )
        !          135550:  +
        !          135551:  -
        !          135552:  /
        !          135553:  1
        !          135554:  3
        !          135555:  5
        !          135556:  7
        !          135557:  9
        !          135558:  ;
        !          135559:  =
        !          135560:  ?
        !          135561:  A
        !          135562:  C
        !          135563:  E
        !          135564:  G
        !          135565:  I
        !          135566:  K
        !          135567:  M
        !          135568:  O
        !          135569:  Q
        !          135570:  S
        !          135571:  U
        !          135572:  W
        !          135573:  Y
        !          135574:  [
        !          135575:  ]
        !          135576:  _
        !          135577:  a
        !          135578:  c
        !          135579:  e
        !          135580:  g
        !          135581:  i
        !          135582:  k
        !          135583:  m
        !          135584:  o
        !          135585:  q
        !          135586:  s
        !          135587:  u
        !          135588:  w
        !          135589:  y
        !          135590:  {
        !          135591:  }
        !          135592:  
        !          135593:  �
        !          135594:  �
        !          135595:  �
        !          135596:  �
        !          135597:  �
        !          135598:  �
        !          135599:  �
        !          135600:  �
        !          135601:  �
        !          135602:  �
        !          135603:  �
        !          135604:  �
        !          135605:  �
        !          135606:  �
        !          135607:  �
        !          135608:  �
        !          135609:  �
        !          135610:  �
        !          135611:  �
        !          135612:  �
        !          135613:  �
        !          135614:  �
        !          135615:  �
        !          135616:  �
        !          135617:  �
        !          135618:  �
        !          135619:  �
        !          135620:  �
        !          135621:  �
        !          135622:  �
        !          135623:  �
        !          135624:  �
        !          135625:  �
        !          135626:  �
        !          135627:  �
        !          135628:  �
        !          135629:  �
        !          135630:  �
        !          135631:  �
        !          135632:  �
        !          135633:  �
        !          135634:  �
        !          135635:  �
        !          135636:  �
        !          135637:  �
        !          135638:  �
        !          135639:  �
        !          135640:  �
        !          135641:  �
        !          135642:  �
        !          135643:  �
        !          135644:  �
        !          135645:  �
        !          135646:  �
        !          135647:  �
        !          135648:  �
        !          135649:  �
        !          135650:  �
        !          135651:  �
        !          135652:  �
        !          135653:  �
        !          135654:  �
        !          135655:  �
        !          135656:  �
        !          135657:  &        
          ! # % ' ) + - / 1 3 5 7 9 ; = ? A C E G I K M O Q S U W Y [ ] _ a c e g i k m o q s u w y { }  � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �'LO'�O'O
efontw.o�(���&@&�0�3�����0��?�������??��00������?���?���?��������������?���?�������������������?�0000?����������������???�������?�?�������?�����?���<?�<<<?�<�������?�?���������������<������<?�����?�<�<�<�<�<�<�?�������?����<�<<<<�<���������?��?���?�?�����?�������<��<����00��00�?���������?��������������<<���<���<����?��?�<����<��<<�<�<��?����?<<���������<�����<���?�����?���<��<�?������<�<�<?�������?�?��<<�?�<��?��<<�<�<?���<������������<<�<?��<����<�<?����<��?��<�<?��<�<?�?��<�<?�<�?�����������<��?�?���<���<<<���?��<�������?��<��<�<���<�<��<�<<?�<<<����<���<���<�<<<<<<<�����<<?�<<����<<?�<<��<����<<��<�<�<���<�<�<��������������?��<<<<�?�?�<��<�<<<<<<���<�����<�<�<�<�<�<�<�������<?��<�<�<�<�<?���<<<<?�<<�?��<�<�<��?�<��<<<<?�?�<��<?��<����<?�?�3������<<<<<<<<<<<<�<<<<<<<<<<���<�<�<�<�����<�<<���<��<�<<<<<<<���������<�<������<��<���������<<�������?���?<<<<?�<<<<��?��0��0?����?�����?<?������?��<�<��<<�?<����?��?��<<?�<<<<<<?���������?��<<<<�?�<�<<?������<�<�<��<<<<<<<<�<<<<<<���<<<<?�<�?<����?�����?<<<<?��?��?�?�0����������<<<<<<<���<�<�<��<���?�?���������?��?����<�����?���?�����??<���<��<�<�<��BXXXXXXXX    ��BXXXXXXX_     ��BXXXXXX_X     ��BXXXXX_XX     ��BXXXX_XXX     �?BXXX_XXXX     ��BXX_XXXXX     ��BX_XXXXXX     ��B_XXXXXXX     ?�fontw_BXXXXXX__ ��BXXXXX_X_     ��BXXXXX__X     ��BXXXX_XX_     �<BXXXX_X_X     �3BXXXX__XX     �BXXX_XXX_     ��BXXX_XX_X     ��BXXX_X_XX     ��BXXX__XXX     �?BXX_XXXX_     ��BXX_XXX_X     ��BXX_XX_XX     ��BXX_X_XXX     �?BXX__XXXX     ��BX_XXXXX_     ��BX_XXXX_X     ��BX_XXX_XX     ��BX_XX_XXX     �?BX_X_XXXX     ��BX__XXXXX     ��B_XXXXXX_     ?�B_XXXXX_X     ?�B_XXXX_XX     ?�B_XXX_XXX     ??B_XX_XXXX     <�B_X_XXXXX     3�B__XXXXXX     �BXXXXX___     ��BXXXX_X__     �0BXXXX__X_     �BXXXX___X     �BXXX_XX__     ��BXXX_X_X_     ��BXXX_X__X     ��BXXX__XX_     �<BXXX__X_X     �3BXXX___XX     �BXX_XXX__     ��BXX_XX_X_     ��BXX_XX__X     ��BXX_X_XX_     �<BXX_X_X_X     �3BXX_X__XX     �BXX__XXX_     ��BXX__XX_X     ��BXX__X_XX     ��BXX___XXX     �?BX_XXXX__     ��BX_XXX_X_     ��BX_XXX__X     ��BX_XX_XX_     �<BX_XX_X_X     �3BX_XX__XX     �BX_X_XXX_     ��BX_X_XX_X     ��BX_X_X_XX     ��BX_X__XXX     �?BX__XXXX_     ��BX__XXX_X     ��BX__XX_XX     ��BX__X_XXX     �?BX___XXXX     ��B_XXXXX__     ?�B_XXXX_X_     ?�B_XXXX__X     ?�B_XXX_XX_     ?<B_XXX_X_X     ?3B_XXX__XX     ?B_XX_XXX_     <�B_XX_XX_X     <�B_XX_X_XX     <�B_XX__XXX     <?B_X_XXXX_     3�B_X_XXX_X     3�B_X_XX_XX     3�B_X_X_XXX     3?B_X__XXXX     0�B__XXXXX_     �B__XXXX_X     �B__XXX_XX     �B__XX_XXX     ?B__X_XXXX     �B___XXXXX     �BXXXX____     �BXXX_X___     ��BXXX__X__     �0BXXX___X_     �BXXX____X     �BXX_XX___     ��BXX_X_X__     �0BXX_X__X_     �BXX_X___X     �BXX__XX__     ��BXX__X_X_     ��BXX__X__X     ��BXX___XX_     �<BXX___X_X     �3BXX____XX     �BX_XXX___     ��BX_XX_X__     �0BX_XX__X_     �BX_XX___X     �BX_X_XX__     ��BX_X_X_X_     ��BX_X_X__X     ��BX_X__XX_     �<BX_X__X_X     �3BX_X___XX     �BX__XXX__     ��BX__XX_X_     ��BX__XX__X     ��BX__X_XX_     �<BX__X_X_X     �3BX__X__XX     �BX___XXX_     ��BX___XX_X     ��BX___X_XX     ��BX____XXX     �?B_XXXX___     ?�B_XXX_X__     ?0B_XXX__X_     ?B_XXX___X     ?B_XX_XX__     <�B_XX_X_X_     <�B_XX_X__X     <�B_XX__XX_     <<B_XX__X_X     <3B_XX___XX     <B_X_XXX__     3�B_X_XX_X_     3�B_X_XX__X     3�B_X_X_XX_     3<B_X_X_X_X     33B_X_X__XX     3B_X__XXX_     0�B_X__XX_X     0�B_X__X_XX     0�B_X___XXX     0?B__XXXX__     �B__XXX_X_     �B__XXX__X     �B__XX_XX_     <B__XX_X_X     3B__XX__XX     B__X_XXX_     �B__X_XX_X     �B__X_X_XX     �B__X__XXX     ?B___XXXX_     �B___XXX_X     �B___XX_XX     �B___X_XXX     ?B____XXXX     �BXXX_____     �BXX_X____     �BXX__X___     ��BXX___X__     �0BXX____X_     �BXX_____X     �BX_XX____     �BX_X_X___     ��BX_X__X__     �0BX_X___X_     �BX_X____X     �BX__XX___     ��BX__X_X__     �0BX__X__X_     �BX__X___X     �BX___XX__     ��BX___X_X_     ��BX___X__X     ��BX____XX_     �<BX____X_X     �3BX_____XX     �B_XXX____     ?B_XX_X___     <�B_XX__X__     <0B_XX___X_     <B_XX____X     <B_X_XX___     3�B_X_X_X__     30B_X_X__X_     3B_X_X___X     3B_X__XX__     0�B_X__X_X_     0�B_X__X__X     0�B_X___XX_     0<B_X___X_X     03B_X____XX     0B__XXX___     �B__XX_X__     0B__XX__X_     B__XX___X     B__X_XX__     �B__X_X_X_     �B__X_X__X     �B__X__XX_     <B__X__X_X     3B__X___XX     B___XXX__     �B___XX_X_     �B___XX__X     �B___X_XX_     <B___X_X_X     3B___X__XX     B____XXX_     �B____XX_X     �B____X_XX     �B_____XXX     ?BXX______     �BX_X_____     �BX__X____     �BX___X___     ��BX____X__     �0BX_____X_     �BX______X     �B_XX_____     <B_X_X____     3B_X__X___     0�B_X___X__     00B_X____X_     0B_X_____X     0B__XX____     B__X_X___     �B__X__X__     0B__X___X_     B__X____X     B___XX___     �B___X_X__     0B___X__X_     B___X___X     B____XX__     �B____X_X_     �B____X__X     �B_____XX_     <B_____X_X     3B______XX     BX_______     �B_X______     0B__X_____     B___X____     B____X___     �B_____X__     0B______X_     B_______X     B________     0707070064030066621006440000000000000000011777770507310751400004000000006445/newbits/kernel/USRSYS/lib/hs.a]�hs.o�(���&
&����&VW�i�^P�6������b�uhD�������i�^P�6b������F��F�;�|���^������iF�^b��j��P����j��@P������@P�~����t��q���\�D��D��^�������D��D���(&���)&�|��)&����㋇��F�h���P�)����v�W�����F���P��@P����j��P�����6d�F��3��_^�VWU��>bt
        !          135658: �6b������_^�VW��~��i�^b���|t�D@P����������t�����t�'�r�D�D=&uZV�����F�t;�r��F��DP�e������L ��t�d���� t�L�v��?����
        !          135659: �d���LV�&���vV�"����2�_^�VW��~��i�^b���|&uJV������F��~�t8hfhj
        !          135660: hf�����jjh&hf�������Z*�:�[u̓~�t��N����L���_^�VWU��v
        !          135661: jV�~��i�^bP�����_^�VWU��v
        !          135662: jV�~��i�^bP�d����_^�VWU���v�v
        !          135663: �~��i�^bP�?����_^�VWU���v�v
        !          135664: �~��i�^bP�����_^�VW��v��X&*�:�Y&t2��Y&*�ȋ�ي�Z&*�PV�������Y&*�=�rƄY&����Y&�¿���Z*�؊�[*��+���Ǚ.�>���O|9V�����F��|+��Z*�ȋ�ًF���\��Z*�=�rƄZ����Z��V�k����|tVh�j
        !          135665: ��H&P�T����_^�VW��6b�|u�&&�DtL�DP�)�������t7��&t��t�d����L ��t�� t�L��d��V������DP���������t�Dt       jV�������&t:��X&*�ȋ���F��t�����^���Z&�Dt��X&��X&*�=&rƄX&�� tC�D u<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�P�����[��[*�=&rƄ[��^��;dw����_^�VW��v���F�+���)&t��W�DP�������)&����㋇����t+h��DP�����W�t���������P�D@P�������,&%�=&t=t���
        !          135666: ��W�DP����j�D@P�����v�������_^�VWU��v�j����DP�^������� t<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�.�����[��[*�=&rƄ[W�����_^�VWU�����x�x;v|�x�x�_^�VW����t��F��F��F�;�}?iF�^��>b�}t)iF�^��>b��(&����狅�F��F�;F�}�F��F��F�븋F�;t.��.�>��v�o��&���~�th��6�Y�����_^�&d����
        !          135667: +&�&Y~�&�   Y@�&�`@:0 dddddddd�,&�&�&X �@hsload: can't allocate tty's
        !          135668: free_ttsignal_hscycle_�hsparam_�altclk_in_hsclose_�&altclk_out_kclear_sphi_tthup_u_hsioctl_�hsread_Ypoll_hz_cs_sel_inb_outb_nulldev_ttsetgrp_ttclose_ttin_ttout_poll_owner_poll_rate_ttioctl_ttread_hswrite_~timeout_hsstart_�alloc_HSNUM_�wakeup_hsopen_+&spl_hspoll_�HS_PORTS_�ttwrite_printf_allkp_ttstart_hsintr_�sleep_ttopen_hscon_�ttpoll_ � �'� � � �'�'� � � �$'&7%$7"%0($,%376$E0J$T%]7j7v7�0�7� � �$�$�7�7�7�7�%&0&%&%&7"&%>&7N&']&
        !          135669: 0a&'e&'m&
        !          135670: 7&*7�&7�&7�&!0�&7�&0�&%�&7%'% 7#%073)0S%q7u%�7�$%�7�%�7�,7 Q7Z7�' �7�%�0�7�7    7!79&7W7�%�0�7�7�$7"7,7=7i7v7!0�7�7�7�7�!0�%�%&%%%'0%$6%C%T$a'~'� �%�7�'� �'�7�'�0707070064030066421006440000000000000000011777770507310751400004000000003037/newbits/kernel/USRSYS/lib/lp.a]�lp.o�(״�&&&:h&%&VWU��>Ht��H&�&t�2&�t�8&�t�>&�0�<tQ�D&u$h��4�����>Ou��4����=�u�L&j�@@P�����>Ou�j�@@P�p�������_^�VWU����_^�VWU��F%=r��s�~��k�0���D&u�(��D&t��Dt�'�E�>t�@P��������u�&�%�d��F%�
        D�>t
�>�}t�v&�_^�VWU��v��k�����2���_^�VWU��N��k�0���^
        !          135671: �?uI�v
        !          135672: �������}��@P�z��������t�W�4�i���j
�@@P�\���j�@@P�O�����v
        !          135673: �D������|u�D�uN��-=wA����.���&�&j V�M���D�L��u��j
V�6���D��L��DWV�����G$G&t�����t���_^�VWU��v�>�@P���������u#Ou������LjjjV����W�������v
        !          135674: �4�y���j
�@@P�l���j�@@P�_����_^�VW��F��0�<t6�Du�����F��Dt�@P�(������ǀt߁d��V�����у~�thJh��6hJ������_^��&&�6&Q&��xxnonedev_nondsig_sphi_u_inb_outb_nulldev_iogetc_LP0_OK_timeout_cprocp_LPTIME_wakeup_spl_LPWAIT_sleep_lpcon_LPTEST_  ''  "'$'&'( * ,%0
%$$$%$-$3$;$@7T$[7c7z$�7�0�'�$�0�'�$�7�'&' &
        !          135675: ''&
        !          135676: 00&$I&$a&7q&0}&7�&7�&7�&7�&7�& �& �& �& �& �& �& �&0�&00'$
        !          135677: 7/&'7$H7O7`7q7x
7�7�7�$�7�7�%� �$�%7  0707070064030066221006440000000000000000011777770507310751500004000000017452/newbits/kernel/USRSYS/lib/mm.a]�mm.o�(��&�&�&�&�VW��v�D u2V������F��|$�F��F�&�F��F��F��F�Ph�����ǃ>�&u��&Vh`j
        !          135678: h�����_^�VWU�������>}2�h�jC����h�jB�w���j
        !          135679: jB�m���ja�e���
��>~�uja�K���%��Pja�?����>t��P�-����V�!����v�����vh`j
        !          135680: h�����_^�VWU��>�&~�>�&~        ��&u����_^�VW��v
        !          135681: �D�F��<uV������u����Dup� t'���F��&jjh&h�����v������ы>�E$E&t&�w��t�p��F�;Du��6V�]����t+��V�P����|u��� t��V�2����u��_^�&�ismmfunc_mmtim_mmbeeps_&mm_voff_mmcrtsav_�&mmgo_mmwatch_&nondsig_sphi_u_inb_outb_istty_kbunscroll_ttout_mmwrite_ &cprocp_timeout_mmstart_mmtime_`spl_mmvcnt_�&mmesc_&ttstart_sleep_70;%D%K O'T&7W7f'l's7|7�7�7�
        !          135682: '�'�7�
        !          135683: 7�'�'�7�'�7�7� �'�&7�$&$&$&7&76&0@&'M&7T&'[&'g&7j&7s&'|&7�&7�&
'�&        7�&7�&'�&'�&     7�&mmas.o�(���&&��VWU����^�w�O�?t��۽�V���t�~t���t����%�v�V�F�~+ۊf
        !          135684: �f[�f
        !          135685: �^�v�V�~�V��^���B���J��B���V���)��X��^���O+O&O]_^�6�c�Y�%0=0t
�F��F��F�V���!�V��B*��J�
�B*��V��*��B��F��f
        !          135686: �F&�v�v
�^�^+��F�6��n6���f*���:vvK�vVQ�^�^
��.���
        !          135687: .���
        !          135688: ����.���
        !          135689: Q+����� _�P�Y^����.��
        !          135690: ����.��
        !          135691: ��������.��
        !          135692: ����.��
        !          135693: �\I�����r.����€�P}�EI�����r�.���~u�����+I�����r�.��*���:v�I�����r�.���v�H��v���I�����r�.��*Ҋ���.���
        !          135694: ��I�����r�.������}�O��:v
}*Ҋv
����.���
        !          135695: �I�����s�Z�.������I��~�~����s�?�.�������I�<;t!�؀�0��        w9�f�F����FÈF�������I��؀�0��    w�f�F����FÈF�ފ���s���.��     ����I��؀�0��  w�f�F����FÈF��<htL<ltX���s���I��؀�0�� w�f�F����FÈF��<hu�<lu��i����€�*��H��~
u6�&�J��~
u6��:��V��}*Ҁ�Pr�O��Q+Ɋʀ���*�Ѱ �Y��Pr��P��:vv�v�����*���:v
s�v
�&����~u�F&�~u�F&����~u�F�~u�F����:vv�v���€�Pr��P��:vv�v�O���v��*�v
:vr�v�V��*Ҁ�Pr�O�]���:v
}�v
�P�VQ�^����.���
        !          135696: .���
        !          135697: �^��.���
        !          135698: +�~���.���
        !          135699: �P� �*Ҋ���.���
        !          135700: Y^�����6�&���F<u�^�~<&u�^
�]*Ҋv
����.���
        !          135701: �^*��8�F<u�^�T<&u*��4*Ҋv
+��^��F��<t7<&t��.���
        !          135702: *�*�Q� �P���}�Y��Q����.���
        !          135703: +�|� ���Y�u�Q��.���
        !          135704: +�|� ���Y�_�6��g�VQ�^�^��.���
        !          135705: �΃�.���
        !          135706: ������.+��
        !          135707: ~����.���
        !          135708: �P� ��*Ҋ���.���
        !          135709: Y^������V��*Ҁ�Pr�O����F
        !          135710: �u��Ѐ�Pr�O����v��*�:vv�v�V��*Ҁ�Pr�O����:v���v�c��V�v���V�v����:v
}�v
�7����Nt
        !          135711: 
�F���F�����F<u��x�<&u����<u�~�t�䈀�&��<u�̀��<u�p�~�u��$w����������
        !          135712: ��<u�~�u��p����������
        !          135713: �뜀�뗁~�u�,|<<�؀��.
        !          135714: ��
        !          135715: �,,
        !          135716: |(<�؀�.
        !          135717: ��
        !          135718: �,
        !          135719: |<��.���
        !          135720: R�V���Z����F��}*�:Fw�^��}*�:^w:�w
        !          135721: �F
�^��*����v��*�:vv�v�u��F
        !          135722: �u���:vr�v�_�y&y&y&y&y&y&y&&R&�y&�&y&y&y&y&y&y&y&y&y&y&y&y&y&6y&y&y&y&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&��y&y&y&y&&&y&y&y&y&y&�&y&y&y&y&y&y&y&�y&y&y&y&y&y&y&y&y&y&y&y&y&Qy&y&y&y&]y&�y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&&&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&y&��y&
        !          135723: ��&}?�R��y&gy&y&y&��y&y&y&y&y&y&y&y&y&y&`sy&y&����y&y&y&y&y&�y&y&y&y&�y&y&y&�y&y&y&y&y&y&y&y&y&
        !          135724:  "$&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~�����������������@&�&� �`�@�� �`   
        !          135725: �
        !          135726: @�� 
�
`�@�� �`&@ `P0p����!�Ë���)���Þ��&mm_vpa�ZERO   bcolor�
        !          135727: mm_scr�mm_cup�AZERO       0csival�mm_ed�MM_INVIS     mm_new�mm_hprsMM_SROW     fcolor�
        !          135728: mm_sgr�mmspec&mm_cuu
        !          135729: mm_hvp�scrolldownVIDSLOW_*mmbeeps_mm_voff_�
        !          135730: mm_dlmm_el�mmcrtsav_int11_CLOWER       cmm_ilmm_e0�mm_cr�&mminit�mm_e1�csi_q�rowtab�
        !          135731: mmgo_mm_e2�mm_vpr�mm_ssr�HLOWER       hIOUSR     &IO_BASE     IO_IOC     NCB     mm_ri�MM_BASE mmputc�&IO_SEG INTENSE     MM_COL     IOSYS     NHB     �ewait�&REVERSE pCOL     
        !          135732: NRB      �NCR     &islock_mm_cha?MM_FUNC     evaly&reposg&MM_SCOL     mm_von_mm_cghuds_MM_POS SPACE      NCOL     Pasctabmm_cgl/BLINK     �SEMIC     ;MM_ROW     mm_hpa`mm_cbtesctabPOS mm_dmi]mm_cubMM_WRAP     MM_BROW     
mm_ind�mm_emimm_esc6scrollup&mmesc_mmvcnt_mmdataMM_ATTR 
        !          135733: mm_cud�mm_cqh�coltab
        !          135734: csitab    mm_cnl&MM_EROW    mm_cuf�mm_old�mm_cpl}mm_chtRMM_N1     ROW     mm_cql�csi_gt�mmbell&MM_N2 exitPATTR MM_IBROW     csi_n1QMM_LROW csi_n2zMM_SLOW MM_PORT     mm_eagMM_IEROW  '?$'�U'�T7�0&'&T'& -& 2& ;& W& `&0c& n& w& �& �& �& �&0�&0�& �& �& & 0, 1040G L0O0x0� �0�0�0�0000'(0-'80=0P0x0{0�0�0�0�0�0�00 $ ) 3 @ R0X0['`70e0r � �0� �0� �0'70   * 6 B U0[0^0q0�0�0�0�0�0�0�0�0�0�0� ~ � �0�0�0�0  
        !          135735:              " $ & ( * , . 0 2 4 6 8 : < > @ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z | ~ � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �      
        !          135736:              " $ & ( * , . 0 2 4 6 8 : < > @ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z | ~ � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �                                    
        !          135737:                                                                                       "       $       &       (       *       ,       .       0       2       4       6       8       :       <       >       @       B       D       F       H       J       L       N       P       R       T       V       X       Z       \       ^       `       b       d       f       h       j       l       n       p       r       t       v       x       z       |       ~       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       
        !          135738:  
        !          135739:  
        !          135740:  
        !          135741: $�
        !          135742: $'U0707070064030064551006440000000000000000011777770507310751700004000000006256/newbits/kernel/USRSYS/lib/ms.a]�ms.o�(��&�&hD��VW���p�@�r�@@�t��v����F�h��6v�����j�6t�����hr�6
        !          135743: �����v�����+��_^�VWU���6
        !          135744: ����h��6v����j�6t�|����_^�VW��v��i����F��>jt�'P�S��������h��6v�@���jZ�6r�4����6r�*���=Zt
        !          135745: ��v���h��6t�����6p����h��6t������6p�����h��6t������6p�����h��6t������6p����j�6t����jh:h�����jjhHh�����Ph�����jhLh��}���jhPh��o���+����6�j&�v��W���+��_^�VW��E��F�j�6t�9���+����j�v��'���+��_^�VW����F��~
        !          135746: |�~
        !          135747: s�v�^
        !          135748: ����&������v�������>t����+��_^�VWU��f
        !          135749: ���f
        !          135750: ���8#6u�~t       hx�����8#6u�f
        !          135751: ���F
        !          135752: �_^�VWU��jh��v�����>�u��&�>�u��&�_^�VWU��jh��v�S����&6���_^�VWU��j�vh��6����&6���_^�VWU��jh��v�����_^�VWU��j�vh������_^�VWU��j�vh�������&6���_^�VWU��j�vh6������_^�VWU��jh8�v�����6#8ujh�h�h6�������8�_^�VW��>ju��{��F�h��6t�n����6p�d����F�h��6t�T����6p�J����F��~����F�%ǘ�F�h��6t�(����6p�����F�h��6t�����6p�����F��~����F�%ǘ�F�j�6t�����+��F��F��F��u�F�&��%&3F�t�~�tjj�jj&�I&���F� u�F���%3F�t�~�tjj�jj�&���F�F��~�u       �~�u���F�&��F�&��v��A&��;��v��2&��;�~�f��f��~�t7�F���l�F���>��l�F���>���F��6��6�P�������~�t7�F���n�F���>��n�F���>���F��6��6�P�������;�u   ��;�t�6&jh�h������6#8th6�����>~t   hx�u����v��l����_^�VWU��k^�����jh�kF�P�F����F
        !          135753:        6�_^�VWU��F;F
        !          135754: }�F
        !          135755: ��F;F~�F�F�F�_^�VWU��~}�F����F�_^�<
        !          135756: 
        !          135757: ��&�&_0l����"9������@&d@&d@&d@&d@&dms_readcrs_�msunload__MSPORT_clrivec_pollopen_ms_setmick_�nonedev_ms_setup_lsetivec_sphi_ms_wait_9u_abs_�msclose_�&inb_outb_nulldev_msioctl_�&blkmvms_readmick_�msload_MSIRQ_
        !          135758: wakeup_ioctls_&c_range_�spl_ms_readbtns_msopen_�ms_setcrs_�ms_readstat_"mspoll_0sleep_kucopy_ukcopy_button_�msintr_rpollwake_mscon_  ''' ''   " $ & ( * , . 0 2 4$%
        !          135759: $
%$%$%"7% %/72%;7> D$H7K7T$f7i%s7v%7�7�    $�'�7�0�%�7�%�7�%�7�'�%�7�%�7�%&7&%&7&%&7&%%&7(&%2&75&%<&7?&%H&7K&$S&%V&7Y&$c&%f&7i&%p&7s&${&%~&7�&$�&%�&7�&'�&$�&$�&7�&7�&   %�&7�&'�&$�&7�&7�&       $''7' $@$D%O7R$X$\%t7z!%�%�%�%�%�7�!$�%�7� $�%�7�!%�7� %7 $$-70 $A7G!$M$Q$^7a$j$z0�7�     %�7�%�7�%�7�%�7�%�7�%�7�%�7�%�7�%7%50P%b0}%�0�%�%�0�%�0�%�$�%�$�%�%�%�%�0&%$%$#%+%/%6%:0>%D%G%K%P%T$Z%a%d7g$m$q$v7y%�%�7�$7�%�%�%�7�$�0707070064030064521006440000000000000000011777770507310752000004000000002245/newbits/kernel/USRSYS/lib/rm.a]�rm.o�(C��&�&�X�{VWU���_^�VW��F��~�}%k^�,�����tk^�,���� ������F����_^�VW��F%�����k�,���N����+҉F��V���T�F��V��~
        !          135760: u�t0�F�F�t�F�F�t�F��V�;V�u;F�u�F�F�u�F�F�u��o�F�F�td�F�F�u\h0��F��V��       �������������RP�����D���u��,�F��V���T�E�U�D�T�D*jhRP������D*�_^�VW��~�����k�,���~����+҉F��V���T�F��V��t�F�F�t�F��V�;V�u;F�u�|*u��*�L*�F�F�u�|*t�'��t�Y�����D�_^�VW��v�D�F�%�����k�,���N�����+҉F��V���U�F�V��t�F��V�;V�u;F�t�L��F��V���������F�V��D��    �ȋ�+�D
        !          135761: T-&��;V�w�r;F�s��D
        !          135762: �T�   ������EU�F��V��|&u�D+�RP�t�t�v��v���D+�RP�v��v��t�t�m���V�f����_^�VWU��v��%�����k�,"��h@�j&V�v
        !          135763: W�8���
        !          135764: �_^�VWU��v��%�����k�,"��h@�jV�v
        !          135765: W�
        !          135766: ���
        !          135767: �_^�C,&�&��    nonedev_u_pclear_nulldev_salloc_bdone_plrcopy_sfree_rmcon_�ioreq_     
        !          135768: '''  %"%&%275%X'�&7�'�&7 &%@&'�&&'�&&7�&%�&07�7�%�7�    %�7� 0707070064030064441006440000000000000000011777770507310752000004000000022006/newbits/kernel/USRSYS/lib/rs.a]�rs0.o�(w��&#&n  <�&YVWU����        �����Kh�������uhDj��������_^�VWU��jjjh�����j����jh�����jh������_^�VWU��6�Ft���h��y���������t����|2�u�F�D2�|0u�D�D0�
�
*�=&uF�D0;Du��
        !          135769: u-��� ��� �
        !          135770: �F�t�&
        !          135771: ���_�����F�tM�uE�jjh&h�������>�E$E&t�����t��
u��
        !          135772: �
        !          135773: ��_^�VWU��
*�=&uc�
        !          135774: t[��        ;�     t5�jjh&h�q�����
*�=&u0�>�E$E&t��Q��t���
        !          135775: �+���     ��      �����
�_^�VWU��v
        !          135776: �|Vh�����;|u>�Dt��0�jjh&h��������G$G&t�����t���_^�VWU��v
        !          135777: �Dt��      +�     �     ��#>�   ;|w��CVh� �����P�|t0�jjh&h�|������G$G&t��f��t���_^�VWU��v
        !          135778: ������&t%��;�u�~t       h�2�����;�u������t%��  ;�t�~t     h������     ;�     t�������_^�VWU��h�����������t��>tNh������C�t;�
        !          135779: u3�&���>
t&����t�6��t;|0u      Vj&�����t�硲;�t �>t   h�j����>t h�Z����>t&�u h��D�������%��Ph��3����&���>uS�� ;�     t��&�>t��  ;�     u7h�&��,��    +�     %�=�s �>t  h������> t h�����jhj
        !          135780: h�������_^�VWU��h���������-=v�X&����.��j��.�th���������t)h��u����>�����&���&u
        !          135781: ���&����t��t��th��6����y��t7�6���Fƅ�������Fƅ������Fh������������6��:�h�������>���ƅ��&����h��������� t���t*��u  �&�����u   �&������t�&���>����ƈ���&�����t���%=t���>����ƈ���r�����_^�VWU���t�&�
        !          135782: uh��%�������u��������       ;�     u��h��������� u����    ���     *���&u��� |���
u��t{�
        !          135783: �v��
        !          135784: u,�t�>tb���      �
�T� tL��E��u
�>t9��3��        u.�%=u� ��*����t��    �       ����    �&�     �Vh��5���W�.����_^�VW��F
        !          135785: -&T=v�H&����.�����<��   ;�     t3�jjh&h�������>�E$E&t�����t���&�~
        !          135786: Tu@h��������~u����@���&�����Vh�������j�F�P�v�m����>t��F��F��
        !          135787: ;F�t  �F�
        !          135788: ��u�&���~
        !          135789: Tt������~jj�F�P�����
        !          135790: �F��F��F�j�v�F�P������M�F=w����.���%-��     ��      �.���������F�t=&t
        !          135791: ��&�      �&���b��_^�VWU�������
        !          135792: uj��>
u�
        !          135793: u�jh��t����
        !          135794: ���㋇�     ���t%h�h��T���Vh��J�������Ph��;����
        !          135795: %0���CC.;��u%.�g 0����+��
�&�����
        !          135796: %=&t=t�
        !          135797: ������
        !          135798: @t���t��@Vh������+��
        !          135799: t��
        !          135800: �t��&Vh�����W�����_^�
        !          135801: i^&�&4�3�� Y@�&�`@0procq_clrivec_pollopen_sendsig_nondsig_RS0CFLAG_�     setivec_sphi_u_rs0tty_"inb_outb_nulldev_rsin_rsout_cprocp_timeout_memset_wakeup_spl_rs0con_n     sleep_kucopy_ukcopy_pollwake_ r       t      'v       x     z       |      '~      '�     �     �       �      %%
07
        !          135802:  "7'0-%?7B7J&7U7`'p'{07�
        !          135803: '�0�'�   '�    '�    '�    '�    '�    '�    '�    $�'� '�    0�%&&%&'&   '&    '!&    7$&'+&       '/&7:&'B&  'H&    'N&    0S&'W&'d&    'o&    %v&%z&'�&      '�&    7�&'�&       '�&    '�&7�&'�&  '�&    0�&%�&%�&%�&%�&'�&     %�&7�&
'�&'       '    7'       '7%'-%D%H%L%R'[%b7e0k'u '    7�'�       '�7�'�%�%�'�       7�%�%�%�%�'�   7�%�%&7
        !          135804: ''   '-    '3    76'?       'G    'O    'U    '[    'e'i7v%�%�'�       '�    7�'�       '�    7�'�       '�    7�
        !          135805: 7�'�      '�    %�%�0�'�   %�%�'�      7�%%' '    7'"       '(    7+ 3%87;7M
        !          135806: 0_ h j l n p r7x
        !          135807: 7�
        !          135808: %�%�'�     '�    %�%�'�      '�    7�
        !          135809: 0�'�        %�%�%�7�
        !          135810: %%
        !          135811: 0
7
        !          135812: %%%"%'0,72
        !          135813: ';   'G    'T    0Y'b 0g'k 's    %y%}%�%�0�'�     0�%�%�%�0�0�0�'�       0�'� 7�
        !          135814: 0�7�%�%�0�7�
        !          135815: 0%%'  0#0+'4      '9    'K    'S    'Z    %_'h 'p    '|    '�    '�    '�    '�    %�'� '�    %�%�7�7�0� � � � � � �  %%        '    '    7'#       ''72':0>7K
        !          135816: 'Z   '`    'l    'r    70�7�'�0�'�       '�    '�    '�    0�'� '�    0�%�%�7�'�      '�    '�    7   ! #%&%)%.%1'7'L  'T    0Y7e'k    'w    '~    7�'�       $�7�7�7�'�   � � � � �'              '              ',             7;     'D            'O             7^     7e    rs1.o�(w��&#&n       <�&YVWU����        �����Kh�������uhDj��������_^�VWU��jjjh�����j����jh�����jh������_^�VWU��6�Ft���h��y���������t����|2�u�F�D2�|0u�D�D0�
�
*�=&uF�D0;Du��
        !          135817: u-��� ��� �
        !          135818: �F�t�&
        !          135819: ���_�����F�tM�uE�jjh&h�������>�E$E&t�����t��
u��
        !          135820: �
        !          135821: ��_^�VWU��
*�=&uc�
        !          135822: t[��        ;�     t5�jjh&h�q�����
*�=&u0�>�E$E&t��Q��t���
        !          135823: �+���     ��      �����
�_^�VWU��v
        !          135824: �|Vh�����;|u>�Dt��0�jjh&h��������G$G&t�����t���_^�VWU��v
        !          135825: �Dt��      +�     �     ��#>�   ;|w��CVh� �����P�|t0�jjh&h�|������G$G&t��f��t���_^�VWU��v
        !          135826: ������&t%��;�u�~t       h�2�����;�u������t%��  ;�t�~t     h������     ;�     t�������_^�VWU��h�����������t��>tNh������C�t;�
        !          135827: u3�&���>
t&����t�6��t;|0u      Vj&�����t�硲;�t �>t   h�j����>t h�Z����>t&�u h��D�������%��Ph��3����&���>uS�� ;�     t��&�>t��  ;�     u7h�&��,��    +�     %�=�s �>t  h������> t h�����jhj
        !          135828: h�������_^�VWU��h���������-=v�X&����.��j��.�th���������t)h��u����>�����&���&u
        !          135829: ���&����t��t��th��6����y��t7�6���Fƅ�������Fƅ������Fh������������6��:�h�������>���ƅ��&����h��������� t���t*��u  �&�����u   �&������t�&���>����ƈ���&�����t���%=t���>����ƈ���r�����_^�VWU���t�&�
        !          135830: uh��%�������u��������       ;�     u��h��������� u����    ���     *���&u��� |���
u��t{�
        !          135831: �v��
        !          135832: u,�t�>tb���      �
�T� tL��E��u
�>t9��3��        u.�%=u� ��*����t��    �       ����    �&�     �Vh��5���W�.����_^�VW��F
        !          135833: -&T=v�H&����.�����<��   ;�     t3�jjh&h�������>�E$E&t�����t���&�~
        !          135834: Tu@h��������~u����@���&�����Vh�������j�F�P�v�m����>t��F��F��
        !          135835: ;F�t  �F�
        !          135836: ��u�&���~
        !          135837: Tt������~jj�F�P�����
        !          135838: �F��F��F�j�v�F�P������M�F=w����.���%-��     ��      �.���������F�t=&t
        !          135839: ��&�      �&���b��_^�VWU�������
        !          135840: uj��>
u�
        !          135841: u�jh��t����
        !          135842: ���㋇�     ���t%h�h��T���Vh��J�������Ph��;����
        !          135843: %0���CC.;��u%.�g 0����+��
�&�����
        !          135844: %=&t=t�
        !          135845: ������
        !          135846: @t���t��@Vh������+��
        !          135847: t��
        !          135848: �t��&Vh�����W�����_^�
        !          135849: i^&�&4�3�� Y@�&�`@0procq_clrivec_pollopen_sendsig_nondsig_setivec_RS1CFLAG_� sphi_u_rs1tty_"inb_outb_nulldev_rsin_rsout_cprocp_timeout_memset_wakeup_spl_rs1con_n sleep_kucopy_ukcopy_pollwake_ r       t      'v       x     z       |      '~      '�     �     �       �      %%
07
        !          135850:  "7'0-%?7B7J&7U7`'p'{07�
        !          135851: '�0�'�   '�    '�    '�    '�    '�    '�    '�    $�'� '�    0�%&&%&'&   '&    '!&    7$&'+&       '/&7:&'B&  'H&    'N&    0S&'W&'d&    'o&    %v&%z&'�&      '�&    7�&'�&       '�&    '�&7�&'�&  '�&    0�&%�&%�&%�&%�&'�&     %�&7�&
'�&'       '    7'       '7%'-%D%H%L%R'[%b7e0k'u '    7�'�       '�7�'�%�%�'�       7�%�%�%�%�'�   7�%�%&7
        !          135852: ''   '-    '3    76'?       'G    'O    'U    '[    'e'i7v%�%�'�       '�    7�'�       '�    7�'�       '�    7�
        !          135853: 7�'�      '�    %�%�0�'�   %�%�'�      7�%%' '    7'"       '(    7+ 3%87;7M
        !          135854: 0_ h j l n p r7x
        !          135855: 7�
        !          135856: %�%�'�     '�    %�%�'�      '�    7�
        !          135857: 0�'�        %�%�%�7�
        !          135858: %%
        !          135859: 0
7
        !          135860: %%%"%'0,72
        !          135861: ';   'G    'T    0Y'b 0g'k 's    %y%}%�%�0�'�     0�%�%�%�0�0�0�'�       0�'� 7�
        !          135862: 0�7�%�%�0�7�
        !          135863: 0%%'  0#0+'4      '9    'K    'S    'Z    %_'h 'p    '|    '�    '�    '�    '�    %�'� '�    %�%�7�7�0� � � � � � �  %%        '    '    7'#       ''72':0>7K
        !          135864: 'Z   '`    'l    'r    70�7�'�0�'�       '�    '�    '�    0�'� '�    0�%�%�7�'�      '�    '�    7   ! #%&%)%.%1'7'L  'T    0Y7e'k    'w    '~    7�'�       $�7�7�7�'�   � � � � �'              '              ',             7;     'D            'O             7^     7e    rsas.o�(x��&j&&��
        !          135865: VWU���^
        !          135866: ����O�#�^�w;wt�@F#7�;w��w�^
        !          135867: ��O]_^�VWU���^
        !          135868: ���O�(�^�w&�G�@F#7;w��uON#7A�w�^
        !          135869: ��O]_^�Q_IX    IO_BASE     IO_IOC     Q_OX     rsin_Q_MASK rsout_>uds_Q_CC     ''L0707070064030064411006440000000000000000011777770507310752200004000000012557/newbits/kernel/USRSYS/lib/st.a]�st.o�(���&Q&�
        !          135870: �DCVWU���6�
        !          135871: �����h���
        !          135872: @P�����j�
        !          135873: ��j ��
        !          135874: @P�����h��6�
        !          135875: ������_^�VWU���6�
        !          135876: �����6�
        !          135877: ����j��
        !          135878: @P�����_^�VW��v�~
        !          135879: �>u��&�>t�'�&��t
��t��u&��     �}��f&�E��F�j��
        !          135880: P�6���j ��
        !          135881: @P�)����v�� ���h�����   �|��2�����`t�&�&��u�2�����t����΁���+ң*�,�u�*&�,�
        !          135882: �*�,�������*�,�*,t%h ��6,�6*�����0�u
�.*�,�҃>0u���0�G�.��u�&�+���0�G�W�"�$��u       �*�,�+��У&�(��u�@�����>��� �:�<�3�����tj�^���_^�VWU��v�>t��>t&j`��>t�ƀt�2�����&u     h�����ƀu��|�j!���j&�����60�{����0��_^�VW��v
        !          135883: �D�F��|u��&(u,�>t�F�;Dum��e� ���t��U�&�ˋ|�Ǚ;(|;&v�&��W�t�6$�6"�������;�u&|)|�Ǚ)&(�Ǚ&"$�r��_^�VWU��v
        !          135884: �|tg�|�Ǚ;(|;&v�&��W�6$�6"�t������;�u6&|)|�Ǚ&"$�Ǚ)&(�&(u�1&� ���t��L�_^�VWU��>t�&� �F
        !          135885: ���CC.;��t�.�g
        !          135886: &de"9��j"�&���dj$��>t�>tj`�d&���j!�ԃ>t9j`�K&����)�>u"�>u h��,&����&�(� ��_^�VWU��>0�E�U�"�$�*�,�&�(�l&�>0�E�U�"�$�*�,+&(�&�(�> t�&�(�_^�VWU��&�(;,u     ;*u�jh�6(�6&�����t)j&�6$�6"h�������"&�$�.&&�(���>0�E�U�"�$�*�,+&(�&�(��>0�E�U�"�$�*�,�&�(�_^�VWU�������>&t,�>}�>���F���Pjjh&h�O������~&�� �:jd�&���F�P�6�
        !          135887: ����j`��
        !          135888: @P����V�����_^�VWU��������>&tjjh&h��������~&�� �:jd����;u�D���P�6�
        !          135889: ����j`��
        !          135890: @P�����>&tjjh&h�~�����V�u����_^�VWU���f�����
        !          135891: @P�\������� u���:�-=v��&����.����  &��bj ��
        !          135892: @P�����>�u�����8�&�>t�&����LJ��&j0��
        !          135893: @P������6h�6$�6"�6�
        !          135894: ����
        !          135895: �>�u��
        !          135896: @P����%=u��j��
        !          135897: @@P�����6�
        !          135898: �~����9&��u�0&�6�
        !          135899: �h����.&�(�>(x/u�>&t&�"�$�6h�6$�6"�6�
        !          135900: �)���
        !          135901: �j ��
        !          135902: @P��������&2��&3��&���
        !          135903: @P�����%H����u��6�
        !          135904: ������8��2j`��
        !          135905: @P�����j���j ��
        !          135906: @P�����8�8=ug��_�2�����&tj��
        !          135907: P�����&�9�2�����fu�3�����`t� ��>@u�2�����t� �rW�;����_^�VWU��j ��
        !          135908: @P�%���jd��&���;u
        !          135909: �6�
        !          135910: �
        !          135911: ������P�6�
        !          135912: �����j`��
        !          135913: @P������~&�� �:�_^�VWU��j ��
        !          135914: @P�����~�&jd�~&���>tC��>�狅�P�6�
        !          135915: ����j`��
        !          135916: @P�z����~&�� �:�      h�W����_^�VWU���H�����
        !          135917: @P�>������� u������@t�:��:�:=|��W�
����_^�VWU��2����� th������n�2�����@th��3����� th1�֠2�����thG�Š2�����thb봠3�����@th�룠2����3����Ph������_^�VW��o��F��>&t*jjh&h�X����>�E$E&t��v��C��������v��5���+��_^�VWU��vN}��_^�&m"�9��       Cst: Unselected Drive
        !          135918: st: Cartridge missing
        !          135919: st: No data detected
        !          135920: st: Bad block not located
        !          135921: st: Unrecoverable data error
        !          135922: st: Illegal command
        !          135923: st: %x
        !          135924: st_>stcon_�
        !          135925: clrivec_STPORT_�
        !          135926: dmaoff_nonedev_setivec_sphi_u_drvl_inb_STDMA_�
        !          135927: outb_nulldev_stuload_Csalloc_lrremcprocp_dmago_wakeup_dmaon_spl_printf_STIRQ_�
        !          135928: sfree_kpcopy_sleep_upcopy_pucopy_ �
        !          135929:  �
        !          135930: '�
        !          135931:  �
        !          135932:  �
        !          135933:  �
        !          135934: '�
        !          135935: 
 �
        !          135936:  �
        !          135937:  $7
        !          135938: $70 $(7- 3$77:$J7M$T7W$_7d'{'�0�'�'�0�'�0�0�'�0�7�$�7�$�7�7�0�0�'�'&&0&'
&'&0&'+&'/&'7&'=&'E&'I&'R&'V&'Y&']&'f&'j&7m&'s&'{&'�&'�&'�&0�&'�&'�&'�&'�&'�&'�&'�&'�&'�&'�&'�&'�&'�&'�&'�&'''0',02'6'A'M0\0h0q0y'�7�'�'�0�'�'�'�'�'�'�0�0�'�'�'�''7'!'%','003'O'W'\'c'g7m'�'�'�'�'�'�0�'�'�0�'�0�'� �0� � � � � �0�''0''$0,'3';'B0K'R'X'^'c'f's'|'�'�'�'�'�0�'�'�'�'�'�'�'�'�'�'�'�'�'�'�'�'�0�'�'�7�''%7'''"'''.'7';'>'B'F'J'M'Q0T'X'a'e'h'l'o's7'�'�'�'�'�'�7�'�        '�'�'�0�'�$�7�$�7�7�7''7'$    '*'0'60='C'G0L'Q'T$Y7\$d7i'p'}7�7�7�$�7�
        !          135939: 0�0�'�'�0� � � � � � � � �$�7�'�'�'0'0'''0$$)7.'5'<'@$D7G'N$U7Z
        !          135940: 'i$p7v$}7�0�0�$�7�'�'�'�'�'�'�'�'�'�$�7�$�7�'�0�'�'�'�0$7
        !          135941: $7
        !          135942: '&'*$/740<$D7I'P'S'\'c$q7x''�'�'�'�'�'�0�7�$�7�0�'�'�$�7�'�$      7      $
    7      '            '     '%    '+    $;    7@      'G            'M     0T    '[      'b    'f    'l    'o    $t    7w      $    7�      '�            '�     '�    '�    '�    7�    7�    $�    7�      
        !          135943: 0�    '�      '�    '�    0�    7�      '
        !          135944: $
        !          135945: 7
        !          135946: '
        !          135947: $#
        !          135948: '(
        !          135949: $4
        !          135950: '9
        !          135951: $E
        !          135952: 'J
        !          135953: $V
        !          135954: '[
        !          135955: $g
        !          135956: 'l
        !          135957: 'r
        !          135958: $|
        !          135959: 7
        !          135960: 7�
        !          135961: '�
        !          135962: '�
        !          135963: 7�
        !          135964: '�
        !          135965: 7�
        !          135966: 7�
        !          135967: 0707070064030064351006440000000000000000011777770507310752300004000000015626/newbits/kernel/USRSYS/lib/tn.a]�tn.o�(���&H&�b�VW���F��~�|�w�^��ヿ"t�^��ヿ*t�^��ヿu*�^���LJ*�^���LJ"�^���LJ�F����멋^��㋇*�Dyj@P�����ty��������t�Dy�ɋ^��㋇"+ҹ�������F��V�jhRP�I����F��V�h4��RP�2����F��V���RP����=4t�v��v��
����j0jh �����������u�v�h<������̋F��D,�D�D�D�D�D�D"��D0��D�D�D$�D2�tD�D�D�D�D@�D*�D ���W����=�t+j&�DyP�x����F���F��n�&�^��F��V��u��W�Q���=�u
        !          135968: W�E����D{����G�W���F��V��F��~�&}j�v��v�h�����F�F� �V���j j����P�����j j���P������Dw�j�ty�����j�Dy@P�����j
�Dy@P����j&�Dy@P�����\@�w�Dy@P�����^�����
        !          135969: �^����������tw�ty�x��������&�_^�VW����+���}M�|yuG�����j�ty�=����������/����D�F��t
        !          135970: P�v��������t�����
        !          135971: �����_^�VW��F%�F��F%����F��~��~�i^������yu��$�~�~�~��烽2t�iF������~��Es�_^�VW��~��i�������F%0���F�����Osu6�^���ދG8���t&�]��F��^���ދE�G8WV����v��?������_^�VW����yv���|yu��������F����t]��+�����؋ʃ�|C���&v=���&t+����G�W�F��V�j&��RP�}�����&DŽ�&����DŽ����t���u
j&�Dy@P�����v��������&t�c�DŽ�+���|�S������ȋ�كLt�����FP�R���G���_^�VW�6�v�N��i�����F
        !          135972: =&Nt
=Nt��&�DP�����F�������ȋ��GW�F��V�����F��.�>��ڊ�*�ȋF��.�>���ߊ��*�#�tj&�j�DP����j�DP���P����j �F�P�v��v�����j �DP�F�P����j�F�P�F��V���RP�n�����+F�V��F��V�j�D(P�F�P�K����~
        !          135973: Nu9j �v��v��6���j�F��V���RPh�����~�uDž�Dž���+��_^�VW��~��i�����F%0���F��F��F
        !          135974: t���t�N��F
        !          135975: &t�~�����}8t�N�&�F
        !          135976: t�|Du���&t�N��~�uT�~tN�F
        !          135977: &t$�F����FP�q����~�����}8t�&�&�F
        !          135978: t�DfP�N����|Du���&t���F��_^�VWU��h�=���_^�VWU��h��+���_^�VWU��h�&����_^�VWU��hy����_^�VW��v�ty������F��Dwj�ty������F�u�j�Dy@P������+������k�
        !          135979: �F������������&����~��|�~��~���&t���&����DŽ�&DŽ��N������=uA���&u:����G�W�F�V�j&��RP����j j����P�������&DŽ�&�F�tM�f�~�j
�Dy@P�����j�Dy@P������D@���t�u�Dy@P������DB���t�u�Dy@P�����DB���u��&�Lw&�F�&u��&�E@�W�����F�W�����ȸ&+��F��~�&uW�h����ȸ+��F��F�tx����G�W�F�V�j&��RP�����v��F�V���RP�����F����ȋ��&F�V�j&�F�V���RP����v��F�V���RP�����~�u�����G�W�F�V�j&��RP�l���F����ȋ��&F�V�j&�F�V���RP�E��j&�F�V���RP�/���F��.�>��ڊ�*�F��F��.�>���ދF����F��.�>���ދF���DŽ�&�E�DB�DD�E�|D�DB���t�u�Dy@P�����:�����dw��DŽ��|rt�Dr�DrPh������|lt
�DfPh������D@���u��&�Lw��F��u��&�E�D@�t�]�w�Dy@P�����E��dw��E�W�����F�W�{����F��t       �|{u�D{W�d����F��uW�V���E����&t�������&DŽ�&�F��.�>��ڊ�*�F��F��.�>���ފ��*�#F�tw����G�W�F�V�j&��RP����F����ȋ��&F�V�j&�F�V���RP�}���F��.�>���ދF��� ���F��.�>���ދF���DŽ�&W����F��F��~�~�^��㋇2;F�t�N����^��str�^���ރ8t�^���ދ_8��
        !          135980: �^���މ8��^��nt��^��Gn��F�nPh����F����ȋ�كLt�F����FPh����WV�K���tw�ty�����_^�VW��v
        !          135981: �N��i�����F%0���F��|BwmVj���V�E{�P����|@u8��j ���PV���j ���PV�u��j ���P�h��Dž��\���&�| t�&j ���PV�E���&�<�F�^���ߋG8�F��u�D&�F���ljF�^��G�^�G8�^��G�v��&���^��G�VS�����F�P����V�v�����P�����v������F��t�^��G�F�F�F��&�$�v�����F��t�^��G�F�F�F��+F��F��~�t#�D;F�s�F��v��t�v��f���F�)D&D���tf����G�W�F��V�j&��RP�����v��v��v������F����ȋ�+�&F�V�j&�F��V���RP����v��v��v�����v�W�G���O�Dt��v������8��^��Gn&h�j&h���F�nP����v�������u�X���_^�VW��v
        !          135982: �N��i�����|r�|�&v��&V�\��V�U���F��F��.�>��ڸ&�����ȋF��.�>���ߊ��*�#�t�&�y&��F��ED�F��u���^��G�ED�G�v�������^��G�jS������v��v�������D�F��~��vj�v���������&+F��F�P�v������^��G�F�F�F��v�S�t�����F�&D)D�D�^��G�r��}Bu2�F��EB�^��w�Ey@P�X����Mw&�EwP�uy�F����:����     �F��]B�G�v��+�����DtN����G�W�F�V�j&��RP����F����ȋ��&F�V�j&�F�V���RP������Er&jjh&�ErP����v�������u�Y���_^�VW��v�~
        !          135983: ��F��|@u%�|@�u�Dy@P�y���Lw��DwP�ty�g����\@��E�v��Q���_^�VW�j�F�P�v
        !          135984: �v�5���F�&F�V�j�v
        !          135985: �v�F�P����_^�
        !          135986: �c)r���&���& @��� @�tn%d: out of memory
        !          135987: tncon_�utcopy_tucopy_TNPORT_*clrivec_pollopen_fclear_nonedev_TNPREFIX_2nondsig_kclear_tncycle_�setivec_sphi_u_tnuload_�drvl_tnclose_cinb_outb_nulldev_iogetc_getubd_tnet_Lsplo_salloc_tnread_)tnload_iowrite_tngetc_defer_TNSEL_"ffword_ptov_memset_fkcopy_kfcopy_wakeup_tnwrite_rTNIRQ_spl_tn0intr_�tn1intr_�vrelse_TNTIME_:tn2intr_�tn3intr_printf_tnintf_
        !          135988: ioputc_putubd_tnopen_�sfree_sfword_sleep_kucopy_lbolt_tnputc_tnintr_pollwake_tn_rxena_a � �'� � � �'     
        !          135989:    '0$$*$6$B$M$X$l7v7$�7�!7�57� 7�+7&$&7&/7r&7�&7�&7�&'�&87�&$7"7"7*777D7Q7b$n$w7z7�0�'�'�'�7�$�7�7�+7�4'/'6$H'S'u7�
0�7�('�'�0�7�
'�8'�8077g7p(0}0�7�;'�'�0�7�7
 $ (7C27T77f#7v77�#'�8'�87�77�'�87�$7�'7�7�'�0�'�0�'�0�'
        !          135990: 0
7#760C7M'S8'W8'j8'n80�7�"77757L0[0j7t7~7�0�0�0  0      0"      0+      0H      0o      0�       �      $�       �       �      7�      $�    '
        !          135991: %7
        !          135992: '(
        !          135993: ;7+
        !          135994: 0:
        !          135995: 0I
        !          135996: 7a
        !          135997: 7y
        !          135998: 7�
        !          135999: 7�
        !          136000: 7�
        !          136001:  �
        !          136002: $�
        !          136003:  �
        !          136004: 007 C Y7n$�'�%7�'
        !          136005: ;7
07 '>7X17d17p
7{7�7�
        !          136006: 7�0�0�7�0�7�
0�7�(7

7
17!
7(
171
7W
7�
0�
0�
0�
00'(7/(7Q67Z(7`     0g'k'�'�0�7�7� � �'�0�7�
0�7 (797&97>97V97t&7�
7�7�$�7�(0�0�0$'+7@67I(7O  0V'Z7n
7�7�7�(7�#7�$tnas.o�(���&&&zd
        !          136007: VU��^�7���7*�]^�WU��F�^�?���?]_�VWU���^
        !          136008: �?�v��N���������?]_^�VWU���^�~
        !          136009: ��7�N���������7]_^�utcopy_)tucopy_Qtngetc_uds_tnputc_':'`0707070064030064341006440000030000030000011777770507310752500004400000000131/newbits/kernel/USRSYS/lib/ldrts0.o&�����v�v�v�Ѓ��main_7&0707070064030064321006440000030000030000011777770507310752500004400000002315/newbits/kernel/USRSYS/lib/ldmain.o&�&*�&�VW��6�t;6|Vh�&�����j&�����k�
        !          136010: ��u���ヿtVh�&����j�������&���&�y&��&k�
        !          136011: LJ����LJ�������>t
����P���jjh&h�&�\�����G$&t�>�&uރ>t
����P���k�
        !          136012: LJ����LJ����LJ+���}.���㋇;tG��W���������LJ����LJ��h�����+���&s=���㋇�F��~�t)�^��G�F���;F�ujjj�v������͋^����G�j�����_^�VWU��>�&t
�v
        !          136013: �v��&���>u��&�_^�VWU��>�&t
        !          136014: �v��&����&u        h�&�=����_^�ldrv:%d: bad dev
        !          136015: ldrv:%d: dev bsy
        !          136016: main_clrivec_uexit_Kdefend_ldrvipc_u_ldrvics_ldrvcon_drvl_drvn_timq_ldrvsel_con_timeout_kcall_cprocp_ucs_wakeup_printf_ldrvpsy_getcs_sleep_''      $77!'+'6$=7@7H'N$Q'T$W'[ ]'a c'j'l't'v'}'�'�'�$�7�'�$�'�'�'�'�'�'�'�7&&'&'&' &7#&'6&
        !          136017: 7K&7\&
7p&$�&$�&'�&$�&$�&$�&$�&$�&7�&0707070064030064271006440000030000030000011777770507310752600004400000005305/newbits/kernel/USRSYS/lib/ldswap.o&j��&VW��>tj&������h������+j���F����F�F���&j�F��F��F��>��u��E"&t�N��m8�F�)E:�}:Њ}�E:Њ�}�ӋF�E8�F�;E8s����E8�F�&�} u��F��F��~�}0�^���ߋG���t�D&ujh�t�t�-���&F��F��ʃ~�u�F�&�E8E<+��v��F�;F�w�{��F�~��r�h������~�u�~�t����G$&u����v������t�v��&���u��v���&���F���F�h�����>��tE�E"�t�}���E"&uW�&���t�h�h���딃}:�~�}8uҋE:;F�}ʉF��~���h�A����~�t�~�~
        !          136018: �^��O"��v��T&�hhj2hh����
        !          136019: jjh&h��������j&������_^�VW��v�F��F��F��~�}<�^���ދG���u�F����E&u�E�U;V�|�;F�v�E�U�F��V��ԡ��F��V���=�E�U�F�V�+F�V�;V�|
        !          136020: ;F�r�&��E�UEU�F��V���u�+��_^�VW��v�D"%�F��F��F��~�}5�^���ދG���u�F���~�t�E
        !          136021: �E&u�W����u��F��ۃ~�u�L"&�d"���F��_^�VW��v�D"%�F��d"���F��F��~�};�^���ދG���u�F���~�u�M
        !          136022: �E&t�}
        !          136023: u�W����t��F��ՁL"�F��_^�VWU��vh�R����D&uz�t�t������u
h�0���+��g�D
        !          136024: �u�u�t�t�u�uj�����L
        !          136025: ��\��D��G�]�7�E�D��w���L&�E�U�D�TV�����h������&�_^�VWU��vh�����|
        !          136026: th����+���D&tm�t�t�t�����tفd���E�U�D�TV�k����D
        !          136027: �t�t�u�u�t�tj&�N����L
        !          136028: ��\��D��G�]�7�E�D��w��h�����&�_^�VW�jh�v
        !          136029: �v�&����F��V����F�V���D��=tjh�t�t�����DT����F��V��F�V�+F�V�;V�|K;F�rF�jW���������<�u�E&�E
        !          136030: &�F�V
        !          136031: �E�U�F�V�+F�V��E�U����D�T�F�V���t�]�+��_^�VW����F��V�����=t�D�T����F��V�+F�V�;V
        !          136032: |G;FrB�jW������\�?�D�E�|�5�E&�E
        !          136033: &�F�V
        !          136034: �E�U�F��V��E�U����D�TDT�F��V���t�s�+��_^�procq_main_xdalloc_�segcore_�testcore_lock_segdisk_Bsexflag_seglink_corebot_uexit_xmalloc_�kclear_pnxgate_segswap_coretop_swapbot_lrdivkcall_cprocp_vremap_unlock_swaptop_Ktimeout_swapio_segdq_stimer_utimer_Kwakeup_sleep_segmq_proccore_�procdisk_2'7
        !          136035: ''
7'#%'%='P'T0Y7�0�0&'   &
7&0&'"&0,&0/&05&0B&0L&0R&'b&
7e&'l&'p&0�&'�&
7�&'�&
7�&0�&'�&'�&'�&'�&7�&'�&7�&0' 7
        !          136036: 'r   'v    ''�0
0�'�7�0�'�7�7�7-'376'K7N'Z7]0e0u7�7�'�7�7�'        '
''7.'<'@'a7g'�0�'�  '�    '�'�'�'�'7']0b0707070064030111361006440000000000000000011777770507310752600004500000001106/newbits/kernel/USRSYS/lib/support.a]�cs_sel.o�(���&D&+��cs_sel_clocked.o�(���&�&&��6VW��~dra�F+�.�6��uS�F+�RPjh�4������F�����F�j6jC������F�%�Pj@�����F���Pj@�����v������F���F����F��_^�VW��v�{����F��u�F
        !          136037: ��F��_^�VW���F��~�tjd�M�����F��_^�daltclk_in_yaltclk_out_�sphi_outb_altclk_altclk_rate_vrdivspl_ 7'707:7I7X7a0�'�'�0�'�0707070064030111341006440000000000000000011777770507310752600004100000010376/newbits/kernel/USRSYS/lib/tty.a]�tty.o�(�i�&�&p�tVWU��vDŽ6&�D���(&�D���)&Ƅ*&Ƅ+&DŽ,&Ƅ.&Ƅ/&Ƅ0&Ƅ1&Ƅ2&Ƅ3&��|t��\tV�t��\�����V�T���_^�VWU��v�>�}0u��4&u�E��4&��4&�E0�}2�u�F
        !          136038: �E2�_^�VWU��v�<t7�E����<t�Ljjh&V�.���W�'�����G$G&t����t�V� ��+���4&�D�_^�VW��v�~
        !          136039: �E�F��}u�&����F��D
        !          136040: P������F��}v�Du��v���������,&`t�Du�E;F�r��Et��ρLh�j&h��D
        !          136041: P�z�����G$G&t��h��t��E;F�u��떃|
        !          136042: (<�Dt�d���D&t)�d����0&�PV�-����}V�&������V����v��
�����,&`u
        !          136043: ��2&�;F�t,W�v�������|��,&`t����~�
        !          136044: t
��3&�;F�t����_^�VW��v�~
        !          136045: �Et�}�w��+E;w��W�����F��|{�Du���|��F��<�|:V�s���<�|-�L&jjh&V�V�����G$G&t��D��t���3�v�V�2����}V�+���!����v������w����F�V�
���v������_^�VW��v�~�F��F��F��F��F
        !          136046: -@=v�2&����.��>yp�%,Q3HY`ggg`jW�D
        !          136047: P������jW��(&���F��F��F�j��(&PW�s�����,&`t�&�+��F��F�j��(&PW�Q����~�t���,&`u��|"u��D$�F���D"$�F��F�;F�s�^��F���P�D
        !          136048: P�������D"�gjW��.&�W��F��F�j��.&�j��L��G�d��@�L@�9����u�&�+�d���$jW�D���F��F���L��d������,&@t�D t�d��V����~�t+�<t&�Ljjh&V�^�����G$G&t��L��tՃ~�tV�����~�t$�|t��\tV�t��\�����V�T���_^�VWU��v�f
        !          136049: ���F
        !          136050: &t"�|
        !          136051: u�~t��8&P������|
        !          136052: u�f
        !          136053: ���F
        !          136054: t �<(|�~t��@&P�����<(|�f
        !          136055: ���F
        !          136056: &u�Du�N
        !          136057: �F
        !          136058: �_^�VWU��v�| t�L �D!����c�Dt
        !          136059: �d���
        !          136060: �RV�h������}������,&�u7��
        !          136061: u��,&t
        !          136062: �L�
� ��   u��,&t��$&
���ЈD �D! � ��,&�uL��u
��$&t@��$&�:��
uDŽ$&�-��  u��$&
@��$&��� |��~~���|
        !          136063: �����$&���_^�VW��v�~
        !          136064: ��,&@uV��.&���;�ujV�������/&���;�uj�犄1&���;�u�D t���L ���0&���;�u�d����Dt���,&@t��&��
u��,&t�
        !          136065: ��6&t\��\u��6&�B��*&���;�t��+&���;�u�π��6&��6&t�|"�}�\"�D"��G$\��WV�6����,&u�$W���*&���;�t����,& t����6&t�|"�}�\"�D"��G$\��6&���|"u��&�L"�\"ފG$��F���,&u��&��,&t���=u�&�u�&��u�&���u�&��t��      tjV�8���j V�/���j�k&��     t�j&��&&�6&�F��F��F�;D"}&��؊G$�����u�N��
��     u�N��F��F��ҋF��F�;�$&|�&jV������抄+&���;�u<��,& u4�D"DŽ6&��,&u���� }j^V������@WV����j
        !          136066: ����,&`t>W�D
        !          136067: P�p����Dt�d���D
        !          136068: Ph�W�����>&t4DŽ>&��8&Ph�<���|"u��$&��&&��\u��6&�WV�r����,&t"��,&@u��2&���;�tWV�����V�����D
        !          136069: �F�=|�L�/��,&&t'�D&u �~��&|�L&��1&�PV����V����_^�VW��v�~
        !          136070: 
        !          136071: t��2&�;F
        !          136072: t
        !          136073: ��3&�;F
        !          136074: ur�|$��D"$�F��^��F��F
        !          136075: �;~�s��G��P�D
        !          136076: P�[������D"DŽ6&�Dt�d���D
        !          136077: Ph�5�����>&t+DŽ>&��8&Ph������|"�}�\"�D"ދF
        !          136078: �G$�_^�VWU��v�|�� uu��t�<u��u�| u�d��Vh�M��\tV�t��\�����V�T���<(0��&t�d��Vh������F&tDŽF&��@&Ph�y����_^�VWU��v�D
        !          136079: P�c���V�\����Dt
�D
        !          136080: Ph�H����Dt
        !          136081: Vh�7�����>&tDŽ>&��8&Ph������F&tDŽF&��@&Ph�&����D"DŽ6&�d�<�_^�VWU��^��4&�t%S�d�����E��=t;u0u�W�v
        !          136082: ������_^�VWU��v�d��V�.���j&V�����_^�procq_ttsignal_waitq_pollopen_sendsig_super_getq_clrq_nondsig_sphi_tthup_Ou_iogetc_ttsetgrp_tttclose_�ttin_@ttout_jttioctl_ttread_&defer_cprocp_putq_ttflush_�
        !          136083: ttstash_V    ld_call_wakeup_spl_ttwrite_8ioputc_ttstart_
        !          136084: sleep_ttopen_ukcopy_kucopy_pollwake_ttpoll_�7b'~7�  7�7�'�7�0�0&7&  7)&'>&7E&0K&'m&7�&'�&7�&'�&7�&0�&7�&0�&7�&7
002'^0b7f'{07�    0�7�'�7�'�7�0�7�7�0�7�        0�7�03 < > @ B D F H J L N P R T V X Z \ ^7h!0n7� 7� 0�0�0�7�0
074'<0O'i0�7�'�7�0�7�77A7�0�0c0i0�0�0�0�0�00,000>0I0r0�0�0�0�0�7�7�0�0�0,720`7k7v0~7�'�7�'�"7�0�7      0    7F      0M    7�      '�    7�    '�    "7�    '3
        !          136085: 7G
        !          136086: 'g
        !          136087: 7j
        !          136088: '�
        !          136089: "7�
        !          136090: 7�
        !          136091: 7�
        !          136092: '�
        !          136093: 7�
        !          136094: '�
        !          136095: 7�
        !          136096: '�
        !          136097: "7�
        !          136098: '�
        !          136099: "7�
        !          136100: 0('.'67D0^0g0707070064030111331006440000000000000000011777770507310752700004300000055321/newbits/kernel/USRSYS/lib/ldlib.a]�__.SYMDEF�(�[�&�
        !          136101: abs_alloc_�bclaim_0&bdone_�&blkmv`boot_�bread_pbrelease_altclk_in_�altclk_out_�clrq_�cs_sel_{dblock_�dclose_sdefer_    devmsg_�     dmago_G
        !          136102: dmaunlock_�
        !          136103: dmalock_�
        !          136104: dmaoff_dmaon_�dmareq_?
dopen_�
drvmap_odwrite_fclear_�fdisk_7ffbyte_�ffword_=ffmem_�fkcopy_#fpxcopy_�free_Sfucopy_�getcs_�getq_�getubd_{getuwd_inb_�int11_iogetc_�iomapvp_Aioputc_�ioread_qioreq_ iowrite_�ipcaccess_9kcall_�kfcopy_Rkclear_�kpcopy_�kucopy_lock_�lldivJlrdivJllmul lrmul llrem� lrrem� llmod�!lrmod�!llsgn�!lrsgn�!memset_�#memtest_V$nmidisable_�$nmienable_�%nondsig_&nonedev_�&nulldev_9'outb_�'panic_(pclear_�(pkcopy_5)plrcopy_�)pollopen_e*pollwake_�*printf_�+prlcopy_-,ptov_�,pucopy_]-putchar_�-putq_�.putubd_%/putuwd_�/rucopy_U0s5_to_sg_�0s5_to_tc_�1salloc_2sclear_�2sendsig_M3clrivec_�3setivec_�3sfree_6sfbyte_�6sfword_7sfmem_�7sg_to_s5_8sleep_�8slrcopy_79sphi_�9spl_/:splo_�:super_�:swapio_�;tc_to_s5_%<timeout_�<ttclose_>tthup_�>ttflush_??ttin_�?ttioctl_o@ttopen_Attout_�Attpoll_7Bttread_�Bttsetgrp_gCttsignal_�Cttstart_�Dttwrite_/Euexit_�Eufcopy__Fukcopy_�Funlock_�Gupcopy_'Hurcopy_�Hvprint_WIvrelse_�Ivremap_�Jvtop_Kvldiv�Kvrdiv�Kvlmul�Lvrmul�Lvlrem�Mvrrem�Mwaitq_�Nwakeup_SOabsL.o�(�[�&|&
        !          136105: <
        !          136106: ��`�abs_xcalledKabs_'&'&allocL.o�(�[�&|&
        !          136107: <
        !          136108: ��`�xcalledalloc_Kalloc_'&'bclaimL.o�(�[�&|&
        !          136109: <
        !          136110: ��`�bclaim_Kbclaim_xcalled'&&'bdoneL.o�(�[�&|&
        !          136111: <
        !          136112: ��`�xcalledbdone_Kbdone_'&'blkmvL.o�(�[�&\&VWU��N�     �v
        !          136113: �~��F��]_^�blkmvbootL.o�(�[�&|&
        !          136114: <
        !          136115: ��`�boot_xcalledKboot_'&'&breadL.o�(�[�&|&
        !          136116: <
        !          136117: ��`�xcalledbread_Kbread_'&'breleaseL.o�(�[�&|&
        !          136118: <
        !          136119: ��`�xcalledbrelease_Kbrelease_'&'clockedfL.o�(�[�&'&��YVW��~dra�F+�.�6��uS�F+�RPjh�4������F�����F�j6jC������F�%�Pj@�����F���Pj@�����v������F���F����F��_^�VW��v�{����F��u�n��F��F
        !          136120: ��b���v��Y����F��_^�VW���F��~�t!jd�8����2��F���P�����F��_^�daltclk_in_yaltclk_out_�sphi_cs_sel_outb_altclk_altsel_vrdivspl_ 7'707:7I7X7a0�7�'�7�'�7�'�0�7�'�'�7�clrqL.o�(�[�&|&
        !          136121: <
        !          136122: ��`�clrq_Kclrq_xcalled'&&'cs_selfL.o�(�[�&D&���cs_sel_dblockL.o�(�[�&|&
        !          136123: <
        !          136124: ��`�dblock_Kdblock_xcalled'&&'dcloseL.o�(�[�&|&
        !          136125: <
        !          136126: ��`�dclose_xcalledKdclose_'&'&deferL.o�(�[�&�&<
        !          136127: U���v�v�P�����]�defer_kcall_Kldefer'7&devmsgL.o�(�[�&|&
        !          136128: <
        !          136129: ��`�xcalleddevmsg_Kdevmsg_'&'dmagoL.o�(�[�&|&
        !          136130: <
        !          136131: ��`�xcalleddmago_Kdmago_'&'dmalockL.o�(�[�&&&>�VWU��v����D�F
        !          136132: �D�vhVh������_^�VWU��vVh������_^�Kdmalock_dmaunlock_(Kldtimcall_kcall_Kdmaunlock_getcs_dmalock_7     ''7'275dmaoffL.o�(�[�&|&
        !          136133: <
        !          136134: ��`�dmaoff_Kdmaoff_xcalled'&&'dmaonL.o�(�[�&|&
        !          136135: <
        !          136136: ��`�xcalleddmaon_Kdmaon_'&'dmareqL.o�(�[�&|&
        !          136137: <
        !          136138: ��`�dmareq_xcalledKdmareq_'&'&dopenL.o�(�[�&|&
        !          136139: <
        !          136140: ��`�Kdopen_xcalleddopen_'&'&drvmapL.o�(�[�&|&
        !          136141: <
        !          136142: ��`�xcalleddrvmap_Kdrvmap_'&'dwriteL.o�(�[�&|&
        !          136143: <
        !          136144: ��`�xcalleddwrite_Kdwrite_'&'fclearL.o�(�[�&|&
        !          136145: <
        !          136146: ��`�fclear_Kfclear_xcalled'&&'fdiskL.o�(�[�&|&
        !          136147: <
        !          136148: ��`�xcalledfdisk_Kfdisk_'&'ffbyteL.o�(�[�&R&WU���~+�&�]_�ffbyte_ffwordL.o�(�[�&P&WU���~&�]_�ffword_ffmemL.o�(�[�&^&VWU���v�~�N��������]_^�ffmem_fkcopyL.o�(�[�&|&
        !          136149: <
        !          136150: ��`�xcalledfkcopy_Kfkcopy_'&'fpxcopyL.o�(�[�&|&
        !          136151: <
        !          136152: ��`�xcalledfpxcopy_Kfpxcopy_'&'freeL.o�(�[�&|&
        !          136153: <
        !          136154: ��`�free_Kfree_xcalled'&&'fucopyL.o�(�[�&|&
        !          136155: <
        !          136156: ��`�Kfucopy_xcalledfucopy_'&'&getcsL.o�(�[�&D&���getcs_getqL.o�(�[�&|&
        !          136157: <
        !          136158: ��`�getq_Kgetq_xcalled'&&'getubdL.o�(�[�&|&
        !          136159: <
        !          136160: ��`�getubd_xcalledKgetubd_'&'&getuwdL.o�(�[�&|&
        !          136161: <
        !          136162: ��`�xcalledgetuwd_Kgetuwd_'&'inbL.o�(�[�&J&
        !          136163: �܋W+���inb_int11L.o�(�[�&|&
        !          136164: <
        !          136165: ��`�int11_Kint11_xcalled'&&'iogetcL.o�(�[�&|&
        !          136166: <
        !          136167: ��`�iogetc_xcalledKiogetc_'&'&iomapvpL.o�(�[�&|&
        !          136168: <
        !          136169: ��`�iomapvp_xcalledKiomapvp_'&'&ioputcL.o�(�[�&|&
        !          136170: <
        !          136171: ��`�xcalledioputc_Kioputc_'&'ioreadL.o�(�[�&|&
        !          136172: <
        !          136173: ��`�ioread_xcalledKioread_'&'&ioreqL.o�(�[�&|&
        !          136174: <
        !          136175: ��`�Kioreq_xcalledioreq_'&'&iowriteL.o�(�[�&|&
        !          136176: <
        !          136177: ��`�xcallediowrite_Kiowrite_'&'ipcaccessL.o�(�[�&|&
        !          136178: <
        !          136179: ��`�ipcaccess_Kipcaccess_xcalled'&&'kcallL.o�(�[�&e&([XS�`[SS�xcalledkcall_'kfcopyL.o�(�[�&|&
        !          136180: <
        !          136181: ��`�xcalledkfcopy_Kkfcopy_'&'kclearL.o�(�[�&|&
        !          136182: <
        !          136183: ��`�kclear_Kkclear_xcalled'&&'kpcopyL.o�(�[�&|&
        !          136184: <
        !          136185: ��`�Kkpcopy_xcalledkpcopy_'&'&kucopyL.o�(�[�&|&
        !          136186: <
        !          136187: ��`�Kkucopy_xcalledkucopy_'&'&lockL.o�(�[�&|&
        !          136188: <
        !          136189: ��`�lock_Klock_xcalled'&&'lxdivL.o�(�[�&�&d��������lldivllsgnlrdivlrsgnvrdiv'&7'7
        !          136190: &lxmulL.o�(�[�&�&d��������llsgnlrsgnllmullrmulvrmul'&7&'7
        !          136191: lxremL.o�(�[�&�&d��������llmodllremlrmodlrremvrrem'&7'7
        !          136192: lxsgnL.o�(�[�&�&&p@&�&�+���&����VWU��S�؋�S+��y
        !          136193: �^�W���V�F�y���؃���r&FRP�V
        !          136194: �F�y���؃�FRP�V���
        !          136195: ��s���؃�[��]_^�ahigh     
        !          136196: bhigh      llmod   l0l1,l22lrmodl3Bl4Vllsgnl5ilrsgnalow   blow     bptr     fptr     ��memsetL.o�(�[�&�&PVWU��N�F
        !          136197: �~��F]_^�Count  memset_String Char     
        !          136198: memtestL.o�(�[�&|&
        !          136199: <
        !          136200: ��`�xcalledmemtest_Kmemtest_'&'nmidisableL.o�(�[�&|&
        !          136201: <
        !          136202: ��`�Knmidisable_xcallednmidisable_'&'&nmienableL.o�(�[�&|&
        !          136203: <
        !          136204: ��`�nmienable_Knmienable_xcalled'&&'nondsigL.o�(�[�&|&
        !          136205: <
        !          136206: ��`�nondsig_Knondsig_xcalled'&&'nonedevL.o�(�[�&g&(VWU����_^�nonedev_u_'&nulldevL.o�(�[�&J&
        !          136207: VWU���_^�nulldev_outbL.o�(�[�&J&
        !          136208: �܋W�G��outb_panicL.o�(�[�&|&
        !          136209: <
        !          136210: ��`�xcalledpanic_Kpanic_'&'pclearL.o�(�[�&|&
        !          136211: <
        !          136212: ��`�pclear_xcalledKpclear_'&'&pkcopyL.o�(�[�&|&
        !          136213: <
        !          136214: ��`�Kpkcopy_xcalledpkcopy_'&'&plrcopyL.o�(�[�&|&
        !          136215: <
        !          136216: ��`�xcalledplrcopy_Kplrcopy_'&'pollopenL.o�(�[�&|&
        !          136217: <
        !          136218: ��`�pollopen_Kpollopen_xcalled'&&'pollwakeL.o�(�[�&|&
        !          136219: <
        !          136220: ��`�Kpollwake_xcalledpollwake_'&'&printfL.o�(�[�&|&
        !          136221: <
        !          136222: ��`�xcalledprintf_Kprintf_'&'prlcopyL.o�(�[�&|&
        !          136223: <
        !          136224: ��`�xcalledprlcopy_Kprlcopy_'&'ptovL.o�(�[�&|&
        !          136225: <
        !          136226: ��`�xcalledptov_Kptov_'&'pucopyL.o�(�[�&|&
        !          136227: <
        !          136228: ��`�Kpucopy_xcalledpucopy_'&'&putcharL.o�(�[�&|&
        !          136229: <
        !          136230: ��`�putchar_xcalledKputchar_'&'&putqL.o�(�[�&|&
        !          136231: <
        !          136232: ��`�xcalledputq_Kputq_'&'putubdL.o�(�[�&|&
        !          136233: <
        !          136234: ��`�xcalledputubd_Kputubd_'&'putuwdL.o�(�[�&|&
        !          136235: <
        !          136236: ��`�putuwd_Kputuwd_xcalled'&&'rucopyL.o�(�[�&|&
        !          136237: <
        !          136238: ��`�rucopy_Krucopy_xcalled'&&'s5_to_sgL.o�(�[�&|&
        !          136239: <
        !          136240: ��`�s5_to_sg_Ks5_to_sg_xcalled'&&'s5_to_tcL.o�(�[�&|&
        !          136241: <
        !          136242: ��`�Ks5_to_tc_xcalleds5_to_tc_'&'&sallocL.o�(�[�&|&
        !          136243: <
        !          136244: ��`�xcalledsalloc_Ksalloc_'&'sclearL.o�(�[�&|&
        !          136245: <
        !          136246: ��`�sclear_xcalledKsclear_'&'&sendsigL.o�(�[�&|&
        !          136247: <
        !          136248: ��`�sendsig_Ksendsig_xcalled'&&'setivecL.o�(�[�&&��dVWU����f�~�烽u�~�烽t�'�J�~��F
        !          136249: ���~�����~�����vh�����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh�\�������Dž����Dž�_^�clrivec_|Kclrivec_setivec_ldrvipc_u_ldrvics_Ksetivec_ldrvint_kcall_ucs_'''"')'8'@ 'D'M'S7V']'i't'�'�    '�'�&7�'�'�sfreeL.o�(�[�&|&
        !          136250: <
        !          136251: ��`�xcalledsfree_Ksfree_'&'sfbyteL.o�(�[�&R&WU���~�F&�]_�sfbyte_sfwordL.o�(�[�&R&WU���~�F&�]_�sfword_sfmemL.o�(�[�&^&VWU���~�v�N��������]_^�sfmem_sg_to_s5L.o�(�[�&|&
        !          136252: <
        !          136253: ��`�sg_to_s5_Ksg_to_s5_xcalled'&&'sleepL.o�(�[�&|&
        !          136254: <
        !          136255: ��`�Ksleep_xcalledsleep_'&'&slrcopyL.o�(�[�&|&
        !          136256: <
        !          136257: ��`�xcalledslrcopy_Kslrcopy_'&'sphiL.o�(�[�&D&�X��sphi_splL.o�(�[�&J&
        !          136258: X[SSP�X�spl_sploL.o�(�[�&D&�X��splo_superL.o�(�[�&|&
        !          136259: <
        !          136260: ��`�super_Ksuper_xcalled'&&'swapioL.o�(�[�&|&
        !          136261: <
        !          136262: ��`�xcalledswapio_Kswapio_'&'tc_to_s5L.o�(�[�&|&
        !          136263: <
        !          136264: ��`�Ktc_to_s5_xcalledtc_to_s5_'&'&timeoutL.o�(�[�&6&&V�(VWU��v�~t�~
        !          136265: jjjVh�����
        !          136266: �+���������D�F�D�vh�v
        !          136267: Vh����
        !          136268: W�����_^�sphi_Kldtimcall_kcall_timeout_spl_Ktimeout_getcs_'77'7,';&'B7E7LttcloseL.o�(�[�&|&
        !          136269: <
        !          136270: ��`�xcalledttclose_Kttclose_'&'tthupL.o�(�[�&|&
        !          136271: <
        !          136272: ��`�tthup_xcalledKtthup_'&'&ttflushL.o�(�[�&|&
        !          136273: <
        !          136274: ��`�xcalledttflush_Kttflush_'&'ttinL.o�(�[�&|&
        !          136275: <
        !          136276: ��`�xcalledttin_Kttin_'&'ttioctlL.o�(�[�&|&
        !          136277: <
        !          136278: ��`�xcalledttioctl_Kttioctl_'&'ttopenL.o�(�[�&|&
        !          136279: <
        !          136280: ��`�Kttopen_xcalledttopen_'&'&ttoutL.o�(�[�&|&
        !          136281: <
        !          136282: ��`�xcalledttout_Kttout_'&'ttpollL.o�(�[�&|&
        !          136283: <
        !          136284: ��`�Kttpoll_xcalledttpoll_'&'&ttreadL.o�(�[�&|&
        !          136285: <
        !          136286: ��`�xcalledttread_Kttread_'&'ttsetgrpL.o�(�[�&|&
        !          136287: <
        !          136288: ��`�ttsetgrp_xcalledKttsetgrp_'&'&ttsignalL.o�(�[�&|&
        !          136289: <
        !          136290: ��`�ttsignal_Kttsignal_xcalled'&&'ttstartL.o�(�[�&|&
        !          136291: <
        !          136292: ��`�Kttstart_xcalledttstart_'&'&ttwriteL.o�(�[�&|&
        !          136293: <
        !          136294: ��`�xcalledttwrite_Kttwrite_'&'uexitL.o�(�[�&|&
        !          136295: <
        !          136296: ��`�uexit_Kuexit_xcalled'&&'ufcopyL.o�(�[�&|&
        !          136297: <
        !          136298: ��`�Kufcopy_xcalledufcopy_'&'&ukcopyL.o�(�[�&|&
        !          136299: <
        !          136300: ��`�Kukcopy_xcalledukcopy_'&'&unlockL.o�(�[�&|&
        !          136301: <
        !          136302: ��`�xcalledunlock_Kunlock_'&'upcopyL.o�(�[�&|&
        !          136303: <
        !          136304: ��`�Kupcopy_xcalledupcopy_'&'&urcopyL.o�(�[�&|&
        !          136305: <
        !          136306: ��`�urcopy_Kurcopy_xcalled'&&'vprintL.o�(�[�&|&
        !          136307: <
        !          136308: ��`�vprint_Kvprint_xcalled'&&'vrelseL.o�(�[�&|&
        !          136309: <
        !          136310: ��`�xcalledvrelse_Kvrelse_'&'vremapL.o�(�[�&|&
        !          136311: <
        !          136312: ��`�xcalledvremap_Kvremap_'&'vtopL.o�(�[�&|&
        !          136313: <
        !          136314: ��`�xcalledvtop_Kvtop_'&'vxdivL.o�(�[�&�&Fx�Ë܋_��Ë܍_VWU��P�V
        !          136315: �F+�+�� ��������;wrw;?r+?w@��[��]_^�ahigh  
        !          136316: bhigh      vldivvrdiv       alow       blow     vxmulL.o�(�[�&�&:x�Ë܋_��Ë܍_VWU��P�F�'����F�g��F
        !          136317: �'��֋�[��]_^�ahigh       
        !          136318: bhigh      vlmulalow blow     vrmul   vxremL.o�(�[�&�&Dx�Ë܋_��Ë܍_VWU��P�v
        !          136319: �~+�+�� ��������;Wrw;r+W��[��]_^�ahigh    
        !          136320: bhigh      vlremvrrem       alow       blow     waitqL.o�(�[�&|&
        !          136321: <
        !          136322: ��`�waitq_Kwaitq_xcalled'&&'wakeupL.o�(�[�&|&
        !          136323: <
        !          136324: ��`�xcalledwakeup_Kwakeup_'&'0707070064030111131006440000000000000000011777770507310753500004000000031053/newbits/kernel/USRSYS/lib/ss.a]�ss.o�(M��&o+&\jbqVW�
        !          136325: �F��F����F��z+ҹ����������jh RP���������������hZ�RP����h�<������RP����hZ��������-��RP�w���h�<�������-��RP�Y����6��6��K���=Z�uZ������RP�1���=�<u@�������-��RP����=Z�u �������-��RP�����=�<th�������F�&�v���?&�CC.;��t�.�g@�M&�&|&��������������������� ��a��������������������� @�2��������������������� @� &� *���!v�~�uj�F��~�}�>v�N�����&t    �F��F��F��F��݃~�uh�������F�&�,iF��P�6������ �uh���iF��P�6 �����~�u6� �F��F��~�}%�>v�N�����&t�~���F��F���� �F���h��6x�b����& ���F�@P�Q���� 5�~�u&�F��~�}�>v�N�����&tQ�����F����  N�_^�VWU��> t
        !          136326: �6 ���������6��6�������6x������_^�VW��v����%�F���%�F�����%�F��~��狅 �F�"�F�������u�&�N���#vu�F���v�V�z������ƀt
�~�t�F����ƀt�F��~�tX�~����uM��
�%���F��v�P�3����t,�~���U�~��EL�UN�EH�EJ�~�����������F�.�r��~�tE�~��EL�UN�F��V�^���ߋ~���~��E�U
        !          136327: GW;V�wr;F�v
�F�B�%�,��~�t�~���~��EEu
�F�c������~��E�_^�VW��F��%�F��~��狅 �F����~��M�_^�VWU��h@�j&�v�v
        !          136328: h��9���
        !          136329: �_^�VWU��h@�j�v�v
        !          136330: h�����
        !          136331: �_^�VW��v�F�����%�F�~��狅 �F�"�F�F
        !          136332: =&Ht=HtU��F�����F�"�F�~�����|�F�F��~�����~*�F��~�����*�F�j�v�F�P�����C�F�"�F�j�F�P�v�s����~����F|�~����F�*䈅~�~����F�*䈅�F��F��_^�VW��v�F��D�F�%�F��F���%�F��F���%�F��~��狅 �F��F��t�F��F�"�F��D�D�~����u>�~�u1�D
        !          136333: Du�|tt�F�w�L�~�t�v��v�����V���w�F��܀|&u�~���~��D
        !          136334: �T;Uu;Et‹^���^��|��    ��+�D
        !          136335: T;Wwr;Gv�F���D�&u�|u�F��|�V�v��0����v��Q
        !          136336: ���_^�VW���        �F��~��t!�v��拼 �}ruPh*��v�h������_^�VW��F�&�v�拼 �}ru�vh*��������@�u�����F��F�P�%���u���~�u��6��6�����%�F��F�*�P���=w�����.���PPPPPPP�P�P��6��6��?����F��t=u�j`�6��6��#����m�j�6��6�����h����6��6�������F��D��F��<��6��6�������+��v�������_^�VW��F��~�},�~��狅 �F��~�t�~��}t�v�h*�����F����_^�VW��F��F��~��}7�6��6��k����F��v����F�*���F��#�;�u�F�&��F��‹F��_^�VW�j�F�&�~�狅 �F��~���^���
��F��vh������~�t6�F�P�vhw�R���t�F��~�u�F�&�h��h��v�������~�u���F�P�vh3����u���F�&�F�*䙹�������F��V��F�*䙹�������F��V��F�*����ȊF�*����+�F�V�F�V��~���U�F�*䙹�������F��V��F�*䙹�������F��V��F�*����ȊF�*����+�F�V�F�V��~��E�URP�u�5h������
        !          136337: �h!�v�������~�u�&�F�P�vh��%���u���F�*���F�*���ljF��F�*�ȊF�*�����F�*�������Ǚ�F��V��F�*�F�R�v�h6�i����F�*�PhP�Z����v�hZ�N����~����|u+�~���F���|�~���F�*䈅~�~���F����J�~����|hb�����~����~*�Phz�����~����*�Ph�����        h��v������F��_^�VW��~�狅 �F��~��E �F��F�&�v�~�E+D�F��F��~��E�E���F��F�P��&���u��&�~�u�&�6��6��W��%�F��~�u�E�F��F�&�F�*�P�Z��=w�����.���(
���������e�z���6��6������F��F�*�%�CC.;��t�a�.�g��G��G�����F�*�~��Ej`�6��6������j�6��6����h����6��6��{���~��E����v��~��E+D�F��~�~F�|�D��E*�P�6��6��A���~�&t���~�}&t���~�u���v�������F����~�u�~�}&u��F�&h�F�EURP�6��6�����
        !          136338: �\��~�u��~�}u��F�&h�6��6��F�EURP���
        !          136339: �{��~�t       �v�����~�t+���&�_^�VW�   �{�F��~�&�F��F��F�� +�;V�wr:;F�v5�6��6��F���F��F�t�F�&��F�&�V����F�&u��~��v�����F��_^�VW��F��F��F��F��F��F��F��?�tRj�v����tCjjj�F�Pj�F�P����t)�F�*�]�CC.;��u.�gkkk�F�&�F��_^�VW��F��F��F��F��F��F�6�F���t-j�v�<���tjjj6�v
        !          136340: j�F�P����t�F�&�F��_^�VW��F��F��F��F�?�F��F�\�F��^�t-j�v�����tjjj\�v
        !          136341: j�F�P�3���t�F�&�F��_^�VW��F��F�%�F��F��F��F��F��F��F��F��F����t-j�v�p���tjjj�v
        !          136342: j
        !          136343: �F�P��
        !          136344: ���t�F�&�F��_^�VW��F�&�~���^���
��F��~�tFj �6��6��-���� *�P�6��6�����j0�6��6��        ���h���s����u�F��~�tA�&�N�� *��P�6��6�����h��6��6�����h&&�,����u�F��~�t#h��6��6����h�����u�F��~�t3h��6��6��p��j�6��6��`��h�������u�F��F��_^�VW��F����6��6��.���F��F�$tE�6��6�����F�� *���F�*�#�t$�F�*�#vt� *��� F��F��n�t�F����F��_^�VW��~�狅 �F��
        !          136345:  &�>
        !          136346:  u��&�~��E �F��Er*�-=v�&����.��ntj��6��6�������ǀt6�~���������j&�v�D���t�v�!���j&�v����낋~����t��������j���
        !          136347:  �^��6��6��������$tT�&�N�� *����6��6�����#�t1�~����������>& �u�F�& ��& ;F�?�t�]��e��~����t���������j�K��~�u
        !          136348: �~��Er����>& �uj�6��6��t������!uT�6��6��^������!u>�~����������v�����t�F�& j&�v����d�j
        !          136349: �v���������F�=��t�vh�&���~�����~����drj��j�Ƌ~����t���v��{��_^�VW�
        !          136350: �~�狅 �F��~��E �F��Er*�=v��&����.��h�z��UUU3�v�!����t�
        !          136351:  j�v�4���~��Er�&j&�v���&�v�M���u�&�~����&t�&��������&�v�#���F��~��E �~��E�F�%�F��F��t�F��F�"�F��~�t�v�����~��E
        !          136352: �UDT
        !          136353: �      �~��E
        !          136354: �U�~��E�U
        !          136355: �~��}&u       �~��E(��~��E*�~��E�E�U
        !          136356: ��������~��E�E�U
        !          136357: ��������~��E�E�U
        !          136358: ��������~��E�E�E�E�E�E&�E�E
        !          136359: �v����~�ƅ�ƅ�ƅ��Er�|�
        !          136360:  �t�& ;Ft�>& �uZ�F�& h��6��6������~��Er�:�& ;Fu�& ���v������u�t��~��j �6��6������~��Erj(�v�w&���_^�VW��F�j �6��6����� *�P�6��6��{��j0�6��6��k���F��~��}:�6��6��Q�����ǀt�F�&��F������=��t�j �6��6��%���F��_^�VW��F��&�N�� *��P�6��6�����h��6��6�����h&&�N���tPh��6��6�����h�0���t2�~
        !          136361: th��h��6��6����h��6��6�����F�&�F��_^�VW��F�h��6��6��d��h �����th��6��6��F���F�&�F��_^�VW��~�狅 �F��~������������������
        !          136362:  �vh�v
        !          136363: sP�����_^�VW��~�狅 �F��~����t�����������������v������_^�VW��~�狅 �F��~��E �F��E���Eƅ��_^�VW��~�狅 �F��~��E �F�����~����
        !          136364: su�F
        !          136365: =v�����.���&&���~�����~����s�Erj�v�������~��Er&�z�~��Er�q�~�����~����r��Er�Z�~��Er�Q�~�tB�~��M�E%�P�E��%�Ph�����~��u�u
        !          136366: �}&uh��h�h�����v����_^�VW��~�狅 �F��~��E �F��F�&�& ;Fu�& ���~����������~�t5�~��Eu�m�~��Eu�}u�~��E �v�����F��~�te�~��Erƅ�ƅ�ƅ��E&�U
        !          136367: �E�U
        !          136368: ��������~��E�E�U
        !          136369: ��������~��E�E�U
        !          136370: ��������~��E�E�E��
        !          136371:  �~��Er�v����_^�VW��F�F��F��~�|�F��~��烽 t*�~��狽 �}ru
�v��R���t�v�h*�B����F�;Fu��_^�VW��~�狅 �F��v�W���F��~�tQ�~��E=u�Erj2�v���@�~��}u�}u�v�U����)�~��E=uj��~��E=uj�j&�v�7����_^�VW��F��F��F��F��F�&�F����F�����F��F�P�����u�3&�~�u�*&�6��6��Y��%�F��F�*�P�m��=w�����.�����������>��*���6��6��
���F��t=u�j`�6��6������m�j�6��6�����h����6��6������F��D��F�;F
        !          136372: s3�~��F�~�*�P�6��6�����F�;F
        !          136373: t���v�������F��&��F�;Fs��~��F�~�6��6��c�������F�;Fs��6��6��~��F�~�*�P�F��v��4���~�u�~�t�~�u�F�&�F��_^�VW��
        !          136374: �F�h��6��6�����j2�(��j �6��6�����j2����v������_^�VW��F��F�;F}�F��~�0u}�F����F����_^�VW��F�&��F��F��~�|��6�F��~��t      �v
        !          136375: ����v�v
        !          136376: �V���un�v
        !          136377: �F���v�v
        !          136378: �V���uU�v
        !          136379: �����t!j2�d����v
        !          136380: ����v�v
        !          136381: �V���u'����v
        !          136382: ������v�v
        !          136383: �V���u�F��i��F��v������F��_^�VW�&�F�F��> t�f���Ft�N��Ft�N��F�*��_^�
#�����2��Error - host failed memory test
        !          136384: Error - ss has no valid target id's
        !          136385: Error - ss can't allocate structs
        !          136386: bad LUN or SCSI idbad special partitionbad partition tablepartition exceeds drive capacitypartition not foundinvalid requestno partition tablepartition overruninvalid byte countSCSI ID %d  LUN 0
        !          136387: Not Direct Access DeviceInquiry FailedCapacity=%ld blocks  Block length=%ld
        !          136388: Read Capacity FailedPhysical:  cylinders=%ld heads=%d spt=%d
        !          136389: Logical:  cylinders=%d heads=%d spt=%d
        !          136390: Mode Sense Failed(%d,%d): %s error bno=%ld
        !          136391: readwritefree_sscon_\clrivec_SS_INT_xkclear_setivec_sphi_u_drvl_nulldev_splo_bufq_wr_tail_ffbyte_bufq_init_bufq_rlse_defer_devmsg_timeout_ffcopy_bdone_ffword_ptov_alloc_sfbyte_spl_fdisk_vrelse_printf_bufq_rd_head_allkp_sfword_ukcopy_kucopy_drv_parm_|NSDRIVE_vbufq_rm_head_ss_mach_*ioreq_SS_BASE_z ` b d f h j'l  n p r't   $%$%(72%8%<%E%I7Q%Z%^7i%r%v7�%�%�7�%�%�7�%�%�7�%�%�7�%�%�7
&$&7&$&& ,&0;& G& I& K&%N&%R&%[&%_&%b&%f&%o&%s&%w&%}&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&%�&$�&$�&$7 '477%=$D%P7S%_$q%� �$�7�%�7�
%�$�0�%�%�%�7�7%   %
7$7%Q$q$x'|7�0�$�7�$0$I'M0Q$m'q0u'y%�'�%�7�%%�7�%%'%0.$A$Q$`7q 7�$�$�$�%$C7W7^$e$�$�0�7�0�0�%�  7%) 5780>0A0H7K0U0_0h%l%p7s0� � � � � � � � � � � � � � � � �%�%�7�%�%�7�0�%�%�7�%�%�7&0
        !          136392: 0%%70#7)%J b7e%�%�7�%�$�$�7� 
  0      $+      $0      76      0B     L      0O      0Y      $
        !          136393: 7
        !          136394: $
        !          136395: 7$
        !          136396: 00
        !          136397:  :
        !          136398: 0=
        !          136399: 0G
        !          136400: $�
        !          136401: 7�
        !          136402: $�
        !          136403: 7�
        !          136404: $�
        !          136405: 7�
        !          136406: $�
        !          136407: $�
        !          136408: $�
        !          136409: $�
        !          136410: $�
        !          136411: $�
        !          136412: 7�
        !          136413: $$7$$$7'$,72%K0�0�0�%�%�7�7�0� � � � � � � � � � � � � � � � �%�%&7 0! 7 9 ; = ? A C E%V%Z7]0c%i%m7p%|%�7�0�%�%�7�0�0�0�7�0�0�%
%
7 
0&
%A
%E
7T
0Z
7f
7�
        !          136414: %�
%�
%�
7�
7�
00$0> M e g i0�0�0�0�000g0s0�$�%�%�7�%�%�%�7�%�%�7�0�%%$%(7+%5%97<0E%^%b7e0n%�%�7�%�%�7�0�%�%�7�%�%�7�%�$%%7%>%D0J0c l n p r%v%z7}0�0�0�%�0�%�%�7�%%
%7%.%7%<0B0I0L0h0x%|%�%�7�%�%�7�0�0�%�0�0�0�0�0� �7�00(0.01%D0] f h j l n p r t v x0~%�0�0�0�0�7�0�0�7�#0�%�%�%�%�%�%�7%%0"0,%7%;7>0P%h%l7o%u%|%�7�%�%�7�%�%�7�0�%�%�7�%�%%7   %%70#%1%5780A%Z%^7a%k%o7r%�%�7�0�%�%�7�%�%� 7
        !          136415: % 0L%b%�0� � � � � � � �0�0�$A7D$Y$^$a7d0m%�%�%�7�%[0j%�%�7� �7�%�0�000J7}0�0�0�%�%�7�0� � � � � � � � � � � � � � � � �%�%�7�%%
        !          136416: 7
0%%7 %,%0730<%V%Z7]0k7q0w0%�%�7�0�%�%�0�7�7�
        !          136417: %�%70
%%70%7.7p0�0�0�0�0�0�0�0�0�07%4ssas.o�(O��&�&&z,&U��WV�v�ށ��~���&���uHu������^_]�U��WV�v�~�߁����&&���uHu������^_]�U��WV�v�~�N�^_]�ss_getb_ss_putb_0CSR_OFF        ffcopy_aG01G02REQ_LIM �&G03%G04(RS_REQUEST     P01FP02IP03VP04YBSIZE     bufq.o�(O��&�&~&�LVW��~~2kFP�6�������&�t�F�&kFP�6�&������F�~&��F��F��_^�VWU���~&�>�&t
        !          136418: �6�&�����_^�VW��F;~&}dkF�&�F��y��F��~��}u�F
        !          136419: �E�+��~
        !          136420: �E��'�~��}�F
        !          136421: ��~
        !          136422: ��~��E�~
        !          136423: �E�F
        !          136424: �~��E�~��E�v��&����_^�VW��F;~&}kF�&�F��~���+��_^�VW��F;~&}[kF�&�F�����F��~��}~1��F��E=&u  +��E���~��=��~���=�E�~��M��F��v�������F��F��_^�free_kclear_sphi_bufq_wr_tail_jbufq_init_bufq_rlse_Jalloc_spl_bufq_rd_head_�allkp_bufq_rm_head_&' 7%%.71&%:%Q%W%^7a%u%7�7�%�%�%&%&7#&7k&fdisk.o�(O��&�&&��(VW��v
        !          136425: �F�����F�j&j�v������>uej&jj�v������F��tF�^�����&U�u/�F��~�}j�F�����&P�ƃ�P�����F����F�&�v������v�v����v��m����F��_^�sphi_u_dclose_blkmvbread_brelease_spl_fdisk_dopen_77'#&727l77�7�0707070064030114661006440000030000030000011777770507310754000004000000010407/newbits/kernel/USRSYS/lib/dg.a]�dg.o�'���&�&�6:�&VWU��P�QP�6�������������������
        !          136426: �&P�PR�6��������P�6������&P�:���6������F��F��%&=&u���s&�P�6��y����6��o����F��F��%&=&u�
    �F&�*   P�P����P�6��B����dP�����6��.���%=t�>,t�:      �&�
        !          136427: P��ոP�6������Y        P������Z�P�6�6�������<P����RP������Z�P������RP������<P������RP�����6�6����=Z�uN����RP�s���=�<u4������RP�Y���=Z�u������RP�?���=�<t�m �!��    P�+����P�6������6&��   P�
�����]_^�VWU��>4t�4+�P����RP������P�6�������6�������6�6����]_^�VWU���F�t#�>.t�'�7�>6t+�.&�2�"�F@t�>0uփ>8t�0&���]_^�VWU���F�t&�.�>2uB�7&�t;�6�8&��   �#�F@t#�0�&�t�8�4&��    P����]_^�VWU��v
        !          136428: ]_^�VWU��P�v
        !          136429: �F�t7V������F��|_�>2}WP�2����RP�����2���F@t/V�����F��|!P�2� ��RP�{����2�ы�]_^�VWU��P�P�v�P�U���+�P���P+�P�P�A���]_^�VWU���,�&P��P�v�P����]_^�VWU��F�,]_^�VWU��+�P����RP������P�6��������P��������RP�����=GDt�>,t��        P����+���
        !          136430: P�0��Ÿ
        !          136431: P�����&]_^�VWU��P�P��@��RP�m�����P��B��RP�T���+�P��D��RP�<����P��F��RP�#���+�P��H��RP����� P��J��RP������
        !          136432: P�6�������P�6�������dP������@��RP�����t�>,t
�-
        !          136433: P������&�
        !          136434: P�)��ǸN
        !          136435: P�����&P��@��RP�s����P��B��RP�Z����P��D��RP�A���+�P�� 
��RP�)����
        !          136436: P�6������P�6��
�����&P������� 
��RP�����=OSt?�>,t/�q
        !          136437: P�������@��RP�����P��
        !          136438: P����+����
        !          136439: P�=�뤸�
        !          136440: P������"��RP�����:�&P����RP�o�����
��RP�Z����F����P�F����RP�9������P�F����RP�����F�%�P��
��RP������dP�����<&�><t �>,t
��
        !          136441: P��������
        !          136442: P�[����ٸ�
        !          136443: P�����&��]_^�VWU�����
��RP�����F���
��RP�}����F���
��RP�e����F���
��RP�M����F��>4u����
��RP�+�������
��RP����;�u����
��RP������F��F��~�}3��~�F�؋ʋF������RP�����E��F��NJF�*�P�F�*�P�F�*�P�F�*�P��
        !          136444: P����
        !          136445: �F�%�P��
��RP�v����3��><t1�<��
��RP�Q���P��
��RP�;�����]_^�P��&Error - board type is PC/Xi
        !          136446: Error - board type is PC/Xm
        !          136447: PC/Xe ID found
        !          136448: Error - PC/Xe failed to reset
        !          136449: PC/Xe passed reset
        !          136450: Error - PC/Xe failed memory test
        !          136451: PC/Xe passed memory test
        !          136452: PC/Xe waiting for BIOS load
        !          136453: PC/Xe waiting for FEPOS load
        !          136454: PC/Xe ready for use
        !          136455: Error - PC/Xe BIOS won't start
        !          136456: PC/Xe BIOS started
        !          136457: Error - PC/Xe FEPOS move failed
        !          136458: PC/Xe FEPOS relocated to host RAM
        !          136459: Error - PC/Xe FEPOS won't start
        !          136460: Failure code (%x)
        !          136461: PC/Xe FEPOS started
        !          136462: Error - PC/Xe no FEPOS interrupts
        !          136463: PC/Xe interrupts working
        !          136464: %x %x %x %x
        !          136465: clrivec_setivec_u_inb_outb_nulldev_iogetc_ffbyte_DG_IOB_�timeout_ffword_ptov_DG_RAM_�dgcon_�wakeup_sfbyte_vrelse_printf_sfword_DG_INT_�sleep_ � �'� � �'�'�'� � �'� $7&$$%%%)%679%?%C$K7N0X$_7b$w0z$�7�$�7�$�0�$�7�$�7�0�$�7�%�$�0�0�$�7�$&7&%&%&7&%"&%&&71&%;&%?&7J&%T&%X&7c&%j&%n&7q&
        !          136466: %|&%�&7�&
        !          136467: %�&%�&7�&
        !          136468: %�&%�&7�&
        !          136469: $�&$�&7�&$�&7�&%�&$�&7�&%%
        !          136470: %%7!$,7/$679%@%D7G%^'e%l%s%y%�%�%�'�%�%�0�%�%�$�%�0�%�%�$�7�7#%1%9%>%B7M%T7a%o%t%x7�%�%�'�%�7�      %�7�%� �%�7�   %�%%7$70)%/%37>
        !          136471: %J$P7T0b$g7k%�%�7�%�%�7�%�%�7�%�%�7�%�%�7�%�%&7$7$%7(02%8%<7G
        !          136472: %R$X7\0b0i$n7r%|%�7�%�%�7�%�%�7�%�%�7�$�7�$�7�0�%&%7
        !          136473: %$"7&%,%07;
        !          136474: $B7F0N0U$Z7^%d%h7s%y%�%�7�%�%�7�
        !          136475: %�%�7�%�%�7�%�%�70%%% $&7*0007$?7C%Z%^7i
        !          136476: %r%v7�
        !          136477: %�%�7�
        !          136478: %�%�7�
        !          136479: %�0�%�%�7�
        !          136480: %�%�7�
        !          136481: 0�%�%�7
        !          136482: %,%07?$e7i%y%}7�0�%�%�%�%�7�
        !          136483: %�%�7�0707070064030114701006440000030000030000011777770507310754100004000000035235/newbits/kernel/USRSYS/lib/gm.a]�mm.o�&�Q�&�&�&�&�VWU����v�D u3V������F��|%�F��F�&�F��F��F��F�P�P�����ƃ>u�V�iP�
        !          136484: P�P������]_^�VWU�������>}>���P�CP�v�����P�BP�h����
        !          136485: P�BP�Z����aP�P���
��>~�u�aP�4���%��P�aP�&����>t��P�����V�����v������v�iP�
        !          136486: P�P�����]_^�VWU��>�&~�>�&~     ��&u���]_^�VWU����v
        !          136487: �D�F��<uV�����u����Dur� t)���F��&+�PP�&P�P�s����v��j����ϋ>�E$E&t&�V��t�O��F�;Du��6V�<����t+��V�/����|u��� t��V�����u���]_^�&�ismmfunc_mmtim_mmbeeps_&mm_voff_mmcrtsav_�&mmgo_mmwatch_&nondsig_sphi_u_inb_outb_istty_kbunscroll_ttout_mmwrite_=&cprocp_timeout_mmstart_mmtime_ispl_mmvcnt_�&mmesc_&ttstart_sleep_70>%G%N R'Z&7^7o'u'|7�7�7�7�
        !          136488: '�'�7�
        !          136489: 7�'�'�7�'�7�7� &'&&7&$$&$+&$2&77&7U&0_&'l&7s&'z&'�&7�&7�&'�&7�&7�&
'�&        7�&7�&'�&'�&     7�&gr.o�&�Q�&�&d2nonedev_grread_nulldev_grwrite_grcon_''''
        !          136490: &''''''gmas.o�&�Q�&h&N ��8(+dp& VWU����^�w�O�?t��۽N�v�V�F�~�F#F&1��&&1���&1�0&1�0�+��f����.����ڀ~(u����F#F&1��&&1���&1�0&1�0�[�^�v�V�~������&��^���O+O&O]_^�6�c����Q��V���B.���JK}�Y��������$t������F���F���F�F�F��F&�FP*Ҋv�v
�^�^+��F��6���y6��s*���:v~U�vVQ�^�^
��.���.�������.���Q+���VWQ�Y_^�������F#F_W�@&�_����@&�Y^�&����.����ڀ~(u����I�����.���        ����I�����.��� �~(t�V*������������Ȏػ��3F#F�W&�&��N�3F#F�&�&��N�3F#F�&�&��N�3F#F�&�&��N�3F#F�&�&��N�3F#F�&�&��N�3F#F�&�&��N�F3F#F�&�&_^+���:V}
�I�����.���      *���:v���v���V*�������n�����ػ��3F�W&�&&�eO&�aP�ǟ�3F�&�&&�eO&�aP�ǟ�3F�&�&&�eO&�aP�ǟ�
        !          136491: f3F�&�&&�eO&�aP_^+���:V}
�I�����.���      *���:v���v�*��>���I�����.���       *Ҋ���.�����I�����.��� ��}�V����:v
}*Ҋv
�<������I��~�~����.���
        !          136492: �����I�<;t!�؀�0��     w9�f�F����FÈF������I��؀�0��    w�f�F����FÈF�ފ���.�������I��؀�0��   w�f�F����FÈF��<htL<ltX���a���I��؀�0�� w�f�F����FÈF��<hu��<lu���~����€�*��Z��~
u6�&�_��~
u6��O��V��}*�:Vr�V���$���QV+Ɋʀ���*�ыv�~Pu���A��F#ƫ&�A�&�EN&�AN&���&���&���&���&��>&&��>&&���&&���&&���&&���&F#�&��.&��.�+�^Y:V|*V��:v~�v�C���*���:v
s�v
����~u�F&���~u�F�{���:vv�v�Y���:Vr*V��:vv�v�V���=��v��*�v
:vr�v�V��*�:Vr�V������:v
}�v
��VQ�^����.���.����^��.���+�~1��VWQ�Y_^�������.���W�@&�F#F�_����@&�*�Y^��6�&���F<u�^�M&<&u�^
�r*Ҋv
����.����^*��<�F<u�^�!&<&u*��H*Ҋv
+��^��F��<u�&&<&t,��.���*�*�Q�F#F�@&�ǀ}�@&�����}�Y��RQW�F#F��.�������.���+�~��WQ�Y_����Y����.���+����׋���P������P������P������P������P������P������P�������}������P������P������P������P������P������P������P�����+�YZ�I�RQW�F#F��.�������.���+�~��WQ�Y_����_+ɊN*ʀ~(u��׋���P������P������P������P������P������P������P�������}������P������P������P������P������P������P������P�����+�YZ�y�6���VQ�^�^��.����΃�.���������.+��~3��VWQ��Y_^�������.���W�@&�F#F��_����@&�*�Y^���V��*�:Vr�V������F
        !          136493: �u���:Vr�V������v��*�:vv�v�V��*�:Vr�V������:v���v�W��V�v���V�v����:v
}�v
�����Nt
        !          136494: 
�F�����F���F<u�F���F�F�!<&u�F���<u�F���<u�F����I��~Pu�F(�����F�����~(u�FP���F��
        !          136495: ��F��}*�:Fw�^��}*�:^w:�w
        !          136496: �F
�^��*�����v��*�:vv�v����F
        !          136497: �u���:vr�v���&�&�&�&�&�&�&)&Aq7&��&)a        w       �&�&�&�&�&�&�&�&�&�&�&\�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&���&�&�&�&1&1&�&�&�&�&�&�7&�&�&�&�&�&�&�&��&�&�&�&�&�&�&�&�&�&�&�&�&r�&�&�&�&��&��&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&1&1&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&��&�&�/<A7&[Xq?&��&��&�&�&���&�&�&�&�&,�&�&�&�&�&���&�&�       �       �X�&�&�&�&�&% �&�&�&�&�       �&�&�& �&�&�&�&�&�&�&�&�&��
        !          136498: ����� #�%(�*-�/2�47�9<�>A�CF�HK�MP�RU�WZ�\_�ad�fi�kn�ps�ux�z}�VWU��n
        !          136499: �~t����~���؋F+ҹP������������&u�P+�;N~�N�-)N&NV�^����P+�;N~�N�)N&N���+���]_^�VWU��n
        !          136500: �~t��؋v�����F+ҹP�������������&u�P+�;N~�N�)N&NW�_����P+�;N~�N�)N&N���+��ĺ���ú���6��&�������P&mmbeeps_mm_voff_8mmcrtsav_fontw_mmgo_grread_J
grwrite_�
islock_mm_von_?uds_mmesc_mmvcnt_ N'(       $- a'�'�
        !          136501:  �0'&',&'3&
        !          136502:  Q& V& _&0�& �& �&0�& �&0�&'�& p0|0�0� 000 ' 2 ?0W0Z m0p0� �0�0�0�0 0'0*09'D0I'T0Y0o0�0&000 0-0:0V0�0� � � � �0�'�0�0�0 0)0I T0y � � �0�0J Z c0'0$ 4 > J f0�0�0�0�0�0�0�0�0            0      0      0#      0_      0u      0�      0�      0�      0�       �       �       �       �       �       �       �       �       �       �       �       �       �       �       �       
        !          136503:  
        !          136504:  
        !          136505:  
        !          136506:  
        !          136507:  
        !          136508: 
        !          136509:  
        !          136510:  
        !          136511:  
        !          136512:  
        !          136513:  
        !          136514:  
        !          136515:  
        !          136516:  
        !          136517:  
        !          136518:  
        !          136519:   
        !          136520:  "
        !          136521:  $
        !          136522:  &
        !          136523:  (
        !          136524:  *
        !          136525:  ,
        !          136526:  .
        !          136527:  0
        !          136528:  2
        !          136529:  4
        !          136530:  6
        !          136531:  8
        !          136532:  :
        !          136533:  <
        !          136534:  >
        !          136535:  @
        !          136536:  B
        !          136537:  D
        !          136538:  F
        !          136539:  H
        !          136540:  J
        !          136541:  L
        !          136542:  N
        !          136543:  P
        !          136544:  R
        !          136545:  T
        !          136546:  V
        !          136547:  X
        !          136548:  Z
        !          136549:  \
        !          136550:  ^
        !          136551:  `
        !          136552:  b
        !          136553:  d
        !          136554:  f
        !          136555:  h
        !          136556:  j
        !          136557:  l
        !          136558:  n
        !          136559:  p
        !          136560:  r
        !          136561:  t
        !          136562:  v
        !          136563:  x
        !          136564:  z
        !          136565:  |
        !          136566:  ~
        !          136567:  �
        !          136568:  �
        !          136569:  �
        !          136570:  �
        !          136571:  �
        !          136572:  �
        !          136573:  �
        !          136574:  �
        !          136575:  �
        !          136576:  �
        !          136577:  �
        !          136578:  �
        !          136579:  �
        !          136580:  �
        !          136581:  �
        !          136582:  �
        !          136583:  �
        !          136584:  �
        !          136585:  �
        !          136586:  �
        !          136587:  �
        !          136588:  �
        !          136589:  �
        !          136590:  �
        !          136591:  �
        !          136592:  �
        !          136593:  �
        !          136594:  �
        !          136595:  �
        !          136596:  �
        !          136597:  �
        !          136598:  �
        !          136599:  �
        !          136600:  �
        !          136601:  �
        !          136602:  �
        !          136603:  �
        !          136604:  �
        !          136605:  �
        !          136606:  �
        !          136607:  �
        !          136608:  �
        !          136609:  �
        !          136610:  �
        !          136611:  �
        !          136612:  �
        !          136613:  �
        !          136614:  �
        !          136615:  �
        !          136616:  �
        !          136617:  �
        !          136618:  �
        !          136619:  �
        !          136620:  �
        !          136621:  �
        !          136622:  �
        !          136623:  �
        !          136624:  �
        !          136625:  �
        !          136626:  �
        !          136627:  �
        !          136628:  �
        !          136629:  �
        !          136630:  �
        !          136631:       
        !          136632:              " $ & ( * , . 0 2 4 6 8 : < > @ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z | ~ � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �      
        !          136633:              " $ & ( * , . 0 2 4 6 8 : < > @ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z | ~ � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �'[
  '�
    'Hfontw.o�&�Q�&@&�0�3��3��0�?���������?��?�?�����?����?���?���30��30?�����?�������������?���?�����0000����������������3?��������<<<<��?�����?��?�<?�<<<?�<���3���?�?�3�������������<��?���<��������<�<�<�<�<�<�?����������<<?�0�<<������?��?��������������������<?�<��?������0<<��<<0��?�����?���<<<<<<<<?�<?�<<�?��?�<���<�<���<<�<�<���<<�<����?�����?<<����<<��?�����?���<��<�?��<�����<�<?��?�����?��<<<�<<?�?��<<�<�<?���<�������?�<?�<<<<��<�������?����<��?��<�<?��<�<?�?�����?���?�������<��?�?���<��?��<��?��<�<�<���?�?�������������<<<<?�<<<<���<<���<<���?�<<<<<<?�����<<0?�<0<����<<0?�<0<��<<����<<��<�<�<���<�<�<���������������?��<<�?�??�<��<�<<<<<���<�������<�<�<�<�<�<�����<�<?��<�<�<�<�<?���<<<<?�<<�?���������?����<<<<?�?�<��<?���<���?����0?�<<<<<<<<<<<<�<<<<<<<<<<���<�<�<�<�����<�<�<<��<��<�<������?�?��?�<���<<�??�<<<<<?��<��<?������?��<��<��<��<�<��<<�?<<<<<���<<<��<<�<<<<�?������?��<?�?�<�������?���������������������������?��<<<<�?�?��<��������������<�<?�?<<<<<�<?��<�<�<?���<<<<?�<�<�������<��?��<�<?���<����������<<<<<<<���<�<����<��<<��<��<�<<<<<�<?����<���<�?�����?0�0<���<<<?�fontw_kb.o�&�Q�&�&����oVWU��>�uO�P�aP������V)N}���P�aP�����+�Nu��`P��������P�aP�����MP�aP�����&�P�&P������P����]_^�VWU��&P�w���]_^�VWU���F�t��P���t�R��u��:�v��P�=����7�������u�����P����V�����W]_^�VWU���+���}
����LJF���F�^+���}9����F������㋿
�F��F��F���G���^���=��t   �~�r��F�‹�]_^�VWU��������u����P����V����]_^�VWU��+�P�v
        !          136634: ��P�f����>�t
        !          136635: ��P�U���]_^�VWU��F
        !          136636: ��&�CC.;��u.�gMN��    .�&�&� ����v�v
        !          136637: ��P����V�
        !          136638: ����V�v�v
        !          136639: �Q���H�*�1\�2���|���������#�)�1��2\�����|�����]_^�VWU��P�~�u�^��sc��P�F
        !          136640: �F
        !          136641: P����F��+���}
����LJG��^+���}1���㉷��F�F��F
        !          136642: �F
        !          136643: P�K����^���=��t��r��G�ʋ�]_^�VWU��f
        !          136644: ���F
        !          136645: &t#�>�u�~t
        !          136646: ��     P�����>�u�f
        !          136647: ���F
        !          136648: ]_^�VWU����F��>u��P��P������&�`P�����%��F��aP��������
�P�aP����V�aP�����>FtG�F�~��t��&�\�%&��Z����� t���Z�����t��V�`P�J�����&�>H~�H�&�~��u  �H�&�~��u�&�F�%H���F��u��Ru�Z�%=u������*���ǀu��F��t:��5u�&Z��W&��;�u�&Z��G&��u�&Z��:&��7t�2&�&Z��*&��;�u�Z�&��5u�Z&�
&��u�Z�&��7u�Z����9u�6Z�����Dt���6Z ���F��t���>�u���Z�����t,��u��
u��I�
        !          136649: �D��t��t���\*�%�,�Z�#�t�Z�����t��0u��\�
        !          136650: ��0u�*�����tT���t�Z�����t�΀V�#����v��5��&F��~�t#���F���P�`P�����F&�v�������]_^�VWU��P�F�+��F-=Dv�=&����.���8�������������������������������������������>>>>>>>>>>�a��������������U��Z�����t�^��1�㋷��^��;��J��    @uv�F��� t��       ��J�\�]��   ��J�\&�O�N�N+��Z����� t�&�Z�����t��&�Z�����@t������ȋF-G.�.���ً�,
�t�<t�<�t��F��%�P�p����F���]_^�VWU��v�ƻ&�CC.;��uE.�g
        !          136651: =>ctuJQX<C�Z �#�&Z���Z@��&Z����Z����]_^�VWU��v�
        !          136652: *���ƈ�
        !          136653: �
        !          136654: �
        !          136655: *�=&r�
        !          136656: ]_^�VWU��v�\����X&*�:�Y&u���Y&*�ȋ�ي�Z&*����Y&*�=�rƄY&���Y&�>t��.&���;�t��/&���;�u
        !          136657: WV������5��bu�>Lu��6LV������׃�cu�>Lt�P������>L�d�]_^�VWU��P���F���P�`P�����F&�v�������]_^�VWU���\���]_^�
        !          136658: �^&�&�&}�)1234567890-=      qwertyuiop[]
�asdfghjkl;'`�\zxcvbnm,./�*� ����������������-���+�����!@#$%^&*()_+�QWERTYUIOP{}
�ASDFGHJKL:"~�|ZXCVBNM<>?�*� ����������������-���+�����������ccccccccccccn
t
z
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�

        !          136659: !')-137;=AEGKOQ��������������������7?w8?x9?y4?t75?u6?v1?q2?r3?s[@0?p.?nismmfunc_clrivec_pollopen_super_initkeys_�updleds_Jisuload_}mmwatch_isclose_^&setivec_boot_sphi_u_putchar_isioctl_�&drvl_isread_�&inb_outb_nulldev_getubd_isload_isspecial_�ttsetgrp_istty_�ttclose_kbunscroll_yttin_isfunction_Uttioctl_ttread_islock_mmwrite_defer_mmstart_isturbo_�mmtime_mm_von_isopen_�spl_ispoll_�putubd_isrint_ttopen_iscon_�isbusy_ � �'� �'�  �'�'� � � �'�"$77)787H7V'] b7j   $p7t"7�&$
$
$
$
        !          136660: 
$
$
$
$
$
$
$
$
$
$
$ 
$"
$$
$&
$(
$*
'�$�7�'�$�7�7�$�$�0�$�$�7�+7�'0�%&%&%(&$0&%O&7d&$j&7o&$t&7x&7&'$�&7�&$�&$�&7�&$ �& �& �& �& �&7�&$�&7�&7�&'0$$$$$$$$)$0$5$:$?$D$I$N%c%g7w)%�%�%�7�%�$�$�7�$�'-$$ (7,!'3-7<7L7^7i%p%w0�%�%�%�7�0�%�%�0�%�0�0�%�7
        !          136661: $
        !          136662: 0%'0+$.%70;%D0H0P%T0X$[%d0h%q0u%~0�%�0�%�0�0�0�%�0�$�0�%�0�$�%�%$$$%70H0S7b7p%w7'$,
$.
$0
$2
$4
$6
$8
$:
$<
$>
$@
$B
$D
$F
$H
$J
$L
$N
$P
$R
$T
$V
$X
$Z
$\
$^
$`
$b
$d
$f
$h
$j
$l
0� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �      
        !          136663:              " $ & ( * , . 0 2 4 6$90<%?%T0W%b$f$q$x%|%�$�%�%�%�%�%� �$�0�  2 4 6 8 :%>%E%L%S'Z%`0d0g$v$�$�$�$�7�%'�-0�'�7%'%7"%07:
%A0D7Q7_%f7n'%�0�0707070064030114471006440000030000030000011777770507310754400004100000012750/newbits/kernel/USRSYS/lib/msg.a]�msgcon.o&'>6&�&$&&&��VWU��>u����>u�]_^�VWU��v�F
        !          136664: -M=v������.��>Fx���DP����P�DP����P�DP����P����PV������DP����P�DP�v���P�DP�k���P�d��̍DP�[���P�DP�P���P�DP�E���P�DP�:���P�3���뛍DP�'���P�D
        !          136665: P����P�DP����P�DP����P�DP�����P�DP�����P������P��]_^�putuwd_nonedev_u_nulldev_msginit_umsgget_umsgctl_umsgsnd_msqs_umsgrcv_msgcon_&&getuwd_ *&',&'.&&'0&&'2&& 4&'6&'8&':&'<&'7
''03 < > @ B D7K7V7a7h7p0v7}7�7�7�7�7�7�7�7�7�7�7�7�7&7&7& 0&'&msg.o&'>6&�&�&
        !          136666: ��VWU���
        !          136667: �>$
        !          136668: u� 
        !          136669: �>&
        !          136670: u� 
        !          136671: �> 
        !          136672: u+��&�> 
        !          136673: �v� 
        !          136674: ��P�
        !          136675: P�$
        !          136676: +�RP�����F��V��P�:P� 
        !          136677: +�RP����F�V��F��V��~�    |�~�@v
�(
        !          136678: P�r����$&�F�P�6�a����
        !          136679: �u���F�P+�P�6
        !          136680: �F���� 
        !          136681: .�.
        !          136682: 
        !          136683: �
        !          136684: �&
        !          136685: +�RP�$
        !          136686: RP�%����F��V��~�|)�~��v#�P
        !          136687: P�����6
        !          136688: ������ 
        !          136689: �
        !          136690: ���P�v��v��������
        !          136691: �>�
        !          136692: u�6$
        !          136693: �v
        !          136694: P�����뽋6
        !          136695: �F��F�; 
        !          136696: s!����D
        !          136697: �D*�D.�D,�D2�D6�D4�F���:�֋6
        !          136698: �$
        !          136699: .�.
        !          136700: 
        !          136701: ����
        !          136702: ��;
        !          136703: r/�&
        !          136704: +�)F�V��F��E�D��|���6 
        !          136705: ��
        !          136706: P�K���� 
        !          136707: ��]_^�VWU��P�~~�F�.�>
        !          136708: ; 
        !          136709: s�>
        !          136710: u������F�.�>
        !          136711: .�.
        !          136712: 
        !          136713: ���t��D�tփ~
        !          136714: t�D
        !          136715: ;FuȋF
        !          136716: =v�����.��2G�8V���������&u�
�&�*P�vV�����|,t*�΃�*�D,;�t�FP����
P�FP�v����|4t*�΃�2�D4;�t�FP�W���
P�FP�F����D
        !          136717: ;Fu�,&��$&�>t�;t�&�&�FP�����F��>t���>t;Dw��v�������F@@P������D�d��FP�����%�&    D�F��D��>t�;u��D���t��D�
        !          136718: �G����
        !          136719: �Gt�g��S�{����
        !          136720: �0t
�
        !          136721: *P�d����D�D�D�D
        !          136722: %�=�u�d
        !          136723: �D
        !          136724: �DtV�4����|0t
        !          136725: �D*P�$����|8t
        !          136726: �D2P�����D�>t���+���]_^�VWU��P+��>
        !          136727: u����>
        !          136728: u��&�F%�&�F�� 
        !          136729: .�.
        !          136730: 
        !          136731: ����:��;
        !          136732: vg�D�u�t�E&�U(;T(|�;D&v؋��ԋFF
        !          136733: t̋F�V
        !          136734: ;Tu�;Du��Ft�Ft������D#F�;F�u��
���Fu��׋Nj��u����D�D�D�D�"
        !          136735: �D�D�D�D�D �D"�D$���D&�T(���D��D�D�F�
��D�F�V
        !          136736: �D�T�D
        !          136737: ��]_^�VWU��~~�F�.�>
        !          136738: ; 
        !          136739: s�F;&
        !          136740: w�>
        !          136741: u�����e&�F�.�>
        !          136742: .�.
        !          136743: 
        !          136744: ���D
        !          136745: ;Fu��D�t�V�c��������u�
���
        !          136746: �t�D;Dwi�Ft�롋D;Dw�L+�PP�&PV��
        !          136747: �O+�PP�&PS������G$G&t����t��V��F;D
        !          136748: t��!�F��
        !          136749: ��F�E�P�EP�v
        !          136750: �����v��
        !          136751: �w�u�F
        !          136752: P����;Ft��>t�����
        !          136753: �G��|t�\�?��|�|�F&D�D��G�D���D�T �Dt�d��V�:����|0t
        !          136754: �D*P�*���+�]_^�VWU����~~�F�.�>
        !          136755: ; 
        !          136756: s�>
        !          136757: u�����B�F�.�>
        !          136758: .�.
        !          136759: 
        !          136760: ���D
        !          136761: ;Fu��D�t�V���������&u�
���|�F��~y~�F��F��F�V���؃��F�V�t?�E�U;V|;Fv�~��=��~�t�^��E�U;W|�;Gsމ~��F��F��Ӌ~��F��F��F�V���؃��F�V�)�~x#u�~t�t�E�U;Vu;Ft�~��=���uQ�Ft�����L+�PP�&PV�������G$G&t����t�����F;D
        !          136762: u����!���F;Es�Fu����F;Ev�E�F�P�v
        !          136763: �EP�|����v�F
        !          136764: P��
        !          136765: �w�u�b���;Ft��>t�S��~�t  ��^�����D;|u�F��D�E)D�L��G�D���D"�T$�Dt�d��V������|8t
        !          136766: �D2P������6
        !          136767: �D��|�Dt�d��V������
        !          136768: �0t
�
        !          136769: *P�����F��]_^�VWU��~~�F�.�>
        !          136770: ; 
        !          136771: s�>
        !          136772: u� ��F�.�>
        !          136773: .�.
        !          136774: 
        !          136775: ���D�t�D
        !          136776: ;Ft��m�f
        !          136777: ���F
        !          136778: &t"�|u�~t
        !          136779: �D*P�<����f
        !          136780: ����F�F
        !          136781: t5�D;Dr�~t"�D2��>
        !          136782: �}u�~t
�
        !          136783: *P������f
        !          136784: ���F
        !          136785: ]_^�:
        !          136786: &        
        !          136787: �invalid NMSQID or NMSG kernel variable
        !          136788: invalid NMSG or NMSC kernel variable
        !          136789: could not salloc %u messages
        !          136790: could not kalloc %u message ids
        !          136791: timer_free_pollopen_putuwd_ipcaccess_NMSC_&
        !          136792: nondsig_u_NMSG_$
        !          136793: msgs_
        !          136794: msginit_umsgget_msgpoll_V    salloc_umsgctl_�&umsgsnd_ANMSQB_"
        !          136795: msqs_
        !          136796: umsgrcv_�cprocp_memset_alloc_NMSQID_ 
        !          136797: wakeup_getuwd_printf_allkp_fucopy_ufcopy_vrmulsleep_ukcopy_kucopy_pollwake_$
        !          136798: $$$$$0,$0$8$E7L$`7g$�7�0�'�7�$�0�$�7�$� �$�$�$�$�7�$�7�$�7&&&$&$&0&7 &
%&&%*&$1&$4&78&$A&$M&$t&$w& |&$�&$�&$�&$�&$�&7�&$�& �&$�&$�&'�&0�& �& �&$&0' 0 2 4 67:'I0M7X 7w7�7�7�0�'�0�'�'�'�0�7�'�0�'77730E'I'O$e$s7�$�$�7�!7�7�!7�!'�0�$0$'!0%$1 6$:$E'�0�0�'�'�'�$�''
        !          136799: '' S$W$`$f'm0t } �$�7�'�$�'�$�7�'&7'0'$0($,7C%M7]'i'n0t$z'�'�'�7�7�! �$�$�'0  $73'B'   0
7'%70'80<0G'K0O'b0f7� %�7�'�'�0�'�'�'�7     7    !$    71      $8    $A      7H      ! h    $l      $r      0{       �       �      $�      7�      $�    $�      7
        !          136800: ipc.o&'?6&�&�&H(VWU��v�>u��&�/�;t;Du�D��;Dt;Du�D���D���%�&]_^�ipcaccess_u_'
        !          136801: &'&'&&ipcas.o&'?6&�&&&vPVWU���FHFr(;w"��ۋv�~
        !          136802: �N��������F]_^�+�]_^�VWU���FHFr�;w��~�v�N��������F]_^�udl_uds_fucopy_@ufcopy_''&'R'X&0707070064030114461006440000030000030000011777770507310754500004000000001300/newbits/kernel/USRSYS/lib/qq.a]�qq.o!(���&�&�
        !          136803: �|VWU���&�&�P�P�6&�6&������
        !          136804: &�&]_^�VWU���6&�6
        !          136805: &����]_^�VWU��]_^�VWU��]_^�VWU��P�v
        !          136806: �|t8�&�
        !          136807: &&RP�����F�VP�z���=��t�&�&�.�>��&�‹�]_^�VWU����v
        !          136808: �F�V�D����F��|"�~�}P�F��
        !          136809: &&RP�!����F��Ћ�]_^�IR[�2qqcon_�qqclose_Rnulldev_iogetc_qqread_[ffbyte_ptov_sfbyte_qqwrite_�vrelse_ioputc_qqopen_I � �'� � �'�'&'& & &'&%%
%%7"%(%,%9%=7@       %k%p%t7y7�
        !          136810: %�%� �%�7�%�%�7�0707070064030114451006440000030000030000011777770507310754500004000000004410/newbits/kernel/USRSYS/lib/rp.a]�rp.o'Z�&�&���&z&VWU����>�v���>�u��0�P��+ҹ������RP������\�>\u����f�>\�E�U�F��V���������;�vC�P�P�v��v������F��V���D��D�T�F��V��D�T
        !          136811: �� �F��V��+���]_^�VWU�쾜������;�v�DDt�t�t�%����� �ك>\t�6\�����\��P+�P��P�����]_^�VWU��P����F��>�u����}��v�������F%�;�r���]_^�VWU��F
        !          136812: �g&�CC.;��uD.�gHPQT�&y&y&�&�~����������v�r�����F%�����P�K����]_^�VWU����v
        !          136813: �F%��������1��F��}u     ��F��uJ�Dt���E
+�PP�&P�EP������M
��G$G&t�����t��v��������e�E&�v�������F�;Dv�D�F��v��tW�����F�&D)D�}t
        !          136814: �EP�����}t
        !          136815: �EP�����E�}
t
        !          136816: �EP�s�����]_^�VWU����v
        !          136817: �F%��������M��F��}u
�+�F�=sJ�Dt���E+�PP�&P�EP�����M��G$G&t��&��t��v��������n�E&�v�������F�;Dv�D�F��v�W�t������F�&D)D�E�}
t
        !          136818: �EP�����}t
        !          136819: �EP�����|t�?��}t
        !          136820: �EP������]_^�VWU��F%��������f
        !          136821: ���F
        !          136822: &t�D;Du�~t
        !          136823: �DP�D����f
        !          136824: ���F
        !          136825: t�D;Dt�~t
        !          136826: �DP� ����f
        !          136827: ���F
        !          136828: ]_^�VWU��v�����<t?�|t9�D
+�PP�&P�DP������L
��G$G&t�����t�W�������<�<t�D�T�D�T
        !          136829: �W�����|t
        !          136830: �DP�����|t
        !          136831: �DP����]_^�
        !          136832: &�&�N&��urcopy_rucopy_rpcon_�pollopen_putuwd_nonedev_NRP_�nondsig_sphi_u_nulldev_salloc_cprocp_ptov_memset_wakeup_spl_vrelse_sfree_sleep_rppoll_�pollwake_ �'�
        !          136833: '� � � �'�
        !          136834: '�
        !          136835: '�
        !          136836:  � �$
        !          136837: $$0$$74%:%>%J%Y$\%c7x
%�$�%�7�%�%�7�%�%&7&7&%&0#&'+&    72&$?&'E&     W& q& s& u& w&%�&7�&%�&0�&'�&       %�&7�&'�&    0�&7'
        !          136838: 77'&       737N&7g7w7�%�7�'�   0�7�'�7�7'     7767S7c0o7|%�7�7�7�7'!7,74';  7W7g7wrpas.o'Z�&�&b<
        !          136839: VWU���v�^
        !          136840: �N�W����#����F��&�]_^�VWU���^�~
        !          136841: �N�W��w��#����F��w)�]_^�rucopy_1urcopy_uds_''G0707070064030114441006440000030000030000011777770507310754600004100000007621/newbits/kernel/USRSYS/lib/sem.a]�semcon.o&'M6&�&a&���VWU��v�F
        !          136842: -S=v�����.��%a��DP�����P�DP�����P�DP����P�DP����P����PV�����_�DP����P�DP����P�DP����P�DP�w���P�p��DP�g���P�DP�\���P�DP�Q���P�J�����]_^�putuwd_nonedev_u_seminit_usemget_nulldev_usemctl_semcon_�getuwd_usemop_'�'�'�&'�&'�& �'�'�'�'�0   ! #7*757@7K7R7Z7f7q7|7�7�7�7�7�7�    '�sem.o&'M6&�&
&�,�&GVWU���.�&�P�6��������t ��.�.��������;�r�D���6���P������]_^�VWU����>t��F;�r�.�.�����D�u��&V�r�������&u�
��&�F
        !          136843: ;Dr���&�F
        !          136844: ���D���F=  v�&����.���"�&�&6&0&�B&<&�o&��&V���������t��~}�"�z&�F��t�}t�E�        �}t
        !          136845: �EP�����+��T&�E�N&�E�H&�E�B&�D�F��|�N�|ۋ߃��7�F�FP�����>t��&V���������u���D�F��|�N�|,�v�k����F��}�>u�"��F���F���π>u�f���P�vV�-����R��>t�;t�&��v������F@@P������D�FP�����%�&
��D�        ��>t�;u��D
        !          136846: �D���D������;Dr"�}t
        !          136847: �EP�����}t��EP�������t�����D��������]_^�VWU��P�F��>t����W&�F;�r����.�.��������;�r|�D�u �~�t�^��G�W;T|�;DvӉv��΋FF
        !          136848: tƋF�V
        !          136849: ;Tu�;Du��Ft�Ft��|��N���&�D#F;�t�
�c��D;Fr��d��Fu��F��~�u��8��v��F���P�6�����D�|tڋF�D�D�D���D�T�F���D������;Dr+��E�E�E�����D��D�D�F%�&
��D�F�V
        !          136850: �D�T��+��.�>���]_^�VWU����>t��&�F;�r���&�F;�r��&�F.�.�����D�t�V���������u�
�&�F
        !          136851: �F��F�F��~�u�&�v������F��F�@@P�w����F��F�P�g����F��>u�F�;DrO�n��F�;F
        !          136852: r1P�B����F��F�@@P�3����F��F����D���v�W�o&���À>t������F����D���v�W�����F��}\�n��F�;F
        !          136853: r-P������F�F�@@P������F�P�F���DP�&���ǀ>t��F�t��w�~�}_�E�]�F��N�����F
        !          136854: �F��F�F��~�t,�v��h����F����D�F��G�^�G�N��F��Ρ��D�T�F���EPV����|�}������]_^�VWU��P�v�~
        !          136855: ��F��}&���؋�;<wB)<�<u�|t
        !          136856: �DP������F��)�~��=�v�"�&<�|tߍD�Ӄ<tո����]_^�VWU��v�~
        !          136857: )<t�|t�D� �|t
        !          136858: �DP����]_^�VWU��P�v�~
        !          136859: �D
        !          136860: �F��+�PP�&PW�]����D
        !          136861: ;F�t
        !          136862: �!�����
��G$G&t�7��t���+���]_^�could not allocate %u semaphore ids
        !          136863: timer_free_putuwd_ipcaccess_nondsig_NSEM_�u_seminit_usemget_�usemctl_WNSEMID_�cprocp_alloc_wakeup_getuwd_printf_allkp_sleep_usemop_�kucopy_$ '7$$  %$)$4$A$D7H$O'a0g$n0s x$|0�7�'�0�'�0�0� � � � � � � � � � � �0�7�'&&0&7&&
0.&04&0:&0@&7`&'g&0m&7q&0&7�&'�&'�&'�&0�&0�&7�&0�&'�&'�&'�&0�&7�&7&70 '$'*7T
7d
7o&0z'~'�0�$�'�$� �$�$�'0'3070B0E'P0T'^0b'q7t'�'�'�'�$� �'    0$'0 $''-01 9$=7J'Y0]0r7x7�7�'�7�7�0�'�0�'�0�07(770L'U0['f0~7�'�'�'�0�0�7
'57z
7�'�'�7�'�ipc.o&'M6&�&�&H(VWU��v�>u��&�/�;t;Du�D��;Dt;Du�D���D���%�&]_^�ipcaccess_u_'
        !          136864: &'&'&&ipcas.o&'M6&�&&&vPVWU���FHFr(;w"��ۋv�~
        !          136865: �N��������F]_^�+�]_^�VWU���FHFr�;w��~�v�N��������F]_^�udl_uds_fucopy_@ufcopy_''&'R'X&0707070064030114431006440000030000030000011777770507310754700004100000005772/newbits/kernel/USRSYS/lib/shm.a]�shmcon.o&'P6&�&>&|BT&&VWU��>�ta��.�&x��W�6�������u�6���P��������/��.�.z���.�.z����&��;r�D��+�]_^�VWU����v
        !          136866: �D�F��D�F�;�r������F�.�.z���E�u�!��W�E�������&u�
�ȋE��F�V��F�+ҋ؋ʋD��;V�w�r;F�w��^�����G�F��F��F��t�t�v�P������u�o��D+���]_^�VWU����v
        !          136867: �D�F��D�F�;�r������F�.�.z���E�u�!��W���������tʋE��F�V��F�+ҋ؋ʋD��;V�w�r;F�w��^�����G�F��F��F��t�v�P�t�5����u�v��D+���]_^�VWU��F
        !          136868: =CHt=GHt8��x�FP�����P�FP�����P�F@@P�����P������=�FP�����P�FP����P�FP����P�F@@P����P����P�v����]_^�(&s.&�&couldn't kalloc %u shared memory ids
        !          136869: putuwd_ipcaccess_nonedev_u_shmsegs_nulldev_ushmget_ushmctl_NSHMID_�shmids_shmcon_|alloc_getuwd_printf_allkp_ufcopy_fucopy_'�'�'� � � �'�'� �'�$$
 '7'"  $*$-71
$8$? D'H        'K$N S'W 'b    $�'�0� �'�      '�7�&'�'�7&0&$G&'M&0T& \&'`&  'm&7t&&'�&7�&0�&'�&7777%747B7P7]7d7nshm.o&'P6&�&�&�&�VWU��P�F��>t������F;r���F.�.����D�t�F
        !          136870: =v�����.��Q��WV��������&u�
른&P�vV�����F��|�>t�;t�&�b�v�c�����F@@P�U����D�d��FP�@���%�& D밃>t�;u��D
        !          136871: �~��>�5�����D���F����F���]_^�VWU��P�F��>t����Z&�.�.�����&��;s��D�u �~�t�~��E"�U$;T$|�;D"vЉv��ˋFF
        !          136872: tËF�V
        !          136873: ;Tu�;Du��Ft�Ft�늋~���&�D#F;�t�
�q��D;Fr���^��Fu��O��~�u��A��v���+�.�>�����>�@P�F+�RP������tʋF�D�D�D�D�D ���D"�T$�>�E�D���D��D�D�F%�&
��D�F�V
        !          136874: �D�T�FF
        !          136875: u�L��+�.�>���]_^�&timer_ipcaccess_u_shmsegs_ushmget_&salloc_ushmctl_NSHMID_cprocp_shmids_getuwd_sfree_kucopy_'
0''# .'2       0F O Q S U7Y&'h7v'�'�'�7�
        !          136876: 7�
        !          136877: 7�
        !          136878: '�'�'�7�'�'&0&' & %&')&  '4&    09&'�&'�&0�&0�&'�&0�&'�&0�&'�&0�&'�&  �&'�&7�&'!'%'/'8'@'q       wipc.o&'P6&�&�&H(VWU��v�>u��&�/�;t;Du�D��;Dt;Du�D���D���%�&]_^�ipcaccess_u_'
        !          136879: &'&'&&ipcas.o&'P6&�&&&vPVWU���FHFr(;w"��ۋv�~
        !          136880: �N��������F]_^�+�]_^�VWU���FHFr�;w��~�v�N��������F]_^�udl_uds_fucopy_@ufcopy_''&'R'X&0707070064030114421006440000000000000000011777770507310754700004300000000746/newbits/kernel/USRSYS/lib/stubs.a]�msgstub.o&'\6&�&�&DxVWU�� ]_^�VWU���]_^�VWU���]_^�VWU���]_^�VWU���]_^�u_umsgget_msgpoll_umsgctl_6umsgsnd_(umsgrcv_''!'/'=semstub.o&'\6&�&J&
        !          136881: VWU��]_^�semexit_shmstub.o&'\6&�&J&
        !          136882: VWU��]_^�shmexit_0707070064030114411006440000000000000000011777770507310754700004700000000746/newbits/kernel/USRSYS/lib/stubs.a.310]�msgstub.o&'\6&�&�&DxVWU�� ]_^�VWU���]_^�VWU���]_^�VWU���]_^�VWU���]_^�u_umsgget_msgpoll_umsgctl_6umsgsnd_(umsgrcv_''!'/'=semstub.o&'\6&�&J&
        !          136883: VWU��]_^�semexit_shmstub.o&'\6&�&J&
        !          136884: VWU��]_^�shmexit_0707070064030116141006440000000000000000011777770507310755000004100000013642/newbits/kernel/USRSYS/lib/gkb.a]�gkb.o�(>��&�&�:���VWU��>�u?jja������V)N}�h�ja�����+�Nu�j`�������h�ja�����jMja�����&h�j&����h������_^�VWU��j&�����_^�VWU���F�t��N���t�h��u��8�vh��T����N�������u���h��2���V�+�����_^�VW�+���}
����LJ�F���F��+���}9����F�������㋿�
�F��F��F���G���^���=��t        �~��r��F���_^�VWU��������u����h�����V�����_^�VWU��j�v
        !          136885: h������>�t        h��u����_^�VWU��F
        !          136886: ��&�CC.;��u.�gMN���&
�&�&�@����v�v
        !          136887: h��2���V�+����V�v�v
        !          136888: �Q���H�8*��\����
|�
��k
�l
��#�8)�����\�
��
|�k
��l
�_^�VW��~�u�����sc��P�F
        !          136889: �F
        !          136890: P����F��+���}
����LJ�G���+���}1���㉷���F�F��F
        !          136891: �F
        !          136892: P�l����^���=��t���r��G���_^�VWU��f
        !          136893: ���F
        !          136894: &t"�>�u�~t       h
        !          136895: �+����>�u�f
        !          136896: ���F
        !          136897: �_^�VW��F��>uh�h�������&j`�����%��F�ja���������
�Pja�����Vja������>�t=���~��t�C���%&���� t����t��Vj`������>�~����F����CC.;��u.�g�������>�t����&����F�%H���F��u��Ru��%=u����B
*���ǀu��F��tK��5u     �&����&�8�;�u        �&����t&��u   �&����f&��7t�^&�>�t�������!��H&�8�;�u  ���7&��5u   ��&�)&��u   ���&��7u�>�t�&��   ��&��9u�6�������Dt���6� ���F��t���>�u����&t��:�X��t,��u��
u��C�
        !          136898: �>��t��t����*�%�&#>�t��t��0u����
        !          136899: ��0u􊄒*�����t[���t��t�΀V�U����v��>��&F��~�t.���F�h�j`������&�v��y������&����_^�VW��F�+��F-=Dv�c&����.���JPq���������������������������>�t�����t�������>�t������t�^��1�㋷���^��;����
        !          136900: @uo�F��� t�
        !          136901: 
        !          136902: ������V�
        !          136903: �����&�H�N�N+��� t�&��t��&��@t��>�t+�����N��Gk���ڋ��
�t�<t�<�t��F��%�P�s����F��_^�VWU��v�ƻ\�CC.;��uJ.�g
        !          136904: =>ctu���rz�� �'�&������@��&��������>����_^�VWU��v�2
        !          136905: *���ƈ�4
        !          136906: �2
        !          136907: �2
        !          136908: *�=&r�2
        !          136909: �_^�VWU��v�!����X&*�:�Y&u���Y&*�ȋ�ي�Z&*����Y&*�=�rƄY&���Y&�>t��.&���;�t��/&���;�u
        !          136910: WV������3��bu�>�u��6�V�����׃�cu�>�t�j�����>��f��_^�VW��t��F�h�j`�i�����&�v��Z����_^�VWU��������_^�
        !          136911: zB&k&�&i�)�������{[]}\���@����������~����������������������������������������������������������|��1234567890�'      qwertzuiop�+
�asdfghjkl��^�#yxcvbnm,.���� ����������������-���+�������<��!"$%&/()=?`�QWERTZUIOP�*
�ASDFGHJKL����'YXCVBNM;:���� ����������������-���+�������>��������cccccccccccc
        !          136912: "(.4:@FLRX^djpv|����������������������������������������������������7?w8?x9?y4?t75?u6?v1?q2?r3?s[@0?p.?n/_-*ismmfunc_Aclrivec_pollopen_super_initkeys_�updleds_�isuload_immwatch_isclose_B&setivec_boot_sphi_u_putchar_isioctl_�&drvl_isread_k&inb_outb_nulldev_getubd_isload_isspecial_�ttsetgrp_agmaptab_:istty_�ttclose_kbunscroll_�ttin_isfunction_4ttioctl_ttread_islock_mmwrite_defer_mmstart_isturbo_�mmtime_mm_von_isopen_zspl_ispoll_�putubd_isrint_�ttopen_iscon_�isbusy_ � �'� �'�! �'�'� � � �'�#$77"7/7<7F'M R7W   $]7`#7q&$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
'�$�7�'�$�7�7�$�$�0�$�$�7�,7�(0�%�%�%&$&%5&7H&$N&7S&$X&7[&7b&($v&7y&$�&$�&7�&% �& �& �& �& �&7�&$�&7�&7�&(0�&$�&$�&$�&$�&$�&$$$$$$$#$($-%B%F7V*%k%s%�7�%�$�$�7�$�'�.$� &7"'.77 7079%@%G0S%V%`%l7z0�%�%�0� � � � �%�%�%�%�%�7�
        !          136913: $�0�%0$%0"%+0008%<%K0N$Q%Z0_%h0m%v0{%�%�0�%�0�0�0�%�0�$�0�%�$�%�0$%%$%$1%E0Q0\7k7v%}7�(%�%�$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$�
$$0� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �      
        !          136914:              " $ & ( * , . 0 2 4 6 8 : < > @ B D F H$K0N%R$X0[%_$f0i$l0o%s0y$|0%�%�0�%�$�$�$�%�%�$�%�%�%�%�%�%�$03 L h j l n p%t%|%�%�'� %�0�0�$�$�$�$�$�7�&'�.0�'  7>%L'S %Y7]%k7s
%z0}7�7�%�7�(%�0�0707070064030110651006440000000000000000011777770507310755100004000000013142/newbits/kernel/USRSYS/lib/kb.a]�kb.o�(���&D&F���lVWU��>`u?jja������V)N}�h�ja�����+�Nu�j`�������h�ja�����jMja�����&h�j&����hb�����_^�VWU��j&�����_^�VWU���F�t��N���t�h��u��8�vhb�T����N���~�~�u���hb�2���V�+����0�_^�VW�+���}
����LJ�F���F�+���}9����F�������㋿��F��F��F���G���^���=��t  �~��r��F���_^�VWU�������~u����hb����V�����_^�VWU��j�v
        !          136915: hb�����>bt        hb�u����_^�VWU��F
        !          136916: ��&�CC.;��u.�gMN���&
�&�&�@����v�v
        !          136917: hb�2���V�+����V�v�v
        !          136918: �Q���H��*��\����?|�@�������#��)�����\�?��@|������_^�VW��~�u����sc��P�F
        !          136919: �F
        !          136920: P����F��+���}
����LJ�G��+���}1���㉷���F�F��F
        !          136921: �F
        !          136922: P�l����^���=��t���r��G���_^�VWU��f
        !          136923: ���F
        !          136924: &t"�>lu�~t       h�      �+����>lu�f
        !          136925: ���F
        !          136926: �_^�VW��F��>uhbh\������&j`�����%��F�ja���������
�Pja�����Vja������>tE��~��t��&��%&������� t��������t��Vj`�|�����&�>~��&�~��u        ��&�~��u�&�F�%H���F��u��Ru��%=u�*���j*���ǀu��F��t:��5u�&��T&���;�u�&��D&��u�&��7&��7t�/&�&��'&���;�u��&��5u�&�
        !          136927: &��u�����7u�����9u�6�����Dt���6 ���F��t���>~u�������t,��u��
u��I�
        !          136928: �D��t��t���*�%�,��#�t������t��0u���
        !          136929: ��0u��*�����tQ���t������t�΀V�����v��0��&F��~�t ����F�h�j`������&�v������_^�VW��F�+��F-=Dv�9&����.��w&��������������������������������������������*bbb�___�\\\\\��������t�^��1�㋷���^��;���� @ur�F��� t��       ����Y��   ���&�K�N�N+������� t�&������t��&������@t�����N��Gk���ڋ���t�<t�<�t��F��%�P�n����F��_^�VWU��v�ƻ��CC.;��uE.�g
        !          136930: =>ctu
�� �#�&���@��&���������_^�VWU��v��        *���ƈ��       ��     ��      *�=&r��      �_^�VWU��v�����X&*�:�Y&u���Y&*�ȋ�ي�Z&*����Y&*�=�rƄY&���Y&�>t��.&���;�t��/&���;�u
        !          136931: WV�8����3��bu�>u��6V�����׃�cu�>t�j�����>�f��_^�VW�����F�h�j`������&�v�������_^�VWU�������_^�
        !          136932: zB&k&�&i�)1234567890-=      qwertyuiop[]
�asdfghjkl;'`�\zxcvbnm,./�*� ����������������-���+�����!@#$%^&*()_+�QWERTYUIOP{}
�ASDFGHJKL:"~�|ZXCVBNM<>?�*� ����������������-���+�����������cccccccccccc(
.
4
:
@
F
L
R
X
^
d
j
p
v
|
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
&     ��������������������7?w8?x9?y4?t75?u6?v1?q2?r3?s[@0?p.?nismmfunc_�clrivec_pollopen_super_initkeys_�updleds_isuload_immwatch_isclose_B&setivec_boot_sphi_u_putchar_isioctl_�&drvl_isread_k&inb_outb_nulldev_getubd_isload_isspecial_Sttsetgrp_istty_bttclose_kbunscroll_5ttin_isfunction_4ttioctl_ttread_islock_mmwrite_defer_mmstart_isturbo_`mmtime_mm_von_isopen_zspl_ispoll_�putubd_isrint_�ttopen_iscon_Fisbusy_ J L'N P'R  T'V'X Z \ ^'x"$77"7/7<7F'M R7W    $]7`"7q&$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�'�$�7�'�$�7�7�$�$�0�$�$�7�+7�'0�%�%�%&$&%5&7H&$N&7S&$X&7[&7b&'$v&7y&$�&$�&7�&$ �& �& �& �& �&7�&$�&7�&7�&'0�&$�&$�&$�&$�&$�&$$$$$$$#$($-%B%F7V)%k%s%�7�%�$�$�7�$�'�-$� &7!'-77 7079%@%G0S%V%_%o7�0�%�%�0�%�0�0�%�7�
        !          136933: $�0�%�0�$�%0   %00%"0&$)%206%?0C%L0P%Y0]%f0j0m0u%y0�$�0�%�0�$�%�%�$�$�%00!707;%B7J'$�$�$�$�$�$�$�$�$�$�$�$�$�$
$
$
$
$
$
        !          136934: 
$
$
$
$
$
$
$
$
$
$
$ 
$"
$$
$&
0l u w y { }  � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �$0%%0 %+$/$:$A%E%I$O%S%W%e%t%�$�0� � � � � � �%&%%%'%#0'0*$9$C$G$J$U7e%'i-0z'�7�%�'�%�7�%�7�
%077%$7,'%<0@0707070064030110641006440000000000000000011777770507310755300004100000014656/newbits/kernel/USRSYS/lib/nkb.a]�nkb.o�(*��&�&�
        !          136935: �,<�VWU����
        !          136936: �~���&h&j&�����h�
        !          136937: �����h0@jh������t�>tu  hT�����v�_^�VWU��>�
        !          136938: t     h�����j&�����>tt�~�6t�v����_^�VWU���F�t��H��t�Q��u��2�vh�
        !          136939: �=����7�����u�h�
        !          136940: ����V�����_^�VWU�������u       h�
        !          136941: �����V������_^�VWU��j�v
        !          136942: h�
        !          136943: ������>�
        !          136944: t     h�
        !          136945: ������_^�VWU��F
        !          136946: -�=w/����.��T&\&\&r&j&�v�v
        !          136947: �
        !          136948: ���+�v�)� �v�&������v�v
        !          136949: h�
        !          136950: �u���V�n����_^�VW�jh����h�����t�G�W�F��V�+���&r�jh��v�'���j�v��v�h������F��V��F��*��;�t�>�tVh�������%����*��;�tF뚠�*�%��D�CC.;��u,.�g@��bVh(Vh�������Vh���Vh���h�������jh����h��&����
        !          136951: �F��g����6�
        !          136952: �^�������t�N��j`�6�
        !          136953: �E����F�2�N����
        !          136954: �F��6�
        !          136955: �+�������t�N���6�
        !          136956: �6�
        !          136957: ������
        !          136958: �F��6�
        !          136959: ��������t�N��W������~�_^�VW��>t�E�U�F��V�+���&s.jh��v��v�����j�vh������F��V��FF���_^�VW��F��~�u#�>�u��4&�6v�v
        !          136960: �6�
        !          136961: �c���� &���>�
        !          136962: t
        !          136963: �6�
        !          136964: �J����>�
        !          136965: t
        !          136966: �6�
        !          136967: �9���j&�F�P�v
        !          136968: �*����v&�F
        !          136969: @��+��F�*�;�v�v��FP����=�u�G���6v�6�������
        !          136970: �F�*���P�6�������
        !          136971: �>�
        !          136972: t�>�
        !          136973: u5�>�
        !          136974: t�6�
        !          136975: ������
        !          136976: �>�
        !          136977: t�6�
        !          136978: ������
        !          136979: ��T��
        !          136980: @���F
        !          136981: @�F
        !          136982: +��F�*�;�v,�����
        !          136983: �7��F�F��F
        !          136984: �F
        !          136985: P�_����^��*�=�u�G�ˊF�*��
        !          136986: ���&�_^�VWU��f
        !          136987: ���F
        !          136988: &t"�>u�~t       h.�����>u�f
        !          136989: ���F
        !          136990: �_^�VWU��>uh�
        !          136991: h�������&�6�
        !          136992: �����%����6�
        !          136993: ����������
        !          136994: P�6�
        !          136995: ����V�6�
        !          136996: �����ǻl�CC.;��t�.�g�������������&�uh��i����j�6x�6�
        !          136997: �Y����Zh����
        !          136998: =w0����.�������h����
        !          136999: h�
        !          137000: �%����
        !          137001: �6z��6�
        !          137002: h3�
�베��PW������_^�VW��>~u��&j�F�P�tkF����+�GWRP������F�*�;Ft�&�F�*�F��F�u���F�*�H=wl����.��n�tt�~
        !          137003: t��F�*���&����1r��k�~
        !          137004: ue�F�*���&����1r��"@uH� t
�&�P�&���3�'��~
        !          137005: t�F�*���&������!r��F�*���&����        r�|�rt        �|���r0t�|�rt�|�r�u���|&���~
        !          137006: t��>u���>|�E�*�=�u��F�t�ru�F�&t�rt�|��&������>|�E�*�F��F�tT�~�u�~
        !          137007: u
        !          137008: �>�
        !          137009: t�@��>�t@�>�
        !          137010: �*�;F�v3�~���>�
        !          137011: ����t"�*�=�t��F�*�P�`�����v��U���_^�VWU��v�ƻ&�CC.;��u1.�g
        !          137012: =>ctuUUO<G�r����&r������_^�VWU��v�N*���ƈ�P�N�N*�=&r�N�_^�VWU��v�p����X&*�:�Y&u���Y&*�ȋ�ي�Z&*����Y&*�=�rƄY&���Y&�>t��.&���;�t��/&���;�u
        !          137013: WV�����3��bu�>�u��6�V������׃�cu�>�t�j������>��f��_^�VWU��r��%Ph������_^�VWU��6�
        !          137014: ����N~�6�
        !          137015: ��������u���
        !          137016: �r��%�z�x�h��6�
        !          137017: �m���W�f����_^�VWU��&r�����_^�VWU���E����>�
        !          137018: th�j&h�h�
        !          137019: �.�������
        !          137020: &�6�
        !          137021: N~�6�
        !          137022: ��������u��uhG�����'�v�6�
        !          137023: ������>�
        !          137024: th�j&h�h�
        !          137025: �������W������_^�VWU��������>�
        !          137026: th�j&h�h�
        !          137027: ��������
        !          137028: �F
        !          137029: �z�F�x�6�
        !          137030: N~�6�
        !          137031: ��������u��uh\�p����'�v�6�
        !          137032: �a����>�
        !          137033: th�j&h�h�
        !          137034: �I�����W�@����_^�`ad�&'
        !          137035: ��&;&Z�kb: unable to allocate keyboard table segment
        !          137036: kb: keyboard busy during unload
        !          137037: kb: incorrect or unsorted table entry %d
        !          137038: kb: bad key mode
        !          137039: kb: keyboard BAT failed
        !          137040: kb: keyboard buffer overrun
        !          137041: kb: ACK while keyboard idle
        !          137042: kb: bad kbstate %d
        !          137043: kb: command timeout
        !          137044: kb: command timeout
        !          137045: ismmfunc_free_updleds2_O  isgettable_process_key_
        !          137046: KBFLAG_�
        !          137047: KBDATA_�
        !          137048: clrivec_pollopen_super_issettable_�&updleds_4    isuload_Zmmwatch_isclose_�setivec_boot_sphi_KBTIMEOUT_�
        !          137049: u_putchar_isioctl_;&drvl_isread_&inb_outb_nulldev_KBSTS_CMD_�
        !          137050: getubd_isload_ttsetgrp_istty_�
        !          137051: ttclose_salloc_kbunscroll_�    ttin_KBBOOT_�
        !          137052: isfunction_oKBCTRL_�
        !          137053: ttioctl_ttread_mmwrite_islock_defer_mmstart_mmtime_alloc_mm_von_fkcopy_kfcopy_wakeup_isopen_�spl_kb_cmd2_7
        !          137054: printf_ispoll_�allkp_sfree_KBCMDBYTE_�
        !          137055: sleep_isrint_&ttopen_kucopy_ukcopy_iscon_�
        !          137056: isbusy_kb_cmd_�         �
        !          137057:  �
        !          137058: '�
        !          137059:  �
        !          137060: '�
        !          137061: ) �
        !          137062: '�
        !          137063: '�
        !          137064: 
 �
        !          137065:  �
        !          137066:  �
        !          137067: ',$%
%' 7!$'7*,78!%>%B$H7K6%R$a$g7j67r%y%�%�7�9'�$�7�     '�$�7�7�$�$�$�$�7�=7�47�$�$&&7& 7&4$&7"&($)&$/&72&- R& T& V& X& Z&0c&0n&0v&7{&$�&7�&'7�&40�&0�&%�&0�&%�&7�&?%�&7�&1%�&%$
76'0%%, 4 N P R T0[$o7r60z0�0�$�7�$�7�$�7�$�$�7�$�$�7�$�$�7�74%%'%@7I0%T7W>%�'�0�%�$�7�>0�%�$�$�7�&$�$�7�&7�?%�%�7�%'87.$'!87$.$*$.$5$<$C7F&$M$S$Z7]&$d'j$p$�7�$�%�$�$�7�$�'A$ 7+'A$!7$$073$>$C7F$N7Q Y0h | ~ � � � � �%�$�7�6%�$�7�$�$� � � � � �$�$�$�7�2$�%�$�$�7�6%�0�%%0%"7700G0X l n p r0{%�0�%�0�$�$�$�0�$�%�%�%&%%0%% %&%.%40;%?0D0M$Q0W%]0j%t%�%�%�$�7�%�$�$�0�0  2 4 6 8 :%>0C%I'Q*$b$l$p$s$~7�/'�A0�'�*7�#%�'      *%
        !          137068:        7      #%    7$      %+    0.      %:      0F      $V      7Y      $b    7e      $t    %y      %�      %�      $�      7�      7�    4%�    0�      7�      $�    $�      7�      ;$�    $�      $�      7�      $�    7�      6$
        !          137069: 
        !          137070: 7
        !          137071: $
        !          137072: $"
        !          137073: 7%
        !          137074: ;7.
        !          137075: 47=
        !          137076: $C
        !          137077: $Q
        !          137078: 7T
        !          137079: ;$]
        !          137080: %e
        !          137081: %k
        !          137082: $o
        !          137083: $v
        !          137084: 7y
        !          137085: $�
        !          137086: 7�
        !          137087: 6$�
        !          137088: 7�
        !          137089: $�
        !          137090: $�
        !          137091: 7�
        !          137092: ;7�
        !          137093: 40707070064030127160407550000030000030000011777770507310755400003700000000000/newbits/kernel/USRSYS/confdrv0707070064030116111004440000030000030000011777770507310755400004300000001065/newbits/kernel/USRSYS/confdrv/al0:
        !          137094: : 'Serial Lines COM1 and COM3'
        !          137095: :
        !          137096: UNDEF="${UNDEF} -u a0con_ lib/al.a"
        !          137097: PATCH="${PATCH} drvl_+50=a0con_"
        !          137098: :
        !          137099: if [ -d "${DEV-/dev}" ]
        !          137100: then
        !          137101:        umask 0111
        !          137102:        /etc/mknod -f ${DEV-/dev}/com1l  c 5 128        || exit 1
        !          137103:        /etc/mknod -f ${DEV-/dev}/com1r  c 5 0          || exit 1
        !          137104:        /etc/mknod -f ${DEV-/dev}/com1pl c 5 192        || exit 1
        !          137105:        /etc/mknod -f ${DEV-/dev}/com1pr c 5 64         || exit 1
        !          137106: 
        !          137107:        /etc/mknod -f ${DEV-/dev}/com3l  c 5 129        || exit 1
        !          137108:        /etc/mknod -f ${DEV-/dev}/com3r  c 5 1          || exit 1
        !          137109:        /etc/mknod -f ${DEV-/dev}/com3pl c 5 193        || exit 1
        !          137110:        /etc/mknod -f ${DEV-/dev}/com3pr c 5 65         || exit 1
        !          137111: fi
        !          137112: 0707070064030116101004440000030000030000011777770507310755500004300000001065/newbits/kernel/USRSYS/confdrv/al1:
        !          137113: : 'Serial Lines COM2 and COM4'
        !          137114: :
        !          137115: UNDEF="${UNDEF} -u a1con_ lib/al.a"
        !          137116: PATCH="${PATCH} drvl_+60=a1con_"
        !          137117: :
        !          137118: if [ -d "${DEV-/dev}" ]
        !          137119: then
        !          137120:        umask 0111
        !          137121:        /etc/mknod -f ${DEV-/dev}/com2l  c 6 128        || exit 1
        !          137122:        /etc/mknod -f ${DEV-/dev}/com2r  c 6 0          || exit 1
        !          137123:        /etc/mknod -f ${DEV-/dev}/com2pl c 6 192        || exit 1
        !          137124:        /etc/mknod -f ${DEV-/dev}/com2pr c 6 64         || exit 1
        !          137125: 
        !          137126:        /etc/mknod -f ${DEV-/dev}/com4l  c 6 129        || exit 1
        !          137127:        /etc/mknod -f ${DEV-/dev}/com4r  c 6 1          || exit 1
        !          137128:        /etc/mknod -f ${DEV-/dev}/com4pl c 6 193        || exit 1
        !          137129:        /etc/mknod -f ${DEV-/dev}/com4pr c 6 65         || exit 1
        !          137130: fi
        !          137131: 0707070064030116071004440000030000030000011777770507310755500004200000003034/newbits/kernel/USRSYS/confdrv/at:
        !          137132: : AT Hard Disk
        !          137133: :
        !          137134: MAJOR=11
        !          137135: 
        !          137136: case "${ARG}" in
        !          137137: *1?)   HD_TYPE=at1 ;;
        !          137138: *)     HD_TYPE=at0 ;;
        !          137139: esac
        !          137140: :
        !          137141: :      needed by config
        !          137142: :
        !          137143: UNDEF="${UNDEF} -u atcon_ lib/at.a"
        !          137144: PATCH="${PATCH} drvl_+110=atcon_"
        !          137145: 
        !          137146: case ${ARG} in
        !          137147: at0a)  MAKEDEV="makedev(11,0)" ;;
        !          137148: at0b)  MAKEDEV="makedev(11,1)" ;;
        !          137149: at0c)  MAKEDEV="makedev(11,2)" ;;
        !          137150: at0d)  MAKEDEV="makedev(11,3)" ;;
        !          137151: at1a)  MAKEDEV="makedev(11,4)" ;;
        !          137152: at1b)  MAKEDEV="makedev(11,5)" ;;
        !          137153: at1c)  MAKEDEV="makedev(11,6)" ;;
        !          137154: at1d)  MAKEDEV="makedev(11,7)" ;;
        !          137155: at)
        !          137156:        ;;
        !          137157: *)
        !          137158:        /bin/echo "invalid argument: ${ARG}"
        !          137159:        exit 1
        !          137160:        ;;
        !          137161: esac
        !          137162: 
        !          137163: :
        !          137164: : needed for both build and config
        !          137165: :
        !          137166: DEV=${DEV-/dev}
        !          137167: if [ -d "$DEV" ]
        !          137168: then
        !          137169:        umask 077
        !          137170:        /etc/mknod -f $DEV/at0a  b 11 0         || exit 1
        !          137171:        /etc/mknod -f $DEV/at0b  b 11 1         || exit 1
        !          137172:        /etc/mknod -f $DEV/at0c  b 11 2         || exit 1
        !          137173:        /etc/mknod -f $DEV/at0d  b 11 3         || exit 1
        !          137174:        /etc/mknod -f $DEV/at0x  b 11 128       || exit 1
        !          137175:        /etc/mknod -f $DEV/rat0a c 11 0         || exit 1
        !          137176:        /etc/mknod -f $DEV/rat0b c 11 1         || exit 1
        !          137177:        /etc/mknod -f $DEV/rat0c c 11 2         || exit 1
        !          137178:        /etc/mknod -f $DEV/rat0d c 11 3         || exit 1
        !          137179:        /etc/mknod -f $DEV/rat0x c 11 128       || exit 1
        !          137180:        /etc/mknod -f $DEV/at1a  b 11 4         || exit 1
        !          137181:        /etc/mknod -f $DEV/at1b  b 11 5         || exit 1
        !          137182:        /etc/mknod -f $DEV/at1c  b 11 6         || exit 1
        !          137183:        /etc/mknod -f $DEV/at1d  b 11 7         || exit 1
        !          137184:        /etc/mknod -f $DEV/at1x  b 11 129       || exit 1
        !          137185:        /etc/mknod -f $DEV/rat1a c 11 4         || exit 1
        !          137186:        /etc/mknod -f $DEV/rat1b c 11 5         || exit 1
        !          137187:        /etc/mknod -f $DEV/rat1c c 11 6         || exit 1
        !          137188:        /etc/mknod -f $DEV/rat1d c 11 7         || exit 1
        !          137189:        /etc/mknod -f $DEV/rat1x c 11 129       || exit 1
        !          137190:        chown sys $DEV/at* $DEV/rat*
        !          137191:        chgrp sys $DEV/at* $DEV/rat*
        !          137192: fi
        !          137193: 0707070064030115721004440000030000030000011777770507310755500004300000000140/newbits/kernel/USRSYS/confdrv/ati:
        !          137194: : 'Array Technologies Inc - Graphics Solution - excludes Keyboard'
        !          137195: UNDEF="${UNDEF} lib/ati.a"
        !          137196: 0707070064030115151004440000030000030000011777770507310755500004200000001164/newbits/kernel/USRSYS/confdrv/fl:
        !          137197: : AT Floppy Driver
        !          137198: :
        !          137199: UNDEF="${UNDEF} -u flcon_ lib/fl.a"
        !          137200: PATCH="${PATCH} drvl_+40=flcon_"
        !          137201: :
        !          137202: if [ -d "${DEV-/dev}" ]
        !          137203: then
        !          137204:        umask 0133
        !          137205:        /etc/mknod -f ${DEV-/dev}/f9a0 b 4 12   || exit 1
        !          137206:        /etc/mknod -f ${DEV-/dev}/f9a1 b 4 28   || exit 1
        !          137207:        /etc/mknod -f ${DEV-/dev}/f9d0 b 4  4   || exit 1
        !          137208:        /etc/mknod -f ${DEV-/dev}/f9d1 b 4 20   || exit 1
        !          137209:        /etc/mknod -f ${DEV-/dev}/fha0 b 4 14   || exit 1
        !          137210:        /etc/mknod -f ${DEV-/dev}/fha1 b 4 30   || exit 1
        !          137211:        /etc/mknod -f ${DEV-/dev}/fqa0 b 4 13   || exit 1
        !          137212:        /etc/mknod -f ${DEV-/dev}/fqa1 b 4 29   || exit 1
        !          137213:        /etc/mknod -f ${DEV-/dev}/fva0 b 4 15   || exit 1
        !          137214:        /etc/mknod -f ${DEV-/dev}/fva1 b 4 31   || exit 1
        !          137215: fi
        !          137216: 0707070064030115141004440000030000030000011777770507310755500004200000000423/newbits/kernel/USRSYS/confdrv/gm:
        !          137217: : Tecmar Graphics Master
        !          137218: :
        !          137219: UNDEF="${UNDEF} -u iscon_ -u grcon_ lib/gm.a"
        !          137220: PATCH="${PATCH} drvl_+20=iscon_ drvl_+300=grcon_"
        !          137221: :
        !          137222: if [ -d "${DEV-/dev}" ]
        !          137223: then
        !          137224:        umask 0111
        !          137225:        /etc/mknod -f ${DEV-/dev}/console c  2 0 || exit 1
        !          137226:        /etc/mknod -f ${DEV-/dev}/gr      c 30 0 || exit 1
        !          137227: fi
        !          137228: 0707070064030115131004440000030000030000011777770507310755600004200000000344/newbits/kernel/USRSYS/confdrv/gr:
        !          137229: : Graphics Display on PC Color Card - excludes keyboard
        !          137230: :
        !          137231: UNDEF="${UNDEF} -u grcon_ lib/gr.a"
        !          137232: PATCH="${PATCH} drvl_+300=grcon_"
        !          137233: :
        !          137234: if [ -d "${DEV-/dev}" ]
        !          137235: then
        !          137236:        umask 0111
        !          137237:        /etc/mknod -f ${DEV-/dev}/gr      c 30 0 || exit 1
        !          137238: fi
        !          137239: 0707070064030115121004440000030000030000011777770507310755600004200000001744/newbits/kernel/USRSYS/confdrv/hs:
        !          137240: : 'Hostess/Arnet multi-port Serial Support (Version 7 Compatible)'
        !          137241: :
        !          137242: UNDEF="${UNDEF} -u hscon_ lib/hs.a"
        !          137243: PATCH="${PATCH} drvl_+70=hscon_"
        !          137244: :
        !          137245: : non modem control devices
        !          137246: :
        !          137247: umask 0111
        !          137248: /etc/mknod -f ${DEV-/dev}/hs00 c 7  0 || exit 1
        !          137249: /etc/mknod -f ${DEV-/dev}/hs01 c 7  1 || exit 1
        !          137250: /etc/mknod -f ${DEV-/dev}/hs02 c 7  2 || exit 1
        !          137251: /etc/mknod -f ${DEV-/dev}/hs03 c 7  3 || exit 1
        !          137252: /etc/mknod -f ${DEV-/dev}/hs04 c 7  4 || exit 1
        !          137253: /etc/mknod -f ${DEV-/dev}/hs05 c 7  5 || exit 1
        !          137254: /etc/mknod -f ${DEV-/dev}/hs06 c 7  6 || exit 1
        !          137255: /etc/mknod -f ${DEV-/dev}/hs07 c 7  7 || exit 1
        !          137256: :
        !          137257: : modem control versions
        !          137258: :
        !          137259: /etc/mknod -f ${DEV-/dev}/hs00r c 7 128 || exit 1
        !          137260: /etc/mknod -f ${DEV-/dev}/hs01r c 7 129 || exit 1
        !          137261: /etc/mknod -f ${DEV-/dev}/hs02r c 7 130 || exit 1
        !          137262: /etc/mknod -f ${DEV-/dev}/hs03r c 7 131 || exit 1
        !          137263: /etc/mknod -f ${DEV-/dev}/hs04r c 7 132 || exit 1
        !          137264: /etc/mknod -f ${DEV-/dev}/hs05r c 7 133 || exit 1
        !          137265: /etc/mknod -f ${DEV-/dev}/hs06r c 7 134 || exit 1
        !          137266: /etc/mknod -f ${DEV-/dev}/hs07r c 7 135 || exit 1
        !          137267: 0707070064030115111004440000030000030000011777770507310755600004200000000560/newbits/kernel/USRSYS/confdrv/lp:
        !          137268: : Parallel Line Printers LPT1, LPT2 and LPT3
        !          137269: :
        !          137270: UNDEF="${UNDEF} -u lpcon_ lib/lp.a"
        !          137271: PATCH="${PATCH} drvl_+30=lpcon_"
        !          137272: :
        !          137273: if [ -d "${DEV-/dev}" ]
        !          137274: then
        !          137275:        umask 0555
        !          137276:        /etc/mknod -f ${DEV-/dev}/lpt1 c 3 0            || exit 1
        !          137277:        /etc/mknod -f ${DEV-/dev}/lpt2 c 3 1            || exit 1
        !          137278:        /etc/mknod -f ${DEV-/dev}/lpt3 c 3 2            || exit 1
        !          137279:        : /bin/ln  -f ${DEV-/dev}/lpt1 ${DEV-/dev}/lp   || exit 1
        !          137280: fi
        !          137281: 0707070064030115101004440000030000030000011777770507310755600004200000000117/newbits/kernel/USRSYS/confdrv/mm:
        !          137282: : 'Memory Mapped (Text) Video - excludes Keyboard'
        !          137283: UNDEF="${UNDEF} lib/mm.a"
        !          137284: 0707070064030115071004440000030000030000011777770507310755600004200000000302/newbits/kernel/USRSYS/confdrv/ms:
        !          137285: : 'Microsoft Bus Mouse'
        !          137286: :
        !          137287: UNDEF="${UNDEF} -u mscon_ lib/ms.a"
        !          137288: PATCH="${PATCH} drvl_+100=mscon_"
        !          137289: :
        !          137290: if [ -d "${DEV-/dev}" ]
        !          137291: then
        !          137292:        umask 0333
        !          137293:        /etc/mknod -f ${DEV-/dev}/mouse c 10 0 || exit 1
        !          137294: fi
        !          137295: 0707070064030115061004440000030000030000011777770507310755600004300000000313/newbits/kernel/USRSYS/confdrv/msg:
        !          137296: : System V Compatible Messaging
        !          137297: :
        !          137298: UNDEF="${UNDEF} -u msgcon_ lib/msg.a"
        !          137299: PATCH="${PATCH} drvl_+250=msgcon_"
        !          137300: :
        !          137301: if [ -d "${DEV-/dev}" ]
        !          137302: then
        !          137303:        umask 0333
        !          137304:        /etc/mknod -f ${DEV-/dev}/msg c 25 0 || exit 1
        !          137305: fi
        !          137306: 0707070064030115041004440000030000030000011777770507310755600004200000001112/newbits/kernel/USRSYS/confdrv/rm:
        !          137307: : Dual RAM Disk
        !          137308: : Default each to 512K for now...
        !          137309: :
        !          137310: UNDEF="${UNDEF} -u rmcon_ lib/rm.a"
        !          137311: PATCH="${PATCH} drvl_+80=rmcon_"
        !          137312: :
        !          137313: if [ -d "${DEV-/dev}" ]
        !          137314: then
        !          137315:        umask 0111
        !          137316:        /etc/mknod -f ${DEV-/dev}/ram0 b 8 8 || exit 1
        !          137317:        /etc/mknod -f ${DEV-/dev}/rram0 c 8 8 || exit 1
        !          137318:        /etc/mknod -f ${DEV-/dev}/ram0close b 8 0 || exit 1
        !          137319:        /etc/mknod -f ${DEV-/dev}/rram0close c 8 0 || exit 1
        !          137320: 
        !          137321:        /etc/mknod -f ${DEV-/dev}/ram1 b 8 136 || exit 1
        !          137322:        /etc/mknod -f ${DEV-/dev}/rram1 c 8 136 || exit 1
        !          137323:        /etc/mknod -f ${DEV-/dev}/ram1close b 8 128 || exit 1
        !          137324:        /etc/mknod -f ${DEV-/dev}/rram1close c 8 128 || exit 1
        !          137325: fi
        !          137326: 0707070064030115031004440000030000030000011777770507310755700004200000000513/newbits/kernel/USRSYS/confdrv/rp:
        !          137327: : Ram Pipes
        !          137328: :
        !          137329: UNDEF="${UNDEF} -u rpcon_ lib/rp.a"
        !          137330: PATCH="${PATCH} NRP_=4 drvl_+220=rpcon_"
        !          137331: :
        !          137332: if [ -d "${DEV-/dev}" ]
        !          137333: then
        !          137334:        umask 0111
        !          137335:        /etc/mknod -f ${DEV-/dev}/rp0 c 22 0 || exit 1
        !          137336:        /etc/mknod -f ${DEV-/dev}/rp1 c 22 1 || exit 1
        !          137337:        /etc/mknod -f ${DEV-/dev}/rp2 c 22 2 || exit 1
        !          137338:        /etc/mknod -f ${DEV-/dev}/rp3 c 22 3 || exit 1
        !          137339: fi
        !          137340: 0707070064030115021004440000030000030000011777770507310755700004300000000421/newbits/kernel/USRSYS/confdrv/rs0:
        !          137341: : 'Raw (fast) Serial Line COM1 (System V Compatible)'
        !          137342: :
        !          137343: UNDEF="${UNDEF} -u rs0con_ lib/rs.a"
        !          137344: PATCH="${PATCH} drvl_+50=rs0con_"
        !          137345: :
        !          137346: if [ -d "${DEV-/dev}" ]
        !          137347: then
        !          137348:        umask 0111
        !          137349:        /etc/mknod -f ${DEV-/dev}/rs0  c 5 0    || exit 1
        !          137350:        /etc/mknod -f ${DEV-/dev}/rs0r c 5 128  || exit 1
        !          137351: fi
        !          137352: 0707070064030115011004440000030000030000011777770507310755700004300000000421/newbits/kernel/USRSYS/confdrv/rs1:
        !          137353: : 'Raw (fast) Serial Line COM2 (System V Compatible)'
        !          137354: :
        !          137355: UNDEF="${UNDEF} -u rs1con_ lib/rs.a"
        !          137356: PATCH="${PATCH} drvl_+60=rs1con_"
        !          137357: :
        !          137358: if [ -d "${DEV-/dev}" ]
        !          137359: then
        !          137360:        umask 0111
        !          137361:        /etc/mknod -f ${DEV-/dev}/rs1  c 6 0    || exit 1
        !          137362:        /etc/mknod -f ${DEV-/dev}/rs1r c 6 128  || exit 1
        !          137363: fi
        !          137364: 0707070064030114771004440000030000030000011777770507310755700004300000000314/newbits/kernel/USRSYS/confdrv/sem:
        !          137365: : System V Compatible Semaphores
        !          137366: :
        !          137367: UNDEF="${UNDEF} -u semcon_ lib/sem.a"
        !          137368: PATCH="${PATCH} drvl_+230=semcon_"
        !          137369: :
        !          137370: if [ -d "${DEV-/dev}" ]
        !          137371: then
        !          137372:        umask 0333
        !          137373:        /etc/mknod -f ${DEV-/dev}/sem c 23 0 || exit 1
        !          137374: fi
        !          137375: 0707070064030114761004440000030000030000011777770507310755700004300000000313/newbits/kernel/USRSYS/confdrv/shm:
        !          137376: : System V Subset Shared Memory
        !          137377: :
        !          137378: UNDEF="${UNDEF} -u shmcon_ lib/shm.a"
        !          137379: PATCH="${PATCH} drvl_+240=shmcon_"
        !          137380: :
        !          137381: if [ -d "${DEV-/dev}" ]
        !          137382: then
        !          137383:        umask 0111
        !          137384:        /etc/mknod -f ${DEV-/dev}/shm c 24 0 || exit 1
        !          137385: fi
        !          137386: 0707070064030114741004440000030000030000011777770507310755700004200000001114/newbits/kernel/USRSYS/confdrv/st:
        !          137387: : Archive SC-400 Streaming Tape Drive.
        !          137388: :
        !          137389: :      Minor device 0 allocates a maximum sized read/write cache [up to 256k].
        !          137390: :      Minor device n [1..127] allocates a n Kbyte sized read/write cache.
        !          137391: :      Adding 128 to one of the above minor devices inhibits rewind on close.
        !          137392: :
        !          137393: UNDEF="${UNDEF} -u stcon_ lib/st.a"
        !          137394: PATCH="${PATCH} drvl_+120=stcon_"
        !          137395: 
        !          137396: if [ -d "${DEV-/dev}" ]
        !          137397: then
        !          137398:        umask 077
        !          137399:        /etc/mknod -f ${DEV-/dev}/rst    c 12   0       || exit 1
        !          137400:        /etc/mknod -f ${DEV-/dev}/rst32  c 12  32       || exit 1
        !          137401:        /etc/mknod -f ${DEV-/dev}/rst64  c 12  64       || exit 1
        !          137402:        /etc/mknod -f ${DEV-/dev}/nrst   c 12 128       || exit 1
        !          137403: fi
        !          137404: 0707070064030114731004440000030000030000011777770507310755700004200000000543/newbits/kernel/USRSYS/confdrv/tn:
        !          137405: : 'Tiac PC-234/6 ARCNET LAN boards [0..3]'
        !          137406: :
        !          137407: UNDEF="${UNDEF} -u tncon_ lib/tn.a"
        !          137408: PATCH="${PATCH} drvl_+200=tncon_"
        !          137409: :
        !          137410: if [ -d "${DEV-/dev}" ]
        !          137411: then
        !          137412:        umask 0111
        !          137413:        /etc/mknod -f ${DEV-/dev}/tn0 c 20 0 || exit 1
        !          137414:        /etc/mknod -f ${DEV-/dev}/tn1 c 20 1 || exit 1
        !          137415:        /etc/mknod -f ${DEV-/dev}/tn2 c 20 2 || exit 1
        !          137416:        /etc/mknod -f ${DEV-/dev}/tn3 c 20 3 || exit 1
        !          137417: fi
        !          137418: 0707070064030114751004440000030000030000011777770507310755700004200000003231/newbits/kernel/USRSYS/confdrv/ss:
        !          137419: : Hard Disk on Seagate ST01/ST02 series SCSI controller.
        !          137420: :
        !          137421: MAJOR=13
        !          137422: 
        !          137423: case "${ARG}" in
        !          137424: *1?)   HD_TYPE=ss1 ;;
        !          137425: *)     HD_TYPE=ss0 ;;
        !          137426: esac
        !          137427: :
        !          137428: :      needed by config
        !          137429: :
        !          137430: UNDEF="${UNDEF} -u sscon_ lib/ss.a"
        !          137431: PATCH="${PATCH} drvl_+130=sscon_"
        !          137432: 
        !          137433: case ${ARG} in
        !          137434: ss0a)  MAKEDEV="makedev(13,0)" ;;
        !          137435: ss0b)  MAKEDEV="makedev(13,1)" ;;
        !          137436: ss0c)  MAKEDEV="makedev(13,2)" ;;
        !          137437: ss0d)  MAKEDEV="makedev(13,3)" ;;
        !          137438: ss1a)  MAKEDEV="makedev(13,16)" ;;
        !          137439: ss1b)  MAKEDEV="makedev(13,17)" ;;
        !          137440: ss1c)  MAKEDEV="makedev(13,18)" ;;
        !          137441: ss1d)  MAKEDEV="makedev(13,19)" ;;
        !          137442: ss)
        !          137443:        ;;
        !          137444: *)
        !          137445:        /bin/echo "invalid argument: ${ARG}"
        !          137446:        exit 1
        !          137447:        ;;
        !          137448: esac
        !          137449: 
        !          137450: :
        !          137451: : needed for both build and config
        !          137452: :
        !          137453: if [ -d "${DEV-/dev}" ]
        !          137454: then
        !          137455:        umask 077
        !          137456:        /etc/mknod -f ${DEV-/dev}/ss0a  b 13 0          || exit 1
        !          137457:        /etc/mknod -f ${DEV-/dev}/ss0b  b 13 1          || exit 1
        !          137458:        /etc/mknod -f ${DEV-/dev}/ss0c  b 13 2          || exit 1
        !          137459:        /etc/mknod -f ${DEV-/dev}/ss0d  b 13 3          || exit 1
        !          137460:        /etc/mknod -f ${DEV-/dev}/ss0x  b 13 128        || exit 1
        !          137461:        /etc/mknod -f ${DEV-/dev}/rss0a c 13 0          || exit 1
        !          137462:        /etc/mknod -f ${DEV-/dev}/rss0b c 13 1          || exit 1
        !          137463:        /etc/mknod -f ${DEV-/dev}/rss0c c 13 2          || exit 1
        !          137464:        /etc/mknod -f ${DEV-/dev}/rss0d c 13 3          || exit 1
        !          137465:        /etc/mknod -f ${DEV-/dev}/rss0x c 13 128        || exit 1
        !          137466:        /etc/mknod -f ${DEV-/dev}/ss1a  b 13 16         || exit 1
        !          137467:        /etc/mknod -f ${DEV-/dev}/ss1b  b 13 17         || exit 1
        !          137468:        /etc/mknod -f ${DEV-/dev}/ss1c  b 13 18         || exit 1
        !          137469:        /etc/mknod -f ${DEV-/dev}/ss1d  b 13 19         || exit 1
        !          137470:        /etc/mknod -f ${DEV-/dev}/ss1x  b 13 144        || exit 1
        !          137471:        /etc/mknod -f ${DEV-/dev}/rss1a c 13 16         || exit 1
        !          137472:        /etc/mknod -f ${DEV-/dev}/rss1b c 13 17         || exit 1
        !          137473:        /etc/mknod -f ${DEV-/dev}/rss1c c 13 18         || exit 1
        !          137474:        /etc/mknod -f ${DEV-/dev}/rss1d c 13 19         || exit 1
        !          137475:        /etc/mknod -f ${DEV-/dev}/rss1x c 13 144        || exit 1
        !          137476: fi
        !          137477: 0707070064030035651004440000030000030000021777770507310756000004700000003126/newbits/kernel/USRSYS/confdrv/aha154x:
        !          137478: : Hard Disk on Adaptec AHA154x series host adaptor
        !          137479: :
        !          137480: MAJOR=13
        !          137481: 
        !          137482: case "${ARG}" in
        !          137483: *1?)   HD_TYPE=sd1 ;;
        !          137484: *)     HD_TYPE=sd0 ;;
        !          137485: esac
        !          137486: :
        !          137487: :      needed by config
        !          137488: :
        !          137489: UNDEF="${UNDEF} -u sdcon_ lib/aha154x.a"
        !          137490: PATCH="${PATCH} drvl_+130=sdcon_"
        !          137491: 
        !          137492: case ${ARG} in
        !          137493: sd0a)  MAKEDEV="makedev(13,0)" ;;
        !          137494: sd0b)  MAKEDEV="makedev(13,1)" ;;
        !          137495: sd0c)  MAKEDEV="makedev(13,2)" ;;
        !          137496: sd0d)  MAKEDEV="makedev(13,3)" ;;
        !          137497: sd1a)  MAKEDEV="makedev(13,16)" ;;
        !          137498: sd1b)  MAKEDEV="makedev(13,17)" ;;
        !          137499: sd1c)  MAKEDEV="makedev(13,18)" ;;
        !          137500: sd1d)  MAKEDEV="makedev(13,19)" ;;
        !          137501: sd)
        !          137502:        ;;
        !          137503: aha154x)
        !          137504:        ;;
        !          137505: *)
        !          137506:        /bin/echo "invalid argument: ${ARG}"
        !          137507:        exit 1
        !          137508:        ;;
        !          137509: esac
        !          137510: 
        !          137511: :
        !          137512: : needed for both build and config
        !          137513: :
        !          137514: DEV=${DEV-/dev}
        !          137515: if [ -d "$DEV" ]
        !          137516: then
        !          137517:        umask 077
        !          137518:        /etc/mknod -f $DEV/sd0a  b 13 0         || exit 1
        !          137519:        /etc/mknod -f $DEV/sd0b  b 13 1         || exit 1
        !          137520:        /etc/mknod -f $DEV/sd0c  b 13 2         || exit 1
        !          137521:        /etc/mknod -f $DEV/sd0d  b 13 3         || exit 1
        !          137522:        /etc/mknod -f $DEV/sd0x  b 13 128       || exit 1
        !          137523:        /etc/mknod -f $DEV/rsd0a c 13 0         || exit 1
        !          137524:        /etc/mknod -f $DEV/rsd0b c 13 1         || exit 1
        !          137525:        /etc/mknod -f $DEV/rsd0c c 13 2         || exit 1
        !          137526:        /etc/mknod -f $DEV/rsd0d c 13 3         || exit 1
        !          137527:        /etc/mknod -f $DEV/rsd0x c 13 128       || exit 1
        !          137528:        /etc/mknod -f $DEV/sd1a  b 13 16        || exit 1
        !          137529:        /etc/mknod -f $DEV/sd1b  b 13 17        || exit 1
        !          137530:        /etc/mknod -f $DEV/sd1c  b 13 18        || exit 1
        !          137531:        /etc/mknod -f $DEV/sd1d  b 13 19        || exit 1
        !          137532:        /etc/mknod -f $DEV/sd1x  b 13 144       || exit 1
        !          137533:        /etc/mknod -f $DEV/rsd1a c 13 16        || exit 1
        !          137534:        /etc/mknod -f $DEV/rsd1b c 13 17        || exit 1
        !          137535:        /etc/mknod -f $DEV/rsd1c c 13 18        || exit 1
        !          137536:        /etc/mknod -f $DEV/rsd1d c 13 19        || exit 1
        !          137537:        /etc/mknod -f $DEV/rsd1x c 13 144       || exit 1
        !          137538:        chown sys $DEV/sd* $DEV/rsd*
        !          137539:        chgrp sys $DEV/sd* $DEV/rsd*
        !          137540: fi
        !          137541: 0707070064030035651004440000030000030000021777770507310756000004200000000000/newbits/kernel/USRSYS/confdrv/sd0707070064030115051004440000030000030000011777770507310756000004200000000300/newbits/kernel/USRSYS/confdrv/qq:
        !          137542: : 'Dummy driver for write to absolute RAM area'
        !          137543: :
        !          137544: UNDEF="${UNDEF} -u qqcon_ lib/qq.a"
        !          137545: PATCH="${PATCH} drvl_+70=qqcon_"
        !          137546: :
        !          137547: : devices
        !          137548: :
        !          137549: umask 0111
        !          137550: /etc/mknod -f ${DEV-/dev}/qq c 7  0 || exit 1
        !          137551: 0707070064030115161004440000030000030000011777770507310756100004200000000424/newbits/kernel/USRSYS/confdrv/dg:
        !          137552: : 'Driver for Digiboard PC/Xe'
        !          137553: :
        !          137554: UNDEF="${UNDEF} -u dgcon_ lib/dg.a"
        !          137555: PATCH="${PATCH} drvl_+210=dgcon_"
        !          137556: :
        !          137557: : devices
        !          137558: :
        !          137559: umask 0111
        !          137560: /etc/mknod -f ${DEV-/dev}/dg c 21  0 || exit 1
        !          137561: /etc/mknod -f ${DEV-/dev}/dgx c 21  128 || exit 1
        !          137562: /etc/mknod -f ${DEV-/dev}/dgy c 21  64 || exit 1
        !          137563: 0707070064030066730407550000030000030000011777770507310756100004300000000000/newbits/kernel/USRSYS/confdrv/RCS0707070064030057011004440000030000030000011777770507310756100005500000003633/newbits/kernel/USRSYS/confdrv/RCS/aha154x,vhead     1.1;
        !          137564: branch   ;
        !          137565: access   ;
        !          137566: symbols  ;
        !          137567: locks    bin:1.1; strict;
        !          137568: comment  @# @;
        !          137569: 
        !          137570: 
        !          137571: 1.1
        !          137572: date     91.07.15.14.11.11;  author bin;  state Exp;
        !          137573: branches ;
        !          137574: next     ;
        !          137575: 
        !          137576: 
        !          137577: desc
        !          137578: @initial version prov by hal
        !          137579: @
        !          137580: 
        !          137581: 
        !          137582: 
        !          137583: 1.1
        !          137584: log
        !          137585: @Initial revision
        !          137586: @
        !          137587: text
        !          137588: @:
        !          137589: : Hard Disk on Adaptec AHA154x series host adaptor
        !          137590: :
        !          137591: MAJOR=13
        !          137592: 
        !          137593: case "${ARG}" in
        !          137594: *1?)   HD_TYPE=sd1 ;;
        !          137595: *)     HD_TYPE=sd0 ;;
        !          137596: esac
        !          137597: :
        !          137598: :      needed by config
        !          137599: :
        !          137600: UNDEF="${UNDEF} -u sdcon_ lib/aha154x.a"
        !          137601: PATCH="${PATCH} drvl_+130=sdcon_"
        !          137602: 
        !          137603: case ${ARG} in
        !          137604: sd0a)  MAKEDEV="makedev(13,0)" ;;
        !          137605: sd0b)  MAKEDEV="makedev(13,1)" ;;
        !          137606: sd0c)  MAKEDEV="makedev(13,2)" ;;
        !          137607: sd0d)  MAKEDEV="makedev(13,3)" ;;
        !          137608: sd1a)  MAKEDEV="makedev(13,16)" ;;
        !          137609: sd1b)  MAKEDEV="makedev(13,17)" ;;
        !          137610: sd1c)  MAKEDEV="makedev(13,18)" ;;
        !          137611: sd1d)  MAKEDEV="makedev(13,19)" ;;
        !          137612: sd)
        !          137613:        ;;
        !          137614: aha154x)
        !          137615:        ;;
        !          137616: *)
        !          137617:        /bin/echo "invalid argument: ${ARG}"
        !          137618:        exit 1
        !          137619:        ;;
        !          137620: esac
        !          137621: 
        !          137622: :
        !          137623: : needed for both build and config
        !          137624: :
        !          137625: if [ -d "${DEV-/dev}" ]
        !          137626: then
        !          137627:        umask 077
        !          137628:        /etc/mknod -f ${DEV-/dev}/sd0a  b 13 0          || exit 1
        !          137629:        /etc/mknod -f ${DEV-/dev}/sd0b  b 13 1          || exit 1
        !          137630:        /etc/mknod -f ${DEV-/dev}/sd0c  b 13 2          || exit 1
        !          137631:        /etc/mknod -f ${DEV-/dev}/sd0d  b 13 3          || exit 1
        !          137632:        /etc/mknod -f ${DEV-/dev}/sd0x  b 13 128        || exit 1
        !          137633:        /etc/mknod -f ${DEV-/dev}/rsd0a c 13 0          || exit 1
        !          137634:        /etc/mknod -f ${DEV-/dev}/rsd0b c 13 1          || exit 1
        !          137635:        /etc/mknod -f ${DEV-/dev}/rsd0c c 13 2          || exit 1
        !          137636:        /etc/mknod -f ${DEV-/dev}/rsd0d c 13 3          || exit 1
        !          137637:        /etc/mknod -f ${DEV-/dev}/rsd0x c 13 128        || exit 1
        !          137638:        /etc/mknod -f ${DEV-/dev}/sd1a  b 13 16         || exit 1
        !          137639:        /etc/mknod -f ${DEV-/dev}/sd1b  b 13 17         || exit 1
        !          137640:        /etc/mknod -f ${DEV-/dev}/sd1c  b 13 18         || exit 1
        !          137641:        /etc/mknod -f ${DEV-/dev}/sd1d  b 13 19         || exit 1
        !          137642:        /etc/mknod -f ${DEV-/dev}/sd1x  b 13 144        || exit 1
        !          137643:        /etc/mknod -f ${DEV-/dev}/rsd1a c 13 16         || exit 1
        !          137644:        /etc/mknod -f ${DEV-/dev}/rsd1b c 13 17         || exit 1
        !          137645:        /etc/mknod -f ${DEV-/dev}/rsd1c c 13 18         || exit 1
        !          137646:        /etc/mknod -f ${DEV-/dev}/rsd1d c 13 19         || exit 1
        !          137647:        /etc/mknod -f ${DEV-/dev}/rsd1x c 13 144        || exit 1
        !          137648: fi
        !          137649: @
        !          137650: 0707070064030116131004440000030000030000011777770507310756100005100000001453/newbits/kernel/USRSYS/confdrv/RCS/al0,vhead     1.1;
        !          137651: branch   ;
        !          137652: access   ;
        !          137653: symbols  ;
        !          137654: locks    bin:1.1; strict;
        !          137655: comment  @# @;
        !          137656: 
        !          137657: 
        !          137658: 1.1
        !          137659: date     91.07.15.14.11.25;  author bin;  state Exp;
        !          137660: branches ;
        !          137661: next     ;
        !          137662: 
        !          137663: 
        !          137664: desc
        !          137665: @initial version prov by hal
        !          137666: @
        !          137667: 
        !          137668: 
        !          137669: 
        !          137670: 1.1
        !          137671: log
        !          137672: @Initial revision
        !          137673: @
        !          137674: text
        !          137675: @:
        !          137676: : 'Serial Lines COM1 and COM3'
        !          137677: :
        !          137678: UNDEF="${UNDEF} -u a0con_ lib/al.a"
        !          137679: PATCH="${PATCH} drvl_+50=a0con_"
        !          137680: :
        !          137681: if [ -d "${DEV-/dev}" ]
        !          137682: then
        !          137683:        umask 0111
        !          137684:        /etc/mknod -f ${DEV-/dev}/com1l  c 5 128        || exit 1
        !          137685:        /etc/mknod -f ${DEV-/dev}/com1r  c 5 0          || exit 1
        !          137686:        /etc/mknod -f ${DEV-/dev}/com1pl c 5 192        || exit 1
        !          137687:        /etc/mknod -f ${DEV-/dev}/com1pr c 5 64         || exit 1
        !          137688: 
        !          137689:        /etc/mknod -f ${DEV-/dev}/com3l  c 5 129        || exit 1
        !          137690:        /etc/mknod -f ${DEV-/dev}/com3r  c 5 1          || exit 1
        !          137691:        /etc/mknod -f ${DEV-/dev}/com3pl c 5 193        || exit 1
        !          137692:        /etc/mknod -f ${DEV-/dev}/com3pr c 5 65         || exit 1
        !          137693: fi
        !          137694: @
        !          137695: 0707070064030076071004440000030000030000011777770507310756200005100000001453/newbits/kernel/USRSYS/confdrv/RCS/al1,vhead     1.1;
        !          137696: branch   ;
        !          137697: access   ;
        !          137698: symbols  ;
        !          137699: locks    bin:1.1; strict;
        !          137700: comment  @# @;
        !          137701: 
        !          137702: 
        !          137703: 1.1
        !          137704: date     91.07.15.14.11.27;  author bin;  state Exp;
        !          137705: branches ;
        !          137706: next     ;
        !          137707: 
        !          137708: 
        !          137709: desc
        !          137710: @initial version prov by hal
        !          137711: @
        !          137712: 
        !          137713: 
        !          137714: 
        !          137715: 1.1
        !          137716: log
        !          137717: @Initial revision
        !          137718: @
        !          137719: text
        !          137720: @:
        !          137721: : 'Serial Lines COM2 and COM4'
        !          137722: :
        !          137723: UNDEF="${UNDEF} -u a1con_ lib/al.a"
        !          137724: PATCH="${PATCH} drvl_+60=a1con_"
        !          137725: :
        !          137726: if [ -d "${DEV-/dev}" ]
        !          137727: then
        !          137728:        umask 0111
        !          137729:        /etc/mknod -f ${DEV-/dev}/com2l  c 6 128        || exit 1
        !          137730:        /etc/mknod -f ${DEV-/dev}/com2r  c 6 0          || exit 1
        !          137731:        /etc/mknod -f ${DEV-/dev}/com2pl c 6 192        || exit 1
        !          137732:        /etc/mknod -f ${DEV-/dev}/com2pr c 6 64         || exit 1
        !          137733: 
        !          137734:        /etc/mknod -f ${DEV-/dev}/com4l  c 6 129        || exit 1
        !          137735:        /etc/mknod -f ${DEV-/dev}/com4r  c 6 1          || exit 1
        !          137736:        /etc/mknod -f ${DEV-/dev}/com4pl c 6 193        || exit 1
        !          137737:        /etc/mknod -f ${DEV-/dev}/com4pr c 6 65         || exit 1
        !          137738: fi
        !          137739: @
        !          137740: 0707070064030076121004440000030000030000011777770507310756200005000000003531/newbits/kernel/USRSYS/confdrv/RCS/at,vhead     1.1;
        !          137741: branch   ;
        !          137742: access   ;
        !          137743: symbols  ;
        !          137744: locks    bin:1.1; strict;
        !          137745: comment  @# @;
        !          137746: 
        !          137747: 
        !          137748: 1.1
        !          137749: date     91.07.15.14.11.28;  author bin;  state Exp;
        !          137750: branches ;
        !          137751: next     ;
        !          137752: 
        !          137753: 
        !          137754: desc
        !          137755: @initial version prov by hal
        !          137756: @
        !          137757: 
        !          137758: 
        !          137759: 
        !          137760: 1.1
        !          137761: log
        !          137762: @Initial revision
        !          137763: @
        !          137764: text
        !          137765: @:
        !          137766: : AT Hard Disk
        !          137767: :
        !          137768: MAJOR=11
        !          137769: 
        !          137770: case "${ARG}" in
        !          137771: *1?)   HD_TYPE=at1 ;;
        !          137772: *)     HD_TYPE=at0 ;;
        !          137773: esac
        !          137774: :
        !          137775: :      needed by config
        !          137776: :
        !          137777: UNDEF="${UNDEF} -u atcon_ lib/at.a"
        !          137778: PATCH="${PATCH} drvl_+110=atcon_"
        !          137779: 
        !          137780: case ${ARG} in
        !          137781: at0a)  MAKEDEV="makedev(11,0)" ;;
        !          137782: at0b)  MAKEDEV="makedev(11,1)" ;;
        !          137783: at0c)  MAKEDEV="makedev(11,2)" ;;
        !          137784: at0d)  MAKEDEV="makedev(11,3)" ;;
        !          137785: at1a)  MAKEDEV="makedev(11,4)" ;;
        !          137786: at1b)  MAKEDEV="makedev(11,5)" ;;
        !          137787: at1c)  MAKEDEV="makedev(11,6)" ;;
        !          137788: at1d)  MAKEDEV="makedev(11,7)" ;;
        !          137789: at)
        !          137790:        ;;
        !          137791: *)
        !          137792:        /bin/echo "invalid argument: ${ARG}"
        !          137793:        exit 1
        !          137794:        ;;
        !          137795: esac
        !          137796: 
        !          137797: :
        !          137798: : needed for both build and config
        !          137799: :
        !          137800: if [ -d "${DEV-/dev}" ]
        !          137801: then
        !          137802:        umask 077
        !          137803:        /etc/mknod -f ${DEV-/dev}/at0a  b 11 0          || exit 1
        !          137804:        /etc/mknod -f ${DEV-/dev}/at0b  b 11 1          || exit 1
        !          137805:        /etc/mknod -f ${DEV-/dev}/at0c  b 11 2          || exit 1
        !          137806:        /etc/mknod -f ${DEV-/dev}/at0d  b 11 3          || exit 1
        !          137807:        /etc/mknod -f ${DEV-/dev}/at0x  b 11 128        || exit 1
        !          137808:        /etc/mknod -f ${DEV-/dev}/rat0a c 11 0          || exit 1
        !          137809:        /etc/mknod -f ${DEV-/dev}/rat0b c 11 1          || exit 1
        !          137810:        /etc/mknod -f ${DEV-/dev}/rat0c c 11 2          || exit 1
        !          137811:        /etc/mknod -f ${DEV-/dev}/rat0d c 11 3          || exit 1
        !          137812:        /etc/mknod -f ${DEV-/dev}/rat0x c 11 128        || exit 1
        !          137813:        /etc/mknod -f ${DEV-/dev}/at1a  b 11 4          || exit 1
        !          137814:        /etc/mknod -f ${DEV-/dev}/at1b  b 11 5          || exit 1
        !          137815:        /etc/mknod -f ${DEV-/dev}/at1c  b 11 6          || exit 1
        !          137816:        /etc/mknod -f ${DEV-/dev}/at1d  b 11 7          || exit 1
        !          137817:        /etc/mknod -f ${DEV-/dev}/at1x  b 11 129        || exit 1
        !          137818:        /etc/mknod -f ${DEV-/dev}/rat1a c 11 4          || exit 1
        !          137819:        /etc/mknod -f ${DEV-/dev}/rat1b c 11 5          || exit 1
        !          137820:        /etc/mknod -f ${DEV-/dev}/rat1c c 11 6          || exit 1
        !          137821:        /etc/mknod -f ${DEV-/dev}/rat1d c 11 7          || exit 1
        !          137822:        /etc/mknod -f ${DEV-/dev}/rat1x c 11 129        || exit 1
        !          137823: fi
        !          137824: @
        !          137825: 0707070064030105601004440000030000030000011777770507310756200005100000000744/newbits/kernel/USRSYS/confdrv/RCS/ati,vhead     1.1;
        !          137826: branch   ;
        !          137827: access   ;
        !          137828: symbols  ;
        !          137829: locks    bin:1.1; strict;
        !          137830: comment  @# @;
        !          137831: 
        !          137832: 
        !          137833: 1.1
        !          137834: date     91.07.15.14.11.29;  author bin;  state Exp;
        !          137835: branches ;
        !          137836: next     ;
        !          137837: 
        !          137838: 
        !          137839: desc
        !          137840: @initial version prov by hal
        !          137841: @
        !          137842: 
        !          137843: 
        !          137844: 
        !          137845: 1.1
        !          137846: log
        !          137847: @Initial revision
        !          137848: @
        !          137849: text
        !          137850: @:
        !          137851: : 'Array Technologies Inc - Graphics Solution - includes Keyboard'
        !          137852: :
        !          137853: UNDEF="${UNDEF} -u iscon_ lib/ati.a"
        !          137854: PATCH="${PATCH} drvl_+20=iscon_"
        !          137855: :
        !          137856: if [ -d "${DEV-/dev}" ]
        !          137857: then
        !          137858:        umask 0111
        !          137859:        /etc/mknod -f ${DEV-/dev}/console c 2 0 || exit 1
        !          137860: fi
        !          137861: @
        !          137862: 0707070064030031671004440000030000030000011777770507310756300005000000001012/newbits/kernel/USRSYS/confdrv/RCS/dg,vhead     1.1;
        !          137863: branch   ;
        !          137864: access   ;
        !          137865: symbols  ;
        !          137866: locks    bin:1.1; strict;
        !          137867: comment  @# @;
        !          137868: 
        !          137869: 
        !          137870: 1.1
        !          137871: date     91.07.15.14.11.30;  author bin;  state Exp;
        !          137872: branches ;
        !          137873: next     ;
        !          137874: 
        !          137875: 
        !          137876: desc
        !          137877: @initial version prov by hal
        !          137878: @
        !          137879: 
        !          137880: 
        !          137881: 
        !          137882: 1.1
        !          137883: log
        !          137884: @Initial revision
        !          137885: @
        !          137886: text
        !          137887: @:
        !          137888: : 'Driver for Digiboard PC/Xe'
        !          137889: :
        !          137890: UNDEF="${UNDEF} -u dgcon_ lib/dg.a"
        !          137891: PATCH="${PATCH} drvl_+210=dgcon_"
        !          137892: :
        !          137893: : devices
        !          137894: :
        !          137895: umask 0111
        !          137896: /etc/mknod -f ${DEV-/dev}/dg c 21  0 || exit 1
        !          137897: /etc/mknod -f ${DEV-/dev}/dgx c 21  128 || exit 1
        !          137898: /etc/mknod -f ${DEV-/dev}/dgy c 21  64 || exit 1
        !          137899: @
        !          137900: 0707070064030066701004440000030000030000011777770507310756300005000000001552/newbits/kernel/USRSYS/confdrv/RCS/fl,vhead     1.1;
        !          137901: branch   ;
        !          137902: access   ;
        !          137903: symbols  ;
        !          137904: locks    bin:1.1; strict;
        !          137905: comment  @# @;
        !          137906: 
        !          137907: 
        !          137908: 1.1
        !          137909: date     91.07.15.14.11.30;  author bin;  state Exp;
        !          137910: branches ;
        !          137911: next     ;
        !          137912: 
        !          137913: 
        !          137914: desc
        !          137915: @initial version prov by hal
        !          137916: @
        !          137917: 
        !          137918: 
        !          137919: 
        !          137920: 1.1
        !          137921: log
        !          137922: @Initial revision
        !          137923: @
        !          137924: text
        !          137925: @:
        !          137926: : AT Floppy Driver
        !          137927: :
        !          137928: UNDEF="${UNDEF} -u flcon_ lib/fl.a"
        !          137929: PATCH="${PATCH} drvl_+40=flcon_"
        !          137930: :
        !          137931: if [ -d "${DEV-/dev}" ]
        !          137932: then
        !          137933:        umask 0133
        !          137934:        /etc/mknod -f ${DEV-/dev}/f9a0 b 4 12   || exit 1
        !          137935:        /etc/mknod -f ${DEV-/dev}/f9a1 b 4 28   || exit 1
        !          137936:        /etc/mknod -f ${DEV-/dev}/f9d0 b 4  4   || exit 1
        !          137937:        /etc/mknod -f ${DEV-/dev}/f9d1 b 4 20   || exit 1
        !          137938:        /etc/mknod -f ${DEV-/dev}/fha0 b 4 14   || exit 1
        !          137939:        /etc/mknod -f ${DEV-/dev}/fha1 b 4 30   || exit 1
        !          137940:        /etc/mknod -f ${DEV-/dev}/fqa0 b 4 13   || exit 1
        !          137941:        /etc/mknod -f ${DEV-/dev}/fqa1 b 4 29   || exit 1
        !          137942:        /etc/mknod -f ${DEV-/dev}/fva0 b 4 15   || exit 1
        !          137943:        /etc/mknod -f ${DEV-/dev}/fva1 b 4 31   || exit 1
        !          137944: fi
        !          137945: @
        !          137946: 0707070064030127101004440000030000030000011777770507310756300005000000001011/newbits/kernel/USRSYS/confdrv/RCS/gm,vhead     1.1;
        !          137947: branch   ;
        !          137948: access   ;
        !          137949: symbols  ;
        !          137950: locks    bin:1.1; strict;
        !          137951: comment  @# @;
        !          137952: 
        !          137953: 
        !          137954: 1.1
        !          137955: date     91.07.15.14.11.31;  author bin;  state Exp;
        !          137956: branches ;
        !          137957: next     ;
        !          137958: 
        !          137959: 
        !          137960: desc
        !          137961: @initial version prov by hal
        !          137962: @
        !          137963: 
        !          137964: 
        !          137965: 
        !          137966: 1.1
        !          137967: log
        !          137968: @Initial revision
        !          137969: @
        !          137970: text
        !          137971: @:
        !          137972: : Tecmar Graphics Master
        !          137973: :
        !          137974: UNDEF="${UNDEF} -u iscon_ -u grcon_ lib/gm.a"
        !          137975: PATCH="${PATCH} drvl_+20=iscon_ drvl_+300=grcon_"
        !          137976: :
        !          137977: if [ -d "${DEV-/dev}" ]
        !          137978: then
        !          137979:        umask 0111
        !          137980:        /etc/mknod -f ${DEV-/dev}/console c  2 0 || exit 1
        !          137981:        /etc/mknod -f ${DEV-/dev}/gr      c 30 0 || exit 1
        !          137982: fi
        !          137983: @
        !          137984: 0707070064030056311004440000030000030000011777770507310756300005000000001024/newbits/kernel/USRSYS/confdrv/RCS/gr,vhead     1.1;
        !          137985: branch   ;
        !          137986: access   ;
        !          137987: symbols  ;
        !          137988: locks    bin:1.1; strict;
        !          137989: comment  @# @;
        !          137990: 
        !          137991: 
        !          137992: 1.1
        !          137993: date     91.07.15.14.11.32;  author bin;  state Exp;
        !          137994: branches ;
        !          137995: next     ;
        !          137996: 
        !          137997: 
        !          137998: desc
        !          137999: @initial version prov by hal
        !          138000: @
        !          138001: 
        !          138002: 
        !          138003: 
        !          138004: 1.1
        !          138005: log
        !          138006: @Initial revision
        !          138007: @
        !          138008: text
        !          138009: @:
        !          138010: : Graphics Display on PC Color Card
        !          138011: :
        !          138012: UNDEF="${UNDEF} -u iscon_ -u grcon_ lib/gr.a"
        !          138013: PATCH="${PATCH} drvl_+20=iscon_ drvl_+300=grcon_"
        !          138014: :
        !          138015: if [ -d "${DEV-/dev}" ]
        !          138016: then
        !          138017:        umask 0111
        !          138018:        /etc/mknod -f ${DEV-/dev}/console c  2 0 || exit 1
        !          138019:        /etc/mknod -f ${DEV-/dev}/gr      c 30 0 || exit 1
        !          138020: fi
        !          138021: @
        !          138022: 0707070064030055771004440000030000030000011777770507310756300005000000002332/newbits/kernel/USRSYS/confdrv/RCS/hs,vhead     1.1;
        !          138023: branch   ;
        !          138024: access   ;
        !          138025: symbols  ;
        !          138026: locks    bin:1.1; strict;
        !          138027: comment  @# @;
        !          138028: 
        !          138029: 
        !          138030: 1.1
        !          138031: date     91.07.15.14.11.33;  author bin;  state Exp;
        !          138032: branches ;
        !          138033: next     ;
        !          138034: 
        !          138035: 
        !          138036: desc
        !          138037: @initial version prov by hal
        !          138038: @
        !          138039: 
        !          138040: 
        !          138041: 
        !          138042: 1.1
        !          138043: log
        !          138044: @Initial revision
        !          138045: @
        !          138046: text
        !          138047: @:
        !          138048: : 'Hostess/Arnet multi-port Serial Support (Version 7 Compatible)'
        !          138049: :
        !          138050: UNDEF="${UNDEF} -u hscon_ lib/hs.a"
        !          138051: PATCH="${PATCH} drvl_+70=hscon_"
        !          138052: :
        !          138053: : non modem control devices
        !          138054: :
        !          138055: umask 0111
        !          138056: /etc/mknod -f ${DEV-/dev}/hs00 c 7  0 || exit 1
        !          138057: /etc/mknod -f ${DEV-/dev}/hs01 c 7  1 || exit 1
        !          138058: /etc/mknod -f ${DEV-/dev}/hs02 c 7  2 || exit 1
        !          138059: /etc/mknod -f ${DEV-/dev}/hs03 c 7  3 || exit 1
        !          138060: /etc/mknod -f ${DEV-/dev}/hs04 c 7  4 || exit 1
        !          138061: /etc/mknod -f ${DEV-/dev}/hs05 c 7  5 || exit 1
        !          138062: /etc/mknod -f ${DEV-/dev}/hs06 c 7  6 || exit 1
        !          138063: /etc/mknod -f ${DEV-/dev}/hs07 c 7  7 || exit 1
        !          138064: :
        !          138065: : modem control versions
        !          138066: :
        !          138067: /etc/mknod -f ${DEV-/dev}/hs00r c 7 128 || exit 1
        !          138068: /etc/mknod -f ${DEV-/dev}/hs01r c 7 129 || exit 1
        !          138069: /etc/mknod -f ${DEV-/dev}/hs02r c 7 130 || exit 1
        !          138070: /etc/mknod -f ${DEV-/dev}/hs03r c 7 131 || exit 1
        !          138071: /etc/mknod -f ${DEV-/dev}/hs04r c 7 132 || exit 1
        !          138072: /etc/mknod -f ${DEV-/dev}/hs05r c 7 133 || exit 1
        !          138073: /etc/mknod -f ${DEV-/dev}/hs06r c 7 134 || exit 1
        !          138074: /etc/mknod -f ${DEV-/dev}/hs07r c 7 135 || exit 1
        !          138075: @
        !          138076: 0707070064030053341004440000030000030000011777770507310756400005000000001146/newbits/kernel/USRSYS/confdrv/RCS/lp,vhead     1.1;
        !          138077: branch   ;
        !          138078: access   ;
        !          138079: symbols  ;
        !          138080: locks    bin:1.1; strict;
        !          138081: comment  @# @;
        !          138082: 
        !          138083: 
        !          138084: 1.1
        !          138085: date     91.07.15.14.11.34;  author bin;  state Exp;
        !          138086: branches ;
        !          138087: next     ;
        !          138088: 
        !          138089: 
        !          138090: desc
        !          138091: @initial version prov by hal
        !          138092: @
        !          138093: 
        !          138094: 
        !          138095: 
        !          138096: 1.1
        !          138097: log
        !          138098: @Initial revision
        !          138099: @
        !          138100: text
        !          138101: @:
        !          138102: : Parallel Line Printers LPT1, LPT2 and LPT3
        !          138103: :
        !          138104: UNDEF="${UNDEF} -u lpcon_ lib/lp.a"
        !          138105: PATCH="${PATCH} drvl_+30=lpcon_"
        !          138106: :
        !          138107: if [ -d "${DEV-/dev}" ]
        !          138108: then
        !          138109:        umask 0555
        !          138110:        /etc/mknod -f ${DEV-/dev}/lpt1 c 3 0            || exit 1
        !          138111:        /etc/mknod -f ${DEV-/dev}/lpt2 c 3 1            || exit 1
        !          138112:        /etc/mknod -f ${DEV-/dev}/lpt3 c 3 2            || exit 1
        !          138113:        : /bin/ln  -f ${DEV-/dev}/lpt1 ${DEV-/dev}/lp   || exit 1
        !          138114: fi
        !          138115: @
        !          138116: 0707070064030004051004440000030000030000011777770507310756400005000000000723/newbits/kernel/USRSYS/confdrv/RCS/mm,vhead     1.1;
        !          138117: branch   ;
        !          138118: access   ;
        !          138119: symbols  ;
        !          138120: locks    bin:1.1; strict;
        !          138121: comment  @# @;
        !          138122: 
        !          138123: 
        !          138124: 1.1
        !          138125: date     91.07.15.14.11.34;  author bin;  state Exp;
        !          138126: branches ;
        !          138127: next     ;
        !          138128: 
        !          138129: 
        !          138130: desc
        !          138131: @initial version prov by hal
        !          138132: @
        !          138133: 
        !          138134: 
        !          138135: 
        !          138136: 1.1
        !          138137: log
        !          138138: @Initial revision
        !          138139: @
        !          138140: text
        !          138141: @:
        !          138142: : 'Memory Mapped (Text) Video - includes Keyboard'
        !          138143: :
        !          138144: UNDEF="${UNDEF} -u iscon_ lib/mm.a"
        !          138145: PATCH="${PATCH} drvl_+20=iscon_"
        !          138146: :
        !          138147: if [ -d "${DEV-/dev}" ]
        !          138148: then
        !          138149:        umask 0111
        !          138150:        /etc/mknod -f ${DEV-/dev}/console c 2 0 || exit 1
        !          138151: fi
        !          138152: @
        !          138153: 0707070064030003531004440000030000030000011777770507310756400005000000000670/newbits/kernel/USRSYS/confdrv/RCS/ms,vhead     1.1;
        !          138154: branch   ;
        !          138155: access   ;
        !          138156: symbols  ;
        !          138157: locks    bin:1.1; strict;
        !          138158: comment  @# @;
        !          138159: 
        !          138160: 
        !          138161: 1.1
        !          138162: date     91.07.15.14.11.35;  author bin;  state Exp;
        !          138163: branches ;
        !          138164: next     ;
        !          138165: 
        !          138166: 
        !          138167: desc
        !          138168: @initial version prov by hal
        !          138169: @
        !          138170: 
        !          138171: 
        !          138172: 
        !          138173: 1.1
        !          138174: log
        !          138175: @Initial revision
        !          138176: @
        !          138177: text
        !          138178: @:
        !          138179: : 'Microsoft Bus Mouse'
        !          138180: :
        !          138181: UNDEF="${UNDEF} -u mscon_ lib/ms.a"
        !          138182: PATCH="${PATCH} drvl_+100=mscon_"
        !          138183: :
        !          138184: if [ -d "${DEV-/dev}" ]
        !          138185: then
        !          138186:        umask 0333
        !          138187:        /etc/mknod -f ${DEV-/dev}/mouse c 10 0 || exit 1
        !          138188: fi
        !          138189: @
        !          138190: 0707070064030076151004440000030000030000011777770507310756400005100000000701/newbits/kernel/USRSYS/confdrv/RCS/msg,vhead     1.1;
        !          138191: branch   ;
        !          138192: access   ;
        !          138193: symbols  ;
        !          138194: locks    bin:1.1; strict;
        !          138195: comment  @# @;
        !          138196: 
        !          138197: 
        !          138198: 1.1
        !          138199: date     91.07.15.14.11.36;  author bin;  state Exp;
        !          138200: branches ;
        !          138201: next     ;
        !          138202: 
        !          138203: 
        !          138204: desc
        !          138205: @initial version prov by hal
        !          138206: @
        !          138207: 
        !          138208: 
        !          138209: 
        !          138210: 1.1
        !          138211: log
        !          138212: @Initial revision
        !          138213: @
        !          138214: text
        !          138215: @:
        !          138216: : System V Compatible Messaging
        !          138217: :
        !          138218: UNDEF="${UNDEF} -u msgcon_ lib/msg.a"
        !          138219: PATCH="${PATCH} drvl_+250=msgcon_"
        !          138220: :
        !          138221: if [ -d "${DEV-/dev}" ]
        !          138222: then
        !          138223:        umask 0333
        !          138224:        /etc/mknod -f ${DEV-/dev}/msg c 25 0 || exit 1
        !          138225: fi
        !          138226: @
        !          138227: 0707070064030105511004440000030000030000011777770507310756400005000000000666/newbits/kernel/USRSYS/confdrv/RCS/qq,vhead     1.1;
        !          138228: branch   ;
        !          138229: access   ;
        !          138230: symbols  ;
        !          138231: locks    bin:1.1; strict;
        !          138232: comment  @# @;
        !          138233: 
        !          138234: 
        !          138235: 1.1
        !          138236: date     91.07.15.14.11.37;  author bin;  state Exp;
        !          138237: branches ;
        !          138238: next     ;
        !          138239: 
        !          138240: 
        !          138241: desc
        !          138242: @initial version prov by hal
        !          138243: @
        !          138244: 
        !          138245: 
        !          138246: 
        !          138247: 1.1
        !          138248: log
        !          138249: @Initial revision
        !          138250: @
        !          138251: text
        !          138252: @:
        !          138253: : 'Dummy driver for write to absolute RAM area'
        !          138254: :
        !          138255: UNDEF="${UNDEF} -u qqcon_ lib/qq.a"
        !          138256: PATCH="${PATCH} drvl_+70=qqcon_"
        !          138257: :
        !          138258: : devices
        !          138259: :
        !          138260: umask 0111
        !          138261: /etc/mknod -f ${DEV-/dev}/qq c 7  0 || exit 1
        !          138262: @
        !          138263: 0707070064030066711004440000030000030000011777770507310756500005000000001500/newbits/kernel/USRSYS/confdrv/RCS/rm,vhead     1.1;
        !          138264: branch   ;
        !          138265: access   ;
        !          138266: symbols  ;
        !          138267: locks    bin:1.1; strict;
        !          138268: comment  @# @;
        !          138269: 
        !          138270: 
        !          138271: 1.1
        !          138272: date     91.07.15.14.11.37;  author bin;  state Exp;
        !          138273: branches ;
        !          138274: next     ;
        !          138275: 
        !          138276: 
        !          138277: desc
        !          138278: @initial version prov by hal
        !          138279: @
        !          138280: 
        !          138281: 
        !          138282: 
        !          138283: 1.1
        !          138284: log
        !          138285: @Initial revision
        !          138286: @
        !          138287: text
        !          138288: @:
        !          138289: : Dual RAM Disk
        !          138290: : Default each to 512K for now...
        !          138291: :
        !          138292: UNDEF="${UNDEF} -u rmcon_ lib/rm.a"
        !          138293: PATCH="${PATCH} drvl_+80=rmcon_"
        !          138294: :
        !          138295: if [ -d "${DEV-/dev}" ]
        !          138296: then
        !          138297:        umask 0111
        !          138298:        /etc/mknod -f ${DEV-/dev}/ram0 b 8 8 || exit 1
        !          138299:        /etc/mknod -f ${DEV-/dev}/rram0 c 8 8 || exit 1
        !          138300:        /etc/mknod -f ${DEV-/dev}/ram0close b 8 0 || exit 1
        !          138301:        /etc/mknod -f ${DEV-/dev}/rram0close c 8 0 || exit 1
        !          138302: 
        !          138303:        /etc/mknod -f ${DEV-/dev}/ram1 b 8 136 || exit 1
        !          138304:        /etc/mknod -f ${DEV-/dev}/rram1 c 8 136 || exit 1
        !          138305:        /etc/mknod -f ${DEV-/dev}/ram1close b 8 128 || exit 1
        !          138306:        /etc/mknod -f ${DEV-/dev}/rram1close c 8 128 || exit 1
        !          138307: fi
        !          138308: @
        !          138309: 0707070064030056231004440000030000030000011777770507310756500005000000001101/newbits/kernel/USRSYS/confdrv/RCS/rp,vhead     1.1;
        !          138310: branch   ;
        !          138311: access   ;
        !          138312: symbols  ;
        !          138313: locks    bin:1.1; strict;
        !          138314: comment  @# @;
        !          138315: 
        !          138316: 
        !          138317: 1.1
        !          138318: date     91.07.15.14.11.38;  author bin;  state Exp;
        !          138319: branches ;
        !          138320: next     ;
        !          138321: 
        !          138322: 
        !          138323: desc
        !          138324: @initial version prov by hal
        !          138325: @
        !          138326: 
        !          138327: 
        !          138328: 
        !          138329: 1.1
        !          138330: log
        !          138331: @Initial revision
        !          138332: @
        !          138333: text
        !          138334: @:
        !          138335: : Ram Pipes
        !          138336: :
        !          138337: UNDEF="${UNDEF} -u rpcon_ lib/rp.a"
        !          138338: PATCH="${PATCH} NRP_=4 drvl_+220=rpcon_"
        !          138339: :
        !          138340: if [ -d "${DEV-/dev}" ]
        !          138341: then
        !          138342:        umask 0111
        !          138343:        /etc/mknod -f ${DEV-/dev}/rp0 c 22 0 || exit 1
        !          138344:        /etc/mknod -f ${DEV-/dev}/rp1 c 22 1 || exit 1
        !          138345:        /etc/mknod -f ${DEV-/dev}/rp2 c 22 2 || exit 1
        !          138346:        /etc/mknod -f ${DEV-/dev}/rp3 c 22 3 || exit 1
        !          138347: fi
        !          138348: @
        !          138349: 0707070064030056131004440000030000030000011777770507310756500005100000001007/newbits/kernel/USRSYS/confdrv/RCS/rs0,vhead     1.1;
        !          138350: branch   ;
        !          138351: access   ;
        !          138352: symbols  ;
        !          138353: locks    bin:1.1; strict;
        !          138354: comment  @# @;
        !          138355: 
        !          138356: 
        !          138357: 1.1
        !          138358: date     91.07.15.14.11.39;  author bin;  state Exp;
        !          138359: branches ;
        !          138360: next     ;
        !          138361: 
        !          138362: 
        !          138363: desc
        !          138364: @initial version prov by hal
        !          138365: @
        !          138366: 
        !          138367: 
        !          138368: 
        !          138369: 1.1
        !          138370: log
        !          138371: @Initial revision
        !          138372: @
        !          138373: text
        !          138374: @:
        !          138375: : 'Raw (fast) Serial Line COM1 (System V Compatible)'
        !          138376: :
        !          138377: UNDEF="${UNDEF} -u rs0con_ lib/rs.a"
        !          138378: PATCH="${PATCH} drvl_+50=rs0con_"
        !          138379: :
        !          138380: if [ -d "${DEV-/dev}" ]
        !          138381: then
        !          138382:        umask 0111
        !          138383:        /etc/mknod -f ${DEV-/dev}/rs0  c 5 0    || exit 1
        !          138384:        /etc/mknod -f ${DEV-/dev}/rs0r c 5 128  || exit 1
        !          138385: fi
        !          138386: @
        !          138387: 0707070064030056051004440000030000030000011777770507310756500005100000001007/newbits/kernel/USRSYS/confdrv/RCS/rs1,vhead     1.1;
        !          138388: branch   ;
        !          138389: access   ;
        !          138390: symbols  ;
        !          138391: locks    bin:1.1; strict;
        !          138392: comment  @# @;
        !          138393: 
        !          138394: 
        !          138395: 1.1
        !          138396: date     91.07.15.14.11.40;  author bin;  state Exp;
        !          138397: branches ;
        !          138398: next     ;
        !          138399: 
        !          138400: 
        !          138401: desc
        !          138402: @initial version prov by hal
        !          138403: @
        !          138404: 
        !          138405: 
        !          138406: 
        !          138407: 1.1
        !          138408: log
        !          138409: @Initial revision
        !          138410: @
        !          138411: text
        !          138412: @:
        !          138413: : 'Raw (fast) Serial Line COM2 (System V Compatible)'
        !          138414: :
        !          138415: UNDEF="${UNDEF} -u rs1con_ lib/rs.a"
        !          138416: PATCH="${PATCH} drvl_+60=rs1con_"
        !          138417: :
        !          138418: if [ -d "${DEV-/dev}" ]
        !          138419: then
        !          138420:        umask 0111
        !          138421:        /etc/mknod -f ${DEV-/dev}/rs1  c 6 0    || exit 1
        !          138422:        /etc/mknod -f ${DEV-/dev}/rs1r c 6 128  || exit 1
        !          138423: fi
        !          138424: @
        !          138425: 0707070064030074571004440000030000030000011777770507310756600005000000003633/newbits/kernel/USRSYS/confdrv/RCS/sd,vhead     1.1;
        !          138426: branch   ;
        !          138427: access   ;
        !          138428: symbols  ;
        !          138429: locks    bin:1.1; strict;
        !          138430: comment  @# @;
        !          138431: 
        !          138432: 
        !          138433: 1.1
        !          138434: date     91.07.15.14.11.41;  author bin;  state Exp;
        !          138435: branches ;
        !          138436: next     ;
        !          138437: 
        !          138438: 
        !          138439: desc
        !          138440: @initial version prov by hal
        !          138441: @
        !          138442: 
        !          138443: 
        !          138444: 
        !          138445: 1.1
        !          138446: log
        !          138447: @Initial revision
        !          138448: @
        !          138449: text
        !          138450: @:
        !          138451: : Hard Disk on Adaptec AHA154x series host adaptor
        !          138452: :
        !          138453: MAJOR=13
        !          138454: 
        !          138455: case "${ARG}" in
        !          138456: *1?)   HD_TYPE=sd1 ;;
        !          138457: *)     HD_TYPE=sd0 ;;
        !          138458: esac
        !          138459: :
        !          138460: :      needed by config
        !          138461: :
        !          138462: UNDEF="${UNDEF} -u sdcon_ lib/aha154x.a"
        !          138463: PATCH="${PATCH} drvl_+130=sdcon_"
        !          138464: 
        !          138465: case ${ARG} in
        !          138466: sd0a)  MAKEDEV="makedev(13,0)" ;;
        !          138467: sd0b)  MAKEDEV="makedev(13,1)" ;;
        !          138468: sd0c)  MAKEDEV="makedev(13,2)" ;;
        !          138469: sd0d)  MAKEDEV="makedev(13,3)" ;;
        !          138470: sd1a)  MAKEDEV="makedev(13,16)" ;;
        !          138471: sd1b)  MAKEDEV="makedev(13,17)" ;;
        !          138472: sd1c)  MAKEDEV="makedev(13,18)" ;;
        !          138473: sd1d)  MAKEDEV="makedev(13,19)" ;;
        !          138474: sd)
        !          138475:        ;;
        !          138476: aha154x)
        !          138477:        ;;
        !          138478: *)
        !          138479:        /bin/echo "invalid argument: ${ARG}"
        !          138480:        exit 1
        !          138481:        ;;
        !          138482: esac
        !          138483: 
        !          138484: :
        !          138485: : needed for both build and config
        !          138486: :
        !          138487: if [ -d "${DEV-/dev}" ]
        !          138488: then
        !          138489:        umask 077
        !          138490:        /etc/mknod -f ${DEV-/dev}/sd0a  b 13 0          || exit 1
        !          138491:        /etc/mknod -f ${DEV-/dev}/sd0b  b 13 1          || exit 1
        !          138492:        /etc/mknod -f ${DEV-/dev}/sd0c  b 13 2          || exit 1
        !          138493:        /etc/mknod -f ${DEV-/dev}/sd0d  b 13 3          || exit 1
        !          138494:        /etc/mknod -f ${DEV-/dev}/sd0x  b 13 128        || exit 1
        !          138495:        /etc/mknod -f ${DEV-/dev}/rsd0a c 13 0          || exit 1
        !          138496:        /etc/mknod -f ${DEV-/dev}/rsd0b c 13 1          || exit 1
        !          138497:        /etc/mknod -f ${DEV-/dev}/rsd0c c 13 2          || exit 1
        !          138498:        /etc/mknod -f ${DEV-/dev}/rsd0d c 13 3          || exit 1
        !          138499:        /etc/mknod -f ${DEV-/dev}/rsd0x c 13 128        || exit 1
        !          138500:        /etc/mknod -f ${DEV-/dev}/sd1a  b 13 16         || exit 1
        !          138501:        /etc/mknod -f ${DEV-/dev}/sd1b  b 13 17         || exit 1
        !          138502:        /etc/mknod -f ${DEV-/dev}/sd1c  b 13 18         || exit 1
        !          138503:        /etc/mknod -f ${DEV-/dev}/sd1d  b 13 19         || exit 1
        !          138504:        /etc/mknod -f ${DEV-/dev}/sd1x  b 13 144        || exit 1
        !          138505:        /etc/mknod -f ${DEV-/dev}/rsd1a c 13 16         || exit 1
        !          138506:        /etc/mknod -f ${DEV-/dev}/rsd1b c 13 17         || exit 1
        !          138507:        /etc/mknod -f ${DEV-/dev}/rsd1c c 13 18         || exit 1
        !          138508:        /etc/mknod -f ${DEV-/dev}/rsd1d c 13 19         || exit 1
        !          138509:        /etc/mknod -f ${DEV-/dev}/rsd1x c 13 144        || exit 1
        !          138510: fi
        !          138511: @
        !          138512: 0707070064030111411004440000030000030000011777770507310756600005100000000702/newbits/kernel/USRSYS/confdrv/RCS/sem,vhead     1.1;
        !          138513: branch   ;
        !          138514: access   ;
        !          138515: symbols  ;
        !          138516: locks    bin:1.1; strict;
        !          138517: comment  @# @;
        !          138518: 
        !          138519: 
        !          138520: 1.1
        !          138521: date     91.07.15.14.11.42;  author bin;  state Exp;
        !          138522: branches ;
        !          138523: next     ;
        !          138524: 
        !          138525: 
        !          138526: desc
        !          138527: @initial version prov by hal
        !          138528: @
        !          138529: 
        !          138530: 
        !          138531: 
        !          138532: 1.1
        !          138533: log
        !          138534: @Initial revision
        !          138535: @
        !          138536: text
        !          138537: @:
        !          138538: : System V Compatible Semaphores
        !          138539: :
        !          138540: UNDEF="${UNDEF} -u semcon_ lib/sem.a"
        !          138541: PATCH="${PATCH} drvl_+230=semcon_"
        !          138542: :
        !          138543: if [ -d "${DEV-/dev}" ]
        !          138544: then
        !          138545:        umask 0333
        !          138546:        /etc/mknod -f ${DEV-/dev}/sem c 23 0 || exit 1
        !          138547: fi
        !          138548: @
        !          138549: 0707070064030074501004440000030000030000011777770507310756600005100000000701/newbits/kernel/USRSYS/confdrv/RCS/shm,vhead     1.1;
        !          138550: branch   ;
        !          138551: access   ;
        !          138552: symbols  ;
        !          138553: locks    bin:1.1; strict;
        !          138554: comment  @# @;
        !          138555: 
        !          138556: 
        !          138557: 1.1
        !          138558: date     91.07.15.14.11.43;  author bin;  state Exp;
        !          138559: branches ;
        !          138560: next     ;
        !          138561: 
        !          138562: 
        !          138563: desc
        !          138564: @initial version prov by hal
        !          138565: @
        !          138566: 
        !          138567: 
        !          138568: 
        !          138569: 1.1
        !          138570: log
        !          138571: @Initial revision
        !          138572: @
        !          138573: text
        !          138574: @:
        !          138575: : System V Subset Shared Memory
        !          138576: :
        !          138577: UNDEF="${UNDEF} -u shmcon_ lib/shm.a"
        !          138578: PATCH="${PATCH} drvl_+240=shmcon_"
        !          138579: :
        !          138580: if [ -d "${DEV-/dev}" ]
        !          138581: then
        !          138582:        umask 0111
        !          138583:        /etc/mknod -f ${DEV-/dev}/shm c 24 0 || exit 1
        !          138584: fi
        !          138585: @
        !          138586: 0707070064030074461004440000030000030000011777770507310756600005000000003617/newbits/kernel/USRSYS/confdrv/RCS/ss,vhead     1.1;
        !          138587: branch   ;
        !          138588: access   ;
        !          138589: symbols  ;
        !          138590: locks    bin:1.1; strict;
        !          138591: comment  @# @;
        !          138592: 
        !          138593: 
        !          138594: 1.1
        !          138595: date     91.07.15.14.11.44;  author bin;  state Exp;
        !          138596: branches ;
        !          138597: next     ;
        !          138598: 
        !          138599: 
        !          138600: desc
        !          138601: @initial version prov by hal
        !          138602: @
        !          138603: 
        !          138604: 
        !          138605: 
        !          138606: 1.1
        !          138607: log
        !          138608: @Initial revision
        !          138609: @
        !          138610: text
        !          138611: @:
        !          138612: : Hard Disk on Seagate ST01/ST02 series SCSI controller.
        !          138613: :
        !          138614: MAJOR=13
        !          138615: 
        !          138616: case "${ARG}" in
        !          138617: *1?)   HD_TYPE=ss1 ;;
        !          138618: *)     HD_TYPE=ss0 ;;
        !          138619: esac
        !          138620: :
        !          138621: :      needed by config
        !          138622: :
        !          138623: UNDEF="${UNDEF} -u sscon_ lib/ss.a"
        !          138624: PATCH="${PATCH} drvl_+130=sscon_"
        !          138625: 
        !          138626: case ${ARG} in
        !          138627: ss0a)  MAKEDEV="makedev(13,0)" ;;
        !          138628: ss0b)  MAKEDEV="makedev(13,1)" ;;
        !          138629: ss0c)  MAKEDEV="makedev(13,2)" ;;
        !          138630: ss0d)  MAKEDEV="makedev(13,3)" ;;
        !          138631: ss1a)  MAKEDEV="makedev(13,16)" ;;
        !          138632: ss1b)  MAKEDEV="makedev(13,17)" ;;
        !          138633: ss1c)  MAKEDEV="makedev(13,18)" ;;
        !          138634: ss1d)  MAKEDEV="makedev(13,19)" ;;
        !          138635: ss)
        !          138636:        ;;
        !          138637: *)
        !          138638:        /bin/echo "invalid argument: ${ARG}"
        !          138639:        exit 1
        !          138640:        ;;
        !          138641: esac
        !          138642: 
        !          138643: :
        !          138644: : needed for both build and config
        !          138645: :
        !          138646: if [ -d "${DEV-/dev}" ]
        !          138647: then
        !          138648:        umask 077
        !          138649:        /etc/mknod -f ${DEV-/dev}/ss0a  b 13 0          || exit 1
        !          138650:        /etc/mknod -f ${DEV-/dev}/ss0b  b 13 1          || exit 1
        !          138651:        /etc/mknod -f ${DEV-/dev}/ss0c  b 13 2          || exit 1
        !          138652:        /etc/mknod -f ${DEV-/dev}/ss0d  b 13 3          || exit 1
        !          138653:        /etc/mknod -f ${DEV-/dev}/ss0x  b 13 128        || exit 1
        !          138654:        /etc/mknod -f ${DEV-/dev}/rss0a c 13 0          || exit 1
        !          138655:        /etc/mknod -f ${DEV-/dev}/rss0b c 13 1          || exit 1
        !          138656:        /etc/mknod -f ${DEV-/dev}/rss0c c 13 2          || exit 1
        !          138657:        /etc/mknod -f ${DEV-/dev}/rss0d c 13 3          || exit 1
        !          138658:        /etc/mknod -f ${DEV-/dev}/rss0x c 13 128        || exit 1
        !          138659:        /etc/mknod -f ${DEV-/dev}/ss1a  b 13 16         || exit 1
        !          138660:        /etc/mknod -f ${DEV-/dev}/ss1b  b 13 17         || exit 1
        !          138661:        /etc/mknod -f ${DEV-/dev}/ss1c  b 13 18         || exit 1
        !          138662:        /etc/mknod -f ${DEV-/dev}/ss1d  b 13 19         || exit 1
        !          138663:        /etc/mknod -f ${DEV-/dev}/ss1x  b 13 144        || exit 1
        !          138664:        /etc/mknod -f ${DEV-/dev}/rss1a c 13 16         || exit 1
        !          138665:        /etc/mknod -f ${DEV-/dev}/rss1b c 13 17         || exit 1
        !          138666:        /etc/mknod -f ${DEV-/dev}/rss1c c 13 18         || exit 1
        !          138667:        /etc/mknod -f ${DEV-/dev}/rss1d c 13 19         || exit 1
        !          138668:        /etc/mknod -f ${DEV-/dev}/rss1x c 13 144        || exit 1
        !          138669: fi
        !          138670: @
        !          138671: 0707070064030073201004440000030000030000011777770507310756700005000000001502/newbits/kernel/USRSYS/confdrv/RCS/st,vhead     1.1;
        !          138672: branch   ;
        !          138673: access   ;
        !          138674: symbols  ;
        !          138675: locks    bin:1.1; strict;
        !          138676: comment  @# @;
        !          138677: 
        !          138678: 
        !          138679: 1.1
        !          138680: date     91.07.15.14.11.45;  author bin;  state Exp;
        !          138681: branches ;
        !          138682: next     ;
        !          138683: 
        !          138684: 
        !          138685: desc
        !          138686: @initial version prov by hal
        !          138687: @
        !          138688: 
        !          138689: 
        !          138690: 
        !          138691: 1.1
        !          138692: log
        !          138693: @Initial revision
        !          138694: @
        !          138695: text
        !          138696: @:
        !          138697: : Archive SC-400 Streaming Tape Drive.
        !          138698: :
        !          138699: :      Minor device 0 allocates a maximum sized read/write cache [up to 256k].
        !          138700: :      Minor device n [1..127] allocates a n Kbyte sized read/write cache.
        !          138701: :      Adding 128 to one of the above minor devices inhibits rewind on close.
        !          138702: :
        !          138703: UNDEF="${UNDEF} -u stcon_ lib/st.a"
        !          138704: PATCH="${PATCH} drvl_+120=stcon_"
        !          138705: 
        !          138706: if [ -d "${DEV-/dev}" ]
        !          138707: then
        !          138708:        umask 077
        !          138709:        /etc/mknod -f ${DEV-/dev}/rst    c 12   0       || exit 1
        !          138710:        /etc/mknod -f ${DEV-/dev}/rst32  c 12  32       || exit 1
        !          138711:        /etc/mknod -f ${DEV-/dev}/rst64  c 12  64       || exit 1
        !          138712:        /etc/mknod -f ${DEV-/dev}/nrst   c 12 128       || exit 1
        !          138713: fi
        !          138714: @
        !          138715: 0707070064030073241004440000030000030000011777770507310756700005000000001131/newbits/kernel/USRSYS/confdrv/RCS/tn,vhead     1.1;
        !          138716: branch   ;
        !          138717: access   ;
        !          138718: symbols  ;
        !          138719: locks    bin:1.1; strict;
        !          138720: comment  @# @;
        !          138721: 
        !          138722: 
        !          138723: 1.1
        !          138724: date     91.07.15.14.11.45;  author bin;  state Exp;
        !          138725: branches ;
        !          138726: next     ;
        !          138727: 
        !          138728: 
        !          138729: desc
        !          138730: @initial version prov by hal
        !          138731: @
        !          138732: 
        !          138733: 
        !          138734: 
        !          138735: 1.1
        !          138736: log
        !          138737: @Initial revision
        !          138738: @
        !          138739: text
        !          138740: @:
        !          138741: : 'Tiac PC-234/6 ARCNET LAN boards [0..3]'
        !          138742: :
        !          138743: UNDEF="${UNDEF} -u tncon_ lib/tn.a"
        !          138744: PATCH="${PATCH} drvl_+200=tncon_"
        !          138745: :
        !          138746: if [ -d "${DEV-/dev}" ]
        !          138747: then
        !          138748:        umask 0111
        !          138749:        /etc/mknod -f ${DEV-/dev}/tn0 c 20 0 || exit 1
        !          138750:        /etc/mknod -f ${DEV-/dev}/tn1 c 20 1 || exit 1
        !          138751:        /etc/mknod -f ${DEV-/dev}/tn2 c 20 2 || exit 1
        !          138752:        /etc/mknod -f ${DEV-/dev}/tn3 c 20 3 || exit 1
        !          138753: fi
        !          138754: @
        !          138755: 0707070064030112661004440000030000030000011777770507310757000004300000000353/newbits/kernel/USRSYS/confdrv/gkb:
        !          138756: : Keyboard part of console device
        !          138757: : Fixed, German keyboard table.
        !          138758: :
        !          138759: UNDEF="${UNDEF} -u iscon_ lib/gkb.a"
        !          138760: PATCH="${PATCH} drvl_+20=iscon_"
        !          138761: if [ -d "${DEV-/dev}" ]
        !          138762: then
        !          138763:        umask 0111
        !          138764:        /etc/mknod -f ${DEV-/dev}/console c 2 0 || exit 1
        !          138765: fi
        !          138766: 0707070064030110701004440000030000030000011777770507310757000004200000000344/newbits/kernel/USRSYS/confdrv/kb:
        !          138767: : Keyboard part of console device
        !          138768: : Fixed keyboard table.
        !          138769: :
        !          138770: UNDEF="${UNDEF} -u iscon_ lib/kb.a"
        !          138771: PATCH="${PATCH} drvl_+20=iscon_"
        !          138772: :
        !          138773: if [ -d "${DEV-/dev}" ]
        !          138774: then
        !          138775:        umask 0111
        !          138776:        /etc/mknod -f ${DEV-/dev}/console c 2 0 || exit 1
        !          138777: fi
        !          138778: 0707070064030110671004440000030000030000011777770507310757000004300000000346/newbits/kernel/USRSYS/confdrv/nkb:
        !          138779: : Keyboard part of console device
        !          138780: : Loadable keyboard table.
        !          138781: :
        !          138782: UNDEF="${UNDEF} -u iscon_ lib/nkb.a"
        !          138783: PATCH="${PATCH} drvl_+20=iscon_"
        !          138784: if [ -d "${DEV-/dev}" ]
        !          138785: then
        !          138786:        umask 0111
        !          138787:        /etc/mknod -f ${DEV-/dev}/console c 2 0 || exit 1
        !          138788: fi
        !          138789: 0707070064030064260407770000030000030000011777770507310757000003700000000000/newbits/kernel/USRSYS/objects0707070064030114400407550000030000030000011777770507310757000003300000000000/newbits/kernel/USRSYS/doc0707070064030114101004440000030000030000011777770507310757000004300000000110/newbits/kernel/USRSYS/doc/aha154xaha154x               - Adaptec AHA-154x SCSI H/A (specify: root=sd0a ... root=sd1d)
        !          138790: 0707070064030114071004440000030000030000011777770507310757000003600000000055/newbits/kernel/USRSYS/doc/alal0, al1     - Serial lines COM1/COM3, COM2/COM4
        !          138791: 0707070064030114061004440000030000030000011777770507310757000003600000000066/newbits/kernel/USRSYS/doc/atat           - AT hard disk (specify: root=at0a ... root=at1d)
        !          138792: 0707070064030114051004440000030000030000011777770507310757000003700000000102/newbits/kernel/USRSYS/doc/atiati         - Array Technologies Inc 'Graphics Solution' Display Adapter
        !          138793: 0707070064030114041004440000030000030000011777770507310757000003600000000043/newbits/kernel/USRSYS/doc/flfl           - AT floppy driver (root=fha0)
        !          138794: 0707070064030114031004440000030000030000011777770507310757000003600000000070/newbits/kernel/USRSYS/doc/gmgm           - Tecmar Graphics Master (640x400) graphics display
        !          138795: 0707070064030114021004440000030000030000011777770507310757100003600000000060/newbits/kernel/USRSYS/doc/grgr           - IBM Color card (640x200) graphics display
        !          138796: 0707070064030114011004440000030000030000011777770507310757100003600000000054/newbits/kernel/USRSYS/doc/hshs           - Generic polled multi-line serial card
        !          138797: 0707070064030114001004440000030000030000011777770507310757100003600000000057/newbits/kernel/USRSYS/doc/lplp           - Parallel line printer (LPT1, LPT2, LPT3)
        !          138798: 0707070064030113771004440000030000030000011777770507310757100003600000000041/newbits/kernel/USRSYS/doc/mmmm           - Memory Mapped (Text) Video
        !          138799: 0707070064030113761004440000030000030000011777770507310757100003600000000032/newbits/kernel/USRSYS/doc/msms           - Microsoft bus mouse
        !          138800: 0707070064030113751004440000030000030000011777770507310757100003700000000045/newbits/kernel/USRSYS/doc/msgmsg         - System V compatible messaging
        !          138801: 0707070064030113741004440000030000030000011777770507310757100003600000000024/newbits/kernel/USRSYS/doc/rmrm           - Dual RAM disk
        !          138802: 0707070064030113731004440000030000030000011777770507310757100003600000000020/newbits/kernel/USRSYS/doc/rprp           - Ram pipes
        !          138803: 0707070064030113721004440000030000030000011777770507310757100003600000000054/newbits/kernel/USRSYS/doc/rsrs0, rs1     - Fast raw serial lines COM1, COM2
        !          138804: 0707070064030113711004440000030000030000011777770507310757100003700000000046/newbits/kernel/USRSYS/doc/semsem         - System V compatible semaphores
        !          138805: 0707070064030113701004440000030000030000011777770507310757100003700000000045/newbits/kernel/USRSYS/doc/shmshm         - System V subset shared memory
        !          138806: 0707070064030113671004440000030000030000011777770507310757200003600000000052/newbits/kernel/USRSYS/doc/stst           - Archive SC-400 streaming tape drive
        !          138807: 0707070064030113661004440000030000030000011777770507310757200004000000000046/newbits/kernel/USRSYS/doc/swapswap               - Swap tasks in and out of core
        !          138808: 0707070064030113651004440000030000030000011777770507310757200003600000000050/newbits/kernel/USRSYS/doc/tntn           - Tiac PC-234/6/8 ARCNET LAN Driver
        !          138809: 0707070064030114130407550000030000030000011777770507310757200003700000000000/newbits/kernel/USRSYS/doc/RCS0707070064030114111004440000030000030000011777770507310757200005100000000476/newbits/kernel/USRSYS/doc/RCS/aha154x,vhead     1.1;
        !          138810: branch   ;
        !          138811: access   ;
        !          138812: symbols  ;
        !          138813: locks    bin:1.1; strict;
        !          138814: comment  @# @;
        !          138815: 
        !          138816: 
        !          138817: 1.1
        !          138818: date     91.07.15.14.18.35;  author bin;  state Exp;
        !          138819: branches ;
        !          138820: next     ;
        !          138821: 
        !          138822: 
        !          138823: desc
        !          138824: @initial version prov by hal
        !          138825: @
        !          138826: 
        !          138827: 
        !          138828: 
        !          138829: 1.1
        !          138830: log
        !          138831: @Initial revision
        !          138832: @
        !          138833: text
        !          138834: @aha154x               - Adaptec AHA-154x SCSI H/A (specify: root=sd0a ... root=sd1d)
        !          138835: @
        !          138836: 0707070064030114371004440000030000030000011777770507310757200004400000000443/newbits/kernel/USRSYS/doc/RCS/al,vhead     1.1;
        !          138837: branch   ;
        !          138838: access   ;
        !          138839: symbols  ;
        !          138840: locks    bin:1.1; strict;
        !          138841: comment  @# @;
        !          138842: 
        !          138843: 
        !          138844: 1.1
        !          138845: date     91.07.15.14.18.36;  author bin;  state Exp;
        !          138846: branches ;
        !          138847: next     ;
        !          138848: 
        !          138849: 
        !          138850: desc
        !          138851: @initial version prov by hal
        !          138852: @
        !          138853: 
        !          138854: 
        !          138855: 
        !          138856: 1.1
        !          138857: log
        !          138858: @Initial revision
        !          138859: @
        !          138860: text
        !          138861: @al0, al1      - Serial lines COM1/COM3, COM2/COM4
        !          138862: @
        !          138863: 0707070064030114361004440000030000030000011777770507310757200004400000000454/newbits/kernel/USRSYS/doc/RCS/at,vhead     1.1;
        !          138864: branch   ;
        !          138865: access   ;
        !          138866: symbols  ;
        !          138867: locks    bin:1.1; strict;
        !          138868: comment  @# @;
        !          138869: 
        !          138870: 
        !          138871: 1.1
        !          138872: date     91.07.15.14.18.37;  author bin;  state Exp;
        !          138873: branches ;
        !          138874: next     ;
        !          138875: 
        !          138876: 
        !          138877: desc
        !          138878: @initial version prov by hal
        !          138879: @
        !          138880: 
        !          138881: 
        !          138882: 
        !          138883: 1.1
        !          138884: log
        !          138885: @Initial revision
        !          138886: @
        !          138887: text
        !          138888: @at            - AT hard disk (specify: root=at0a ... root=at1d)
        !          138889: @
        !          138890: 0707070064030114351004440000030000030000011777770507310757200004500000000470/newbits/kernel/USRSYS/doc/RCS/ati,vhead     1.1;
        !          138891: branch   ;
        !          138892: access   ;
        !          138893: symbols  ;
        !          138894: locks    bin:1.1; strict;
        !          138895: comment  @# @;
        !          138896: 
        !          138897: 
        !          138898: 1.1
        !          138899: date     91.07.15.14.18.37;  author bin;  state Exp;
        !          138900: branches ;
        !          138901: next     ;
        !          138902: 
        !          138903: 
        !          138904: desc
        !          138905: @initial version prov by hal
        !          138906: @
        !          138907: 
        !          138908: 
        !          138909: 
        !          138910: 1.1
        !          138911: log
        !          138912: @Initial revision
        !          138913: @
        !          138914: text
        !          138915: @ati           - Array Technologies Inc 'Graphics Solution' Display Adapter
        !          138916: @
        !          138917: 0707070064030114341004440000030000030000011777770507310757200004400000000431/newbits/kernel/USRSYS/doc/RCS/fl,vhead     1.1;
        !          138918: branch   ;
        !          138919: access   ;
        !          138920: symbols  ;
        !          138921: locks    bin:1.1; strict;
        !          138922: comment  @# @;
        !          138923: 
        !          138924: 
        !          138925: 1.1
        !          138926: date     91.07.15.14.18.38;  author bin;  state Exp;
        !          138927: branches ;
        !          138928: next     ;
        !          138929: 
        !          138930: 
        !          138931: desc
        !          138932: @initial version prov by hal
        !          138933: @
        !          138934: 
        !          138935: 
        !          138936: 
        !          138937: 1.1
        !          138938: log
        !          138939: @Initial revision
        !          138940: @
        !          138941: text
        !          138942: @fl            - AT floppy driver (root=fha0)
        !          138943: @
        !          138944: 0707070064030114331004440000030000030000011777770507310757200004400000000456/newbits/kernel/USRSYS/doc/RCS/gm,vhead     1.1;
        !          138945: branch   ;
        !          138946: access   ;
        !          138947: symbols  ;
        !          138948: locks    bin:1.1; strict;
        !          138949: comment  @# @;
        !          138950: 
        !          138951: 
        !          138952: 1.1
        !          138953: date     91.07.15.14.18.39;  author bin;  state Exp;
        !          138954: branches ;
        !          138955: next     ;
        !          138956: 
        !          138957: 
        !          138958: desc
        !          138959: @initial version prov by hal
        !          138960: @
        !          138961: 
        !          138962: 
        !          138963: 
        !          138964: 1.1
        !          138965: log
        !          138966: @Initial revision
        !          138967: @
        !          138968: text
        !          138969: @gm            - Tecmar Graphics Master (640x400) graphics display
        !          138970: @
        !          138971: 0707070064030114321004440000030000030000011777770507310757300004400000000446/newbits/kernel/USRSYS/doc/RCS/gr,vhead     1.1;
        !          138972: branch   ;
        !          138973: access   ;
        !          138974: symbols  ;
        !          138975: locks    bin:1.1; strict;
        !          138976: comment  @# @;
        !          138977: 
        !          138978: 
        !          138979: 1.1
        !          138980: date     91.07.15.14.18.39;  author bin;  state Exp;
        !          138981: branches ;
        !          138982: next     ;
        !          138983: 
        !          138984: 
        !          138985: desc
        !          138986: @initial version prov by hal
        !          138987: @
        !          138988: 
        !          138989: 
        !          138990: 
        !          138991: 1.1
        !          138992: log
        !          138993: @Initial revision
        !          138994: @
        !          138995: text
        !          138996: @gr            - IBM Color card (640x200) graphics display
        !          138997: @
        !          138998: 0707070064030114311004440000030000030000011777770507310757300004400000000442/newbits/kernel/USRSYS/doc/RCS/hs,vhead     1.1;
        !          138999: branch   ;
        !          139000: access   ;
        !          139001: symbols  ;
        !          139002: locks    bin:1.1; strict;
        !          139003: comment  @# @;
        !          139004: 
        !          139005: 
        !          139006: 1.1
        !          139007: date     91.07.15.14.18.40;  author bin;  state Exp;
        !          139008: branches ;
        !          139009: next     ;
        !          139010: 
        !          139011: 
        !          139012: desc
        !          139013: @initial version prov by hal
        !          139014: @
        !          139015: 
        !          139016: 
        !          139017: 
        !          139018: 1.1
        !          139019: log
        !          139020: @Initial revision
        !          139021: @
        !          139022: text
        !          139023: @hs            - Generic polled multi-line serial card
        !          139024: @
        !          139025: 0707070064030114301004440000030000030000011777770507310757300004400000000445/newbits/kernel/USRSYS/doc/RCS/lp,vhead     1.1;
        !          139026: branch   ;
        !          139027: access   ;
        !          139028: symbols  ;
        !          139029: locks    bin:1.1; strict;
        !          139030: comment  @# @;
        !          139031: 
        !          139032: 
        !          139033: 1.1
        !          139034: date     91.07.15.14.18.40;  author bin;  state Exp;
        !          139035: branches ;
        !          139036: next     ;
        !          139037: 
        !          139038: 
        !          139039: desc
        !          139040: @initial version prov by hal
        !          139041: @
        !          139042: 
        !          139043: 
        !          139044: 
        !          139045: 1.1
        !          139046: log
        !          139047: @Initial revision
        !          139048: @
        !          139049: text
        !          139050: @lp            - Parallel line printer (LPT1, LPT2, LPT3)
        !          139051: @
        !          139052: 0707070064030114271004440000030000030000011777770507310757300004400000000427/newbits/kernel/USRSYS/doc/RCS/mm,vhead     1.1;
        !          139053: branch   ;
        !          139054: access   ;
        !          139055: symbols  ;
        !          139056: locks    bin:1.1; strict;
        !          139057: comment  @# @;
        !          139058: 
        !          139059: 
        !          139060: 1.1
        !          139061: date     91.07.15.14.18.41;  author bin;  state Exp;
        !          139062: branches ;
        !          139063: next     ;
        !          139064: 
        !          139065: 
        !          139066: desc
        !          139067: @initial version prov by hal
        !          139068: @
        !          139069: 
        !          139070: 
        !          139071: 
        !          139072: 1.1
        !          139073: log
        !          139074: @Initial revision
        !          139075: @
        !          139076: text
        !          139077: @mm            - Memory Mapped (Text) Video
        !          139078: @
        !          139079: 0707070064030114261004440000030000030000011777770507310757300004400000000420/newbits/kernel/USRSYS/doc/RCS/ms,vhead     1.1;
        !          139080: branch   ;
        !          139081: access   ;
        !          139082: symbols  ;
        !          139083: locks    bin:1.1; strict;
        !          139084: comment  @# @;
        !          139085: 
        !          139086: 
        !          139087: 1.1
        !          139088: date     91.07.15.14.18.42;  author bin;  state Exp;
        !          139089: branches ;
        !          139090: next     ;
        !          139091: 
        !          139092: 
        !          139093: desc
        !          139094: @initial version prov by hal
        !          139095: @
        !          139096: 
        !          139097: 
        !          139098: 
        !          139099: 1.1
        !          139100: log
        !          139101: @Initial revision
        !          139102: @
        !          139103: text
        !          139104: @ms            - Microsoft bus mouse
        !          139105: @
        !          139106: 0707070064030114251004440000030000030000011777770507310757300004500000000433/newbits/kernel/USRSYS/doc/RCS/msg,vhead     1.1;
        !          139107: branch   ;
        !          139108: access   ;
        !          139109: symbols  ;
        !          139110: locks    bin:1.1; strict;
        !          139111: comment  @# @;
        !          139112: 
        !          139113: 
        !          139114: 1.1
        !          139115: date     91.07.15.14.18.42;  author bin;  state Exp;
        !          139116: branches ;
        !          139117: next     ;
        !          139118: 
        !          139119: 
        !          139120: desc
        !          139121: @initial version prov by hal
        !          139122: @
        !          139123: 
        !          139124: 
        !          139125: 
        !          139126: 1.1
        !          139127: log
        !          139128: @Initial revision
        !          139129: @
        !          139130: text
        !          139131: @msg           - System V compatible messaging
        !          139132: @
        !          139133: 0707070064030114241004440000030000030000011777770507310757300004400000000412/newbits/kernel/USRSYS/doc/RCS/rm,vhead     1.1;
        !          139134: branch   ;
        !          139135: access   ;
        !          139136: symbols  ;
        !          139137: locks    bin:1.1; strict;
        !          139138: comment  @# @;
        !          139139: 
        !          139140: 
        !          139141: 1.1
        !          139142: date     91.07.15.14.18.43;  author bin;  state Exp;
        !          139143: branches ;
        !          139144: next     ;
        !          139145: 
        !          139146: 
        !          139147: desc
        !          139148: @initial version prov by hal
        !          139149: @
        !          139150: 
        !          139151: 
        !          139152: 
        !          139153: 1.1
        !          139154: log
        !          139155: @Initial revision
        !          139156: @
        !          139157: text
        !          139158: @rm            - Dual RAM disk
        !          139159: @
        !          139160: 0707070064030114231004440000030000030000011777770507310757300004400000000406/newbits/kernel/USRSYS/doc/RCS/rp,vhead     1.1;
        !          139161: branch   ;
        !          139162: access   ;
        !          139163: symbols  ;
        !          139164: locks    bin:1.1; strict;
        !          139165: comment  @# @;
        !          139166: 
        !          139167: 
        !          139168: 1.1
        !          139169: date     91.07.15.14.18.44;  author bin;  state Exp;
        !          139170: branches ;
        !          139171: next     ;
        !          139172: 
        !          139173: 
        !          139174: desc
        !          139175: @initial version prov by hal
        !          139176: @
        !          139177: 
        !          139178: 
        !          139179: 
        !          139180: 1.1
        !          139181: log
        !          139182: @Initial revision
        !          139183: @
        !          139184: text
        !          139185: @rp            - Ram pipes
        !          139186: @
        !          139187: 0707070064030114221004440000030000030000011777770507310757300004400000000442/newbits/kernel/USRSYS/doc/RCS/rs,vhead     1.1;
        !          139188: branch   ;
        !          139189: access   ;
        !          139190: symbols  ;
        !          139191: locks    bin:1.1; strict;
        !          139192: comment  @# @;
        !          139193: 
        !          139194: 
        !          139195: 1.1
        !          139196: date     91.07.15.14.18.44;  author bin;  state Exp;
        !          139197: branches ;
        !          139198: next     ;
        !          139199: 
        !          139200: 
        !          139201: desc
        !          139202: @initial version prov by hal
        !          139203: @
        !          139204: 
        !          139205: 
        !          139206: 
        !          139207: 1.1
        !          139208: log
        !          139209: @Initial revision
        !          139210: @
        !          139211: text
        !          139212: @rs0, rs1      - Fast raw serial lines COM1, COM2
        !          139213: @
        !          139214: 0707070064030114211004440000030000030000011777770507310757300004500000000434/newbits/kernel/USRSYS/doc/RCS/sem,vhead     1.1;
        !          139215: branch   ;
        !          139216: access   ;
        !          139217: symbols  ;
        !          139218: locks    bin:1.1; strict;
        !          139219: comment  @# @;
        !          139220: 
        !          139221: 
        !          139222: 1.1
        !          139223: date     91.07.15.14.18.45;  author bin;  state Exp;
        !          139224: branches ;
        !          139225: next     ;
        !          139226: 
        !          139227: 
        !          139228: desc
        !          139229: @initial version prov by hal
        !          139230: @
        !          139231: 
        !          139232: 
        !          139233: 
        !          139234: 1.1
        !          139235: log
        !          139236: @Initial revision
        !          139237: @
        !          139238: text
        !          139239: @sem           - System V compatible semaphores
        !          139240: @
        !          139241: 0707070064030114201004440000030000030000011777770507310757400004500000000433/newbits/kernel/USRSYS/doc/RCS/shm,vhead     1.1;
        !          139242: branch   ;
        !          139243: access   ;
        !          139244: symbols  ;
        !          139245: locks    bin:1.1; strict;
        !          139246: comment  @# @;
        !          139247: 
        !          139248: 
        !          139249: 1.1
        !          139250: date     91.07.15.14.18.45;  author bin;  state Exp;
        !          139251: branches ;
        !          139252: next     ;
        !          139253: 
        !          139254: 
        !          139255: desc
        !          139256: @initial version prov by hal
        !          139257: @
        !          139258: 
        !          139259: 
        !          139260: 
        !          139261: 1.1
        !          139262: log
        !          139263: @Initial revision
        !          139264: @
        !          139265: text
        !          139266: @shm           - System V subset shared memory
        !          139267: @
        !          139268: 0707070064030114171004440000030000030000011777770507310757400004400000000440/newbits/kernel/USRSYS/doc/RCS/st,vhead     1.1;
        !          139269: branch   ;
        !          139270: access   ;
        !          139271: symbols  ;
        !          139272: locks    bin:1.1; strict;
        !          139273: comment  @# @;
        !          139274: 
        !          139275: 
        !          139276: 1.1
        !          139277: date     91.07.15.14.18.46;  author bin;  state Exp;
        !          139278: branches ;
        !          139279: next     ;
        !          139280: 
        !          139281: 
        !          139282: desc
        !          139283: @initial version prov by hal
        !          139284: @
        !          139285: 
        !          139286: 
        !          139287: 
        !          139288: 1.1
        !          139289: log
        !          139290: @Initial revision
        !          139291: @
        !          139292: text
        !          139293: @st            - Archive SC-400 streaming tape drive
        !          139294: @
        !          139295: 0707070064030114161004440000030000030000011777770507310757400004600000000434/newbits/kernel/USRSYS/doc/RCS/swap,vhead     1.1;
        !          139296: branch   ;
        !          139297: access   ;
        !          139298: symbols  ;
        !          139299: locks    bin:1.1; strict;
        !          139300: comment  @# @;
        !          139301: 
        !          139302: 
        !          139303: 1.1
        !          139304: date     91.07.15.14.18.47;  author bin;  state Exp;
        !          139305: branches ;
        !          139306: next     ;
        !          139307: 
        !          139308: 
        !          139309: desc
        !          139310: @initial version prov by hal
        !          139311: @
        !          139312: 
        !          139313: 
        !          139314: 
        !          139315: 1.1
        !          139316: log
        !          139317: @Initial revision
        !          139318: @
        !          139319: text
        !          139320: @swap          - Swap tasks in and out of core
        !          139321: @
        !          139322: 0707070064030114151004440000030000030000011777770507310757400004400000000436/newbits/kernel/USRSYS/doc/RCS/tn,vhead     1.1;
        !          139323: branch   ;
        !          139324: access   ;
        !          139325: symbols  ;
        !          139326: locks    bin:1.1; strict;
        !          139327: comment  @# @;
        !          139328: 
        !          139329: 
        !          139330: 1.1
        !          139331: date     91.07.15.14.18.47;  author bin;  state Exp;
        !          139332: branches ;
        !          139333: next     ;
        !          139334: 
        !          139335: 
        !          139336: desc
        !          139337: @initial version prov by hal
        !          139338: @
        !          139339: 
        !          139340: 
        !          139341: 
        !          139342: 1.1
        !          139343: log
        !          139344: @Initial revision
        !          139345: @
        !          139346: text
        !          139347: @tn            - Tiac PC-234/6/8 ARCNET LAN Driver
        !          139348: @
        !          139349: 0707070064030110661004440000030000030000011777770507310757400003600000000103/newbits/kernel/USRSYS/doc/ssss           - Seagate/Future Domain SCSI (specfy: root=sd0a ... root=sd1d)
        !          139350: 0707070064030111320407550000030000030000011777770507310757400003400000000000/newbits/kernel/USRSYS/ldrv0707070064030111311006000000030000030000011777770507310757400004400000023676/newbits/kernel/USRSYS/ldrv/aha154x&�J�&�        .���v�v�v�Ѓ��VW��6�t;6|Vh����j&���k�
        !          139351: ��u���ヿtVh��h��j�����������&��&k�
        !          139352: LJ����LJ�������>t
����P���jjh&h�������G$&t�>�uރ>t
����P���k�
        !          139353: LJ����LJ����LJ+���}.���㋇;tG��W�*������LJ����LJ��h����+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v��.���͋^����G�j�p���_^�VWU��>�t
�v
        !          139354: �v�����>u���_^�VWU��>�t
        !          139355: �v������u        h�����_^�VWU���Vh(�6��6�j�v ���}��_^�VWU��>V~
�6Vh�����6�� ��+��� }���烽�t����������F���_^�VW��F%���%�F�~���jP�6��������~��狅��F�j%�6�����F��~�t�~��烽�uh����#+��&jP�~�������O���F�F��F��F��F��6�v�����F��V����F�%�F�+�;v�}��~��F���F�P�t      ���F�P�j       ���^��G&*�Ȋ*�������+҉F�V���������F�V�^��G*�ȊG*�������+�     F�      V�~��E*�ȊE*�����F�S�Z���F�V�~�EL�UN���~�������~����F��%����
�P�
        !          139356: 
���_^�VW��v�ƀt#��t�h0V��
������V���%���%�F���%���^��ヿ�uV�)����u��n�^��㋇��F��^��GL�WN�F�V�����^��G�W�F��V�����^��G�W
        !          139357: F�V�;V�wr;F�v�%�����^��GGt�Y���_^�VWU�����V�_^�VWU��h@�j&�v�v
        !          139358: h6�3
��
        !          139359: �_^�VWU��h@�j�v�v
        !          139360: h6�
��
        !          139361: �_^�VW��v�F���%���%�F��F
        !          139362: �(�CC.;��t�&.�g&&HH2���B��~��烽�u �F�&V������~��烽�u����~��狅��F���.����ǙRP�~��uN�uL����F�F����F���F�j�v�F�P�o���~�t�~�������"���~���Dž�+��l�~��狅��F�j�F�P�v����F�*���F�*�����RP���RP���RP�F�RP�
        !          139363: ���~�EL�UN��v�v
        !          139364: �
        !          139365: ��������_^�VW��v�D%�F��D%���%�F��D�t�F��D�D�^��㋇��F��^��ヿ�t��~�t��D
        !          139366: Dt���|t��j
�6�
        !          139367: �����uhY������u�F��E
        !          139368: �E�~�t�^���^��D
        !          139369: �TGW
        !          139370: ��D
        !          139371: �T�E�U�E&�{�F��>(u�>(��*�?�>*�v��_�����>h<덋^���^��D��    �ȋ�+�D
        !          139372: T;Ww
s�O�;Gw�G��LV�
        !          139373: ���_^�VWU�������o����_^�VWU�츓�_^�VWU��h�����_^�VWU��6\�F�\���_^�VWU��\�_^�VW��~�u;�^�;u
        !          139374: ��v��o�|�^�u�tD�L�^�u/�u)�s�F��h�?t�_�7�h�w�v��Y�����#�M��EW�)       ��V�  ���v�        ���_^�VWU���6\�      ��%���t��&u�\@@P�g      ������tӸ����v�\@P�
        !          139375: ��+��_^�VWU���6\�7   ��%���u��&u�\@@P�      ������tӸ����\@P� ��%��_^�VW������F��V��n�&�^��F��V��x"u�t�6\����������t��v�'��h��q  ���_^�VWU�졄��O~�\@@P����ȋ���t��u   h��=   ���6\�o����j �6\� �����_^�VWU���N
        !          139376: |
�~�F��������_^�VW��6\�-��=�u�����|�~�F��V��n�&�^��F��V��xu�t�6\�������ǀu֋F�F�u����G�6\��������@t����0�6\������� t�&��6\�������t+������_^�VWU��N|)��~�F�V
        !          139377: %�+҈��F�V
        !          139378: �������F�V
        !          139379: ���_^�VW��~�*䙉F��V���������F��V��v�D*�ȊD&*�������+�    F�      V��X�Z)F�V��F��_^�VWU��j
        !          139380: �����jhn����+���}��nt��n�PVh
���F��h����_^�VWU��>^t �>lt�6l����l�v�����_^�VW��v�;����>lu0�x����P�6�����l�u ��������x��l�j+�;6x}����l����>j+��*�F���6j�'���X�Z�F�P�6�6l���RP�f����x�F�hM�v
        !          139381: ���h�h����j&h����h��6\�z�����}h�t���6\hK�g���E�j&����+���}����E�*�P�����F��F�h�^�x�_^�VW��v�D�F���T�F��V�j>�6�����F��~�u    �������v&�^��G;��D�%���G&�D�%G&�D
��^��G*�=*u�O&��^��O&�^��G�F��G�V���������^��G�F��V���������^��G�F��G�G�F��.�>��G�F��G�G�G
        !          139382: �G�F�P�D
        !          139383: �RP������F�P�t�t������l@P�6�v��q��RP������l�&j�����^��?ujh�h�S������^��uO�tI�D�%P�D���PhZ����+��^��G�;�~�߃�
        !          139384: ^��G*�Ph���G��h�����^��G��ȊG����S������_^�VWU��vj>�6�!�����u;��D
        !          139385: �%���E&�D
        !          139386: �%E&�\�&u
        !          139387: �M&�E(��M&�E*�E�D�T��������E�D�T��������E�D�E�E�\�G+ҹ�������E�\�G��       �E�E�E
        !          139388: �E�EP�G+�RP�n����EP�\�w�w����RP�S������_^�VW��F��d���>nt
        !          139389: W�[����nW�M���h��F��u��&;6x|�����l�?uq�F��v�������F�����l@P�6�v��p��RP���������l�&j�������F��^���h��F��~�u�G�v�����~�tF�t�;6xt�X��n�F��_^�VWU��+�+�;6x}9����j�?t(����j@P�x���Ph��&������j�GF�����_^�VWU��\@@P�&�������ǀu
        !          139390: Vh��O����%H=w+����.�����������jh �$&����Y��        h����j �6\��&���_^�VWU��h���&���_^�VW��v
        !          139391: �F���F�j&j�v�����>uej&jj�v����F��tF�^�����&U�u/�F��~�}j�F�����&P�ƃ�P�D���F����F�&�v��W���v�X���v��-���F��_^���`���`�VWU��N�     �v
        !          139392: �~��F��]_^ø�`���`���`�U���v�v�P�;��]���`���`���`�����܋W+�����`�[XS�`[SSø�`���`��c��c��&�+���&����VWU��S�؋�S+��y
        !          139393: �^�W���V�F�y���؃���r&FRP�V
        !          139394: �F�y���؃�FRP�V���
        !          139395: ��s���؃�[��]_^�VWU���_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          139396: ���~�����~�����vh������>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`��X��X[SSP�X�VWU��v�~t�~
        !          139397: jjjVh�M���
        !          139398: �+������(��D�F�D�vh�v
        !          139399: Vh�'���
        !          139400: W�����_^���`���`���`��Ë܋_��Ë܍_VWU��P�V
        !          139401: �F+�+�� ��������;wrw;?r+?w@��[��]_^��Ë܋_��Ë܍_VWU��P�F�'����F�g��F
        !          139402: �'��֋�[��]_^���`�ldrv:%d: bad dev
        !          139403: ldrv:%d: dev bsy
        !          139404: @ 0
��L������&        aha154x: sdunload() athough %d active
        !          139405: aha154x: out of kernel memory
        !          139406: No tape yetaha154x: no partition table
        !          139407: aha154x: out of kernel memory
        !          139408: �&&no messageerror messages not verboseaha154x: out of kernel memory
        !          139409: aha154x: timeout sending cmd byte
        !          139410: aha154x: aha_poll timed out
        !          139411: [%d] %x 
        !          139412: aha154x: initialization error or host adaptor not found at 0x%x
        !          139413: aha: SCSI ID %d LUN %d. SCSI sense = %x
        !          139414: aha: spurious interrupt %x
        !          139415: aha: multiple interrupts not yet handled
        !          139416: aha_ioctl: Not implemented
        !          139417: Kdopen_ahigh 
        !          139418: ahigh      
        !          139419: ahigh      
        !          139420: free_�bhigh  bhigh     bhigh     Ksleep_sdgetpartitions_Saha_ioctl_�drive_info_ main_Kukcopy_Kkucopy_aha_command_�clrivec_Daha_load_oKioreq_Kfree_SD_SPT_�sdclose_�sdwatch_�uexit_�Kdefend_SDBASE_�kclear_Kclrivec_setivec_�sphi_�ldrvipc_u_aha_start_ ldrvics_buildccb_Bdrvl_ldrvcon_llmodCinb_�Kuexit_dclose_�outb_�nulldev_�drvn_timq_ldrvsel_l0KKkclear_blkmv�Ksetivec_l1fxcalledbread_�lrmod:l2ll3|con_Kldtimcall_l4�llsgnHl5�ldrvint_brelease_�aha_get_base_�SDIRQ_�aha_device_info_�
        !          139421: Kdclose_vldivaha_intr_Mdefer_�devmsg_�aha_completed_�llmul4lrsgn?cprocp_kcall_timeout_�aha_process_�bdone_~Kbread_vtop_
        !          139422: sds_alloc_tucs_aha_unload_?vrdivlrmul.wakeup_�Kbrelease_aha_set_base_�spl_�vlmulZKdevmsg_MAX_MAILBOX_xfdisk_�Ktimeout_Kbdone_printf_�alow  alow     Kvtop_alow allkp_ldrvpsy_blow     blow     blow     SD_HDS_�Kalloc_dopen_�getcs_�vrmulcsdcon_�Kwakeup_bptr sleep_�kucopy_$ukcopy_fptr ��Kprintf_Kldeferioreq_0&'8'$+$*0-05'?#'J$$Q0T0\'b8$e'h8$k'o8 q'u8 w'~#'�g'�$'�8'�S'�-'�8'�8$�0�'�J$�'�8'�8'�#'�$'�-'&!'&S0&'#&!'-&'4&07&'J&,0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � � � � � � � � �%�&%�&$�&$�&0�&'%%$0$$0'%9%D0G'qf0t%{%�'�f0�%�$�0�'�0�%�0�'�Q0�'�#00$0�'�#%�0�'�$�0�0�'�#%0%!0('3%?'�0�'�'�#%�%�0�%�0� 0$ 6 8 : < > @%I0U%a'h0l%u${$0�$�$�0�%�0�%�%�0�$�$$$00"09'B%�%�0�0�0�0�'�f0�$�0�0�0%%#%)%/050;$@0g0o0x0�0�$z$�$�0�%�%�%�0�0%$%20;0A0S0Z0c%s0v%�0�%�0�%�0�%�0�%�0�$     $      %-      00      0C      $H      0K      $Z      %b      0h      $|      0      %�      0�      %�      0�      0�      0�      %�      0�      0�      $�      $�      %
        !          139423: 0
        !          139424: %!
        !          139425: 0$
        !          139426: %8
        !          139427: 0;
        !          139428: %O
        !          139429: 0R
        !          139430: %�
        !          139431: %�
        !          139432: 0&%   0%%!$'0*$306%F%M%T0W%^0f0y%�$�'�f0�%�0�0�$�%�%�$�%�%�'�Q0�%�%�'�Q%�0�0$ 00 0+%5080>$E0H%O$R0U0[0`0w%�%�$�'�f0�0�0� M
0r
0�
%�
'�
Q0�
0�
%�
0�
0�
$�
0�
$0$007'Nf0Q0�0
00,%2090?%C0G%N0Z$a0f%o0}%�'�Q0�0�%�0�0�%�0�0�$�0�%�$
        !          139433: %%#0( /02%>%S0Y$j0m � � � � � � � � � �0�0�$�0�%�0�$�0�0�0�'�00B0U0^0g'ul'x3'`'�3'�O'�3'�X'�3'�B'�3'�x0�'�\'�3'�'�3'�'�3''3'3'/'3'%'(3 /02 508'�w'�3'�'�!'�'�''S'!'='10'%'1'<!'V!'ZS'`'g0j'u'!'�'�3'�_0�0�0�'�9'�_0�0�'�''�3'&
'3'd'3'�q'�30707070064030114641006660000030000030000011777770507310757700004000000022571/newbits/kernel/USRSYS/ldrv/al0&���;���v�v�v�Ѓ��VW��6�t;6|Vh��=��j&����k�
        !          139434: ��u���ヿtVh����j������������&��&k�
        !          139435: LJ����LJ�������>t
����P���jjh&h��~����G$&t�>�uރ>t
����P���k�
        !          139436: LJ����LJ����LJ+���}.���㋇;tG��W��������LJ����LJ��h����+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v������͋^����G�j����_^�VWU��>�t
�v
        !          139437: �v�����>u���_^�VWU��>�t
        !          139438: �v������u        h�����_^�VW��>$t�&i�^P�6����� �u�&k�P�6������u�x&i�^P�6 �  ��k�P�6���������$���> �E��E��E� ��>���E�>�&~0���> ��y���x���r� ^��>�E��E�F��F�;�|��iF�^��> �E��F�iF�^��> �}��F�j@P�{���F�@P�(���uXj�F�P�]��h��F�P�M���~�������v��;���~��狅���P�F�@P�#��j�F�P���iF�^��> �E�
iF�^��> �EEiF�^��> �s��\�F��&�h�j����V����_^�VW��F��F�;�}[iF�^��> �}��F�j@P���j�F�P���jjj��jiF�^ H&P��P�����R���F��j�����6 ��
���6��
���_^�VWU��F%?;�s:���~��?i�^ P����h"�~��?i�^ P�v
        !          139439: �v�~&�����_^�VWU��N��?i�^��> �Mu(����~��?i�^ P�v
        !          139440: �v���V����_^�VWU���v
        !          139441: �~��?i�^ P����_^�VWU��v
        !          139442: �<tV�N��?i�^ P����|V�
�����|o�^��?i�^�� �_�P�������� t؋^��?i�^�� �_�P������� t�W�N��?i�^�� �_�7������_^�VWU��~��?i�^ P�v�v
        !          139443: �v�)���_^�VWU���v�v
        !          139444: �~��?i�^ P����_^�VWU���6"����_^�VW��v�~�F%��F��\��F�@P���������t��&�D�t
        !          139445: �
�u��F���ȁ��k�
        !          139446: ��t�'��&�F@t���u��F@u�&�\�G����㋇=&t˃|t�&�\�tjjh&�DP�������F��F@tj��\�G����㋇�j�F�P���j�F�@P�|���F��t��L $�F�P����F��F�*�\G�F��u`jjh&�DP�����G$G&t���t��F�P��
        !          139447: ��%P�F�P�
        !          139448: ��j�F�@P��
        !          139449: ����v��������d���F�t�d����d���LV�=����     �,&����!�,&V����v�����D�vV�8���F@t�\�G�����LJ�_�g�\�G�����LJ&�T�\�G����㋇=u�>��\�G��؁��㋇=&t�X�� ��F��u    �Du��
        !          139450: �Du�t���_^�VW��^�w�_�G&�v�D���^�G�F��^��?�F��~�tU�^�GPhvj
        !          139451: �GP�
        !          139452: ��jjh&�^�GP�
        !          139453: ���^��[*�F���Z*�:F�u��~�t��N���� uj��@P�x    ����^�G$��@tQ��P�     ��%P��P�L ���F��%��F�k^�
        !          139454: LJ&jjh&kF�
        !          139455: P�� ��k^�
        !          139456: LJ��P����%��P��P�����^�_�G�����LJ���^�_�G�^�GP��
        !          139457: ���_^�VWU��v�����k�
        !          139458: ������=~�~�����k�
        !          139459: P�
        !          139460: ���_^�VW��v�Y     ���\��F�@P�$���F��F�P����F��F�P����F��F
        !          139461: �3
        !          139462: �      CC.;��t��.�g��������&x
        !          139463: �
        !          139464: �
        !          139465: �
        !          139466: Y
        !          139467: p
        !          139468: �
        !          139469: �
        !          139470: �
        !          139471: �F�
@P�F�P������F�%����F�
&P�F��ߋF�%����F�
��F�%���ߋF�
�P�F�P����v�v�����F��P�F�@P����v�늋N���F�%����w��F�P�(���F��F�*�\G�F�*����F�j�v�F�P�*�
        !          139472: �v�v
        !          139473: V����F�*�P�F�@P�+��W����_^�VW��^�G�F��^��7�^��)&��F���(&�:F�t����^��(&����㋇����u+�^�Gt!�g����P�v��%P��P����t}��F���@P�R���F�h���P���WV�������P��@P�p���^��,&%�=&t      =tj�j�j
        !          139474: ��P�F���F�*�P��@P�6���v������_^�VW��v�Du����F��\�P����F��F�*�\G�v������\�Gt>�g��|u  �DP���(�F��u%��F���X&*䈄Y&ƄY�v����V�����\�G&t�g��F�t�d����L ��Y*�=�w"�\�P���
P�\�P�T���Dt�Du=��Yt6��Y&*�ȋ�ي�Z&*�PV�����Y&*�=�s��Y&�ƄY&��Y���F����Z*�Ȋ�[*�+�&F��F��.�>��V��N�|7V�W�����|*��Z*�ȋ�ًLj�\��Z*�=�rƄZ����Z��V�R��Vh?j
        !          139475: ��H&P����_^�VW��v�\�F��\�P�'������t
        !          139476: VhY������ t>��Z*�:�[t2��[*�ȋ�ي�\*�P�\�7�-����[��[*�=&rƄ[�v������_^�VWU��j�v����_^�VW��v�\��F��F�@@P���=v�`&����.�����}�����F�P�g������t�VhY�1����v��J�����|t���,&@u-�ρ���1&�;�u�L 녋ρ���0&�;�u�d���n���Y*�=�s,��X&*�ȋ�ًLj�Z&��X&*�=�s��X&�ƄX&��Y�Du�-���Y*�=�w���F�P���%��P�F�P���H���Z*�:�[u����D t�����[*�ȋ�ي�\*�P�v������[��[*�=&rƄ[��[*�:�Zt��Vh?����F�P�4���\G���_^�VW��F��~�}"�~��狅=u�~������L����F����(�(;&|�(�(�_^�VW����t��F��F��~�}:�~��狅=u'�~��狽��(&����狅��F��F�;F�}�F��F��F����F�;t.��.�>��&���&���~�t�&h��6����_^�&d��`�VWU��N�    �v
        !          139477: �~��F��]_^�VW��~dra�F+�.�6��uS�F+�RPjh�4����F��
        !          139478: �F�j6jC�"&���F�%�Pj@�&���F���Pj@�&���v���&���F���F����F��_^�VW��v�{����F��u�&�F��F
        !          139479: ��P��v��&���F��_^�VW���F��~�t!jd�8����n&�F���P�_&���F��_^�d���U���v�v�P�'��]���`�����܋W+�����`�[XS�`[SSø�`���`���`�VWU���_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          139480: ���~�����~�����vh�`����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`��X��X[SSP�X���`�VWU��v�~t�~
        !          139481: jjjVh����
        !          139482: �+�������D�F�D�vh�v
        !          139483: Vh����
        !          139484: W�����_^���`���`���`���`���`���`���`���`���`���`���`���`���`��Ë܋_��Ë܍_VWU��P�V
        !          139485: �F+�+�� ��������;wrw;?r+?w@��[��]_^���`�ldrv:%d: bad dev
        !          139486: ldrv:%d: dev bsy
        !          139487: 
        !          139488: .�X���X�     �&��     Y@�&�`@:0 dddddddd�,&�&�&X �@Kttstart_ahigh        
        !          139489: free_bhigh  Ksleep_Kttopen_main_Kkucopy_al_sg_clr_�ttsignal_alxtimer_�  clrivec_�albaud_�Kttpoll_Kfree_super_Nuexit_&Kttsignal_al_sg_set_�altclk_in_}Kdefend_nondsig_Naltclk_out_�kclear_:Kclrivec_com_usage_alxstart_�
setivec_vsphi_@ldrvipc_tthup_�u_alxopen_�ldrvics_drvl_ldrvcon_inb_cs_sel_�Kuexit_Ksuper_nulldev_Xoutb_bdrvn_altclk_iogetc_$timq_ldrvsel_Knondsig_Kkclear_ttsetgrp_�blkmv�Ksetivec_xcalledttclose_�ttin_�Ktthup_ttout_�con_Kldtimcall_poll_owner_poll_rate_alxintr_mldrvint_ttioctl_�ttread_�altsel_vldiv0Kiogetc_defer_�cprocp_kcall_.timeout_XKttsetgrp_alp_rate_�Kttclose_Kttin_alxbreak_YKttout_alloc_�tp_table_ucs_vrdiv9wakeup_vKttioctl_Kttread_spl_DC1BAUD_�a0con_�Ktimeout_C3BAUD_�ttwrite_printf_lalow    allkp_ldrvpsy_blow     alxcycle_?Kalloc_ttstart_A0CNT_�alxparam_Egetcs_Kwakeup_sleep_6ttopen_�kucopy_Dalxclose_QKttwrite_Kprintf_Kldeferttpoll_�alxioctl_�      0&'9'$*$*0-05'?"'J#$Q0T0\'b9$e'h9$k'o9 q'u9 w'~"'�^'�#'�9'�P'�.'�9'�9$�0�'�E$�'�9'�9'�"'�#'�.'&!'&P0&'#&!'-&'4&07&'J&-0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � � � � � � � � � �%�&0�&$�&'�&]0�&%0$']0%0!$%%,0/$6%<0?0E%K$N%R%\%b'eO%i$u${%%�%�'�O%�$�0�%�%�0�0�00$0%$10=0L%Z _%j o%z0}0� �0�0�$�%�0�0�%�0�00%0%"0%$;0@%O0S%Y%h0r'{%�0�%�0�0�%�0�%0
        !          139490: 0%-09%U0a%~0�%�0�%�0�%�0�0'!0%0/06'I"'P0T'_;0m'|0�0�0�'�O0�0�0�00%',E070E0V0c'j0q0w0�$�$�0�0�0�'�0�'�'0'!0)0,0F'J0h �0�0�0�0        0      '+      "';    "0?    'J      "0U    0e      'z      0    0�      '�      "'�    "'�    "0�    0�      0�      0
        !          139491: 0
        !          139492:   
        !          139493: 0/
        !          139494:  G
        !          139495:  I
        !          139496:  K
        !          139497:  M
        !          139498:  O
        !          139499:  Q
        !          139500:  S
        !          139501:  U
        !          139502:  W
        !          139503: 0h
        !          139504: 0n
        !          139505: 0�
        !          139506: 0�
        !          139507: 0�
        !          139508: 0�
        !          139509: 0�
        !          139510: 00$050<'p0t$�0�0�0�0�0�0�0�00*03090P0S0b0y0�0�0�0�0�0
0;
 {
0�
0�
 �
0�
0�
0�
 0030P0d0�0� � � � � � � � �0� �0�0�00O0]0g0x0{0�0�0�0� �0�0�0�''O0%+%.%2%8%='K;0R'k'yO$�'�<'�< �%�0�'�;'�; �'�<0�'�a'�4 0+040>0M0\0e0�0�'�+0�'�A0�'�+0�0�'�+'�A0�'&m0'
'4'%C'(4'24';0'>4'E'H4'O/'R4'ml'p4'}'�!'�'�'�'�P'�!'�>'�30�'�'�'�!'!'P''0'#'-!'7':4'O''R4'tX0w00�'�:'�X0�0�'�J'�4'�7'�4'�K'�4'�S'�4'�'�4'�M'�4'�
'�4'�T'�4'�H'4'  '4''4'k' 4''&'*4'wf'z40707070064030114631006660000030000030000011777770507310760100004000000022571/newbits/kernel/USRSYS/ldrv/al1&���;���v�v�v�Ѓ��VW��6�t;6|Vh��=��j&����k�
        !          139511: ��u���ヿtVh����j������������&��&k�
        !          139512: LJ����LJ�������>t
����P���jjh&h��~����G$&t�>�uރ>t
����P���k�
        !          139513: LJ����LJ����LJ+���}.���㋇;tG��W��������LJ����LJ��h����+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v������͋^����G�j����_^�VWU��>�t
�v
        !          139514: �v�����>u���_^�VWU��>�t
        !          139515: �v������u        h�����_^�VW��>$t�&i�^P�6����� �u�&k�P�6������u�x&i�^P�6 �  ��k�P�6���������$���> �E��E��E� ��>���E&�>�&~0���> ��y���x���r� ^��>�E��E�F��F�;�|��iF�^��> �E��F�iF�^��> �}��F�j@P�{���F�@P�(���uXj�F�P�]��h��F�P�M���~�������v��;���~��狅���P�F�@P�#��j�F�P���iF�^��> �E�
iF�^��> �EEiF�^��> �s��\�F��&�h�j����V����_^�VW��F��F�;�}[iF�^��> �}��F�j@P���j�F�P���jjj��jiF�^ H&P��P�����R���F��j�����6 ��
���6��
���_^�VWU��F%?;�s:���~��?i�^ P����h"�~��?i�^ P�v
        !          139516: �v�~&�����_^�VWU��N��?i�^��> �Mu(����~��?i�^ P�v
        !          139517: �v���V����_^�VWU���v
        !          139518: �~��?i�^ P����_^�VWU��v
        !          139519: �<tV�N��?i�^ P����|V�
�����|o�^��?i�^�� �_�P�������� t؋^��?i�^�� �_�P������� t�W�N��?i�^�� �_�7������_^�VWU��~��?i�^ P�v�v
        !          139520: �v�)���_^�VWU���v�v
        !          139521: �~��?i�^ P����_^�VWU���6"����_^�VW��v�~�F%��F��\��F�@P���������t��&�D�t
        !          139522: �
�u��F���ȁ��k�
        !          139523: ��t�'��&�F@t���u��F@u�&�\�G����㋇=&t˃|t�&�\�tjjh&�DP�������F��F@tj��\�G����㋇�j�F�P���j�F�@P�|���F��t��L $�F�P����F��F�*�\G�F��u`jjh&�DP�����G$G&t���t��F�P��
        !          139524: ��%P�F�P�
        !          139525: ��j�F�@P��
        !          139526: ����v��������d���F�t�d����d���LV�=����     �,&����!�,&V����v�����D�vV�8���F@t�\�G�����LJ�_�g�\�G�����LJ&�T�\�G����㋇=u�>��\�G��؁��㋇=&t�X�� ��F��u    �Du��
        !          139527: �Du�t���_^�VW��^�w�_�G&�v�D���^�G�F��^��?�F��~�tU�^�GPhvj
        !          139528: �GP�
        !          139529: ��jjh&�^�GP�
        !          139530: ���^��[*�F���Z*�:F�u��~�t��N���� uj��@P�x    ����^�G$��@tQ��P�     ��%P��P�L ���F��%��F�k^�
        !          139531: LJ&jjh&kF�
        !          139532: P�� ��k^�
        !          139533: LJ��P����%��P��P�����^�_�G�����LJ���^�_�G�^�GP��
        !          139534: ���_^�VWU��v�����k�
        !          139535: ������=~�~�����k�
        !          139536: P�
        !          139537: ���_^�VW��v�Y     ���\��F�@P�$���F��F�P����F��F�P����F��F
        !          139538: �3
        !          139539: �      CC.;��t��.�g��������&x
        !          139540: �
        !          139541: �
        !          139542: �
        !          139543: Y
        !          139544: p
        !          139545: �
        !          139546: �
        !          139547: �
        !          139548: �F�
@P�F�P������F�%����F�
&P�F��ߋF�%����F�
��F�%���ߋF�
�P�F�P����v�v�����F��P�F�@P����v�늋N���F�%����w��F�P�(���F��F�*�\G�F�*����F�j�v�F�P�*�
        !          139549: �v�v
        !          139550: V����F�*�P�F�@P�+��W����_^�VW��^�G�F��^��7�^��)&��F���(&�:F�t����^��(&����㋇����u+�^�Gt!�g����P�v��%P��P����t}��F���@P�R���F�h���P���WV�������P��@P�p���^��,&%�=&t      =tj�j�j
        !          139551: ��P�F���F�*�P��@P�6���v������_^�VW��v�Du����F��\�P����F��F�*�\G�v������\�Gt>�g��|u  �DP���(�F��u%��F���X&*䈄Y&ƄY�v����V�����\�G&t�g��F�t�d����L ��Y*�=�w"�\�P���
P�\�P�T���Dt�Du=��Yt6��Y&*�ȋ�ي�Z&*�PV�����Y&*�=�s��Y&�ƄY&��Y���F����Z*�Ȋ�[*�+�&F��F��.�>��V��N�|7V�W�����|*��Z*�ȋ�ًLj�\��Z*�=�rƄZ����Z��V�R��Vh?j
        !          139552: ��H&P����_^�VW��v�\�F��\�P�'������t
        !          139553: VhY������ t>��Z*�:�[t2��[*�ȋ�ي�\*�P�\�7�-����[��[*�=&rƄ[�v������_^�VWU��j�v����_^�VW��v�\��F��F�@@P���=v�`&����.�����}�����F�P�g������t�VhY�1����v��J�����|t���,&@u-�ρ���1&�;�u�L 녋ρ���0&�;�u�d���n���Y*�=�s,��X&*�ȋ�ًLj�Z&��X&*�=�s��X&�ƄX&��Y�Du�-���Y*�=�w���F�P���%��P�F�P���H���Z*�:�[u����D t�����[*�ȋ�ي�\*�P�v������[��[*�=&rƄ[��[*�:�Zt��Vh?����F�P�4���\G���_^�VW��F��~�}"�~��狅=u�~������L����F����(�(;&|�(�(�_^�VW����t��F��F��~�}:�~��狅=u'�~��狽��(&����狅��F��F�;F�}�F��F��F����F�;t.��.�>��&���&���~�t�&h��6����_^�&d��`�VWU��N�    �v
        !          139554: �~��F��]_^�VW��~dra�F+�.�6��uS�F+�RPjh�4����F��
        !          139555: �F�j6jC�"&���F�%�Pj@�&���F���Pj@�&���v���&���F���F����F��_^�VW��v�{����F��u�&�F��F
        !          139556: ��P��v��&���F��_^�VW���F��~�t!jd�8����n&�F���P�_&���F��_^�d���U���v�v�P�'��]���`�����܋W+�����`�[XS�`[SSø�`���`���`�VWU���_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          139557: ���~�����~�����vh�`����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`��X��X[SSP�X���`�VWU��v�~t�~
        !          139558: jjjVh����
        !          139559: �+�������D�F�D�vh�v
        !          139560: Vh����
        !          139561: W�����_^���`���`���`���`���`���`���`���`���`���`���`���`���`��Ë܋_��Ë܍_VWU��P�V
        !          139562: �F+�+�� ��������;wrw;?r+?w@��[��]_^���`�ldrv:%d: bad dev
        !          139563: ldrv:%d: dev bsy
        !          139564: 
        !          139565: .�X���X�     �&��     Y@�&�`@:0 dddddddd�,&�&�&X �@Kttstart_ahigh        
        !          139566: free_bhigh  Ksleep_Kttopen_main_Kkucopy_al_sg_clr_�ttsignal_alxtimer_�  clrivec_�albaud_�Kttpoll_Kfree_super_Nuexit_&Kttsignal_al_sg_set_�altclk_in_}Kdefend_nondsig_Naltclk_out_�kclear_:Kclrivec_com_usage_alxstart_�
setivec_vsphi_@ldrvipc_tthup_�u_alxopen_�ldrvics_drvl_ldrvcon_inb_cs_sel_�Kuexit_Ksuper_nulldev_Xoutb_bdrvn_altclk_iogetc_$timq_ldrvsel_Knondsig_Kkclear_ttsetgrp_�blkmv�Ksetivec_xcalledttclose_�ttin_�Ktthup_ttout_�con_Kldtimcall_poll_owner_poll_rate_alxintr_mldrvint_ttioctl_�ttread_�altsel_vldiv0Kiogetc_defer_�cprocp_kcall_.timeout_XKttsetgrp_alp_rate_�Kttclose_Kttin_alxbreak_YKttout_alloc_�tp_table_ucs_vrdiv9wakeup_vKttioctl_Kttread_spl_DC2BAUD_�Ktimeout_a1con_�C4BAUD_�ttwrite_printf_lalow    allkp_ldrvpsy_blow     alxcycle_?Kalloc_ttstart_alxparam_Egetcs_A1CNT_�Kwakeup_sleep_6ttopen_�kucopy_Dalxclose_QKttwrite_Kprintf_Kldeferttpoll_�alxioctl_�      0&'9'$*$*0-05'?"'J#$Q0T0\'b9$e'h9$k'o9 q'u9 w'~"'�^'�#'�9'�P'�.'�9'�9$�0�'�E$�'�9'�9'�"'�#'�.'&!'&P0&'#&!'-&'4&07&'J&-0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � � � � � � � � � �%�&0�&$�&'�&]0�&%0$']0%0!$%%,0/$6%<0?0E%K$N%R%\%b'eO%i$u${%%�%�'�O%�$�0�%�%�0�0�00$0%$10=0L%Z _%j o%z0}0� �0�0�$�%�0�0�%�0�00%0%"0%$;0@%O0S%Y%h0r'{%�0�%�0�0�%�0�%0
        !          139567: 0%-09%U0a%~0�%�0�%�0�%�0�0'!0%0/06'I"'P0T'_;0m'|0�0�0�'�O0�0�0�00%',E070E0V0c'j0q0w0�$�$�0�0�0�'�0�'�'0'!0)0,0F'J0h �0�0�0�0        0      '+      "';    "0?    'J      "0U    0e      'z      0    0�      '�      "'�    "'�    "0�    0�      0�      0
        !          139568: 0
        !          139569:   
        !          139570: 0/
        !          139571:  G
        !          139572:  I
        !          139573:  K
        !          139574:  M
        !          139575:  O
        !          139576:  Q
        !          139577:  S
        !          139578:  U
        !          139579:  W
        !          139580: 0h
        !          139581: 0n
        !          139582: 0�
        !          139583: 0�
        !          139584: 0�
        !          139585: 0�
        !          139586: 0�
        !          139587: 00$050<'p0t$�0�0�0�0�0�0�0�00*03090P0S0b0y0�0�0�0�0�0
0;
 {
0�
0�
 �
0�
0�
0�
 0030P0d0�0� � � � � � � � �0� �0�0�00O0]0g0x0{0�0�0�0� �0�0�0�''O0%+%.%2%8%='K;0R'k'yO$�'�<'�< �%�0�'�;'�; �'�<0�'�a'�4 0+040>0M0\0e0�0�'�+0�'�A0�'�+0�0�'�+'�A0�'&m0'
'4'%C'(4'24';0'>4'E'H4'O/'R4'ml'p4'}'�!'�'�'�'�P'�!'�>'�30�'�'�'�!'!'P''0'#'-!'7':4'O''R4'tW0w00�'�:'�W0�0�'�J'�4'�7'�4'�K'�4'�S'�4'�'�4'�M'�4'�
'�4'�T'�4'�H'4'  '4''4'k' 4''&'*4'wf'z40707070064030111261006000000030000030000011777770507310760300003700000021741/newbits/kernel/USRSYS/ldrv/at&��l����v�v�v�Ѓ��VW��6�t;6|Vh��K��j&�{��k�
        !          139588: ��u���ヿtVh��$��j�T����������&��&k�
        !          139589: LJ����LJ�������>t
����P���jjh&h������G$&t�>�uރ>t
����P���k�
        !          139590: LJ����LJ����LJ+���}.���㋇;tG��W��������LJ����LJ��h���+���&s=���㋇�F��~�t)�^��G�F���;F�ujjj�v������͋^����G�j�,���_^�VWU��>�t
�v
        !          139591: �v�����>u���_^�VWU��>�t
        !          139592: �v������u        h�����_^�VW�jjp�{��jq�5���������T��%�Uj�F�Pjh&�Z��+�����|��=u,jW�F�+҉F��V��F�+ҹ������F�V�RP����@��TuƄT&�}u�E�E*�P�u�E*�P�E*�P�u�E*�P�5Vh��
��j�F�Pjh&��
����F�o�+�����}I��Tu��F������F��E*�RP�E*�RP�1��RP�+�RP�#���^���������Ph�
        !          139593: j�w
���Y�h�6����c�Z�h�6����e�g���_^�VWU��j�
���_^�VWU��jh��
���dNu���*�%Ph�����j���h�&���=&t     hE����+�����|���Tu��F��V��
        !          139594: ���E*�Ph�����E��Ph�&����E*�Ph�&�~��j&h�&�s����Ph�&�f������Ph�&�V���E*�ȋ�����Ph�&�;��h�h�&�/��V�U
        !          139595: ��jh�&���V�C
        !          139596: ���Z��_^�VW�
        !          139597: �v��%�F��ƀt
��%&���F��
        !          139598: ��%�������}��Tu���ƀt��^��������u#�����P�ρ������%����P�C
        !          139599: ���߃����������F��V��^����������F��V��^���������F�V�;V�wr;F�v�%��^��������u��_^�VWU��h@�j&�v�v
        !          139600: hn��
        !          139601: ��
        !          139602: �_^�VWU��h@�j�v�v
        !          139603: hn�
        !          139604: ��
        !          139605: �_^�VW��v�ƀt��%&���%����F��F
        !          139606: =&Ht=Ht"�����j�v�F����P�
        !          139607: ���nj�F����P�v�����~�ƅT&�F����F������*�RP�~������*�RP���RP�~������+�RP�����~���������+��_^�VWU��6<����tH�6N�6L�t�t
        !          139608: �D�tjx�
        !          139609: �R%aP�6Jhq��    ���J�g�L�i�N�k���oW�
        !          139610: ���_^�VW��v�D%�F��D�D�D�t�F��F�������|&u�D
        !          139611: �T;Uu;Eu   V�����^�D��  �ȋ�+�D
        !          139612: T;Urw;Ew
�D�&u�|u�L����><u�6<��>�7�6>�>Wu
        !          139613: ��t�&�_^�VW��X�V�<���u+��&�D%�R�D�t
�R�D%&�       �D%����J�J�����*�F��R������D
        !          139614: �TEU
        !          139615: �D�F�D��   �H�D�T�@�B�|uE�>H&v
�Y��Z��        &�D�F;]u   ;[u���D�F;at��;_t���ǃ>H&t���Y*�;Ju:�D�F;]u-;[u'h�t�t�6c������<�DV�K������Z*�;Ju"�D�F;au;_uh�t�t�6e빃<uW�F�+�RP�6F�6D�  ���F��V��N������+�+F�V��X�X*�=r
        !          139616: �X�Z��>Xt�X*�&H�Y��&�_^�VW��J������D*�RP�D*�RP�6F�6D���RP����N�D*�RP�D*�RP�6F�6D�o��RP�����L�D*�RP�6F�6D����&���P�J;gu]�N;kuT�L;iuK�<�F��6N�6L�~��u�u
        !          139617: �E�tjx�
        !          139618: �R%aP�6Jh�����~��MW�y�����6J����D*�Ph��]���D��Ph�&�M���6Hh�&�@���6Ph�&�3���6Nh�&�&���N��Ph�&����J��L�Ph�&�����><�}u3j0h�&������u�6Jh������6B�6@�%���W�j h�&����W�t�_^�VWU��jh�
        !          139619: �6���_^�VWU��6<�W*�H=v�&����.���
        !          139620: �
        !          139621: &��
��&�&&�t�}�����u
�6Jh��[���X*�;Hu�6�>H�������c��6B�6@�����u��X*�;Hu*�>H������D�F��[��]�J�>H��X�X��@�l�V�D&�F�HuWV����N�O�t�K��@�l�V�D&�F�Ht��"�u�6Jh�������6B�6@�����_^�VW�
        !          139622: �6<h�&����ȋ���!u�G&h�&�����F��W*�=u�X*�;Hu�Vd�3&�F��u�&�Vd�J�g�L�i�N�k�6N�6L�H+҉F��V��X*䙉F��V��D��     �ȋ�+�D
        !          139623: TF�V�+F�V�RP�D�tjx�
        !          139624: �R%aP�6Jh������@u   h������ t  h����F�&t h����F�t h+�o���F�t h@�_���F�@t hP�O���F�t he�?���F��t hx�/���V*�=s      h����h�����+���V�V*�=r����&�_^�VW��6<�p�N�F��V*�H=w9����.���
�
�
�
�
�
�
�N�}'�F��!�J���F��F�;��r�n����F��V*�=sP��u����t�v�h�&�\���F���Ph�&�L���J���Ph�&�9��Wh�&�/���W&�!�W*�=u�X*�;Ht�LV����_^�VWU��v�t�W��<V�>&������t�|��_^�VWU��6��~�I���t���N���vh���&��+��_^�VU���v�&��&��o]^�WU���~�&��&��m]_ú�&����쨀��tKu��ú�&�������uKu���VW��v
        !          139625: �F��%�F�j&j�v�����>uej&jj�v����F��tF�^�����&U�u/�F��~�}j�F�����&P�ƃ�P�D���F����F�&�v��W���v�X���v��&���F��_^���`���`�VWU��N�     �v
        !          139626: �~��F��]_^ø�`���`���`�U���v�v�P�'��]���`�����܋W+�����`�[XS�`[SSø�`���`�VWU���_^��܋W�G�ø�`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          139627: ���~�����~�����vh�`����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`��X��X[SSP�X�VWU��v�~t�~
        !          139628: jjjVh����
        !          139629: �+��������D�F�D�vh�v
        !          139630: Vh����
        !          139631: W�����_^���`���`��Ë܋_��Ë܍_VWU��P�V
        !          139632: �F+�+�� ��������;wrw;?r+?w@��[��]_^��Ë܋_��Ë܍_VWU��P�F�'����F�g��F
        !          139633: �'��֋�[��]_^��Ë܋_��Ë܍_VWU��P�v
        !          139634: �~+�+�� ��������;Wrw;r+W��[��]_^ø�`�ldrv:%d: bad dev
        !          139635: ldrv:%d: dev bsy
        !          139636: Z\�B_|\@�&D2at%d: TO
        !          139637: at%d: ncyl=%d nhead=%d wpcc=%d eccl=%d ctrl=%d landc=%d nspt=%d
        !          139638: at: AT disk controller not present (reset)
        !          139639: at%d%c: bno=%U head=%u cyl=%u <Watchdog Timeout>
        !          139640: at%d%c: bno=%U head=%u cyl=%u <Track Flagged Bad>
        !          139641: at%d%c: bno=%U head=%u cyl=%u <Drive Not Ready> <Write Fault> <No Data Addr Mark> <Track 0 Not Found> <ID Not Found> <Bad Data Checksum> <Command Aborted> <Block Flagged Bad> retrying...
        !          139642: Kpkcopy_Kkpcopy_Kdopen_ahigh  
        !          139643: ahigh      
        !          139644: ahigh      
        !          139645: bhigh      bhigh     bhigh     Ksleep_main_Kukcopy_Kkucopy_clrivec_Kioreq_uexit_�Kdefend_Kclrivec_setivec_�sphi_Nldrvipc_u_ldrvics_drvl_ldrvcon_inb_(Kuexit_dclose_�nulldev_\outb_fdrvn_timq_ldrvsel_blkmv�Ksetivec_xcalledbread_�atsend_�myatbsyw_�con_Kldtimcall_ldrvint_brelease_�Kdclose_atparm_�atrecv_�vldiv�CSR_REG     �&defer_vlremFcprocp_kcall_<timeout_\bdone_�Kbread_sds_alloc_�ucs_vrdiv�vrremOwakeup_�Kbrelease_DRQ_ST     spl_Rvlmulfdisk_Ktimeout_Kbdone_atdrqw_printf_zalow alow     alow     allkp_ldrvpsy_blow     blow     blow     BSY_ST     �atcon_�Kalloc_dopen_pkcopy_pkpcopy_Hgetcs_$vrmulKwakeup_sleep_DATBSYW_�atbsyw_�kucopy_Rukcopy_�Kprintf_Kldeferioreq_20&'''$$*0-05'?'J$Q0T0\'b'$e'h'$k'o' q'u' w'~'�J'�'�''�9'� '�''�'$�0�'�2$�'�''�''�'�'� '&'&90&'#&'-&'4&07&'J&0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � � � � � � � � �0�&0�&%�&%0$0$0P%Y%`$�0�0�0�$�%�0�0�%�%�0 0%'I0%#%''/I02%8%<0L0`$l0x0�0�$�0�$�0�%�0�0�0�0�0�0�00)050<0G0N0T%�'�0�0�%�%�%�0�%�%�%�%�%
        !          139646: %'$%1%5';%S0V%p0s'�0�$�0�$�0�%�$�$    0$ 0'%1%508%G0J'P%V%Z%n%y$|0%�%�%�%�%�%�0�0�0�%�0�%,%3%9%?%C0I0P%^%c%g0r%{%�%�%�$�%�%�%�%�%�%�%�%�%�%�0�%�%%%
        !          139647: 0%%%0%#0(%.04%7%=%B%F%J%P%_0b%j0s0y%|%�%�%�%�%�%�%�%�0�%�%�%�%�%�%�%�%&     %      $      %.      %2      05      0=      %C      %W      %[      0^      0f      %l      %x      %|      0      %�      %�      %�      %�      %�      %�      %�      %�      %�      %�      %�      %�      $�      0�      0�      0�      %�      0�      0
        !          139648: 0
        !          139649: %
        !          139650: 0$
        !          139651: %+
        !          139652: 01
        !          139653: %8
        !          139654: 0>
        !          139655: %D
        !          139656: 0N
        !          139657: %T
        !          139658: %[
        !          139659: 0e
        !          139660: %l
        !          139661: 0z
        !          139662: 0�
        !          139663: %�
        !          139664: $�
        !          139665: 0�
        !          139666: %�
        !          139667: %�
        !          139668: 0�
        !          139669: %�
        !          139670: 0�
        !          139671: %�
        !          139672: '�
        !          139673:  �
        !          139674: 0�
        !          139675: %�
        !          139676: %�
        !          139677: 0�
        !          139678:  �
        !          139679:  �
        !          139680:  �
        !          139681:  �
        !          139682: 0�
        !          139683: 0�
        !          139684: 00   00%$0%#%)'/7%3%<%B%F0I0O%V%\%b%k%o%s%w%z%~%�%�%�%�%�%�%�0�0�0�%�%�%�%�%�0�%�$�0�%�%�0�%
00#0)%2%<%B%H0L0V%Z%^%a%d%g%j%m%q%u%x%�%�%�$�0�$�0�$�0�$�0�$
0     
$
0
$&
0)
$6
09
$F
0I
%O
$Y
0\
$b
0e
%r
%u
0
%�
%�
%�
 �
 �
 �
 �
 �
 �
 �
%�
$�
%�
'�
00%0+05%<%B%L%R0]'p%v%|0�0�0�$�0�$�0�0'04';0J0�0�0�0�'�P'�#'�C'�#'�6'�#'�='�#'�+'�#']0''#'3'6#'@#'I&'L#'S'V#'q't#'{\'~#'�'�'�'�'�'�9'�'�)'�"0�'�'�'�''9''#0&'1';'E     'H#'xB0{0�0�'�('�B0�0�'�'�#'�'�#'�V'�#0707070064030114611006440000030000030000011777770507310760500003700000017175/newbits/kernel/USRSYS/ldrv/fl&�&�P����v�v�v�Ѓ��VW��6�t;6|Vh����j&�7��k�
        !          139685: ��u���ヿtVh���
��j�����������&��&k�
        !          139686: LJ����LJ�������>t
����P���jjh&h��H����G$&t�>�uރ>t
����P���k�
        !          139687: LJ����LJ����LJ+���}.���㋇;tG��W�
������LJ����LJ��h����+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v��
���͋^����G�j��
���_^�VWU��>�t
�v
        !          139688: �v�����>u���_^�VWU��>�t
        !          139689: �v������u        h��
���_^�VWU��j����jjp�0��jq�������ƈu7��
����������%����&���t,����t"�����������&t����%@���>�tt���jh����h�
        !          139690: j����jh����jh�������=t���Ph��~��j�!      �������P�        ������P�     ��W�>���_^�VWU��>�tj����jjjh�!���.jh�����_^�VWU�������F%���;�s�v�������~��������u��_^�VWU��j&�v�v
        !          139691: h��
        !          139692: ���_^�VWU��j�v�v
        !          139693: h��e
        !          139694: ���_^�VW��~
        !          139695: @t���F%������v�D
        !          139696: ���F��F@P�6
        !          139697: ���F��~�&wʋF�;Es��Ft�E�f�F��  �E�f�F������e����+ҹ �����������F���E����j@�vh�h��      ���_^�VW��v�D��   �ȋ�+�D
        !          139698: T-&���F��\�����D
        !          139699: ;��v�LV���c�|@t"�\�����F�;��r�D�D�D@t����D�&t�|@u���d
        !          139700: ���>�u�6�����7�6��>�u�W�A
        !          139701: ���_^�VW��6����=v�����.���&�f�&?�.&�u��j�D%���Ph��;���D%������D%������ظ������D�T�����D
        !          139702: �������Ƈ��D��    ���u��&������F��t����F�;F�t���Ph��~������Ƞ��#�uG��������Ƞ���
Ph��O���;j&h�jdh�2  �������Ƈ����������Ƈ�����Ƞ���
Ph����������؀��u%��������j������P�����&�����>�B���>�t!����>�����>�������>��������>�����>�������>���j�������ȡ����P�
        !          139703: ���>�Pt"����؀��u����P�����؀��t��6���������&�|&tjh�jh�����������Ƈ����jh�h$�Y���t�&�����Ƈ��f���|&t�|uP��&�E�6�h�6��6�j�Z��
        !          139704: �u>�6��6�hL�t����h$����LV�N���+���&�M�6��t�j���W�������ȡ����P�����|@u%���P�����6��������P����h��H�6�����6�����6�������P����6��������؊���P�{��h��r����������Ƈ�j�V��h$�7����������t+�����=}
�����Ƈ��-�X�LV�C���!��u�D����������&�>�u������Ph�j��hk�5���_^�VW���F����=u    �F�����v������_^�VWU��v���%����؀��uO�ށ������=u O���%����؀��u��%=u+����_^�VW���F�+����}H���#�uF����|��������=|���� ����;�uր>�t��?�>�u����������Ƞ���
Ph��0���>�u�.�v�����_^�VWU��j���h$���jh�����jh��������=t���Ph�����j�v&�������P�e&������P�Y&��+�����������������t+���Pho����|�LV�L�������t;|t�jh�jh�O�����_^�VWU���-���2�>�t���V����_^�VWU��v�����V�G���_^�VW��F����F�+�h������ȋ����u�N�u�h�������@th��������sɋ�G�ƈ��뾉>�jh����+�h��x���ȋ����u�N�u�h������@th��Q������sɋ�G�ƈ��뾉>��v��H���_^�VWU��+�h����%�=�tNu�h��H����vh��&���_^�VWU���6��6����%Ph�����>�&|*�������t        h���&���������t    h���&���>�|~�������&t     h���&���������t    h�&���������t    h�&���������t    h �&��������� t    h+�w&��������ǀt    h9�b&���>�|i�������&t     hG�F&���������t    hd�1&���������t    ht�&��������� t    h��&���������@t    h�����h������_^ø�`�VWU��N�       �v
        !          139705: �~��F��]_^ø�`���`�VWU��v�Q�D�F
        !          139706: �D�vhVh�]���_^�VWU��vVh�G���_^ø�`���`���`������`��܋W+�����`�[XS�`[SS�VWU���_^��܋W�G�ø�`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          139707: ���~�����~�����vh�t����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh�(�������Dž����Dž�_^���`��X��X[SSP�X�VWU��v�~t�~
        !          139708: jjjVh�����
        !          139709: �+��������D�F�D�vh�v
        !          139710: Vh����
        !          139711: W�����_^���`���`�ldrv:%d: bad dev
        !          139712: ldrv:%d: dev bsy
        !          139713: &(Nh�~     �&�@&&(#*P�(#*PP#*Ph&&(  #*P�( #*P�P #*P`        PT@PTfd: DMA page straddle at %x:%xfdsfd%d: <Door Open>
        !          139714: flintr: timeout
        !          139715: flsense: timeout
        !          139716: flput: timeout
        !          139717: fd%d: head=%u cyl=%u <Not Ready> <Equipment Check> <Missing Address Mark> <Write Protected> <No Data> <Overrun> <Data Error> <End of Cyl> <Missing Data Address Mark> <Bad Cylinder> <Wrong Cylinder> <Bad Data CRC> <Data Deleted>
        !          139718: Ksleep_main_Kdmalock_clrivec_�dmaoff_�
int11_uexit_nflrecov_
        !          139719: Kdefend_Kclrivec_setivec_@sphi_
        !          139720: ldrvipc_u_ldrvics_Kint11_Kdmaoff_fldone_�
        !          139721: drvl_ldrvcon_fl_hlt_�inb_�
Kuexit_nulldev_outb_"dmareq_�
drvn_getubd_�
timq_ldrvsel_blkmv^
Ksetivec_xcalleddmaunlock_�
con_Kldtimcall_fl_hut_�ldrvint_Kdmareq_Kgetubd_devmsg_z
cprocp_kcall_timeout_bdone_T
dmago_�
Kdmaunlock_fl_srt_�panic_,ucs_wakeup_xspl_dmaon_�
Kdevmsg_Ktimeout_flcon_�Kdmago_Kbdone_printf_6ldrvpsy_flunload_�Kpanic_getcs_�
Kwakeup_sleep_Kdmaon_dmalock_�
Kprintf_0&'"'$$*0-05'?'J$Q0T0\'b"$e'h"$k'o" q'u" w'~'�;'�'�"'�1'�'�"'�"$�0�'�)$�'�"'�"'�'�'�'&'&10&'#&'-&'4&07&'J&0_&0p&0�&$�&$�&'�&
$�&$�&$�&$�&$�&0�& � � � � � � � � � �0�&0�&0�&$$
%%%#%.%80=%C%V%Z0`0j p0u0�0�%�%�0�0�$�$�0�$�0�0�%�0�%�0�'�0%0+$@'G
%\0_%v0y'�
0�$�0�0�'�
'
'
'
'
%0$[0f$0�%�%�%�%�%�0�0�%�%�0� � � � � � � � �'0$%0!%0%9%<%I%R%V%\%_%f%p%x%~%�0�%�0�%�%�%�%�%�%�0�0� �%�0�%�%�%�0�%�%%%00!%$%+%1%80=%C0H%O0S%V%[%`%d%j%o%r%w%z%}%�%�%�%�%�%�%�%�%�%�0�%�%�0�%�%�%�%�%�%�%�0�%�0� 
        !          139722: %00%%"%' -%0030=%@%G%O%a%j%q%u0z%�%�$�0�%�0�0�0�%�%�0�0�%�%�0�%�0�%�0�%&0%0%0%&0)%/04%;0>%D%K0P0Y%`0d%g%n0t%z0}%�%�%�%�%�0�0�%�%�%�%�%�%�0�%� �0�$�0�0       %      %      0      0       %@      $Q      %g      0�      %�      %�      %�      %�      %�      %�      %�      0�      %�      0�      %�      %�      0�      %�      '�      0
        !          139723: 0
        !          139724: %
        !          139725: 0 
        !          139726: 0+
        !          139727: 06
        !          139728: %<
        !          139729: %E
        !          139730: 0M
        !          139731: 0U
        !          139732: $[
        !          139733: $b
        !          139734: 0f
        !          139735: $l
        !          139736: 0r
        !          139737: %z
        !          139738: %~
        !          139739: %�
        !          139740: %�
        !          139741: %�
        !          139742: %�
        !          139743: $�
        !          139744: 0�
        !          139745: 0�
        !          139746: %�
        !          139747:  �
        !          139748: %�
        !          139749: 0�
        !          139750: %�
        !          139751: 0�
        !          139752: 0�
        !          139753: %�
        !          139754: 0�
        !          139755: 0�
        !          139756: %%00 0+$@0C0R%e%k0s0~$�0�0�%�%�0�0�$�0�0�%
        !          139757: %%$0%#%)$508%>$J0M%T%Z$f0i%o${0~%�$�0�%�$�0�%�$�0�%�$�0�%�%�$�0�%�$
0
%      
$
0
%
$*
0-
%3
$?
0B
$H
0K
'U
9'X
 '{
5'~
 '�
8'�
 0�
'�
#'�
0�
'�
.0�
'�
'�
 '�
A'�
 '�
&'�
 '�
''�
 '' ' '-='0 '7C': 'G
'V'b'i
'x'�1'�'�%'�0�'�
'�'�'�'�1'�
'�       0�'�'�'&' '46070?0D'S#'Z60]0d'o'r 'y?'| 0707070064030114601006660000030000030000011777770507310760700003700000042766/newbits/kernel/USRSYS/ldrv/gr&�h`"P���v�v�v�Ѓ��VW��6�t;6|Vh��#��j&�g��k�
        !          139758: ��u���ヿtVh�����j�@����������&��&k�
        !          139759: LJ����LJ�������>t
����P���jjh&h��d����G$&t�>�uރ>t
����P���k�
        !          139760: LJ����LJ����LJ+���}.���㋇;tG��W�������LJ����LJ��h����+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v������͋^����G�j����_^�VWU��>�t
�v
        !          139761: �v�����>u���_^�VWU��>�t
        !          139762: �v������u        h������_^�8(+dp& VWU����^�w�O�?t��۽��v�V�F�~�F#F&1��&1�� +��f����.���
�ڀ~(u����F#F&1��&1�� [�^�v�V�~������&��^���O+O&O]_^�6�c����Q��V���B.���&�JK}�Y��������$t������F���F���F�F�F��F&�FP*Ҋv�v
�^�^+��F�6���y6��s*���:v~U�vVQ�^�^
��.���
.���
����.���
Q+���VWQ�Y_^�� �� �F#F_W���_�� ���Y^�D&����.���
�ڀ~(u����I�����.���
        !          139763: ����I�����.���
        !          139764: �~(t�V*���������2���Ȏػ��3F#F�W�3F#F&�&��N�3F#F��3F#F&�&��N�3F#F��3F#F&�&��N�3F#F��F3F#F&�&_^+���:V}
�I�����.���
        !          139765: *���:v�3��v����oV*�������n�����ػ��3F�W&�!��O�3F�&�!��O�3F�&�!��O�
        !          139766: f3F�&�!_^+���:V}
�I�����.���
        !          139767: *���:v����v�j�����I�����.���
        !          139768: *Ҋ���.���
��I�����.���
        !          139769: ��}�V����:v
}*Ҋv
�|��H���I��~�~����.����2���I�<;t!�؀�0��       w9�f�F����FÈF��� ���I��؀�0��    w�f�F����FÈF�ފ���.��������I��؀�0��   w�f�F����FÈF��<htL<ltX�������I��؀�0�� w�f�F����FÈF��<hu��<lu�������€�*����~
u6�&���~
u6����V��}*�:Vr�V���d�� QV+Ɋʀ���*�ыv�~Pu���A��F#ƫ&�A�&�EN&�AN&���&���&���F#�&�����+�^Y:V|*V��:v~�v�����*���:v
s�v
�����~u�F&����~u�F�����:vv�v�����:Vr*V��:vv�v�V�����v��*�v
:vr�v�V��*�:Vr�V���{���:v
}�v
�n�VQ�^����.���
.���
�^��.���
+�~1��VWQ�Y_^�� �� �.���
W���F#F�_�� ���*�Y^��6�&� ��F<u�^�&<&u�^
�r*Ҋv
����.���
�^*��<�F<u�^��<&u*��H*Ҋv
+��^��F��<u�<&t,��.���
*�*�Q�F#F��������� ��}�Y��RQW�F#F��.���
����.���
+�~��WQ�Y_�� �Y����.���
+�~x�׋���P������P������P������������P������P������P�����+�YZ���RQW�F#F��.���
����.���
+�~��WQ�Y_�� �_+ɊN*ʀ~(u��׋���P������P������P������������P������P������P�����+�YZ�t�6���VQ�^�^��.���
�΃�.���
������.+��
~3��VWQ��Y_^�� �� �.���
W���F#F��_�� ���*�Y^�   ��V��*�:Vr�V������F
        !          139770: �u���:Vr�V������v��*�:vv�v�V��*�:Vr�V������:v���v�R��V�v���V�v����:v
}�v
�����Nt
        !          139771: 
�F�����F���F<u�F���F�F�!<&u�F���<u�F���<u�F����D��~Pu�F(�����F�����~(u�FP���F����F��}*�:Fw�^��}*�:^w:�w
        !          139772: �F
�^��*�����v��*�:vv�v����F
        !          139773: �u���:vr�v��ttttttt���&�      t�0
        !          139774: F
        !          139775: ttttttttttt�tttt��������������������������������������������������������������������������������������������������������������������������������ttttttttttttttttttttttt�        �       tttt��ttttt� &ttttttt�       ttttttttttttt�ttttJt��tttttttttttttttt��ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttStt����&e�������tTttt�     �       ttttt�tttttV l       tt�
        !          139776: �
        !          139777: �      �ttttt�   ttttZ
        !          139778: ttt�        ttttttttt@&��@��
        !          139779: @��
@��@��@��@� �!#@$�%�&(@)�*�+-@.�/�02@3�4�57@8�9�:<@=�>�?VWU��n
        !          139780: �~t����~���؋FF=@wW�F+ҹP������������&u�P+�;N~�N�-)N&NV�^�� �P+�;N~�N�)N&N�� +���]_^�VWU��n
        !          139781: �~t��؋v�����FF=@wҋF+ҹP�������������&u�P+�;N~�N�)N&NW�_�� �P+�;N~�N�)N&N�� +��ĺ���ú���6��&��0�3�����0��?�������??��00������?���?���?��������������?���?�������������������?�0000?����������������???�������?�?�������?�����?���<?�<<<?�<�������?�?���������������<������<?�����?�<�<�<�<�<�<�?�������?����<�<<<<�<���������?��?���?�?�����?�������<��<����00��00�?���������?��������������<<���<���<����?��?�<����<��<<�<�<��?����?<<���������<�����<���?�����?���<��<�?������<�<�<?�������?�?��<<�?�<��?��<<�<�<?���<������������<<�<?��<����<�<?����<��?��<�<?��<�<?�?��<�<?�<�?�����������<��?�?���<���<<<���?��<�������?��<��<�<���<�<��<�<<?�<<<����<���<���<�<<<<<<<�����<<?�<<����<<?�<<��<����<<��<�<�<���<�<�<��������������?��<<<<�?�?�<��<�<<<<<<���<�����<�<�<�<�<�<�<�������<?��<�<�<�<�<?���<<<<?�<<�?��<�<�<��?�<��<<<<?�?�<��<?��<����<?�?�3������<<<<<<<<<<<<�<<<<<<<<<<���<�<�<�<�����<�<<���<��<�<<<<<<<���������<�<������<��<���������<<�������?���?<<<<?�<<<<��?��0��0?����?�����?<?������?��<�<��<<�?<����?��?��<<?�<<<<<<?���������?��<<<<�?�<�<<?������<�<�<��<<<<<<<<�<<<<<<���<<<<?�<�?<����?�����?<<<<?��?��?�?�0����������<<<<<<<���<�<�<��<���?�?���������?��?����<�����?���?�����??<���<��<�<�<��VW��v�D u2V�D���F��|$�F��F�&�F��F��F��F�Ph�����ǃ>u�Vh�j
        !          139782: h����_^�VWU������>}2�h�jC�&��h�jB�&��j
        !          139783: jB�&��ja�C&��
��>~�uja�)&��%��Pja�U&���>t��P�����V����v�z���vh�j
        !          139784: h�   ���_^�VWU��>~�>~      �u����_^�VW��v
        !          139785: �D�F��<uV����u����Dup� t'�&�F��&jjh&h�~&���v��&���ы>�E$E&t&�k�t�>�F�;Du��6V����t+��V����|u��� t��V�����u��_^�����܋W+���[XS�`[SSø�`�VWU����_^�VWU���_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          139786: ���~�����~�����vh�f����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`��X��X[SSP�X�VWU��v�~t�~
        !          139787: jjjVh�����
        !          139788: �+��������D�F�D�vh�v
        !          139789: Vh����
        !          139790: W�����_^���`���`���`���`�ldrv:%d: bad dev
        !          139791: ldrv:%d: dev bsy
        !          139792: >>0�0>>>>������P&&�Kttstart_ZERO    mm_vpa�
        !          139793: ismmfunc_AZERO   0mm_cup�mm_scr�      BXXXXXXXX        ��mm_ed�csivalGKsleep_mmtim_mm_hprl  mm_new�     MM_SROW        main_mmspec�mm_sgr�  mm_cuu�scrolldown�mm_hvp�     clrivec_�mmbeeps_&B_XXXXXXX        ?�BX_XXXXXX     ��BXX_XXXXX     ��BXXX_XXXX     ��BXXXX_XXX     �?BXXXXX_XX     ��BXXXXXX_X     ��BXXXXXXX_     ��BANKSZ      mm_dl�mm_voff_XMSR     �ewait0�mm_el�ewait12CLOWER cmmcrtsav_fontw_2read1\mminit�mm_cr�mm_e0cmm_il�read2upage1�nonedev_0uexit_�mmgo_�&rowtab�
csi_q�mm_e1�page2�mmwatch_2B__XXXXXX �B_X_XXXXX     3�B_XX_XXXX     <�B_XXX_XXX     ??B_XXXX_XX     ?�B_XXXXX_X     ?�B_XXXXXX_     ?�BX__XXXXX     ��BX_X_XXXX     ��BX_XX_XXX     �?BX_XXX_XX     ��BX_XXXX_X     ��BX_XXXXX_     ��BXX__XXXX     ��BXX_X_XXX     �?BXX_XX_XX     ��BXX_XXX_X     ��BXX_XXXX_     ��BXXX__XXX     �?BXXX_X_XX     ��BXXX_XX_X     ��BXXX_XXX_     ��BXXXX__XX     �BXXXX_X_X     �3BXXXX_XX_     �<BXXXXX__X     ��BXXXXX_X_     ��BXXXXXX__     ��mm_e2�Kdefend_nondsig_&HLOWER hmm_ssrZ
        !          139794: mm_vpr�
        !          139795: setivec_\Kclrivec_IO_IOC       IO_BASE     sphi_&ldrvipc_NRB2     @&MM_BASE     mm_ri�  grread_u_NCR2        mm_siF
        !          139796: NRB4       �IO_SEG     mmputc�ldrvics_B___XXXXX     �B__X_XXXX     �B__XX_XXX     ?B__XXX_XX     �B__XXXX_X     �B__XXXXX_     �B_X__XXXX     0�B_X_X_XXX     3?B_X_XX_XX     3�B_X_XXX_X     3�B_X_XXXX_     3�B_XX__XXX     <?B_XX_X_XX     <�B_XX_XX_X     <�B_XX_XXX_     <�B_XXX__XX     ?B_XXX_X_X     ?3B_XXX_XX_     ?<B_XXXX__X     ?�B_XXXX_X_     ?�B_XXXXX__     ?�BX___XXXX     ��BX__X_XXX     �?BX__XX_XX     ��BX__XXX_X     ��BX__XXXX_     ��BX_X__XXX     �?BX_X_X_XX     ��BX_X_XX_X     ��BX_X_XXX_     ��BX_XX__XX     �BX_XX_X_X     �3BX_XX_XX_     �<BX_XXX__X     ��BX_XXX_X_     ��BX_XXXX__     ��BXX___XXX     �?BXX__X_XX     ��BXX__XX_X     ��BXX__XXX_     ��BXX_X__XX     �BXX_X_X_X     �3BXX_X_XX_     �<BXX_XX__X     ��BXX_XX_X_     ��BXX_XXX__     ��BXXX___XX     �BXXX__X_X     �3BXXX__XX_     �<BXXX_X__X     ��BXXX_X_X_     ��BXXX_XX__     ��BXXXX___X     �BXXXX__X_     �BXXXX_X__     �0BXXXXX___     ��NCR4     IOSYS     MM_COL     drvl_ldrvcon_inb_NHB PKuexit_outb_Hnulldev_>drvn_ewait�timq_mm_so0
        !          139797: ldrvsel_Knondsig_istty_Ksetivec_xcalledkbunscroll_B____XXXX       �B___X_XXX     ?B___XX_XX     �B___XXX_X     �B___XXXX_     �B__X__XXX     ?B__X_X_XX     �B__X_XX_X     �B__X_XXX_     �B__XX__XX     B__XX_X_X     3B__XX_XX_     <B__XXX__X     �B__XXX_X_     �B__XXXX__     �B_X___XXX     0?B_X__X_XX     0�B_X__XX_X     0�B_X__XXX_     0�B_X_X__XX     3B_X_X_X_X     33B_X_X_XX_     3<B_X_XX__X     3�B_X_XX_X_     3�B_X_XXX__     3�B_XX___XX     <B_XX__X_X     <3B_XX__XX_     <<B_XX_X__X     <�B_XX_X_X_     <�B_XX_XX__     <�B_XXX___X     ?B_XXX__X_     ?B_XXX_X__     ?0B_XXXX___     ?�BX____XXX     �?BX___X_XX     ��BX___XX_X     ��BX___XXX_     ��BX__X__XX     �BX__X_X_X     �3BX__X_XX_     �<BX__XX__X     ��BX__XX_X_     ��BX__XXX__     ��BX_X___XX     �BX_X__X_X     �3BX_X__XX_     �<BX_X_X__X     ��BX_X_X_X_     ��BX_X_XX__     ��BX_XX___X     �BX_XX__X_     �BX_XX_X__     �0BX_XXX___     ��BXX____XX     �BXX___X_X     �3BXX___XX_     �<BXX__X__X     ��BXX__X_X_     ��BXX__XX__     ��BXX_X___X     �BXX_X__X_     �BXX_X_X__     �0BXX_XX___     ��BXXX____X     �BXXX___X_     �BXXX__X__     �0BXXX_X___     ��BXXXX____     �COL     
        !          139798: ttout_�IO_SEEK  con_Kldtimcall_ldrvint_NRB �NCR     crtdata�&putc16�grwrite_�mmwrite_RMM_FLIP     islock_B_____XXX ?B____X_XX     �B____XX_X     �B____XXX_     �B___X__XX     B___X_X_X     3B___X_XX_     <B___XX__X     �B___XX_X_     �B___XXX__     �B__X___XX     B__X__X_X     3B__X__XX_     <B__X_X__X     �B__X_X_X_     �B__X_XX__     �B__XX___X     B__XX__X_     B__XX_X__     0B__XXX___     �B_X____XX     0B_X___X_X     03B_X___XX_     0<B_X__X__X     0�B_X__X_X_     0�B_X__XX__     0�B_X_X___X     3B_X_X__X_     3B_X_X_X__     30B_X_XX___     3�B_XX____X     <B_XX___X_     <B_XX__X__     <0B_XX_X___     <�B_XXX____     ?BX_____XX     �BX____X_X     �3BX____XX_     �<BX___X__X     ��BX___X_X_     ��BX___XX__     ��BX__X___X     �BX__X__X_     �BX__X_X__     �0BX__XX___     ��BX_X____X     �BX_X___X_     �BX_X__X__     �0BX_X_X___     ��BX_XX____     �BXX_____X     �BXX____X_     �BXX___X__     �0BXX__X___     ��BXX_X____     �BXXX_____     �MM_FUNC     MM_MASK     MM_NCOL     mm_cha�done�cprocp_kcall_timeout_4mmstart_2mmtime_�CSR �evaltrepos_Kttout_MM_SCOL ucs_MM_POS MM_VIS     uds_mm_cgh�mm_von_$B______XX B_____X_X     3B_____XX_     <B____X__X     �B____X_X_     �B____XX__     �B___X___X     B___X__X_     B___X_X__     0B___XX___     �B__X____X     B__X___X_     B__X__X__     0B__X_X___     �B__XX____     B_X_____X     0B_X____X_     0B_X___X__     00B_X__X___     0�B_X_X____     3B_XX_____     <BX______X     �BX_____X_     �BX____X__     �0BX___X___     ��BX__X____     �BX_X_____     �BXX______     �wakeup_�spl_*asctab�
        !          139799: mm_cgl�Ktimeout_MM_ROW       SEMIC     ;POS     MSR     �esctab�mm_cbt�mm_hpaV  printf_RB_______X    B______X_     B_____X__     0B____X___     �B___X____     B__X_____     B_X______     0BX_______     �MM_BROW     
MM_WRAP     mm_cub�mm_dmiJldrvpsy_MM_ATTR 
        !          139800: mmdata�mmvcnt_mmesc_&scrollup
putc84mm_esc�mm_emi�mm_ind�       ttstart_�VSEG    �mm_cqhwmm_cud�getcs_MM_EROW MM_ULINE     mm_cnl&csitab�Kwakeup_mm_cuf�ROW     MM_N1     mm_cht�mm_cplemm_old�  grcon_�sleep_MM_N2        mmbell�csi_gtSmm_cql�B________ exit.MM_CURSE MM_IBROW     Kprintf_MM_LROW csi_n1�MM_PORT csi_n2%MM_IEROW mm_eaT0&'&'$�$*0-05'?�'J�$Q0T0\'b&$e'h&$k'o& q'u& w'~�'��&'��'�&'�R&'��'�&'�&$�0�'�H&$�'�&'�&'��'��'��'&j'&R&0&'#&j'-&_'4&U07&'J&�0_&0p&0�&$�&$�&'�&d$�&$�&$�&$�&$�&0�& � � � � � � � � � � �'U&$ 5$j'��& �0�'�'��&    )0] f 0� �0� � 0*00 �0�0�0� � � �0�0� �0�0# N0Q0~0�0�0�0�0�$�0�$�0�0�0`0c0r0u0�0�0�0�0�0� �  
 *0H'M
        !          139801: &0R0_0i w0�0� �0� � � 0a q z0�'�
        !          139802: &0�   
              5      0T      0j      0�      0�      0�      0�      0�      0�      0�      0�      0�      0�      0.
        !          139803: 0D
        !          139804: 0X
        !          139805: 0�
        !          139806: 0�
        !          139807: 0�
        !          139808:  �
        !          139809:  �
        !          139810:  �
        !          139811:  �
        !          139812:  �
        !          139813:  �
        !          139814:  �
        !          139815:  �
        !          139816:  �
        !          139817:  �
        !          139818:  �
        !          139819:  �
        !          139820:  �
        !          139821:  �
        !          139822:  �
        !          139823:  �
        !          139824:  �
        !          139825:  �
        !          139826:  �
        !          139827:  �
        !          139828:  �
        !          139829:  �
        !          139830:  �
        !          139831:  �
        !          139832:  �
        !          139833:  �
        !          139834:  �
        !          139835:  �
        !          139836:  �
        !          139837:  �
        !          139838:  �
        !          139839:  �
        !          139840:  �
        !          139841:  �
        !          139842:  �
        !          139843:  �
        !          139844:  �
        !          139845:  �
        !          139846:  �
        !          139847:  �
        !          139848:  &        
          ! # % ' ) + - / 1 3 5 7 9 ; = ? A C E G I K M O Q S U W Y [ ] _ a c e g i k m o q s u w y { }  � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � &       
          ! # % ' ) + - / 1 3 5 7 9 ; = ? A C E G I K M O Q S U W Y [ ] _ a c e g i k m o q s u w y { }  � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � &
 
 
 
  
 
 

 
 
 
 
 
 
 
 
 
 !
 #
 %
 '
 )
 +
 -
 /
 1
 3
 5
 7
 9
 ;
 =
 ?
 A
 C
 E
 G
 I
 K
 M
 O
 Q
 S
 U
 W
 Y
 [
 ]
 _
 a
 c
 e
 g
 i
 k
 m
 o
 q
 s
 u
 w
 y
 {
 }
 
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
'*U&'�U&$-0D0m%v%} �'�0�0�'�'�0�0�0�0�'�'�0�0�'��&'��&7'
        !          139849: �&00 !'&0)$9$@$G0L0h0r'�0�'��'��0�0�'�H&0�7��'�d0�0�'��'�d0�'�''�'*�'7d'S�&'V�'cd'rj'~_'�d'�_'�R&'�j'�&'��0�'�d'�_'�j'�j'�R&'�d'�[0�'       _'j'
        !          139850: ' �'Px&0S0[0`'o&&'vx&0y0�'�P&'��'�'��'��'��'��&'��0707070064030114571006440000030000030000011777770507310761400003700000014365/newbits/kernel/USRSYS/ldrv/hs&�������v�v�v�Ѓ��VW��6�t;6|Vh��      ��j&�M��k�
        !          139851: ��u���ヿtVh��~       ��j�&����������&��&k�
        !          139852: LJ����LJ�������>t
����P���jjh&h���    ����G$&t�>�uރ>t
����P���k�
        !          139853: LJ����LJ����LJ+���}.���㋇;tG��W�@  ������LJ����LJ��h�q��+���&s=���㋇�F��~�t)�^��G�F��;;F�ujjj�v��D ���͋^����G�j��     ���_^�VWU��>�t
�v
        !          139854: �v�����>u���_^�VWU��>�t
        !          139855: �v������u        h���   ���_^�VW�i^P�6������uh�������i^P�6�����F��F�;|���^�����
        !          139856: iF�^���j��P���j��@P�t����@P�@���t��!��\�Di�D��^������D��D���(&���)&�|��)&����㋇D�F�h���P����v�W����F���P��@P����j��P�����6��F��3��_^�VWU��>�t
        !          139857: �6�����_^�VW��~��i�^����|t�D@P�r��������t�����t�'�r�D�D=&uZV�����F�t;�<�F��DP�'�����L ��t�d���� t�L�v��
���
        !          139858: �d���LV�&���vV����2�_^�VW��~��i�^����|&uJV�%���F��~�t8h�h�j
        !          139859: h����jjh&h������Z*�:�[u̓~�t��N����L���_^�VWU��v
        !          139860: jV�~��i�^�P�����_^�VWU��v
        !          139861: jV�~��i�^�P����_^�VWU���v�v
        !          139862: �~��i�^�P����_^�VWU���v�v
        !          139863: �~��i�^�P����_^�VW��v��X&*�:�Y&t2��Y&*�ȋ�ي�Z&*�PV�)����Y&*�=�rƄY&����Y&�¿���Z*�؊�[*��+���Ǚ.�>���O|9V����F��|+��Z*�ȋ�ًF���\��Z*�=�rƄZ����Z��V�����|tVh�j
        !          139864: ��H&P�,���_^�VW��6��|u�&&�DtL�DP��������t7��&t��t�d����L ��t�� t�L��d��V�"���DP�������t�Dt       jV�M����&t:��X&*�ȋ���F��t�i���^���Z&�Dt��X&��X&*�=&rƄX&�� tC�D u<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�<����[��[*�=&rƄ[��^��;�w����_^�VW��v���F�+���)&t��W�DP������)&����㋇D���t+h��DP����W�t�������P�D@P�����,&%�=&t=t���
        !          139865: ��W�DP���j�D@P�t���v��M����_^�VWU��v�4���DP� ������ t<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�����[��[*�=&rƄ[W�����_^�VWU��������;�|�����_^�VW����t��F��F��F�;}?iF�^��>��}t)iF�^��>���(&����狅l�F��F�;F�}�F��F��F�븋F�;t.��.�>������&���~�th��6�����_^�&d��`�VW��~dra�F+�.�6�  �uS�F+�RPjh�4�����F���&�F�j6jC�����F�%�Pj@�����F���Pj@�����v��&���F���F����F��_^�VW��v�{����F��u�v&�F��F
        !          139866: ��P��v��e&���F��_^�VW���F��~�t!jd�8����:&�F���P�+&���F��_^�d�����`�����܋W+���[XS�`[SSø�`�VWU���_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          139867: ���~�����~�����vh�t����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh�(�������Dž����Dž�_^���`��X��X[SSP�X�VWU��v�~t�~
        !          139868: jjjVh�����
        !          139869: �+��������D�F�D�vh�v
        !          139870: Vh����
        !          139871: W�����_^���`���`���`���`���`���`���`���`���`���`���`���`���`��Ë܋_��Ë܍_VWU��P�V
        !          139872: �F+�+�� ��������;wrw;?r+?w@��[��]_^���`�ldrv:%d: bad dev
        !          139873: ldrv:%d: dev bsy
        !          139874: ����
        !          139875:     ��    7\�� �       �&��       Y@�&�`@:0 dddddddd�,&�&�&X �@hsload: can't allocate tty's
        !          139876: Kttstart_ahigh  
        !          139877: free_�   bhigh        Ksleep_Kttopen_main_ttsignal_fclrivec_Z
        !          139878: Kttpoll_hscycle_�hsparam_�Kfree_uexit_�Kttsignal_hsclose_�altclk_in_        Kdefend_kclear_� altclk_out_Q     setivec_�     Kclrivec_sphi_�
        !          139879: ldrvipc_tthup_u_hsioctl_�hsread_7ldrvics_poll_hz_ldrvl_ldrvcon_inb_�        cs_sel_�     Kuexit_nulldev_� outb_�     drvn_altclk_timq_ldrvsel_Kkclear_ttsetgrp_\Ksetivec_xcalledttclose_ttin_ Ktthup_ttout_>con_Kldtimcall_poll_owner_poll_rate_ldrvint_ttioctl_*ttread_Raltsel_vldiv�hswrite_\cprocp_kcall_� timeout_�
        !          139880: Kttsetgrp_Kttclose_hsstart_iKttin_Kttout_HSNUM_alloc_�ucs_vrdiv�hsopen_ wakeup_�Kttioctl_Kttread_spl_�
        !          139881: Ktimeout_HS_PORTS_
        !          139882: hspoll_�ttwrite_zprintf_�   alow        allkp_ldrvpsy_blow     Kalloc_ttstart_pgetcs_�  Kwakeup_hsintr_�sleep_�
        !          139883: ttopen_4hscon_*Kttwrite_Kprintf_ttpoll_H0&'1'$%$*0-05'?'J$Q0T0\'b1$e'h1$k'o1 q'u1 w'~'�S'�'�1'�E'�('�1'�1$�0�'�;$�'�1'�1'�'�'�('&'&E0&'#&'-&'4&07&'J&'0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& . 0 2 4 6 8 : < > @ B$�&'�&R0�&%�&$�&00$
        !          139884: %0$#0($2%;0H0T0^0h0k t y$�$�0�0�0�0�%�0�%�%�0%0,';0?'C3'K0]0j0w0�0�0�0�%�0�%� �%�0&%001%O0S%t0x%�0�%�0�0� /080q ~0�%�0�0�0�0�0050�%�0�0�0�$�00
        !          139885: 00G0T0]0c0r0~0�0�0�%�%�%�%�%�'�30$%!%2$?'\4'a4 g%j0m'q3 |'�40�'�3'�U'�, �0�0�0�0�0�0&       0#      00      '9      &0<    '?      80E    'X      &0f    0l      's      &'y    80    '�      '�    ,'�    ,'�    )'�    ,'�    ^'�    ,'�    '�    '
        !          139886: '
        !          139887: '
        !          139888: '
        !          139889: E'"
        !          139890: '+
        !          139891: 5'1
        !          139892: +04
        !          139893: ';
        !          139894: 'G
        !          139895: 'R
        !          139896: 'l
        !          139897: 'p
        !          139898: E'v
        !          139899: '}
        !          139900: 0�
        !          139901: '�
        !          139902: '�
        !          139903: '�
        !          139904: '�
        !          139905: ,'�
        !          139906: L0�
        !          139907: 0�
        !          139908: 0�
        !          139909: '�
        !          139910: 2'�
        !          139911: L0�
        !          139912: 0'
?','/','!A'$,'+I'.,'5'8,'?B'B,'I     'L,'SJ'V,']>'`,'g'j,'q't,'{]'~,'�"'�,'�X'�,0707070064030114551006660000030000030000011777770507310761500003700000003777/newbits/kernel/USRSYS/ldrv/mm&:*��&���v�v�v�Ѓ��VW��6�t;6|Vh@�&��j&����k�
        !          139913: ��u���ヿtVhR�&��j�����<��>��&��&k�
        !          139914: LJ����LJ�������>t
����P���jjh&h:�����G$&t�>:uރ>t
����P���k�
        !          139915: LJ����LJ����LJ+���}.���㋇;tG��W�Z&������LJ����LJ��h���+���&s=���㋇�F��~�t)�^��G�F��};F�ujjj�v��P&���͋^����G�j�&���_^�VWU��><t
�v
        !          139916: �v�<���>u�:�_^�VWU��>>t
        !          139917: �v�>���:u        h:�K&���_^Ì��[XS�`[SSø�`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          139918: ���~�����~�����vh�����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh�F�������Dž����Dž�_^���`�VWU��v�~t�~
        !          139919: jjjVh�����
        !          139920: �+�A������D�F�D�vh�v
        !          139921: Vh�����
        !          139922: W� ���_^���`���`��X��X[SSP�X�ldrv:%d: bad dev
        !          139923: ldrv:%d: dev bsy
        !          139924: Ksleep_main_clrivec_tuexit_Kdefend_setivec_�&Kclrivec_sphi_,ldrvipc_u_ldrvics_drvl_ldrvcon_Kuexit_drvn_timq_ldrvsel_Ksetivec_xcalledcon_Kldtimcall_ldrvint_cprocp_kcall_�&timeout_�ucs_wakeup_"spl_0Ktimeout_printf_�&ldrvpsy_getcs_�&Kwakeup_sleep_�Kprintf_0&''$$*0-05'?'J$Q0T0\'b$e'h$k'o q'u w'~'�'�'�'�'�'�'�$�0�'�$�'�'�'�'�'�'&
        !          139925: '&0&'#&
        !          139926: '-&'4&07&'J&0_&0p&0�&$�&$�&'�&  $�&$�&$�&$�&$�&0�&'�&'�&"'�&'�&   '
        !          139927: ''!      '0'8'<
        !          139928: 'E'K0N'U      'a'l
        !          139929: '�
        !          139930: '�'�      '�0�'�'�
        !          139931: '�'�'�0�0�0�'�'00'
''# '&0707070064030114541004440000030000030000011777770507310761500003700000012304/newbits/kernel/USRSYS/ldrv/ms&�      �Dx8���v�v�v�Ѓ��VW��6�t;6|Vh�     �-��j&�]      ��k�
        !          139932: ��u���ヿtVh�  ���j�6      �����        ���   ��&��&k�
        !          139933: LJ����LJ�������>t
����P���jjh&h�       �n����G$&t�>�    uރ>t
����P���k�
        !          139934: LJ����LJ����LJ+���}.���㋇;tG��W��������LJ����LJ��h����+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v������͋^����G�j����_^�VWU��>�      t
�v
        !          139935: �v�� ���>u��   �_^�VWU��>�    t
        !          139936: �v�� ����  u       h�      �����_^�VW���      �D
        !          139937: ��     @�F
        !          139938: ��     @@�H
        !          139939: ��     �J
        !          139940: �+�F�h��6J
        !          139941: �,��j�6H
        !          139942: � ��hP�6�   �;���v����+��_^�VWU���6�   ���h��6J
        !          139943: ����j�6H
        !          139944: �����_^�VW��v�����F��>>
        !          139945: t�'P��������h��6J
        !          139946: ���jZ�6F
        !          139947: ����6F
        !          139948: �R��=Zt
        !          139949: ��v���h��6H
        !          139950: �n���6D
        !          139951: �,��h��6H
        !          139952: �W���6D
        !          139953: ���h��6H
        !          139954: �@���6D
        !          139955: ����h��6H
        !          139956: �)���6D
        !          139957: ����j�6H
        !          139958: ���jh
        !          139959: hT
        !          139960: ���jjh
        !          139961: hf
        !          139962: ���Phb
        !          139963: ���jh 
        !          139964: hj
        !          139965: ���jh$
        !          139966: hn
        !          139967: �w��+����
        !          139968: 
        !          139969: �>
        !          139970: &�v����+��_^�VW���F�j�6H
        !          139971: ���+����>
        !          139972: �v��}��+��_^�VW��g�F��~
        !          139973: |�~
        !          139974: s�v�^
        !          139975: �����  ������v��;���>t����+��_^�VWU��f
        !          139976: ���f
        !          139977: ���
        !          139978: #
        !          139979: 
        !          139980: u�~t        hL
        !          139981: ����
        !          139982: #
        !          139983: 
        !          139984: u�f
        !          139985: ���F
        !          139986: �_^�VWU��jhT
        !          139987: �v�D���>^
        !          139988: u�^
        !          139989: &�>`
        !          139990: u�`
        !          139991: &�_^�VWU��jhb
        !          139992: �v����&
        !          139993: 
        !          139994: ���_^�VWU��j�vhb
        !          139995: �t���&
        !          139996: 
        !          139997: ���_^�VWU��jhj
        !          139998: �v�����_^�VWU��j�vhj
        !          139999: �@���_^�VWU��j�vhn
        !          140000: �)���&
        !          140001: 
        !          140002: ���_^�VWU��j�vh
        !          140003: 
        !          140004: ����_^�VWU��jh
        !          140005: �v�w���
        !          140006: 
        !          140007: #
        !          140008: ujh�h�h
        !          140009: 
        !          140010: �������
        !          140011: �_^�VW��>>
        !          140012: u����F�h��6H
        !          140013: �����6D
        !          140014: ����F�h��6H
        !          140015: ����6D
        !          140016: �r���F��~����F�%ǘ�F�h��6H
        !          140017: ����6D
        !          140018: �F���F�h��6H
        !          140019: �n���6D
        !          140020: �,���F��~����F�%ǘ�F�j�6H
        !          140021: �C��+��F��F��F��u�F�&�n
        !          140022: %&3F�t�~�tjj�jj&�I&���F� u�F��n
        !          140023: %3F�t�~�tjj�jj�&���F�F�n
        !          140024: �~�u  �~�u���F�&j
        !          140025: �F�&l
        !          140026: �v��A&��;T
        !          140027: �v��2&��;T
        !          140028: ~�f��f��~�t7�F���@
        !          140029: �F���>^
        !          140030: �@
        !          140031: �F���>^
        !          140032: b
        !          140033: �F��6X
        !          140034: �6V
        !          140035: P�����b
        !          140036: �~�t7�F���B
        !          140037: �F���>`
        !          140038: �B
        !          140039: �F���>`
        !          140040: d
        !          140041: �F��6\
        !          140042: �6Z
        !          140043: P����d
        !          140044: �b
        !          140045: ;f
        !          140046: u      �d
        !          140047: ;h
        !          140048: t�
        !          140049: 
        !          140050: &jhb
        !          140051: hf
        !          140052: ����
        !          140053: 
        !          140054: #
        !          140055: th
        !          140056: 
        !          140057: �O���>R
        !          140058: t     hL
        !          140059: �����v���&���_^�VWU��k^����p
        !          140060: jhb
        !          140061: kFr
        !          140062: P�N���F
        !          140063:        
        !          140064: 
        !          140065: �_^�VWU��F;F
        !          140066: }�F
        !          140067: ��F;F~�F�F�F�_^�VWU��~}�F����F�_^�VWU��N�      �v
        !          140068: �~��F��]_^Ì���܋W+���[XS�`[SSø�`�VWU����_^�VWU���_^��܋W�G�ø�`���`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          140069: ���~�����~�����vh�R����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`��X��X[SSP�X�VWU��v�~t�~
        !          140070: jjjVh����
        !          140071: �+��������D�F�D�vh�v
        !          140072: Vh����
        !          140073: W�����_^���`���`���`�ldrv:%d: bad dev
        !          140074: ldrv:%d: dev bsy
        !          140075: <
        !          140076: 
        !          140077: i�&&&�44�&=J{����������@&d@&d@&d@&d@&dmsunload_=ms_readcrs_�Ksleep_MSPORT_�       main_Kukcopy_Kkucopy_clrivec_�pollopen_HKpollwake_nonedev_&ms_setmick_�uexit_�     ms_setup_JKdefend_Kclrivec_setivec_fKpollopen_ms_wait_sphi_0     ldrvipc_u_msclose_�abs_�ldrvics_drvl_ldrvcon_inb_Kuexit_nulldev_4outb_>drvn_msioctl_�timq_ldrvsel_blkmv�Ksetivec_xcalledms_readmick_�msload_�&con_Kldtimcall_ldrvint_cprocp_kcall_timeout_> ucs_MSIRQ_� wakeup_�     ioctls_�     spl_4     c_range_�Ktimeout_msopen_ims_readbtns_�ms_setcrs_{printf_\ldrvpsy_getcs_mspoll_ms_readstat_Kwakeup_sleep_& ukcopy_�     kucopy_button_ymsintr_PKprintf_pollwake_Rmscon_� 0&'('$$*0-05'?'J$Q0T0\'b($e'h($k'o( q'u( w'~'�9'�'�('�.'�"'�('�($�0�'�+$�'�('�('�'�'�"'&'&.0&'#&'-&'4&07&'J&!0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& �     �       �       �       �       �       �       �       �       �       �       �       �       �       
        !          140078:  
        !          140079:  
        !          140080:  
        !          140081:  
        !          140082: $�&%�&$�&%�&$�&%�&$�&%0%
0%0 "$&0)02$D0G%Q0T%]0`0s$}'�0�0�%�0�%�0�%�0�'�%�0�%�0�%�0�%�0�%�0�%0%0%0%&0)$1%407$A%D0G%N0Q$Y%\0_$g%j0m'u$y$}0�0�%�0�'�$�0�0�$�'�'�0�'�$$"%-00$6$:%R0X%_%f%l%s%�0�$�%�0�$�%�0�%�0�%�0�$�$0$0%$+$/$<0?$H$X0^0a%k0n%u0x%�0�%�0�%�0�%�0�%�0�%�0�%�0�%0.%@0[%g0v%}%�0�%�0�%�$�%�$�%�%�%�%�0�%�$�%�$&%  %
%%0%"%%%)%.%2$8%?%B0E$K$O$T0W%^%d0g0p%�%�%�0�$�'%'' %'-'I'L%'S        'V%']C'`%'m'|'�'�'�'�.'�'�*'�$0�'�'�'�'�'�.'�'        0    '      '    ''    '*    %'Z    40]    0e      0j      'y      )'�    40�    0�      '�      '�    %'�    '�    %'�    ='�    %0707070064030114511006660000030000030000011777770507310761700003700000006523/newbits/kernel/USRSYS/ldrv/rm&�DX�3���v�v�v�Ѓ��VW��6�t;6|Vh�����j&�3��k�
        !          140083: ��u���ヿtVh�����j�����������&��&k�
        !          140084: LJ����LJ�������>t
����P���jjh&h��R����G$&t�>�uރ>t
����P���k�
        !          140085: LJ����LJ����LJ+���}.���㋇;tG��W�������LJ����LJ��h���+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v�����͋^����G�j�����_^�VWU��>�t
�v
        !          140086: �v�����>u���_^�VWU��>�t
        !          140087: �v������u        h�����_^�VWU���_^�VW��F��~�}%k^�,�������tk^�,����������F����_^�VW��F%�����k�,����N����+҉F��V���T�F��V��~
        !          140088: u�t0�F�F�t�F�F�t�F��V�;V�u;F�u�F�F�u�F�F�u��o�F�F�td�F�F�u\h0��F��V��       �������������RP�o���D���u��,�F��V���T�E�U�D�T�D*jhRP����D*�_^�VW��~�����k�,����~����+҉F��V���T�F��V��t�F�F�t�F��V�;V�u;F�u�|*u��*�L*�F�F�u�|*t�'��t�{����D�_^�VW��v�D�F�%�����k�,����N�����+҉F��V���U�F�V��t�F��V�;V�u;F�t�L��F��V���������F�V��D��    �ȋ�+�D
        !          140089: T-&��;V�w�r;F�s��D
        !          140090: �T�   ������EU�F��V��|&u�D+�RP�t�t�v��v���D+�RP�v��v��t�t���V�d���_^�VWU��v��%�����k�,���h@�j&V�v
        !          140091: W�D��
        !          140092: �_^�VWU��v��%�����k�,���h@�jV�v
        !          140093: W���
        !          140094: �_^���`������`�[XS�`[SS�VWU����_^�VWU���_^���`���`���`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          140095: ���~�����~�����vh�\����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`���`�VWU��v�~t�~
        !          140096: jjjVh����
        !          140097: �+�A�����D�F�D�vh�v
        !          140098: Vh����
        !          140099: W� ���_^���`���`��X��X[SSP�X�ldrv:%d: bad dev
        !          140100: ldrv:%d: dev bsy
        !          140101: !
        !          140102: ���&�&Ksleep_main_clrivec_�Kioreq_nonedev_uexit_jKdefend_setivec_@Kclrivec_sphi_~ldrvipc_u_pclear_ldrvics_drvl_ldrvcon_Kuexit_nulldev_drvn_timq_ldrvsel_Ksetivec_xcalledsalloc_6con_Kldtimcall_Kpclear_ldrvint_cprocp_kcall_�timeout_bdone_�Ksalloc_plrcopy_"ucs_wakeup_tspl_�Ktimeout_Kbdone_printf_,Kplrcopy_ldrvpsy_sfree_getcs_�Kwakeup_sleep_
        !          140103: Kprintf_rmcon_�Ksfree_ioreq_�0&''$$*0-05'?'J$Q0T0\'b$e'h$k'o q'u w'~'�)'�'�'�"'�'�'�$�0�'�$�'�'�'�'�'�'&
'&"0&'#&
'-&
        !          140104: '4&07&'J&0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � � � � � � � � �%%%0%6'�0�'�0�%'b'z0�%�0�0o0v%�0�%�0�'�&'�'�'�'�''''#('&'-.'0'7 ':'G'V
'b
        !          140105: 'i'x
        !          140106: '�"'�
'�'�0�'�'�
        !          140107: '�
'�
'�"'�'�0�'�
        !          140108: '�
'&0''''0%030;0@'O'V%0Y0`'k'n'u,'x0707070064030111121006000000030000030000011777770507310761700003700000034774/newbits/kernel/USRSYS/ldrv/ss&>$�f�� ���v�v�v�Ѓ��VW��6�t;6|VhD$�}"��j&��#��k�
        !          140109: ��u���ヿtVhV$�V"��j�#����@$��B$��&��&k�
        !          140110: LJ����LJ�������>t
����P���jjh&h>$��"����G$&t�>>$uރ>t
����P���k�
        !          140111: LJ����LJ����LJ+���}.���㋇;tG��W�""������LJ����LJ��h�I!��+���&s=���㋇�F��~�t)�^��G�F��!;F�ujjj�v��N"���͋^����G�j�"���_^�VWU��>@$t
�v
        !          140112: �v�@$���>u�>$�_^�VWU��>B$t
        !          140113: �v�B$���>$u        h>$�]"���_^�VW�
        !          140114: �F��F����F���$+ҹ��������&��&jh RP� ����&��&����&��&hZ�RP�a!��h�<��&��&��RP�I!��hZ���&��&���-��RP�+!��h�<��&��&���-��RP�
!���6�&�6�&����=Z�uZ��&��&��RP���=�<u@��&��&���-��RP���=Z�u ��&��&���-��RP�m��=�<th�$����F�&��$����CC.;��t�.�g@�+�Z��&��&����&�'��&��&���'�'�'��a��&��&����&�'��&��&���'�'�'@�2��&��&����&�'��&��&���'�'�'@�'&�'*���!�$�~�uj�F��~�}�>�$�N�����&t    �F��F��F��F��݃~�uh�$����F�&�,iF��P�6���� '�uh�$��iF��P�6 '�[���~�u6� '�F��F��~�}%�>�$�N�����&t�~���F��F����"'�F���h��6�$�D���2'���F�@P�'���'5�~�u&�F��~�}�>�$�N�����&tQ�����F����' N�_^�VWU��> 't
        !          140115: �6 '�����6�&�6�&�:���6�$�B���_^�VW��v����%�F���%�F�����%�F��~��狅"'�F�"�F�������u�&�N���#�$u�F�%��v�V�������ƀt
�~�t�F�$%���ƀt�F��~�tX�~����uM��
�%���F��v�P����t,�~���U�~��EL�UN�EH�EJ�~�����������F�:%�r��~�tE�~��EL�UN�F��V�^���ߋ~���~��E�U
        !          140116: GW;V�wr;F�v
�F�N%�%�,��~�t�~���~��EEu
�F�o%������~��E�_^�VW��F��%�F��~��狅"'�F����~��M�_^�VWU��h@�j&�v�v
        !          140117: h�&����
        !          140118: �_^�VWU��h@�j�v�v
        !          140119: h�&���
        !          140120: �_^�VW��v�F�����%�F�~��狅"'�F�"�F�F
        !          140121: =&Ht=HtU��F�����F�"�F�~������$�F�F��~������$*�F��~������$*�F�j�v�F�P�G���C�F�"�F�j�F�P�v����~����F�$�~����F�*䈅�$�~����F�*䈅�$�F��F��_^�VW��v�F��D�F�%�F��F���%�F��F���%�F��~��狅"'�F��F��t�F��F�"�F��D�D�~����u>�~�u1�D
        !          140122: Du�|tt�F�%�L�~�t�v��v�����V��w�F�%�܀|&u�~���~��D
        !          140123: �T;Uu;Et‹^���^��|��    ��+�D
        !          140124: T;Wwr;Gv�F�%��D�&u�|u�F�%�|�V�v��p���v��Q
        !          140125: ���_^�VW���        �F��~��t!�v��拼"'�}ruPh��v�h��0���_^�VW��F�&�v�拼"'�}ru�vh������@�u����F��F�P�%���u���~�u��6'�6�&����%�F��F�*�P���=w�����.��v  �       .       .       .       �       .       .       .       �       .       �       .       �       .       �       �6'�6'����F��t=u�j`�6'�6�&�����m�j�6'�6'���h����6'�6'�g���F��D��F��<��6'�6'�K���+��v�����_^�VW��F��~�},�~��狅"'�F��~�t�~��}t�v�h�����F����_^�VW��F��F��~��}7�6'�6�&�����F��v����F�*���F��#�;�u�F�&��F��‹F��_^�VW�j�F�&�~�狅"'�F��~���j$���
��F��vh�%�����~�t6�F�P�vhU�R���t�F��~�u�F�&�h�%�h�%�v�����~�u���F�P�vh����u���F�&�F�*䙹�������F��V��F�*䙹�������F��V��F�*����ȊF�*����+�F�V�F�V��~���U�F�*䙹�������F��V��F�*䙹�������F��V��F�*����ȊF�*����+�F�V�F�V��~��E�URP�u�5h&���
        !          140126: �h-&�v��0���~�u�&�F�P�vh��%���u���F�*���F�*���ljF��F�*�ȊF�*�����F�*�������Ǚ�F��V��F�*�F�R�v�hB&�7���F�*�Ph\&�(���v�hf&����~�����$u+�~���F����$�~���F�*䈅�$�~���F����$�J�~�����$hn&�����~�����$*�Ph�&����~�����$*�Ph�&��        h�&�v��"���F��_^�VW��~�狅"'�F��~��E �F��F�&�v�~�E+D�F��F��~��E�E���F��F�P��&���u��&�~�u�&�6'�6�&����%�F��~�u��F��F�&�F�*�P�Z��=w�����.���
b
b
b
�b
b
b
ob
Cb
Xb
�
�6'�6'�d���F��F�*��CC.;��t�a�.�g��%b
b
%b
b
b
b
�F�*�~��Ej`�6'�6�&�C����j�6'�6'�0��h����6'�6'�����~��E����v��~��E+D�F��~�~F�|�D��E*�P�6'�6'�����~�&t���~�}&t���~�u���v��������F����~�u�~�}&u��F�&h�F�EURP�6'�6'���
        !          140127: �\��~�u��~�}u��F�&h�6'�6'�F�EURP�g��
        !          140128: �{��~�t       �v��l���~�t+���&�_^�VW�   �Y�F��~�&�F��F��F��'+�;V�wr:;F�v5�6'�6�&����F��F�t�F�&��F�&�V����F�&u��~��v������F��_^�VW��F��F��F��F��F��F��F��?�tRj�v����tCjjj�F�Pj�F�P����t)�F�*�;�CC.;��u.�gIII�F�&�F��_^�VW��F��F��F��F��F��F�6�F���t-j�v�<���tjjj6�v
        !          140129: j�F�P����t�F�&�F��_^�VW��F��F��F��F�?�F��F�\�F��^�t-j�v�����tjjj\�v
        !          140130: j�F�P�3���t�F�&�F��_^�VW��F��F�%�F��F��F��F��F��F��F��F��F����t-j�v�p���tjjj�v
        !          140131: j
        !          140132: �F�P��
        !          140133: ���t�F�&�F��_^�VW��F�&�~���j$���
��F��~�tFj �6'�6�&�����'*�P�6'�6'���j0�6'�6�&���h���s����u�F��~�tA�&�N��'*��P�6'�6'�u��h��6'�6�&�d��h&&�,����u�F��~�t#h��6'�6�&�;��h�����u�F��~�t3h��6'�6�&���j�6'�6'���h�������u�F��F��_^�VW��F����6'�6�&����F��F�$tE�6'�6'����F��'*���F�*�#�t$�F�*�#�$t�'*��� F��F��n�t�F����F��_^�VW��~�狅"'�F��'&�>'u��&�~��E �F��Er*�-=v�&����.��LRH��6'�6�&�������ǀt6�~���������j&�v�D���t�v�!���j&�v����낋~����t��������j���'�^��6'�6�&�{������$tT�&�N��'*����6'�6'�T��#�t1�~����������>2'�u�F�2'��2';F�?�t�]��e��~����t���������j�K��~�u
        !          140134: �~��Er����>2'�uj�6'�6�&��
������!uT�6'�6�&��
������!u>�~����������v�����t�F�2'j&�v����d�j
        !          140135: �v���������F�=��t�vh��A
���~�����~����drj��j�Ƌ~����t���v��{��_^�VW�
        !          140136: �~�狅"'�F��~��E �F��Er*�=v��&����.��F�X��333��v�!����t�'j�v�4���~��Er�&j&�v���&�v����u�&�~����&t�&��������&�v�&���F��~��E �~��E�F�%�F��F��t�F��F�"�F��~�t�v�����~��E
        !          140137: �UDT
        !          140138: �      �~��E
        !          140139: �U�~��E�U
        !          140140: �~��}&u       �~��E(��~��E*�~��E�E�U
        !          140141: ��������~��E�E�U
        !          140142: ��������~��E�E�U
        !          140143: ��������~��E�E�E�E�E�E&�E�E
        !          140144: �v����~�ƅ�ƅ�ƅ��Er�|�'�t�2';Ft�>2'�uZ�F�2'h��6'�6�&����~��Er�:�2';Fu�2'���v������u�t��~��j �6'�6�&�b���~��Erj(�v�w&���_^�VW��F�j �6'�6�&�1���'*�P�6'�6'���j0�6'�6�&�
���F��~��}:�6'�6�&�
        !          140145: �����ǀt�F�&��F������=��t�j �6'�6�&�����F��_^�VW��F��&�N��'*��P�6'�6'���h��6'�6�&���h&&�N���tPh��6'�6�&�h��h�0���t2�~
        !          140146: th��h��6'�6'�?��h��6'�6�&�.���F�&�F��_^�VW��F�h��6'�6�&���h �����th��6'�6�&��
        !          140147: ���F�&�F��_^�VW��~�狅"'�F��~������������������'�vh��v
        !          140148: sP��
        !          140149: ���_^�VW��~�狅"'�F��~����t�����������������v������_^�VW��~�狅"'�F��~��E �F��E���Eƅ��_^�VW��~�狅"'�F��~��E �F�����~����
        !          140150: su�F
        !          140151: =v�����.����������~�����~����s�Erj�v�������~��Er&�z�~��Er�q�~�����~����r��Er�Z�~��Er�Q�~�tB�~��M�E%�P�E��%�Ph�&����~��u�u
        !          140152: �}&uh�&�h�&h�&�h���v����_^�VW��~�狅"'�F��~��E �F��F�&�2';Fu�2'���~����������~�t5�~��Eu�m�~��Eu�}u�~��E �v�����F��~�te�~��Erƅ�ƅ�ƅ��E&�U
        !          140153: �E�U
        !          140154: ��������~��E�E�U
        !          140155: ��������~��E�E�U
        !          140156: ��������~��E�E�E��'�~��Er�v����_^�VW��F�F��F��~�|�F��~��烽"'t*�~��狽"'�}ru
�v��     ���t�v�h�����F�;Fu��_^�VW��~�狅"'�F��v�W���F��~�tQ�~��E=u�Erj2�v���@�~��}u�}u�v�U����)�~��E=uj��~��E=uj�j&�v�7����_^�VW��F��F��F��F��F�&�F����F����Q�F��F�P�����u�3&�~�u�*&�6'�6�&����%�F��F�*�P�m��=w�����.����```_````�``��6'�6'�w���F��t=u�j`�6'�6�&����m�j�6'�6'���h����6'�6'�5���F��D��F�;F
        !          140157: s3�~��F�~�*�P�6'�6'�C���F�;F
        !          140158: t���v��a�����F��&��F�;Fs��~��F�~�6'�6'���������F�;Fs��6'�6'�~��F�~�*�P�F��v�����~�u�~�t�~�u�F�&�F��_^�VW����F�h��6'�6�&���j2�(��j �6'�6�&���j2����v�����_^�VW��F��F�;F}�F��~�0u}�F����F����_^�VW��F�&�^�F��F��~�|��6�F��~��t �v
        !          140159: ����v�v
        !          140160: �V���un�v
        !          140161: �F���v�v
        !          140162: �V���uU�v
        !          140163: �����t!j2�d����v
        !          140164: ����v�v
        !          140165: �V���u'����v
        !          140166: ������v�v
        !          140167: �V���u�F��i��F��v�����F��_^�VW�&�F�F��>'t�f���Ft�N��Ft�N��F�*��_^�U��WV�v�ށ��~���&���uHu������^_]�U��WV�v�~�߁����&&���uHu������^_]�U��WV�v�~�N�^_]�VW��~~2kFP�6����6'�t�F�&kFP�66'����F�4'��F��F��_^�VWU���4'�>6't
        !          140168: �66'�S���_^�VW��F;4'}dkF6'�F��s�F��~��}u�F
        !          140169: �E�+��~
        !          140170: �E��'�~��}�F
        !          140171: ��~
        !          140172: ��~��E�~
        !          140173: �E�F
        !          140174: �~��E�~��E�v��$���_^�VW��F;4'}kF6'�F��~���+��_^�VW��F;4'}[kF6'�F����F��~��}~1��F��E=&u  +��E���~��=��~���=�E�~��M��F��v������F��F��_^�VW��v
        !          140175: �F��k�F�j&j�v�����>uej&jj�v����F��tF�^�����&U�u/�F��~�}j�F�����&P�ƃ�P�D���F����F�&�v��W���v�X���v���&���F��_^���`���`�VWU��N�     �v
        !          140176: �~��F��]_^ø�`���`���`�U���v�v�P�S��]���`���`�WU���~+�&�]_�WU���~&�]_���`������`�[XS�`[SSø�`���`�VWU���_^���`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          140177: ���~�����~�����vh�j����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^�WU���~�F&�]_�WU���~�F&�]_ø�`��X��X[SSP�X��X��VWU��v�~t�~
        !          140178: jjjVh����
        !          140179: �+��������D�F�D�vh�v
        !          140180: Vh�{���
        !          140181: W�����_^���`���`���`���`�ldrv:%d: bad dev
        !          140182: ldrv:%d: dev bsy
        !          140183: 
&c�����"
        !          140184: �&��"�Error - host failed memory test
        !          140185: Error - ss has no valid target id's
        !          140186: Error - ss can't allocate structs
        !          140187: bad LUN or SCSI idbad special partitionbad partition tablepartition exceeds drive capacitypartition not foundinvalid requestno partition tablepartition overruninvalid byte countSCSI ID %d  LUN 0
        !          140188: Not Direct Access DeviceInquiry FailedCapacity=%ld blocks  Block length=%ld
        !          140189: Read Capacity FailedPhysical:  cylinders=%ld heads=%d spt=%d
        !          140190: Logical:  cylinders=%d heads=%d spt=%d
        !          140191: Mode Sense Failed(%d,%d): %s error bno=%ld
        !          140192: readwriteKdopen_free_j"Ksleep_main_Kukcopy_Kkucopy_sscon_h$ss_getb_:clrivec_<#Kioreq_Kfree_uexit_$SS_INT_�$Kdefend_kclear_�"Kclrivec_setivec_�"sphi_�#ldrvipc_u_ldrvics_drvl_ldrvcon_Kuexit_dclose_"nulldev_�"drvn_timq_ldrvsel_Kkclear_blkmv�!Ksetivec_xcalledbread_"splo_�#bufq_wr_tail_ ss_putb_jffbyte_H"con_Kldtimcall_bufq_init_�ldrvint_brelease_
        !          140193: "CSR_OFF      bufq_rlse_�Kdclose_devmsg_4"defer_"ffcopy_�cprocp_kcall_�"timeout_�#ffword_Z"bdone_�!Kbread_G01Pptov_�"REQ_LIM �&G02SG03_alloc_�!ucs_G04bsfbyte_�#wakeup_4$Kbrelease_RS_REQUEST     spl_�#Kdevmsg_vrelse_*$fdisk_2!Ktimeout_P01�Kbdone_P02�printf_�"Kptov_P03�allkp_bufq_rd_head_� ldrvpsy_P04�sfword_�#Kalloc_dopen_>"getcs_t"Kwakeup_sleep_�#NSDRIVE_�$drv_parm_�$kucopy_�"ukcopy_ $Kvrelse_bufq_rm_head_� Kprintf_KldeferBSIZE ss_mach_SS_BASE_�$ioreq_x"0&'&'$$*0-05'?'J$Q0T0\'b&$e'h&$k'o& q'u& w'~'�P'�'�&'�='�'�&'�&$�0�'�1$�'�&'�&'�'�'�'&'&=0&'#&'-&'4&
07&'J&0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& l$ n$ p$ r$ t$ v$ x$ z$ |$ ~$ �$$�&%%0%%%#%'0/%8%<0G%P%T0e%n%r0�%�%�0�%�%�0�%�%�0�%�%�0�$�0�$ 
        !          140194: 0 % ' )%,%0%9%=%@%D%M%Q%U%[%_%h%l%o%s%|%�%�%�%�%�%�%�%�%�%�%�%�%�$�$�$�0�'N0%$"%.01%=$O%k s$w0z%�0�%�$�0�%�%�%�0�0�%�%�0�$�0�%/$O$V'Z0b0h$y0�$�0�$''+0/$K'O0S'W%|'�%�0�%�0�%�'0$$/$>0O0i$y$�$�%�$!050<$C$�$�0�0�0�0�%� � �0�%          0      0      0      0&      0)      03      0=      0F      %J      %N      0Q      0c       t       v       x       z       |       ~       �       �       �       �       �       �       �       �       �       �      %�      %�      0�      %�      %�      0�      0�      %�      %�      0�      %�      %�      0�      0�      0�      %�      %�      0�      0&
        !          140195: 0
        !          140196: %(
        !          140197:  @
        !          140198: 0C
        !          140199: %j
        !          140200: %n
        !          140201: 0q
        !          140202: %�
        !          140203: $�
        !          140204: $�
        !          140205: 0�
        !          140206:  �
        !          140207: 0�
        !          140208: $      $00  *0-07$�0�$�00 00%$p0s$0�$�0�$�$�$�$�$�$�0�$�$�0�$�$
0
$
        !          140209: 
0
%)
0g
0q
0z
%~
%�
0�
0�
0�
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
%�
%�
0�
 �
0�
       ! #%4%80;0A%G%K0N%Z%^0a0m%�%�0�0�0�0�0�0�0�%�%�0�0%%#02080D0a%}%�%�0�0�0�00 + C E G0y0�0�0�0�0�0E0Q0j$�%�%�0�%�%�%�0�%�%�0�0�%�%%0  %%00#%<%@0C0L%e%i0l%u%y0|0�%�%�0�%�%�0�%�$�%�%%%"0(0A J L N P%T%X0[0}0�0�%�0�%�%�0�%�%�%�0�%%%0 0'0*0F0V%Z%a%e0h%w%{0~0�0�%�0�0�0�0�0� �0�0�000%"0; D F H J L N P R T V0\%g0q0~0�0�0�0�0�0�0�%�%�%�%�%�%�0�%�%�00
        !          140210: %%00.%F%J0M%S%Z%^0a%j%n0q%�%�0�0�%�%�0�%�%�%�0�%�%�0�0&%%00%8%<0?%I%M0P%q%u0x0�%�%�0�%�%� �0�%�0*%@%n0� � � � � � � �0�0�$0"$7$<$?0B0K%a%u%~0�%90H%r%~0� �0�%�0�0�0�0(0[0e0o0x%|%�0�0� � � � � � � � � � � � � � � � �%�%�0�%�%�0�0�%�%�0�%
        !          140211: %00%4%80;0I0O0U0]%r%v0y0�%�%�0�0�0�%�%�0�0�%�%�0�000N0_0b0q0�0�0�0�0�0�0�0�%'�N0�%�%�0�%�% % % 0 %) %3 09 0� %� %� %� %� 0� 0!0A!0N!'U!0d!0�!0�!0�!0�!'�!S'�! '�!I'�! '&"6'" '"A'" '"-'" ')"_0-"'5"D'8" '?"'B" 'k"
        !          140212: 'n" 'y"      '|" '�" '�"'�" '�"'�" '�"^'�" '�"L'�" '�"'�"'�"'�"'�"'#='#'
#)'#0#'#')#'4#'N#'R#='X#'_#0b#'m#'w#'�#'�# '�#G0�#0�#0�#'�#''$G0$0$'$'$ '!$'$$ '+$\'.$ '5$V'8$ 0707070064030114621006660000030000030000011777770507310762300003700000014471/newbits/kernel/USRSYS/ldrv/dg&�`:���v�v�v�Ѓ��VWU����6�t�;�V��P��
        !          140213: ���&P�E����.�.�&�؃�u���ヿtV��P��
        !          140214: ��+�P�����������&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P��P�Q����G$&t�>�u܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W�
        !          140215: ������LJ����LJ�ϸP�        ��+��&G��&}5���㋇�F��~�t��t       �ȋ^��G;�u+�PPPS�
        !          140216: ���ҋ^����+�P��
        !          140217: ����]_^�VWU��>�t
�v
        !          140218: �v�����>u��]_^�VWU��>�t
        !          140219: �v������u
        !          140220: ��P�
        !          140221: ��]_^�
        !          140222: VWU��P�O      P�6��+ ����������������&P�PR�6�������P�6������&P�:���6�����F��F��%&=&u���s&�P�6�����6��c���F��F��%&=&u�
�F&�4
P�x���P�6��`���dP�����6��"��%=t�>6t�D
�&�
        !          140223: P��ոP�6�� ���c
P� ���Z�P�6�6������<P����RP�����Z�P������RP������<P������RP����6�6�m��=Z�uN����RP�S��=�<u4������RP�9��=Z�u������RP���=�<t�w
�!��
P�S���P�6��;���@&��
P�5����]_^�VWU��>>t�>+�P����RP�����P�6������6��~���6�6�E��]_^�VWU���F�t#�>8t�'�7�>@t+�8&�<�"�F@t�>:uփ>Bt�:&���]_^�VWU���F�t&�8�><uB�7&�t;�@�B&��
�#�F@t#�:�&�t�B�>&��
P�*��]_^�VWU��v
        !          140224: ]_^�VWU��P�v
        !          140225: �F�t7V�����F��|_�><}WP�<����RP����<���F@t/V����F��|!P�<� ��RP�y���<�ы�]_^�VWU��P��P�v�P���+�P���P+�P�P�c��]_^�VWU���6�&P��P�v�&P�I��]_^�VWU��F�6]_^�VWU��+�P����RP�����P�6�������P��������RP���=GDt�>6t�P����+���
        !          140226: P�0��Ÿ#P����&]_^�VWU��P�P��@��RP�}����P��B��RP�d��+�P��D��RP�L���P��F��RP�3��+�P��H��RP���� P��J��RP����
        !          140227: P�6�����P�6������dP������@��RP����t�>6t
�7P������&�
        !          140228: P�)��ǸXP����&P��@��RP����P��B��RP�j���P��D��RP�Q��+�P�� 
��RP�9���
        !          140229: P�6��9���P�6��+����&P������� 
��RP����=OSt?�>6t/�{P�����@��RP���P��P����+����
        !          140230: P�=�뤸�P������"��RP�Y���D�&P����RP�����
��RP�:���F����P�F����RP�I�����P�F����RP�+���F�%�P��
��RP����dP�����F&�>Ft �>6t
��P��&�����
        !          140231: P�[����ٸ�P��&���&��]_^�VWU�����
��RP�u&���F���
��RP�]&���F���
��RP�E&���F���
��RP�-&���F��>>u����
��RP�&������
��RP����;�u����
��RP�����F��F��~�}3��~�F�؋ʋF������RP����E��F��NJF�*�P�F�*�P�F�*�P�F�*�P�&P���
        !          140232: �F�%�P��
��RP�&���3��>Ft1�F��
��RP�1��P��
��RP�K&����]_^�WU���~+�&�]_�WU���~&�]_�����܋W+�����`�[XS�`[SS�VWU��]_^��܋W�G�ø�`���`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          140233: ���~�����~�����v�P�s����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P�&�������Dž����Dž]_^�WU���~�F&�]_�WU���~�F&�]_ø�`�VWU��v�~t�~
        !          140234: +�PPPV�P����
        !          140235: �-�M�����D�F�D�v�P�v
        !          140236: V�P����
        !          140237: W�*��]_^���`���`���`��X��X[SSP�X�ldrv:%d: bad dev
        !          140238: ldrv:%d: dev bsy
        !          140239: N��&�Error - board type is PC/Xi
        !          140240: Error - board type is PC/Xm
        !          140241: PC/Xe ID found
        !          140242: Error - PC/Xe failed to reset
        !          140243: PC/Xe passed reset
        !          140244: Error - PC/Xe failed memory test
        !          140245: PC/Xe passed memory test
        !          140246: PC/Xe waiting for BIOS load
        !          140247: PC/Xe waiting for FEPOS load
        !          140248: PC/Xe ready for use
        !          140249: Error - PC/Xe BIOS won't start
        !          140250: PC/Xe BIOS started
        !          140251: Error - PC/Xe FEPOS move failed
        !          140252: PC/Xe FEPOS relocated to host RAM
        !          140253: Error - PC/Xe FEPOS won't start
        !          140254: Failure code (%x)
        !          140255: PC/Xe FEPOS started
        !          140256: Error - PC/Xe no FEPOS interrupts
        !          140257: PC/Xe interrupts working
        !          140258: %x %x %x %x
        !          140259: Ksleep_main_clrivec_�uexit_�Kdefend_Kclrivec_setivec_:sphi_�ldrvipc_u_ldrvics_drvl_ldrvcon_inb_�
        !          140260: Kuexit_nulldev_outb_drvn_iogetc_�
        !          140261: timq_ldrvsel_Ksetivec_xcalledffbyte_�
        !          140262: con_Kldtimcall_ldrvint_DG_IOB_�Kiogetc_cprocp_kcall_timeout_*ffword_�
        !          140263: ptov_0DG_RAM_�dgcon_�ucs_sfbyte_�wakeup_�spl_�vrelse_�Ktimeout_printf_&Kptov_ldrvpsy_DG_INT_�sfword_getcs_�
        !          140264: Kwakeup_sleep_ Kvrelse_Kprintf_0&''%$-010; E'K'V$]0a0j'p$s'v$y'} '� � �'�'�,'�'�'�$'�'�'�$�0�'�$�'�'� �'&'&'&',&
        !          140265: '0&$06&'A&
        !          140266: 'K&'R&0V&'l&0x&0�&0�&$�&$�&'�&  $�&$�&$�&$�&$�&0�& � � � � � � � � � � � $
        !          140267: 0
$$%#%'%407%=%A$I0L0V$]0`$u0x$�0�$�0�$�0�$�0�$�0�0�$�0�%�$�0�0�$�0�$0%%0% %$0/%9%=0H%R%V0a%h%l0o%z%~0�%�%�0�%�%�0�$�$�0�$�0�%�$�0�%&%%%0$*0-$407%>%B0E%\'c     %j%q%w%�%�%�'�  %�%�0�%�%�$�%�0�%�%�$�0�0!%/%7%<%@0K%R0_%m%r%v0�%�%� �%�0�%�0�%� �%�0�%�%%0$00'%-%10<%H$N0R0`$e0i%�%�0�%�%�0�%�%�0�%�%�0�%�%�0�%�%�0
        !          140268: $0$#0&00%6%:0E%P$V0Z0`0g$l0p%z%~0�%�%�0�%�%�0�%�%�0�$�0�$�0�0�%�%0%$ 0$%*%.09$@0D0L0S$X0\%b%f0q%w%~%�0�%�%�0�%�%�0�%�%�0�%�%�0 0
        !          140269:        %      %      %      $$      0(      0.      05      $=      0A      %X      %\      0g      %p      %t      0      %�      %�      0�      %�      %�      0�      %�      0�      %�      %�      0�      %�      %�      0�      0�      %�      %�      0
        !          140270: %*
        !          140271: %.
        !          140272: 0=
        !          140273: $c
        !          140274: 0g
        !          140275: %w
        !          140276: %{
        !          140277: 0�
        !          140278: 0�
        !          140279: %�
        !          140280: %�
        !          140281: %�
        !          140282: %�
        !          140283: 0�
        !          140284: %�
        !          140285: %�
        !          140286: 0�
        !          140287: '�
        !          140288: ''
        !          140289: ''3'*'1+'4'A     'P
        !          140290: '\'c      'r'z$'~
        !          140291: '�'�0�'�      '�'�
        !          140292: '�
        !          140293: '�$'�      '�0�'�'�
        !          140294: '!'$'E)0I0Q0V'e'm)0q0x'�'�'�2'�'�0'�0707070064030114561006440000030000030000011777770507310762400004300000014732/newbits/kernel/USRSYS/ldrv/hs.310&L�����v�v�v�Ѓ��VWU����6�t�;�V�RP�
        !          140295: ���&P�����.�.�&�؃�u���ヿtV�dP��        ��+�P�����N��P��&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P�LP�;
        !          140296: ����G$&t�>Lu܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W�       ������LJ����LJ�ϸP���+��&G��&}5���㋇�F��~�t���ȋ^��G;�u+�PPPS�  ���ҋ^����+�P�Q
        !          140297: ����]_^�VWU��>Nt
�v
        !          140298: �v�N���>u�L]_^�VWU��>Pt
        !          140299: �v�P���Lu
        !          140300: �LP�M
        !          140301: ��]_^�
        !          140302: VWU����v.�&�P�6����� 
�u
�
P������v.�&�P�6 
�����F��F�;v|���^����㋿x.�.� 
��+�P��P����+�P��@P�����@P����t��a��\�D��D��^����㋇z�D��D���(&���)&�|��)&����㋇��F���P��P�S���v�W�I���F����P��@P�7���P��P�'���6"
�F��+���]_^�VWU���6 
����]_^�VWU��P�F%.�.� 
���|t�D@P���������t�����t�'�r�D�D=&uZV����F�t;�~�F��DP�g�����L ��t�d���� t�L�v��O���
        !          140303: �d���LV�&&���vV�����N��]_^�VWU��P�F%.�.� 
���|&uQV�g���F��~�t?�$
P�BP�
        !          140304: P�$
P����+�PP�&P�$
P������Z*�:�[uƃ~�t��N���L����]_^�VWU��v
        !          140305: +�PV�F%.�.� 
P�5��]_^�VWU��v
        !          140306: +�PV�F%.�.� 
P�7��]_^�VWU���v�v
        !          140307: �F%.�.� 
P����]_^�VWU���v�v
        !          140308: �F%.�.� 
P���]_^�VWU��P�v��X&*�:�Y&t2��Y&*�ȋ�ي�Z&*�PV�`����Y&*�=�rƄY&����Y&�¿���Z*�؊�[*��+���Ǚ.�>���O|9V�;���F��|+��Z*�ȋ�ًF���\��Z*�=�rƄZ����Z��V�4���|tV�P�
        !          140309: P��H&P�^����]_^�VWU��P�6 
�|u�&�DtL�DP�������t7��&t��t�d����L ��t�� t�L��d��V�T���DP��������t�Dt�PV�}����&t:��X&*�ȋ���F��t����^���Z&�Dt��X&��X&*�=&rƄX&�� tC�D u<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�h����[��[*�=&rƄ[��^��;"
w�����]_^�VWU��P�v��F�+���)&t��W�DP�����)&����㋇����t-��P�DP����W�t�����DZ��P�D@P������,&%�=&t=t���
        !          140310: ��W�DP����P�D@P����v��u�����]_^�VWU��v�Z���DP�D������ t<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�>����[��[*�=&rƄ[W���]_^�VWU�����6
�6
;4
|�6
�6
]_^�VWU������t��F��F��F�;v}B.�.���> 
�}t,�F�.�.���> 
��(&����狅��F��F�;F�}�F��F��F�뵋F�;t/��.�>��4
���&���~�t�P�6������]_^�^&d��`�VWU����~drm�F+�.�6�  �u_�F+�RP�P��4P�����F���&�F��6P�CP�����F�%�P�@P�����F����P�@P�����v��&���F���F����F���]_^�VWU����v�i����F��u�&�F��F
        !          140311: ��X��v��o&���F���]_^�VWU�����F��~�t#�dP� ����>&�F���P�/&���F���]_^�d�����`�����܋W+���[XS�`[SSø�`�VWU��]_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          140312: ���~�����~�����v�P�s����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P�&�������Dž����Dž]_^���`��X��X[SSP�X�VWU��v�~t�~
        !          140313: +�PPPV�P�����
        !          140314: �-��������D�F�D�v�P�v
        !          140315: V�P����
        !          140316: W����]_^���`���`���`���`���`���`���`���`���`���`���`���`���`��Ë܋_��Ë܍_VWU��P�V
        !          140317: �F+�+�� ��������;wrw;?r+?w@��[��]_^���`�ldrv:%d: bad dev
        !          140318: ldrv:%d: dev bsy
        !          140319: ����
        !          140320: 3�*
        !          140321: l��*
        !          140322: *
        !          140323: �& �      Y@�&�`@:0 dddddddd�,&�&�&X �@hsload: can't allocate tty's
        !          140324: Kttstart_ahigh  
        !          140325: free_�   bhigh        Ksleep_Kttopen_main_ttsignal_�clrivec_�
        !          140326: Kttpoll_hscycle_hsparam_�Kfree_uexit_�Kttsignal_hsclose_�altclk_in_y        Kdefend_kclear_ 
        !          140327: altclk_out_�    setivec_H
        !          140328: Kclrivec_sphi_ldrvipc_tthup_�u_hsioctl_�hsread_lldrvics_poll_hz_�drvl_ldrvcon_inb_
        !          140329: 
        !          140330: cs_sel_�    Kuexit_nulldev_*
        !          140331: outb_4
        !          140332: drvn_altclk_timq_ldrvsel_Kkclear_ttsetgrp_�Ksetivec_xcalledttclose_zttin_�Ktthup_ttout_�con_Kldtimcall_poll_owner_poll_rate_ldrvint_ttioctl_�ttread_�altsel_vldiv�hswrite_�cprocp_kcall_
        !          140333: timeout_"Kttsetgrp_Kttclose_hsstart_�Kttin_Kttout_HSNUM_valloc_�ucs_vrdivhsopen_3wakeup_BKttioctl_Kttread_spl_Ktimeout_HS_PORTS_xhspoll_�ttwrite_�printf_>
        !          140334: alow       allkp_ldrvpsy_blow     Kalloc_ttstart_�getcs_
        !          140335: Kwakeup_hsintr_�sleep_
        !          140336: ttopen_�hscon_�L0L1Kttwrite_Kprintf_L22ttpoll_�L380&'1'%%$-010; E'K'V$]0a0j'p1$s'v1$y'}1 '�1 � �'�'�S'�'�1'�E'�('�1'�1$�0�'�;$�'�1'�1 �'&'&'&(',&'0&E06&'A&'K&'R&0V&'l&'0x&0�&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � � � � � � � � � �$ 'R0%$!0%0+$. 3%80;$J0O$Z _%c0q0~0�0�0� � �$�$�0�0�0�0%0%'0* B%F0V'e0i'm3'u0�0�0�0�0�0�0� &%0%" &%.02%@0D0d �%�0� �%�0� �%�0� �%�0�0, f0o0� �0�%�0�0�0.0;0U0s0�%�0�00$-0A0K0]0�0�0�0�0�0�0�00%"%%%)%/%4'D30K$\ c%i w%}$�'�4'�4 �%�0�'�3 �'�40�'�3'�U'�,   0      0%      03      0D      0V      0_      0�      0�      '�      &0�    '�      80�    '�      &0�    0�      '�      &'�    80�    '�      '
        !          140337: ,'
        !          140338: ,'!
        !          140339: )'$
        !          140340: ,'?
        !          140341: `'B
        !          140342: ,'O
        !          140343: '^
        !          140344: 'j
        !          140345: 'q
        !          140346: '�
        !          140347: '�
        !          140348: E'�
        !          140349: '�
        !          140350: 5'�
        !          140351: +0�
        !          140352: '�
        !          140353: '�
        !          140354: '�
        !          140355: '�
        !          140356: '�
        !          140357: E'�
        !          140358: '�
        !          140359: 0�
        !          140360: '�
        !          140361: '&'','=L0A0I0N']2'eL0i0p'{?'~,'�/'�,'�A'�,'�I'�,'�'�,'�B'�,'� '�,'�J'�,'�>'�,'�'�,'�'�,'�_'�,'�"'�,'CX'F,0707070064030114531004440000030000030000011777770507310762600004000000017075/newbits/kernel/USRSYS/ldrv/msg&,��i���v�v�v�Ѓ��VWU����6�t�;�V�2P�Q���&P�����.�.�&�؃�u���ヿtV�DP�!��+�P�Z����.��0��&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P�,P�����G$&t�>,u܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W��
������LJ����LJ�ϸP����+��&G��&}5���㋇�F��~�t���ȋ^��G;�u+�PPPS��
���ҋ^����+�P�%����]_^�VWU��>.t
�v
        !          140362: �v�.���>u�,]_^�VWU��>0t
        !          140363: �v�0���,u
        !          140364: �,P���]_^�
        !          140365: VWU��>pu�&�>pu�]_^�VWU��v�F
        !          140366: -M=v������.��<Dv���DP����P�DP����P�DP���P���PV�����DP���P�DP���P�DP���P��̍DP�s��P�DP�h��P�DP�]��P�DP�R��P���뛍DP�?��P�D
        !          140367: P�4��P�DP�)��P�DP���P�DP���P�DP���P�����P��]_^�VWU���
        !          140368: �>xu�t�>zu�t�>tu+��&�>t�v�t��P�
        !          140369: P�x+�RP�q���F��V��P�:P�t+�RP�V��F�V��F��V��~�    |�~�@v
�|P��
        !          140370: ���$&�F�P�6�;
        !          140371: ���p�u���F�P+�P�6p�X
        !          140372: ���t.�.:
p�r�z+�RP�xRP�����F��V��~�|)�~��v#��P�g
        !          140373: ���6p��      ���t�p���P�v��v��R
        !          140374: ���
        !          140375: �>
        !          140376: u�6x��P�&
        !          140377: ��뽋6p�F��F�;ts!����D
        !          140378: �D*�D.�D,�D2�D6�D4�F���:�֋6p�x.�.<
r����
        !          140379: ��;rr/�z+�)F�V��F��E�D��|���6t��P�  ���t��]_^�VWU��P�~~�F�.�>>
;ts�>pu������F�.�>>
.�.:
p���t��D�tփ~
        !          140380: t�D
        !          140381: ;FuȋF
        !          140382: =v�����.��Vk�\V��������&u�
�&�*P�vV����|,t*�΃�*�D,;�t�FP�y��
P�FP�����|4t*�΃�2�D4;�t�FP�I��
P�FP����D
        !          140383: ;Fu�,&��$&�>t�;t�&�&�FP����F��>t���>t;Dw��v������F@@P�����D�d��FP���%�&    D�F��D��>t�;u��D���t��D�p�G����p�Gt�g��S�k        ���p�0t
�p*P����D�D�D�D
        !          140384: %�=�u�d
        !          140385: �D
        !          140386: �DtV�$     ���|0t
        !          140387: �D*P�z���|8t
        !          140388: �D2P�j���D�>t���+���]_^�VWU��P+��>pu����>pu��&�F%�&�F��t.�.:
p����:��;pvg�D�u�t�E&�U(;T(|�;D&v؋��ԋFF
        !          140389: t̋F�V
        !          140390: ;Tu�;Du��Ft�Ft������D#F�;F�u��
���Fu��׋Nj��u����D�D�D�D�v�D�D�D�D�D �D"�D$���D&�T(���D��D�D�F�
��D�F�V
        !          140391: �D�T�D
        !          140392: ��]_^�VWU��~~�F�.�>>
;ts�F;zw�>pu�����e&�F�.�>>
.�.:
p���D
        !          140393: ;Fu��D�t�V��������u�
���p�t�D;Dwi�Ft�롋D;Dw�L+�PP�&PV��p�O+�PP�&PS�D����G$G&t��t��V��F;D
        !          140394: t��!�F��p��F�E�P�EP�v
        !          140395: �g���v�
        !          140396: �w�u�F
        !          140397: P���;Ft��>t�����p�G��|t�\�?��|�|�F&D�D��G�D���D�T �Dt�d��V�*���|0t
        !          140398: �D*P���+�]_^�VWU����~~�F�.�>>
;ts�>pu�����B�F�.�>>
.�.:
p���D
        !          140399: ;Fu��D�t�V��������&u�
���|�F��~y~�F��F��F�V���؃��F�V�t?�E�U;V|;Fv�~��=��~�t�^��E�U;W|�;Gsމ~��F��F��Ӌ~��F��F��F�V���؃��F�V�)�~x#u�~t�t�E�U;Vu;Ft�~��=���uQ�Ft�����L+�PP�&PV� ����G$G&t���t�����F;D
        !          140400: u����!���F;Es�Fu����F;Ev�E�F�P�v
        !          140401: �EP����v�F
        !          140402: P�
        !          140403: �w�u���;Ft��>t�S��~�t ��^�����D;|u�F��D�E)D�L��G�D���D"�T$�Dt�d��V�����|8t
        !          140404: �D2P�B���6p�D��|�Dt�d��V����p�0t
�p*P����F��]_^�VWU��~~�F�.�>>
;ts�>pu� ��F�.�>>
.�.:
p���D�t�D
        !          140405: ;Ft��m�f
        !          140406: ���F
        !          140407: &t"�|u�~t
        !          140408: �D*P�&���f
        !          140409: ����F�F
        !          140410: t5�D;Dr�~t"�D2��>p�}u�~t
�p*P�E&���f
        !          140411: ���F
        !          140412: ]_^�:
        !          140413: &VWU��v�>u��&�/�;t;Du�D��;Dt;Du�D���D���%�&]_^�VWU���FHFr(;w"��ۋv�~
        !          140414: �N��������F]_^�+�]_^�VWU���FHFr�;w��~�v�N��������F]_^ø�`���`������`�[XS�`[SSø�`�VWU��N�F
        !          140415: �~��F]_^ø�`�VWU���]_^�VWU��]_^���`���`���`���`���`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          140416: ���~�����~�����v�P�%����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P���������Dž����Dž]_^���`�VWU��v�~t�~
        !          140417: +�PPPV�P����
        !          140418: �-����v��D�F�D�v�P�v
        !          140419: V�P�i���
        !          140420: W�d��]_^���`���`��Ë܋_��Ë܍_VWU��P�F�'����F�g��F
        !          140421: �'��֋�[��]_^���`��X��X[SSP�X�ldrv:%d: bad dev
        !          140422: ldrv:%d: dev bsy
        !          140423: �&fXXXffff        
        !          140424: �invalid NMSQID or NMSG kernel variable
        !          140425: invalid NMSG or NMSC kernel variable
        !          140426: could not salloc %u messages
        !          140427: could not kalloc %u message ids
        !          140428: timer_ahigh 
        !          140429: free_bhigh  Ksleep_main_Kukcopy_Kkucopy_clrivec_pollopen_pputuwd_�Kpollwake_Count     Kfree_ipcaccess_@
nonedev_Xuexit_�NMSC_zKdefend_nondsig_Nsetivec_�Kclrivec_sphi_Kputuwd_Kpollopen_ldrvipc_NMSG_xu_ldrvics_drvl_ldrvcon_Kuexit_msgs_rnulldev_fdrvn_msginit_$timq_umsgget_*ldrvsel_Knondsig_Ksetivec_xcalledsalloc_�msgpoll_zumsgctl_�con_Kldtimcall_NMSQB_vumsgsnd_eldrvint_msqs_pudl_umsgrcv_
        !          140430: msgcon_Vcprocp_kcall_ timeout_nKsalloc_alloc_�
memset_6ucs_uds_NMSQID_twakeup_spl_"getuwd_vlmul�Ktimeout_printf_�alow       allkp_ldrvpsy_blow     Kalloc_ufcopy_�
fucopy_�
getcs_vrmul�Kwakeup_String     sleep_dKgetuwd_kucopy_,ukcopy_�L0�Kprintf_Char     
        !          140431: pollwake_z0&'-'%"$-010; E'K'V$]0a0j'p-$s'v-$y'}- '�- � �'�'�G'�'�-'�<'�&'�-'�-$�0�'�6$�'�-'�- �'&'&'&&',&'0&<06&'A&'K&'R&0V&'l&$0x&0�&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& Z \ ^ ` b d f h j l$0$'01 : < > @ B0I0T0_0f0n0t0{0�0�0�0�0�0�0�0�0�0�0�0�0&000'$.$5$;$B$H0P$T$\$i0p$�0�$�0�0�'�F0�$�0�$�0�$� �$�$�$�$�0�$0$"0%$,$2070D%J%N$U$X0\$e$q$�$� �$�$�$�$�$�0�$� �$�$'0  !$%0K T V X Z0^'m0q0|0�0�0�0�0�'�0�'�'�'00'0"'&040B0W0i'm's$�$�0�$�$�0�0�0�0'0 $40:$>'E0I$U Z$^$i'�0�0�'�'�'�$'*'.'7'? w${$�$�'�0� � �$�0�'�$�'�$
        0      '%      600    '8      0<    'H      0L    $P      0g      %q      0�      '�      '�    0�    $�      '�      6'�    '�    0�    0�       
        !          140432: $
        !          140433: $"
        !          140434: ')
        !          140435: 00
        !          140436:  9
        !          140437:  >
        !          140438: $B
        !          140439: 0W
        !          140440: 'f
        !          140441: '-010B'I60T'\0`0k'o0s'�0�0�%�0�'�'�0�'6''0&06$=0U$\$e0l �$�$�0� � �$�0�$
$"
0)
'J
'U
'f
'�
3'�
='�
3'�
='�
I')'      
')'Q')'$)'-'0)'O''R)'_'q't)'{'~)'�U'�)'�'�)'�9'�)'�'�'�'�'�'�<'�'�1'�(0�''''1'5<';'B0F'Q'['e'h)'�C0�0�0�'�.'�C0�0�'�'�)'�'�)'N')0707070064030114521006660000030000030000011777770507310763000003700000005560/newbits/kernel/USRSYS/ldrv/qq&�D
        !          140442: �$���v�v�v�Ѓ��VWU����6�t�;�V��P�����&P�;����.�.�&�؃�u���ヿtV��P����+�P�����������&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P��P�G����G$&t�>�u܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W�������LJ����LJ�ϸP��&��+��&G��&}5���㋇�F��~�t��&�ȋ^��G;�u+�PPPS����ҋ^����+�P������]_^�VWU��>�t
�v
        !          140443: �v�����>u��]_^�VWU��>�t
        !          140444: �v������u
        !          140445: ��P���]_^�
        !          140446: VWU�������P�P�6��6��&������]_^�VWU���6��6��B��]_^�VWU��]_^�VWU��]_^�VWU��P�v
        !          140447: �|t8�����RP�u���F�VP���=��t�����.�>����‹�]_^�VWU����v
        !          140448: �F�V�J���F��|"�~�}P�F����RP�'&���F��Ћ�]_^�WU���~+�&�]_������`���`�[XS�`[SS�VWU��]_^���`���`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          140449: ���~�����~�����v�P�}����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P�0�������Dž����Dž]_^�WU���~�F&�]_ø�`�VWU��v�~t�~
        !          140450: +�PPPV�P�����
        !          140451: �-�M�����D�F�D�v�P�v
        !          140452: V�P����
        !          140453: W�*��]_^���`���`���`��X��X[SSP�X�ldrv:%d: bad dev
        !          140454: ldrv:%d: dev bsy
        !          140455: GP$Y�$$$�&0$qqcon_�Ksleep_main_clrivec_�uexit_xKdefend_setivec_BKclrivec_sphi_�ldrvipc_u_ldrvics_qqclose_Pdrvl_ldrvcon_Kuexit_nulldev_$drvn_iogetc_timq_ldrvsel_Ksetivec_xcalledqqread_Yffbyte_�con_Kldtimcall_ldrvint_Kiogetc_cprocp_kcall_timeout_ ptov_8ucs_qqwrite_�sfbyte_wakeup_�spl_�vrelse_�Ktimeout_printf_.Kptov_qqopen_Gioputc_ldrvpsy_getcs_Kwakeup_sleep_Kvrelse_Kprintf_Kioputc_0&''%$-010; E'K
'V$]0a0j'p$s'v$y'} '� � �'�
'�,'�'�'�!'�'�'�$�0�'�$�'�'� �'&
'&'&',&'0&!06&'A&'K&  'R&0V&'l&0x&0�&0�&$�&$�&'�&
        !          140456: $�&$�&$�&$�&$�&0�& � � � � � � � � � � �%%%%0 %&%*%7%;0>%i%n%r0w0�%�%� �%�0�%�%�0�'''2'''/1'2'9)'<'I
        !          140457: 'X'd      'k
        !          140458: 'z   '�!'�'�'�0�'�
        !          140459: '�   '�'�'�!'�
        !          140460: '�0�'�   '�'&'';'0?0G0L'['c'0g0n'y'|'�0'�'�.'�0707070064030114501006660000030000030000011777770507310763100004000000011345/newbits/kernel/USRSYS/ldrv/shm&n l�����v�v�v�Ѓ��VWU����6�t�;�V�t  P�����&P�   ����.�.�&�؃�u���ヿtV��       P���+�P������p   ��r   ��&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P�n P�����G$&t�>n   u܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W�c������LJ����LJ�ϸP�z��+��&G��&}5���㋇�F��~�t��J�ȋ^��G;�u+�PPPS�e���ҋ^����+�P�����]_^�VWU��>p       t
�v
        !          140461: �v�p ���>u�n   ]_^�VWU��>r    t
        !          140462: �v�r ���n  u
        !          140463: �n     P�a��]_^�
        !          140464: VWU��>�      ta��   .�&v��W�6�����u�6�    ��      P������      �/��  .�.x���  .�.x����&��;r�D��+�]_^�VWU����v
        !          140465: �D�F��D�F�;�        r������F�.�.x���E�u�!��W�C������&u�
�ȋE��F�V��F�+ҋ؋ʋD��;V�w�r;F�w��^�����G�F��F��F��t�t�v�P�o���u�o��D+���]_^�VWU����v
        !          140466: �D�F��D�F�;�        r������F�.�.x���E�u�!��W��������tʋE��F�V��F�+ҋ؋ʋD��;V�w�r;F�w��^�����G�F��F��F��t�v�P�t�{���u�v��D+���]_^�VWU��F
        !          140467: =CHt=GHt8��x�FP����P�FP���P�F@@P���P�U���=�FP���P�FP���P�FP�x��P�F@@P�k��P�&��P�v���]_^�(&VWU��P�F��>t������F;�       r���F.�.����D�t�F
        !          140468: =v�����.���E��V�'������&u�
른&P�vV�����F��|�>t�;t�&�b�v�����F@@P����D�d��FP���%�& D밃>t�;u��D
        !          140469: �~��>�5�|���D���F����F���]_^�VWU��P�F��>t����Z&��  .�.�����&��;s��D�u �~�t�~��E"�U$;T$|�;D"vЉv��ˋFF
        !          140470: tËF�V
        !          140471: ;Tu�;Du��Ft�Ft�늋~���&�D#F;�t�
�q��D;Fr���^��Fu��O��~�u��A��v���+�.�>�����>�@P�F+�RP�&����tʋF�D�D�D�D�D ���D"�T$�>�E�D���D��D�D�F%�&
��D�F�V
        !          140472: �D�T�FF
        !          140473: u�L��+�.�>���]_^�&VWU��v�>u��&�/�;t;Du�D��;Dt;Du�D���D���%�&]_^�VWU���FHFr(;w"��ۋv�~
        !          140474: �N��������F]_^�+�]_^�VWU���FHFr�;w��~�v�N��������F]_^ø�`������`�[XS�`[SSø�`�VWU���]_^�VWU��]_^���`���`���`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          140475: ���~�����~�����v�P�[����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P��������Dž����Dž]_^���`���`�VWU��v�~t�~
        !          140476: +�PPPV�P����
        !          140477: �-�C�����D�F�D�v�P�v
        !          140478: V�P����
        !          140479: W� ��]_^���`���`��X��X[SSP�X�ldrv:%d: bad dev
        !          140480: ldrv:%d: dev bsy
        !          140481: ���q,����&�couldn't kalloc %u shared memory ids
        !          140482: timer_Ksleep_main_Kkucopy_clrivec_�putuwd_
        !          140483: ipcaccess_�nonedev_�uexit_L   Kdefend_setivec_Kclrivec_sphi_` Kputuwd_ldrvipc_u_ldrvics_drvl_ldrvcon_Kuexit_nulldev_�shmsegs_drvn_timq_ldrvsel_ushmget_�Ksetivec_xcalledsalloc_ushmctl_zcon_Kldtimcall_ldrvint_NSHMID_�     udl_cprocp_kcall_�timeout_�shmids_shmcon_� Ksalloc_alloc_�ucs_uds_wakeup_V     spl_d     getuwd_�Ktimeout_printf_allkp_ldrvpsy_sfree_�Kalloc_fucopy_�ufcopy_Dgetcs_�Kwakeup_sleep_�Kgetuwd_kucopy_�Kprintf_Ksfree_0&''%$-010; E'K'V$]0a0j'p$s'v$y'} '� � �'�'�2'�'�'�*'�'�'�$�0�'�#$�'�'� �'&'&'&',&'0&*06&'A&'K&'R&     0V&'l&0x&0�&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& �        �       �       �       �       �       �       �       �       �      $$ '10' &$($+0/$6$= B'F&'I$L Q'U&'`&$�'�0� �'�&'�0�'�'�00$E'K0R Z'^&'k0r'�0�0�'�0&000#020@0N0[0b0l'�0�$�'� �'�&0� � � � �0�'�0�'�''00#08'G'M']0b'p'�0�$� �'�&'�&0�''0 0+'/03'>0B'L0P'Y& _'g0u'�'�'�#'�'�'�& �'''"'V"'\+'�"'�+'�4'�'�:'�'�'�'�'�'&<''
''(''%'4'@'G'V'^*'b'k 'q0u'|'�'�'�'�*'�'�0�'�'�'�='�'�&'�'      /0    0      0       '/      '7    /0;    0B      'M      'P    'W    8'Z    0707070064030114670407550000030000030000011777770507310763200004000000000000/newbits/kernel/USRSYS/ldrv/RCS0707070064030114651004440000030000030000011777770507310763200004600000022547/newbits/kernel/USRSYS/ldrv/RCS/al0,vhead     1.1;
        !          140484: branch   ;
        !          140485: access   ;
        !          140486: symbols  ;
        !          140487: locks    bin:1.1; strict;
        !          140488: comment  @# @;
        !          140489: 
        !          140490: 
        !          140491: 1.1
        !          140492: date     91.07.15.14.14.17;  author bin;  state Exp;
        !          140493: branches ;
        !          140494: next     ;
        !          140495: 
        !          140496: 
        !          140497: desc
        !          140498: @initial version prov by hal
        !          140499: @
        !          140500: 
        !          140501: 
        !          140502: 
        !          140503: 1.1
        !          140504: log
        !          140505: @Initial revision
        !          140506: @
        !          140507: text
        !          140508: @&��p#���v�v�v�Ѓ��VW��6�t;6|Vh����j&�;��k�
        !          140509: ��u���ヿtVh��b��j�����������&��&k�
        !          140510: LJ����LJ�������>t
����P���jjh&h�������G$&t�>�uރ>t
����P���k�
        !          140511: LJ����LJ����LJ+���}.���㋇;tG��W�$������LJ����LJ��h�A��+���&s=���㋇�F��~�t)�^��G�F��&;F�ujjj�v��2���͋^����G�j�����_^�VWU��>�t
�v
        !          140512: �v�����>u���_^�VWU��>�t
        !          140513: �v������u        h������_^�VW��>pt�&i^P�6�.���l�u�&kP�6����j�u�x&i^P�6l�U��kP�6j�E���E���p��>l�E��E�j�E�l��>j���E�>&~0��>l��y���x�j��r�l^��>j�E��E�F��F�;|��iF�^��>l�E��F�iF�^��>l�}��F�j@@P�����F�@@P�t���uXj�F�P���h��F�P����~������v�����~��狅��P�F�@@P�o��j�F�P�`��iF�^��>l�Ed
iF�^��>l�E>iF�^��>l�
��\�F��&�h�j�1��V�����_^�VW��F��F�;}[iF�^��>l�}��F�j@@P��
��j�F�P��
��jjj��jiF�^lH&P��P�4������F��j�+���6l�;
���6j�1
���_^�VWU��F%?;s:���~��?i�^lP����hn�~��?i�^lP�v
        !          140514: �v�&�����_^�VWU��N��?i�^��>l�Mu(��
���~��?i�^lP�v
        !          140515: �v���V��
���_^�VWU��j�v
        !          140516: �~��?i�^lP�Z���_^�VWU��v
        !          140517: �<tjV�N��?i�^lP�X���|V�W�����|o�^��?i�^��l�_�P�'������ t؋^��?i�^��l�_�P�������� t�W�N��?i�^��l�_�7�"����_^�VWU��~��?i�^lP�v�v
        !          140518: �v����_^�VWU���v�v
        !          140519: �~��?i�^lP�[
���_^�VWU���6n����_^�VW��v�~�F%��F��\��F�@@P�N��������t���D�t
        !          140520: �e�u��F���ȁ��k�
        !          140521: ��t�'��&�F@@t���u��F@@u�&�\�G����㋇=&t˃|t�&�\�tjjh&�DP���������F��F@@tj��\�G����㋇�j�F�P��
        !          140522: ��j�F�@@P��
        !          140523: ���F��t��L$�F�P�`
        !          140524: ���F��F�*�\G�F��u`jjh&�DP�W����G$G&t��]
        !          140525: �t��F�P�
        !          140526: ��%P�F�P�R
        !          140527: ��j�F�@@P�E
        !          140528: ����v�������d����d���LV����        �,&���!�,&V����v���
        !          140529: ���D�vV����F@@t�\�G�����LJ��g�\�G�����LJ&�T�\�G����㋇=u�I��\�G��؁��㋇=&t�c��+��F��u   �Du��
        !          140530: �Du�t���_^�VW��^�w�_�G&�v�
        !          140531: ���^�G�F��^��?�F��~�tU�^�GPh�j
        !          140532: �GP�
        !          140533: ��jjh&�^�GP�� ���^��[*�F���Z*�:F�u��~�t��N���� uj��@@P������^�G$��@@tQ��P�g��%P��P����F��%��F�k^�
        !          140534: LJ&jjh&kF�
        !          140535: P�H ��k^�
        !          140536: LJ��P���%��P��P�N���^�_�G�����LJ��^�_�G�^�GP�1
        !          140537: ���_^�VWU��v�����k�
        !          140538: ������=~�~�����k�
        !          140539: P�� ���_^�VW��v����\��F�@@P�w���F��F�P�g���F��F�P�W���F��F
        !          140540: �,
        !          140541: �      CC.;��t��.�g��������&q
        !          140542: �
        !          140543: �
        !          140544: �
        !          140545: R
        !          140546: i
        !          140547: �
        !          140548: �
        !          140549: �
        !          140550: �F�
@@P�F�P�K����F�%����F�
&P�F��ߋF�%����F�
��F�%���ߋF�
�P�F�P����v�v������F��P�F�@@P�����v�늋N���F�%����w��F�P�{���F��F�*�\G�F�*����F�j�v�F�P�}�
        !          140551: �v�v
        !          140552: V�����F�*�P�F�@@P�~��W�Y���_^�VW��^�G�F��^��7�^��)&��F���(&�:F�t����^��(&����㋇���u+�^�Gt!�g����P����%P��P�&���t}���F���@@P����F�h���P����WV��������P��@@P�����^��,&%�=&t   =tj�j�j
        !          140553: ��P����F�*�P��@@P����v��b���[�_^�VW��v�Dtb�A�F��\�P����F��F�*�\G�v�����\�Gt-�G�%���|u �DP�1��F��u��X&*䈄Y&V�]����X&*�:�Y&t2��Y&*�ȋ�ي�Z&*�PV�A����Y&*�=�rƄY&����Y&���F����Z*�Ȋ�[*�+�&F��F��.�>&�V��N�|7V������|*��Z*�ȋ�ًLj�\��Z*�=�rƄZ����Z��V���Vh8j
        !          140554: ��H&P�G���_^�VW��v��F��\�P��������t
        !          140555: Vh�
����� t>��Z*�:�[t2��[*�ȋ�ي�\*�P�\�7������[��[*�=&rƄ[�v�����_^�VWU��vjV�a���_^�VW��v�\��F��F�@@@@P�R��=v�&����.��((>�>W>6�F�P�&������t�Vh�
������v��    �����|t���,&@@u-�ρ���1&�;�u�L 녋ρ���0&�;�u�d���n���X&*�ȋ�ًLj�Z&��X&��X&*�=&s�J�ƄX&�B���Z*�:�[u�3��D t�)���[*�ȋ�ي�\*�P�v������[��[*�=&rƄ[��[*�:�Zt���Vh8�'��F�P�4���\G����_^�VW��F��~�}"�~��狅=u�~����������F����t�t;r|�t�t�_^�VW����t��F��F��~�}:�~��狅=u'�~��狽��(&����狅B�F��F�;F�}�F��F��F����F�;t.��.�>(�r���&���~�t�&hB�6����_^�&d��`�VWU��N�      �v
        !          140556: �~��F��]_^�VW��~dra�F+�.�6<�uS�F+�RPjh�4����F��
        !          140557: �F�j6jC�"&���F�%�Pj@@�&���F���Pj@@�&���v���&���F���F����F��_^�VW��v�{����F��u�&�F��F
        !          140558: ��P��v��&���F��_^�VW���F��~�t!jd�8����n&�F���P�_&���F��_^�d���U���v�v�P�'��]���`�����܋W+�����`�[XS�`[SSø�`���`���`�VWU���_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          140559: ���~�����~�����vh�`����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`��X��X[SSP�X���`�VWU��v�~t�~
        !          140560: jjjVh����
        !          140561: �+�������D�F�D�vh�v
        !          140562: Vh����
        !          140563: W�����_^���`���`���`���`���`���`���`���`���`���`���`���`���`��Ë܋_��Ë܍_VWU��P�V
        !          140564: �F+�+�� ��������;wrw;?r+?w@@��[��]_^���`�ldrv:%d: bad dev
        !          140565: ldrv:%d: dev bsy
        !          140566: 
        !          140567: .�������     �&��     Y@@�&�`@@:0 dddddddd�,&�&�&X �@@Kttstart_free_XKsleep_Kttopen_main_Kkucopy_al_sg_clr_ttsignal_Talxtimer_�      clrivec_>albaud_Kttpoll_Kfree_super_�uexit_rKttsignal_al_sg_set_altclk_in_�Kdefend_nondsig_�altclk_out_&kclear_�Kclrivec_com_usage_alxstart_d
setivec_�sphi_�ldrvipc_tthup_u_alxopen_�ldrvics_drvl_ldrvcon_inb_fcs_sel_>Kuexit_Ksuper_nulldev_�outb_�drvn_altclk_iogetc_ptimq_ldrvsel_Knondsig_Kkclear_ttsetgrp_Jblkmv4Ksetivec_xcalledttclose_�ttin_Ktthup_ttout_,con_Kldtimcall_poll_owner_poll_rate_alxintr_�
ldrvint_ttioctl_ttread_@@altsel_vldiv|Kiogetc_defer_Bcprocp_kcall_ztimeout_�Kttsetgrp_alp_rate_BKttclose_Kttin_alxbreak_�
Kttout_alloc_*tp_table_ucs_vrdiv�wakeup_�Kttioctl_Kttread_spl_�C1BAUD_a0con_�Ktimeout_C3BAUD_ttwrite_hprintf_�allkp_ldrvpsy_alxcycle_8Kalloc_ttstart_^A0CNT_alxparam_>getcs_bKwakeup_sleep_�ttopen_"kucopy_�alxclose_JKttwrite_Kprintf_Kldeferttpoll_6alxioctl_�    0&'7'$($*0-05'? 'J!$Q0T0\'b7$e'h7$k'o7 q'u7 w'~ '�['�!'�7'�N'�,'�7'�7$�0�'�C$�'�7'�7'� '�!'�,'&'&N0&'#&'-&'4&07&'J&+0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � �      
        !          140568:   %�&0�&$�&'�&Z0�&%0$'Z0%0!$%%,0/$6%<0?0E%K$N%R%\%b'eM%i$u${%%�%�'�M%�$�0�%�%�0�0�00$0%$10=0L%Z _%j o%z0}0� �0�0�$�%�0�0�%�0�00%0%"0%$;0@@%O0S%Y%h0r'{%�0�%�0�0�%�0�%
        !          140569: 00%10=%Y0e%�0�%�0�%�0�%�0�0'%0)030:'M 'T0X'c90q'�0�0�0�'�M0�0�0�00)'0C0;0I0Z0g'n0u0{0�$�$�0�0�0�'�0�'�'�0'0"0%0?'C0a �0�0�0�0�0
  '$       '4     08    'C       0N    0^      's      0x    0�      '�       '�     '�     0�    0�      0�      0�      0
        !          140570:  
        !          140571: 0(
        !          140572:  @@
        !          140573:  B
        !          140574:  D
        !          140575:  F
        !          140576:  H
        !          140577:  J
        !          140578:  L
        !          140579:  N
        !          140580:  P
        !          140581: 0a
        !          140582: 0g
        !          140583: 0�
        !          140584: 0�
        !          140585: 0�
        !          140586: 0�
        !          140587: 0�
        !          140588: 000.05'i0m$}0�0�0�0�0�0�0�00#0,020I0X0o0�0�0� 
0
0J
 Q
0[
0n
0}
 �
0�
0�
0�
0�
00 & ( * , . 0 2 40> M0P0[0�0�0�0�0�0�0 #0&000<'Z'hM0k%w%z%~%�%�'�90�'�'�M$�'�:'�: �%�0'9'9 ':0'+]'.2 d0w0�0�0�0�0�0�0�'�)0�'�?0�')00'#)')?0/'Mi0Q'Y'\2'qA't2'~2'�.'�2'�'�2'�-'�2'�h'�2'�'�'�'�'�'N''<'10''+'6'P'TN'Z'a0d'o'y'�'�2'�%'�2'�V0�0�0�'�8'�V0�0�'�H'�2'5'2'I'2'Q'2'#'&2'-K'02'7':2'AR'D2'KF'N2'U'X2'_'b2'ig'l2's$'v2'�b'�2@
        !          140589: 0707070064030111301004440000030000030000011777770507310763400004600000022547/newbits/kernel/USRSYS/ldrv/RCS/al1,vhead     1.1;
        !          140590: branch   ;
        !          140591: access   ;
        !          140592: symbols  ;
        !          140593: locks    bin:1.1; strict;
        !          140594: comment  @# @;
        !          140595: 
        !          140596: 
        !          140597: 1.1
        !          140598: date     91.07.15.14.14.20;  author bin;  state Exp;
        !          140599: branches ;
        !          140600: next     ;
        !          140601: 
        !          140602: 
        !          140603: desc
        !          140604: @initial version prov by hal
        !          140605: @
        !          140606: 
        !          140607: 
        !          140608: 
        !          140609: 1.1
        !          140610: log
        !          140611: @Initial revision
        !          140612: @
        !          140613: text
        !          140614: @&��p#���v�v�v�Ѓ��VW��6�t;6|Vh����j&�;��k�
        !          140615: ��u���ヿtVh��b��j�����������&��&k�
        !          140616: LJ����LJ�������>t
����P���jjh&h�������G$&t�>�uރ>t
����P���k�
        !          140617: LJ����LJ����LJ+���}.���㋇;tG��W�$������LJ����LJ��h�A��+���&s=���㋇�F��~�t)�^��G�F��&;F�ujjj�v��2���͋^����G�j�����_^�VWU��>�t
�v
        !          140618: �v�����>u���_^�VWU��>�t
        !          140619: �v������u        h������_^�VW��>pt�&i^P�6�.���l�u�&kP�6����j�u�x&i^P�6l�U��kP�6j�E���E���p��>l�E��E�j�E�l��>j���E&�>&~0��>l��y���x�j��r�l^��>j�E��E�F��F�;|��iF�^��>l�E��F�iF�^��>l�}��F�j@@P�����F�@@P�t���uXj�F�P���h��F�P����~������v�����~��狅��P�F�@@P�o��j�F�P�`��iF�^��>l�Ed
iF�^��>l�E>iF�^��>l�
��\�F��&�h�j�1��V�����_^�VW��F��F�;}[iF�^��>l�}��F�j@@P��
��j�F�P��
��jjj��jiF�^lH&P��P�4������F��j�+���6l�;
���6j�1
���_^�VWU��F%?;s:���~��?i�^lP����hn�~��?i�^lP�v
        !          140620: �v�&�����_^�VWU��N��?i�^��>l�Mu(��
���~��?i�^lP�v
        !          140621: �v���V��
���_^�VWU��j�v
        !          140622: �~��?i�^lP�Z���_^�VWU��v
        !          140623: �<tjV�N��?i�^lP�X���|V�W�����|o�^��?i�^��l�_�P�'������ t؋^��?i�^��l�_�P�������� t�W�N��?i�^��l�_�7�"����_^�VWU��~��?i�^lP�v�v
        !          140624: �v����_^�VWU���v�v
        !          140625: �~��?i�^lP�[
���_^�VWU���6n����_^�VW��v�~�F%��F��\��F�@@P�N��������t���D�t
        !          140626: �e�u��F���ȁ��k�
        !          140627: ��t�'��&�F@@t���u��F@@u�&�\�G����㋇=&t˃|t�&�\�tjjh&�DP���������F��F@@tj��\�G����㋇�j�F�P��
        !          140628: ��j�F�@@P��
        !          140629: ���F��t��L$�F�P�`
        !          140630: ���F��F�*�\G�F��u`jjh&�DP�W����G$G&t��]
        !          140631: �t��F�P�
        !          140632: ��%P�F�P�R
        !          140633: ��j�F�@@P�E
        !          140634: ����v�������d����d���LV����        �,&���!�,&V����v���
        !          140635: ���D�vV����F@@t�\�G�����LJ��g�\�G�����LJ&�T�\�G����㋇=u�I��\�G��؁��㋇=&t�c��+��F��u   �Du��
        !          140636: �Du�t���_^�VW��^�w�_�G&�v�
        !          140637: ���^�G�F��^��?�F��~�tU�^�GPh�j
        !          140638: �GP�
        !          140639: ��jjh&�^�GP�� ���^��[*�F���Z*�:F�u��~�t��N���� uj��@@P������^�G$��@@tQ��P�g��%P��P����F��%��F�k^�
        !          140640: LJ&jjh&kF�
        !          140641: P�H ��k^�
        !          140642: LJ��P���%��P��P�N���^�_�G�����LJ��^�_�G�^�GP�1
        !          140643: ���_^�VWU��v�����k�
        !          140644: ������=~�~�����k�
        !          140645: P�� ���_^�VW��v����\��F�@@P�w���F��F�P�g���F��F�P�W���F��F
        !          140646: �,
        !          140647: �      CC.;��t��.�g��������&q
        !          140648: �
        !          140649: �
        !          140650: �
        !          140651: R
        !          140652: i
        !          140653: �
        !          140654: �
        !          140655: �
        !          140656: �F�
@@P�F�P�K����F�%����F�
&P�F��ߋF�%����F�
��F�%���ߋF�
�P�F�P����v�v������F��P�F�@@P�����v�늋N���F�%����w��F�P�{���F��F�*�\G�F�*����F�j�v�F�P�}�
        !          140657: �v�v
        !          140658: V�����F�*�P�F�@@P�~��W�Y���_^�VW��^�G�F��^��7�^��)&��F���(&�:F�t����^��(&����㋇���u+�^�Gt!�g����P����%P��P�&���t}���F���@@P����F�h���P����WV��������P��@@P�����^��,&%�=&t   =tj�j�j
        !          140659: ��P����F�*�P��@@P����v��b���[�_^�VW��v�Dtb�A�F��\�P����F��F�*�\G�v�����\�Gt-�G�%���|u �DP�1��F��u��X&*䈄Y&V�]����X&*�:�Y&t2��Y&*�ȋ�ي�Z&*�PV�A����Y&*�=�rƄY&����Y&���F����Z*�Ȋ�[*�+�&F��F��.�>&�V��N�|7V������|*��Z*�ȋ�ًLj�\��Z*�=�rƄZ����Z��V���Vh8j
        !          140660: ��H&P�G���_^�VW��v��F��\�P��������t
        !          140661: Vh�
����� t>��Z*�:�[t2��[*�ȋ�ي�\*�P�\�7������[��[*�=&rƄ[�v�����_^�VWU��vjV�a���_^�VW��v�\��F��F�@@@@P�R��=v�&����.��((>�>W>6�F�P�&������t�Vh�
������v��    �����|t���,&@@u-�ρ���1&�;�u�L 녋ρ���0&�;�u�d���n���X&*�ȋ�ًLj�Z&��X&��X&*�=&s�J�ƄX&�B���Z*�:�[u�3��D t�)���[*�ȋ�ي�\*�P�v������[��[*�=&rƄ[��[*�:�Zt���Vh8�'��F�P�4���\G����_^�VW��F��~�}"�~��狅=u�~����������F����t�t;r|�t�t�_^�VW����t��F��F��~�}:�~��狅=u'�~��狽��(&����狅B�F��F�;F�}�F��F��F����F�;t.��.�>(�r���&���~�t�&hB�6����_^�&d��`�VWU��N�      �v
        !          140662: �~��F��]_^�VW��~dra�F+�.�6<�uS�F+�RPjh�4����F��
        !          140663: �F�j6jC�"&���F�%�Pj@@�&���F���Pj@@�&���v���&���F���F����F��_^�VW��v�{����F��u�&�F��F
        !          140664: ��P��v��&���F��_^�VW���F��~�t!jd�8����n&�F���P�_&���F��_^�d���U���v�v�P�'��]���`�����܋W+�����`�[XS�`[SSø�`���`���`�VWU���_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          140665: ���~�����~�����vh�`����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`��X��X[SSP�X���`�VWU��v�~t�~
        !          140666: jjjVh����
        !          140667: �+�������D�F�D�vh�v
        !          140668: Vh����
        !          140669: W�����_^���`���`���`���`���`���`���`���`���`���`���`���`���`��Ë܋_��Ë܍_VWU��P�V
        !          140670: �F+�+�� ��������;wrw;?r+?w@@��[��]_^���`�ldrv:%d: bad dev
        !          140671: ldrv:%d: dev bsy
        !          140672: 
        !          140673: .�������     �&��     Y@@�&�`@@:0 dddddddd�,&�&�&X �@@Kttstart_free_XKsleep_Kttopen_main_Kkucopy_al_sg_clr_ttsignal_Talxtimer_�      clrivec_>albaud_Kttpoll_Kfree_super_�uexit_rKttsignal_al_sg_set_altclk_in_�Kdefend_nondsig_�altclk_out_&kclear_�Kclrivec_com_usage_alxstart_d
setivec_�sphi_�ldrvipc_tthup_u_alxopen_�ldrvics_drvl_ldrvcon_inb_fcs_sel_>Kuexit_Ksuper_nulldev_�outb_�drvn_altclk_iogetc_ptimq_ldrvsel_Knondsig_Kkclear_ttsetgrp_Jblkmv4Ksetivec_xcalledttclose_�ttin_Ktthup_ttout_,con_Kldtimcall_poll_owner_poll_rate_alxintr_�
ldrvint_ttioctl_ttread_@@altsel_vldiv|Kiogetc_defer_Bcprocp_kcall_ztimeout_�Kttsetgrp_alp_rate_BKttclose_Kttin_alxbreak_�
Kttout_alloc_*tp_table_ucs_vrdiv�wakeup_�Kttioctl_Kttread_spl_�C2BAUD_Ktimeout_a1con_�C4BAUD_ttwrite_hprintf_�allkp_ldrvpsy_alxcycle_8Kalloc_ttstart_^alxparam_>getcs_bA1CNT_Kwakeup_sleep_�ttopen_"kucopy_�alxclose_JKttwrite_Kprintf_Kldeferttpoll_6alxioctl_�    0&'7'$($*0-05'? 'J!$Q0T0\'b7$e'h7$k'o7 q'u7 w'~ '�['�!'�7'�N'�,'�7'�7$�0�'�C$�'�7'�7'� '�!'�,'&'&N0&'#&'-&'4&07&'J&+0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � �      
        !          140674:   %�&0�&$�&'�&Z0�&%0$'Z0%0!$%%,0/$6%<0?0E%K$N%R%\%b'eM%i$u${%%�%�'�M%�$�0�%�%�0�0�00$0%$10=0L%Z _%j o%z0}0� �0�0�$�%�0�0�%�0�00%0%"0%$;0@@%O0S%Y%h0r'{%�0�%�0�0�%�0�%
        !          140675: 00%10=%Y0e%�0�%�0�%�0�%�0�0'%0)030:'M 'T0X'c90q'�0�0�0�'�M0�0�0�00)'0C0;0I0Z0g'n0u0{0�$�$�0�0�0�'�0�'�'�0'0"0%0?'C0a �0�0�0�0�0
  '$       '4     08    'C       0N    0^      's      0x    0�      '�       '�     '�     0�    0�      0�      0�      0
        !          140676:  
        !          140677: 0(
        !          140678:  @@
        !          140679:  B
        !          140680:  D
        !          140681:  F
        !          140682:  H
        !          140683:  J
        !          140684:  L
        !          140685:  N
        !          140686:  P
        !          140687: 0a
        !          140688: 0g
        !          140689: 0�
        !          140690: 0�
        !          140691: 0�
        !          140692: 0�
        !          140693: 0�
        !          140694: 000.05'i0m$}0�0�0�0�0�0�0�00#0,020I0X0o0�0�0� 
0
0J
 Q
0[
0n
0}
 �
0�
0�
0�
0�
00 & ( * , . 0 2 40> M0P0[0�0�0�0�0�0�0 #0&000<'Z'hM0k%w%z%~%�%�'�90�'�'�M$�'�:'�: �%�0'9'9 ':0'+]'.2 d0w0�0�0�0�0�0�0�'�)0�'�?0�')00'#)')?0/'Mi0Q'Y'\2'qA't2'~2'�.'�2'�'�2'�-'�2'�h'�2'�'�'�'�'�'N''<'10''+'6'P'TN'Z'a0d'o'y'�'�2'�%'�2'�U0�0�0�'�8'�U0�0�'�H'�2'5'2'I'2'Q'2'#'&2'-K'02'7':2'AR'D2'KF'N2'U'X2'_'b2'ig'l2's$'v2'�b'�2@
        !          140695: 0707070064030111271004440000030000030000011777770507310763600004500000015073/newbits/kernel/USRSYS/ldrv/RCS/dg,vhead     1.1;
        !          140696: branch   ;
        !          140697: access   ;
        !          140698: symbols  ;
        !          140699: locks    bin:1.1; strict;
        !          140700: comment  @# @;
        !          140701: 
        !          140702: 
        !          140703: 1.1
        !          140704: date     91.07.15.14.14.23;  author bin;  state Exp;
        !          140705: branches ;
        !          140706: next     ;
        !          140707: 
        !          140708: 
        !          140709: desc
        !          140710: @initial version prov by hal
        !          140711: @
        !          140712: 
        !          140713: 
        !          140714: 
        !          140715: 1.1
        !          140716: log
        !          140717: @Initial revision
        !          140718: @
        !          140719: text
        !          140720: @&�`:���v�v�v�Ѓ��VWU����6�t�;�V��P��
        !          140721: ���&P�E����.�.�&�؃�u���ヿtV��P��
        !          140722: ��+�P�����������&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P��P�Q����G$&t�>�u܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W�
        !          140723: ������LJ����LJ�ϸP�        ��+��&G��&}5���㋇�F��~�t��t       �ȋ^��G;�u+�PPPS�
        !          140724: ���ҋ^����+�P��
        !          140725: ����]_^�VWU��>�t
�v
        !          140726: �v�����>u��]_^�VWU��>�t
        !          140727: �v������u
        !          140728: ��P�
        !          140729: ��]_^�
        !          140730: VWU��P�O      P�6��+ ����������������&P�PR�6�������P�6������&P�:���6�����F��F��%&=&u���s&�P�6�����6��c���F��F��%&=&u�
�F&�4
P�x���P�6��`���dP�����6��"��%=t�>6t�D
�&�
        !          140731: P��ոP�6�� ���c
P� ���Z�P�6�6������<P����RP�����Z�P������RP������<P������RP����6�6�m��=Z�uN����RP�S��=�<u4������RP�9��=Z�u������RP���=�<t�w
�!��
P�S���P�6��;���@@&��
P�5����]_^�VWU��>>t�>+�P����RP�����P�6������6��~���6�6�E��]_^�VWU���F�t#�>8t�'�7�>@@t+�8&�<�"�F@@t�>:uփ>Bt�:&���]_^�VWU���F�t&�8�><uB�7&�t;�@@�B&��
�#�F@@t#�:�&�t�B�>&��
P�*��]_^�VWU��v
        !          140732: ]_^�VWU��P�v
        !          140733: �F�t7V�����F��|_�><}WP�<����RP����<���F@@t/V����F��|!P�<� ��RP�y���<�ы�]_^�VWU��P��P�v�P���+�P���P+�P�P�c��]_^�VWU���6�&P��P�v�&P�I��]_^�VWU��F�6]_^�VWU��+�P����RP�����P�6�������P��������RP���=GDt�>6t�P����+���
        !          140734: P�0��Ÿ#P����&]_^�VWU��P�P��@@��RP�}����P��B��RP�d��+�P��D��RP�L���P��F��RP�3��+�P��H��RP���� P��J��RP����
        !          140735: P�6�����P�6������dP������@@��RP����t�>6t
�7P������&�
        !          140736: P�)��ǸXP����&P��@@��RP����P��B��RP�j���P��D��RP�Q��+�P�� 
��RP�9���
        !          140737: P�6��9���P�6��+����&P������� 
��RP����=OSt?�>6t/�{P�����@@��RP���P��P����+����
        !          140738: P�=�뤸�P������"��RP�Y���D�&P����RP�����
��RP�:���F����P�F����RP�I�����P�F����RP�+���F�%�P��
��RP����dP�����F&�>Ft �>6t
��P��&�����
        !          140739: P�[����ٸ�P��&���&��]_^�VWU�����
��RP�u&���F���
��RP�]&���F���
��RP�E&���F���
��RP�-&���F��>>u����
��RP�&������
��RP����;�u����
��RP�����F��F��~�}3��~�F�؋ʋF������RP����E��F��NJF�*�P�F�*�P�F�*�P�F�*�P�&P���
        !          140740: �F�%�P��
��RP�&���3��>Ft1�F��
��RP�1��P��
��RP�K&����]_^�WU���~+�&�]_�WU���~&�]_�����܋W+�����`�[XS�`[SS�VWU��]_^��܋W�G�ø�`���`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          140741: ���~�����~�����v�P�s����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P�&�������Dž����Dž]_^�WU���~�F&�]_�WU���~�F&�]_ø�`�VWU��v�~t�~
        !          140742: +�PPPV�P����
        !          140743: �-�M�����D�F�D�v�P�v
        !          140744: V�P����
        !          140745: W�*��]_^���`���`���`��X��X[SSP�X�ldrv:%d: bad dev
        !          140746: ldrv:%d: dev bsy
        !          140747: N��&�Error - board type is PC/Xi
        !          140748: Error - board type is PC/Xm
        !          140749: PC/Xe ID found
        !          140750: Error - PC/Xe failed to reset
        !          140751: PC/Xe passed reset
        !          140752: Error - PC/Xe failed memory test
        !          140753: PC/Xe passed memory test
        !          140754: PC/Xe waiting for BIOS load
        !          140755: PC/Xe waiting for FEPOS load
        !          140756: PC/Xe ready for use
        !          140757: Error - PC/Xe BIOS won't start
        !          140758: PC/Xe BIOS started
        !          140759: Error - PC/Xe FEPOS move failed
        !          140760: PC/Xe FEPOS relocated to host RAM
        !          140761: Error - PC/Xe FEPOS won't start
        !          140762: Failure code (%x)
        !          140763: PC/Xe FEPOS started
        !          140764: Error - PC/Xe no FEPOS interrupts
        !          140765: PC/Xe interrupts working
        !          140766: %x %x %x %x
        !          140767: Ksleep_main_clrivec_�uexit_�Kdefend_Kclrivec_setivec_:sphi_�ldrvipc_u_ldrvics_drvl_ldrvcon_inb_�
        !          140768: Kuexit_nulldev_outb_drvn_iogetc_�
        !          140769: timq_ldrvsel_Ksetivec_xcalledffbyte_�
        !          140770: con_Kldtimcall_ldrvint_DG_IOB_�Kiogetc_cprocp_kcall_timeout_*ffword_�
        !          140771: ptov_0DG_RAM_�dgcon_�ucs_sfbyte_�wakeup_�spl_�vrelse_�Ktimeout_printf_&Kptov_ldrvpsy_DG_INT_�sfword_getcs_�
        !          140772: Kwakeup_sleep_ Kvrelse_Kprintf_0&''%$-010; E'K'V$]0a0j'p$s'v$y'} '� � �'�'�,'�'�'�$'�'�'�$�0�'�$�'�'� �'&'&'&',&
        !          140773: '0&$06&'A&
        !          140774: 'K&'R&0V&'l&0x&0�&0�&$�&$�&'�&  $�&$�&$�&$�&$�&0�& � � � � � � � � � � � $
        !          140775: 0
$$%#%'%407%=%A$I0L0V$]0`$u0x$�0�$�0�$�0�$�0�$�0�0�$�0�%�$�0�0�$�0�$0%%0% %$0/%9%=0H%R%V0a%h%l0o%z%~0�%�%�0�%�%�0�$�$�0�$�0�%�$�0�%&%%%0$*0-$407%>%B0E%\'c     %j%q%w%�%�%�'�  %�%�0�%�%�$�%�0�%�%�$�0�0!%/%7%<%@@0K%R0_%m%r%v0�%�%� �%�0�%�0�%� �%�0�%�%%0$00'%-%10<%H$N0R0`$e0i%�%�0�%�%�0�%�%�0�%�%�0�%�%�0�%�%�0
        !          140776: $0$#0&00%6%:0E%P$V0Z0`0g$l0p%z%~0�%�%�0�%�%�0�%�%�0�$�0�$�0�0�%�%0%$ 0$%*%.09$@@0D0L0S$X0\%b%f0q%w%~%�0�%�%�0�%�%�0�%�%�0�%�%�0        0
        !          140777:        %      %      %      $$      0(      0.      05      $=      0A      %X      %\      0g      %p      %t      0      %�      %�      0�      %�      %�      0�      %�      0�      %�      %�      0�      %�      %�      0�      0�      %�      %�      0
        !          140778: %*
        !          140779: %.
        !          140780: 0=
        !          140781: $c
        !          140782: 0g
        !          140783: %w
        !          140784: %{
        !          140785: 0�
        !          140786: 0�
        !          140787: %�
        !          140788: %�
        !          140789: %�
        !          140790: %�
        !          140791: 0�
        !          140792: %�
        !          140793: %�
        !          140794: 0�
        !          140795: '�
        !          140796: ''
        !          140797: ''3'*'1+'4'A     'P
        !          140798: '\'c      'r'z$'~
        !          140799: '�'�0�'�      '�'�
        !          140800: '�
        !          140801: '�$'�      '�0�'�'�
        !          140802: '!'$'E)0I0Q0V'e'm)0q0x'�'�'�2'�'�0'�@
        !          140803: 0707070064030055021004440000030000030000011777770507310764000004500000017605/newbits/kernel/USRSYS/ldrv/RCS/fl,vhead     1.1;
        !          140804: branch   ;
        !          140805: access   ;
        !          140806: symbols  ;
        !          140807: locks    bin:1.1; strict;
        !          140808: comment  @# @;
        !          140809: 
        !          140810: 
        !          140811: 1.1
        !          140812: date     91.07.15.14.14.26;  author bin;  state Exp;
        !          140813: branches ;
        !          140814: next     ;
        !          140815: 
        !          140816: 
        !          140817: desc
        !          140818: @initial version prov by hal
        !          140819: @
        !          140820: 
        !          140821: 
        !          140822: 
        !          140823: 1.1
        !          140824: log
        !          140825: @Initial revision
        !          140826: @
        !          140827: text
        !          140828: @&�&�P����v�v�v�Ѓ��VW��6�t;6|Vh����j&�7��k�
        !          140829: ��u���ヿtVh���
��j�����������&��&k�
        !          140830: LJ����LJ�������>t
����P���jjh&h��H����G$&t�>�uރ>t
����P���k�
        !          140831: LJ����LJ����LJ+���}.���㋇;tG��W�
������LJ����LJ��h����+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v��
���͋^����G�j��
���_^�VWU��>�t
�v
        !          140832: �v�����>u���_^�VWU��>�t
        !          140833: �v������u        h��
���_^�VWU��j����jjp�0��jq�������ƈu7��
����������%����&���t,����t"�����������&t����%@@���>�tt���jh����h�
        !          140834: j����jh����jh�������=t���Ph��~��j�!      �������P�        ������P�     ��W�>���_^�VWU��>�tj����jjjh�!���.jh�����_^�VWU�������F%���;�s�v�������~��������u��_^�VWU��j&�v�v
        !          140835: h��
        !          140836: ���_^�VWU��j�v�v
        !          140837: h��e
        !          140838: ���_^�VW��~
        !          140839: @@t���F%������v�D
        !          140840: ���F��F@@P�6
        !          140841: ���F��~�&wʋF�;Es��Ft�E�f�F��  �E�f�F������e����+ҹ �����������F���E����j@@�vh�h��     ���_^�VW��v�D��   �ȋ�+�D
        !          140842: T-&���F��\�����D
        !          140843: ;��v�LV���c�|@@t"�\�����F�;��r�D�D�D@@t����D�&t�|@@u���d
        !          140844: ���>�u�6�����7�6��>�u�W�A
        !          140845: ���_^�VW��6����=v�����.���&�f�&?�.&�u��j�D%���Ph��;���D%������D%������ظ������D�T�����D
        !          140846: �������Ƈ��D��    ���u��&������F��t����F�;F�t���Ph��~������Ƞ��#�uG��������Ƞ���
Ph��O���;j&h�jdh�2  �������Ƈ����������Ƈ�����Ƞ���
Ph����������؀��u%��������j������P�����&�����>�B���>�t!����>�����>�������>��������>�����>�������>���j�������ȡ����P�
        !          140847: ���>�Pt"����؀��u����P�����؀��t��6���������&�|&tjh�jh�����������Ƈ����jh�h$�Y���t�&�����Ƈ��f���|&t�|uP��&�E�6�h�6��6�j�Z��
        !          140848: �u>�6��6�hL�t����h$����LV�N���+���&�M�6��t�j���W�������ȡ����P�����|@@u%���P�����6��������P����h��H�6�����6�����6�������P����6��������؊���P�{��h��r����������Ƈ�j�V��h$�7����������t+�����=}
�����Ƈ��-�X�LV�C���!��u�D����������&�>�u������Ph�j��hk�5���_^�VW���F����=u   �F�����v������_^�VWU��v���%����؀��uO�ށ������=u O���%����؀��u��%=u+����_^�VW���F�+����}H���#�uF����|��������=|���� ����;�uր>�t��?�>�u����������Ƞ���
Ph��0���>�u�.�v�����_^�VWU��j���h$���jh�����jh��������=t���Ph�����j�v&�������P�e&������P�Y&��+�����������������t+���Pho����|�LV�L�������t;|t�jh�jh�O�����_^�VWU���-���2�>�t���V����_^�VWU��v�����V�G���_^�VW��F����F�+�h������ȋ����u�N�u�h�������@@th��������sɋ�G�ƈ��뾉>�jh����+�h��x���ȋ����u�N�u�h������@@th��Q������sɋ�G�ƈ��뾉>��v��H���_^�VWU��+�h����%�=�tNu�h��H����vh��&���_^�VWU���6��6����%Ph�����>�&|*�������t      h���&���������t    h���&���>�|~�������&t     h���&���������t    h�&���������t    h�&���������t    h �&��������� t    h+�w&��������ǀt    h9�b&���>�|i�������&t     hG�F&���������t    hd�1&���������t    ht�&��������� t    h��&���������@@t   h�����h������_^ø�`�VWU��N�       �v
        !          140849: �~��F��]_^ø�`���`�VWU��v�Q�D�F
        !          140850: �D�vhVh�]���_^�VWU��vVh�G���_^ø�`���`���`������`��܋W+�����`�[XS�`[SS�VWU���_^��܋W�G�ø�`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          140851: ���~�����~�����vh�t����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh�(�������Dž����Dž�_^���`��X��X[SSP�X�VWU��v�~t�~
        !          140852: jjjVh�����
        !          140853: �+��������D�F�D�vh�v
        !          140854: Vh����
        !          140855: W�����_^���`���`�ldrv:%d: bad dev
        !          140856: ldrv:%d: dev bsy
        !          140857: &(Nh�~     �&�@@&&(#*P�(#*PP#*Ph&&( #*P�( #*P�P #*P`        PT@@PTfd: DMA page straddle at %x:%xfdsfd%d: <Door Open>
        !          140858: flintr: timeout
        !          140859: flsense: timeout
        !          140860: flput: timeout
        !          140861: fd%d: head=%u cyl=%u <Not Ready> <Equipment Check> <Missing Address Mark> <Write Protected> <No Data> <Overrun> <Data Error> <End of Cyl> <Missing Data Address Mark> <Bad Cylinder> <Wrong Cylinder> <Bad Data CRC> <Data Deleted>
        !          140862: Ksleep_main_Kdmalock_clrivec_�dmaoff_�
int11_uexit_nflrecov_
        !          140863: Kdefend_Kclrivec_setivec_@@sphi_
        !          140864: ldrvipc_u_ldrvics_Kint11_Kdmaoff_fldone_�
        !          140865: drvl_ldrvcon_fl_hlt_�inb_�
Kuexit_nulldev_outb_"dmareq_�
drvn_getubd_�
timq_ldrvsel_blkmv^
Ksetivec_xcalleddmaunlock_�
con_Kldtimcall_fl_hut_�ldrvint_Kdmareq_Kgetubd_devmsg_z
cprocp_kcall_timeout_bdone_T
dmago_�
Kdmaunlock_fl_srt_�panic_,ucs_wakeup_xspl_dmaon_�
Kdevmsg_Ktimeout_flcon_�Kdmago_Kbdone_printf_6ldrvpsy_flunload_�Kpanic_getcs_�
Kwakeup_sleep_Kdmaon_dmalock_�
Kprintf_0&'"'$$*0-05'?'J$Q0T0\'b"$e'h"$k'o" q'u" w'~'�;'�'�"'�1'�'�"'�"$�0�'�)$�'�"'�"'�'�'�'&'&10&'#&'-&'4&07&'J&0_&0p&0�&$�&$�&'�&
$�&$�&$�&$�&$�&0�& � � � � � � � � � �0�&0�&0�&$$
%%%#%.%80=%C%V%Z0`0j p0u0�0�%�%�0�0�$�$�0�$�0�0�%�0�%�0�'�0%0+$@@'G
%\0_%v0y'�
0�$�0�0�'�
'
'
'
'
%0$[0f$0�%�%�%�%�%�0�0�%�%�0� � � � � � � � �'0$%0!%0%9%<%I%R%V%\%_%f%p%x%~%�0�%�0�%�%�%�%�%�%�0�0� �%�0�%�%�%�0�%�%%%00!%$%+%1%80=%C0H%O0S%V%[%`%d%j%o%r%w%z%}%�%�%�%�%�%�%�%�%�%�0�%�%�0�%�%�%�%�%�%�%�0�%�0� 
        !          140866: %00%%"%' -%0030=%@@%G%O%a%j%q%u0z%�%�$�0�%�0�0�0�%�%�0�0�%�%�0�%�0�%�0�%&0%0%0%&0)%/04%;0>%D%K0P0Y%`0d%g%n0t%z0}%�%�%�%�%�0�0�%�%�%�%�%�%�0�%� �0�$�0�0      %      %      0      0       %@@     $Q      %g      0�      %�      %�      %�      %�      %�      %�      %�      0�      %�      0�      %�      %�      0�      %�      '�      0
        !          140867: 0
        !          140868: %
        !          140869: 0 
        !          140870: 0+
        !          140871: 06
        !          140872: %<
        !          140873: %E
        !          140874: 0M
        !          140875: 0U
        !          140876: $[
        !          140877: $b
        !          140878: 0f
        !          140879: $l
        !          140880: 0r
        !          140881: %z
        !          140882: %~
        !          140883: %�
        !          140884: %�
        !          140885: %�
        !          140886: %�
        !          140887: $�
        !          140888: 0�
        !          140889: 0�
        !          140890: %�
        !          140891:  �
        !          140892: %�
        !          140893: 0�
        !          140894: %�
        !          140895: 0�
        !          140896: 0�
        !          140897: %�
        !          140898: 0�
        !          140899: 0�
        !          140900: %%00 0+$@@0C0R%e%k0s0~$�0�0�%�%�0�0�$�0�0�%
        !          140901: %%$0%#%)$508%>$J0M%T%Z$f0i%o${0~%�$�0�%�$�0�%�$�0�%�$�0�%�%�$�0�%�$
0
%      
$
0
%
$*
0-
%3
$?
0B
$H
0K
'U
9'X
 '{
5'~
 '�
8'�
 0�
'�
#'�
0�
'�
.0�
'�
'�
 '�
A'�
 '�
&'�
 '�
''�
 '' ' '-='0 '7C': 'G
'V'b'i
'x'�1'�'�%'�0�'�
'�'�'�'�1'�
'�       0�'�'�'&' '46070?0D'S#'Z60]0d'o'r 'y?'| @
        !          140902: 0707070064030111251004440000030000030000011777770507310764200004500000040543/newbits/kernel/USRSYS/ldrv/RCS/gr,vhead     1.1;
        !          140903: branch   ;
        !          140904: access   ;
        !          140905: symbols  ;
        !          140906: locks    bin:1.1; strict;
        !          140907: comment  @# @;
        !          140908: 
        !          140909: 
        !          140910: 1.1
        !          140911: date     91.07.15.14.14.29;  author bin;  state Exp;
        !          140912: branches ;
        !          140913: next     ;
        !          140914: 
        !          140915: 
        !          140916: desc
        !          140917: @initial version prov by hal
        !          140918: @
        !          140919: 
        !          140920: 
        !          140921: 
        !          140922: 1.1
        !          140923: log
        !          140924: @Initial revision
        !          140925: @
        !          140926: text
        !          140927: @&�#��p
���v�v�v�Ѓ��VW��6�t;6|Vh$�"��j&�#��k�
        !          140928: ��u���ヿtVh$��!��j�#����$��$��&��&k�
        !          140929: LJ����LJ�������>t
����P���jjh&h�#�j"����G$&t�>�#uރ>t
����P���k�
        !          140930: LJ����LJ����LJ+���}.���㋇;tG��W��!������LJ����LJ��h�� ��+���&s=���㋇�F��~�t)�^��G�F�� ;F�ujjj�v���!���͋^����G�j�d"���_^�VWU��>$t
�v
        !          140931: �v�$���>u��#�_^�VWU��>$t
        !          140932: �v�$����#u        h�#�"���_^�8(+dp& VWU����^�w�O�?t��۽B$�v�V�F�~�F#F&1��&1�� +��f����.���
�ڀ~(u����F#F&1��&1�� [�^�v�V�~������*�&��^���O+O&O]_^�6�c����Q��V���B.���&�JK}�Y��������$t������F���F���F�F�F��F&�FP*Ҋv�v
�^�^+��F�6���y6��s*���:v~U�vVQ�^�^
��.���
.���
����.���
Q+���VWQ�Y_^�� �� �F#F_W���_�� ���Y^�D&����.���
�ڀ~(u����I�����.���
        !          140933: ����I�����.���
        !          140934: �~(t�V*���������2���Ȏػ��3F#F�W�3F#F&�&��N�3F#F��3F#F&�&��N�3F#F��3F#F&�&��N�3F#F��F3F#F&�&_^+���:V}
�I�����.���
        !          140935: *���:v�3��v����oV*�������n�����ػ��3F�W&�!��O�3F�&�!��O�3F�&�!��O�
        !          140936: f3F�&�!_^+���:V}
�I�����.���
        !          140937: *���:v����v�j�����I�����.���
        !          140938: *Ҋ���.���
��I�����.���
        !          140939: ��}�V����:v
}*Ҋv
�|��H���I��~�~����.����2���I�<;t!�؀�0��       w9�f�F����FÈF��� ���I��؀�0��    w�f�F����FÈF�ފ���.��������I��؀�0��   w�f�F����FÈF��<htL<ltX�������I��؀�0�� w�f�F����FÈF��<hu��<lu�������€�*����~
u6��*&���~
u6��*���V��}*�:Vr�V���d�� QV+Ɋʀ���*�ыv�~Pu���A��F#ƫ&�A�&�EN&�AN&���&���&���F#�&�����+�^Y:V|*V��:v~�v�����*���:v
s�v
�����~u�F&����~u�F�����:vv�v�����:Vr*V��:vv�v�V�����v��*�v
:vr�v�V��*�:Vr�V���{���:v
}�v
�n�VQ�^����.���
.���
�^��.���
+�~1��VWQ�Y_^�� �� �.���
W���F#F�_�� ���*�Y^��6�&� ��F<u�^�&<&u�^
�r*Ҋv
����.���
�^*��<�F<u�^��<&u*��H*Ҋv
+��^��F��<u�<&t,��.���
*�*�Q�F#F��������� ��}�Y��RQW�F#F��.���
����.���
+�~��WQ�Y_�� �Y����.���
+�~x�׋���P������P������P������������P������P������P�����+�YZ���RQW�F#F��.���
����.���
+�~��WQ�Y_�� �_+ɊN*ʀ~(u��׋���P������P������P������������P������P������P�����+�YZ�t�6���VQ�^�^��.���
�΃�.���
������.+��
~3��VWQ��Y_^�� �� �.���
W���F#F��_�� ���*�Y^�   ��V��*�:Vr�V������F
        !          140940: �u���:Vr�V������v��*�:vv�v�V��*�:Vr�V������:v���v�R��V�v���V�v����:v
}�v
�����Nt
        !          140941: 
�F�����F���F<u�F���F�F�!<&u�F���<u�F���<u�F����D��~Pu�F(�����F�����~(u�FP���F����F��}*�:Fw�^��}*�:^w:�w
        !          140942: �F
�^��*�����v��*�:vv�v����F
        !          140943: �u���:vr�v��ttttttt���&�      t�0
        !          140944: F
        !          140945: ttttttttttt�tttt��������������������������������������������������������������������������������������������������������������������������������ttttttttttttttttttttttt�        �       tttt��ttttt� &ttttttt�       ttttttttttttt�ttttJt��tttttttttttttttt��ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttStt����&e�������tTttt�     �       ttttt�tttttV l       tt�
        !          140946: �
        !          140947: �      �ttttt�   ttttZ
        !          140948: ttt�        ttttttttt@@&��@@��
        !          140949: @@��
@@��@@��@@��@@� �!#@@$�%�&(@@)�*�+-@@.�/�02@@3�4�57@@8�9�:<@@=�>�?VWU��n
        !          140950: �~t����~���؋FF=@@wW�F+ҹP������������&u�P+�;N~�N�-)N&NV�^�� �P+�;N~�N�)N&N�� +���]_^�VWU��n
        !          140951: �~t��؋v�����FF=@@wҋF+ҹP�������������&u�P+�;N~�N�)N&NW�_�� �P+�;N~�N�)N&N�� +��ĺ���ú���6��*�&��0�3���0��?������?��������?���?���?�����������?��������������?��?�������0��0������?�?�������?�?��<�<?�?���?��?��0<?00���������������?�00�<?��<?�?�?�<<�?��<�?�����?��<<<<<<<<<<<<���<?<<<<<?������?�?�?��?���?�����?�����������?��0<��<0<��<�����0<<��<<0�?�����?��<<<<<�<���<���<�<�?��?��<?���<����?��0�?�����?����<���<�<<<�30����30��?����??��<��<�?������<�<�<?���?�����?��<<�<��?��<<�<�<?���<<<��<<������<<��?��<����<�<?���<��<<?��<�<?��<�<?�?��<�<?�<�<?��<�?�?�?���??��<��?����������?�?��<�<���<�<�<��<<<<?�<<<<��?��<����<?���<<<<<<<<<<����<<�?�<�<����<<�?�<�<�?��<�<����<?��<�<�<���<�<�<��������������?��<����������<�<<<<<���<�����<�<�<�<�<�<�<�����<�<?��<�<�<�<�<?���<<<<?�<<�?��<�<�<�<�<?����<<<<?�<<<<�<?��<�?�<�<?�?�3�������<�<�<�<�<�<?��<�<�<�<�<<���<�<�<�<�<���<�<<����<��<<<<<<<�������<��<<����������<��<??�<��<���?�<?��<?������<�<�<��?��<��<?�<<?��<�<�<?�?��<���?��<<<�<<<?��<�<?�<?������<�<�<�<������������?����<������<������������<�<�<���<�<�<�<?��<�<�<?����<�<����?��<�<?�<<��?<<<<?��?�<?���?������<�<�<�<?��<�<�<<���<�<�<���<�<<��<��<�<�<�<?�<?�����<�����?������������?�����<<��VWU��>|$u?jja��
        !          140952: ���V)N}�h�ja��
        !          140953: ��+�Nu�j`�
        !          140954: ����h�ja��
        !          140955: ��jMja�
        !          140956: ���&hj&��
        !          140957: ��h~$�\���_^�VWU��j&�9���_^�VWU���F�t��N��$�t�p�u��8�vh~$�����H��$��$�u���$h~$���V�)����_^�VW�+���}
����LJd+F���F��*+���}9����F���d+���㋿>)�F��F��F���G���^���=��t       �~�`+r��F���_^�VWU���
        !          140958: ����$u�
        !          140959: ��h~$���V�
        !          140960: ���_^�VWU��j�v
        !          140961: h~$����>~$t        h~$����_^�VWU��F
        !          140962: ���CC.;��u.�gMN��?�:
        !          140963: ���v�v
        !          140964: h~$�
        !          140965: ��V�)
        !          140966: ���V�v�v
        !          140967: �Q���H��'*�_(\�`(���(|��(��)�)��#��')�_(��`(\��(���(|�)��)�_^�VW��~�u��*��c+sc��P�F
        !          140968: �F
        !          140969: P����F��+���}
����LJd+G�*+���}1���㉷d+��F�F��F
        !          140970: �F
        !          140971: P�(���^���=��t��`+r��G���_^�VWU��f
        !          140972: ���F
        !          140973: &t"�>�$u�~t       h�%�3���>�$u�f
        !          140974: ���F
        !          140975: �_^�VW��F��>uh~$h����&j`���%��F�ja�������
�Pja����Vja�����>�+t=��+�~��t�C��*�%&����* t����*t��Vj`�����>�+~��+��F����CC.;��u.�g�������>�+t��+��+&���+�F�%H���F��u��Ru��*%=u����(*���ǀu��F��tK��5u     �&�*���&��'�;�u        �&�*���t&��u   �&�*���f&��7t�^&�>�+t�������!�*�H&��'�;�u  ��*�7&��5u   ��*&�)&��u   ��*�&��7u�>�+t�&��   �*�&��9u�6�*������Dt���6�* ���F��t���>�$u����*&t���'�X��*t,��u��
u��C�
        !          140976: �>��t��t����(*�%�&#>�*t��*t��0u���(�
        !          140977: ��0u�6(*�����t[���t��*t�΀V�U����v��>��&F��~�t.��F�h�j`�����+&�v��w�����+&���+�_^�VW��F�+��F-=Dv�c&����.���|LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL�L�LLL����������L�
        !          140978: 
        !          140979: 
        !          140980: LL��*���>�+t��*���*t��*���*��>�+t���*���*t�^��1�㋷d+��^��;�ヤ+��%@@uo�F���$ t��%���+��*�V��%���+��*&�H�N�N+���* t�&��*t��&��*@@t��>�+t+�����N��Gk���ڋ�f)�t�<t�<�t��F��%�P�s����F��_^�VWU��v�ƻ��CC.;��uJ.�g
        !          140981: =>ctu�������* �'�&�*�����*@@��&�*������*�>����_^�VWU��v��%*���ƈ��%��%��%*�=&r��%�_^�VWU��v�����X&*�:�Y&u���Y&*�ȋ�ي�Z&*����Y&*�=�rƄY&���Y&�>t��.&���;�t��/&���;�u
        !          140982: WV�2���3��bu�>�+u��6�+V����׃�cu�>�+t�j����>�+�f��_^�VW��n�F�h�j`�g����+&�v��X���_^�VWU����*����_^�VW��v�D u2V����F��|$�F��F�&�F��F��F��F�Ph�����ǃ>�+u��+VhP j
        !          140983: h�����_^�VWU�������>}2�h�jC��&��h�jB�&��j
        !          140984: jB�&��ja�m&��
��>~�uja�S&��%��Pja�&���>t��P�����V�a���v����vhP j
        !          140985: h�[���_^�VWU��>�*~�>�*~        ��*u���_^�VW��v
        !          140986: �D�F��<uV������u����Dup��$ t'��&�F���$&jjh&h~$��&���v���&���ы>�E$E&t&��t�_��F�;Du��6V�[����t+��V�N����|u����$ t��V�0����u��_^���`�U���v�v�P���]������`��܋W+���[XS�`[SSø�`�VWU����_^�VWU���_^��܋W�G�ø�`���`���`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          140987: ���~�����~�����vh�H����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh���������Dž����Dž�_^���`��X��X[SSP�X���`�VWU��v�~t�~
        !          140988: jjjVh����
        !          140989: �+�����x��D�F�D�vh�v
        !          140990: Vh�w���
        !          140991: W�����_^���`���`���`���`���`���`���`���`���`���`�ldrv:%d: bad dev
        !          140992: ldrv:%d: dev bsy
        !          140993: &"&""�"&"&"&"&"������P&
        !          140994: �t&"�!�&"� 2���)�������{[]}\���@@����������~����������������������������������������������������������|��1234567890�'     qwertzuiop�+
�asdfghjkl��^�#yxcvbnm,.���� ����������������-���+�������<��!"$%&/()=?`�QWERTZUIOP�*
�ASDFGHJKL����'YXCVBNM;:���� ����������������-���+�������>��������cccccccccccc�)�)�)�)�)�)�)�)�)�)�)�)�)�)�)***** *$*&***.*0*4*8*:*>*B*D*H*K*M*Q*U*W*[*a*c*g*k*m*q*u*w*{**�*�*�*�*��������������������7?w8?x9?y4?t75?u6?v1?q2?r3?s[@@0?p.?n/_-*&�Kttstart_ismmfunc_sKsleep_mmtim_Kttopen_main_clrivec_�"pollopen_:"mmbeeps_&mm_voff_mmcrtsav_�*fontw_2super_:#nonedev_"uexit_�#initkeys_mmgo_�&mmwatch_� isuload_�updleds_�Kdefend_nondsig_"isclose_tKclrivec_setivec_b"Kpollopen_sphi_,#boot_�!ldrvipc_grread_u_isioctl_�putchar_N"ldrvics_isread_�drvl_ldrvcon_inb_�!Kuexit_Ksuper_outb_0"nulldev_&"drvn_getubd_�!timq_isload_2ldrvsel_Knondsig_istty_~$agmaptab_�'ttsetgrp_�#isspecial_�Ksetivec_xcalledttclose_�#Kboot_ttin_�#kbunscroll_�ttout_�#con_Kldtimcall_Kputchar_isfunction_fldrvint_ttioctl_�#ttread_�#grwrite_�mmwrite_!islock_Kgetubd_defer_�!cprocp_kcall_"timeout_D#Kttsetgrp_isturbo_|$mmstart_�Kttclose_mmtime_P Kttin_Kttout_ucs_uds_mm_von_$wakeup_�#Kttioctl_isopen_�Kttread_spl_0#Ktimeout_ispoll_�printf_D"putubd_X"ldrvpsy_mmvcnt_�*mmesc_&ttstart_�#getcs_�!Kwakeup_isrint_grcon_($sleep_"#ttopen_�#iscon_b$Kprintf_KldeferKputubd_isbusy_0&';'$*$*0-05'?#'J$$Q0T0\'b;$e'h;$k'o; q'u; w'~#'�]'�$'�;'�Q'�.'�;'�;$�0�'�G$�'�;'�;'�#'�$'�.'&!'&Q0&'#&!'-&'4&07&'J&,0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& ,$ .$ 0$ 2$ 4$ 6$ 8$ :$ <$ >$ B$'R$ 5$j'�_ �0�'�'�_    )0] f 0� �0� � 0*00 �0�0�0� � � �0�0� �0�0# N0Q0~0�0�0�0�0�$�0�$�0�0�0`0c0r0u0�0�0�0�0�0� �  
 *0H'MD0R0_0i w0�0� �0� � � 0a q z0�'�D0�     
              5      0T      0j      0�      0�      0�      0�      0�      0�      0�      0�      0�      0�      0.
        !          140995: 0D
        !          140996: 0X
        !          140997: 0�
        !          140998: 0�
        !          140999: 0�
        !          141000:  �
        !          141001:  �
        !          141002:  �
        !          141003:  �
        !          141004:  �
        !          141005:  �
        !          141006:  �
        !          141007:  �
        !          141008:  �
        !          141009:  �
        !          141010:  �
        !          141011:  �
        !          141012:  �
        !          141013:  �
        !          141014:  �
        !          141015:  �
        !          141016:  �
        !          141017:  �
        !          141018:  �
        !          141019:  �
        !          141020:  �
        !          141021:  �
        !          141022:  �
        !          141023:  �
        !          141024:  �
        !          141025:  �
        !          141026:  �
        !          141027:  �
        !          141028:  �
        !          141029:  �
        !          141030:  �
        !          141031:  �
        !          141032:  �
        !          141033:  �
        !          141034:  �
        !          141035:  �
        !          141036:  �
        !          141037:  �
        !          141038:  �
        !          141039:  �
        !          141040:  &        
          ! # % ' ) + - / 1 3 5 7 9 ; = ? A C E G I K M O Q S U W Y [ ] _ a c e g i k m o q s u w y { }  � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � &       
          ! # % ' ) + - / 1 3 5 7 9 ; = ? A C E G I K M O Q S U W Y [ ] _ a c e g i k m o q s u w y { }  � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � &
 
 
 
  
 
 

 
 
 
 
 
 
 
 
 
 !
 #
 %
 '
 )
 +
 -
 /
 1
 3
 5
 7
 9
 ;
 =
 ?
 A
 C
 E
 G
 I
 K
 M
 O
 Q
 S
 U
 W
 Y
 [
 ]
 _
 a
 c
 e
 g
 i
 k
 m
 o
 q
 s
 u
 w
 y
 {
 }
 
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
 �
'*R'�R$- f$ h$ j$ l$ n$ p$ r$ t$ v$ x$ z$ �$$90C0T0a0n0x'# �0�$�0�0�$>)$@@)$B)$D)$F)$H)$J)$L)$N)$P)$R)$T)$V)$X)$Z)$\)$^)$`)$b)$d)'�$�0�'�$�0�0�$�$�0�$�$�0�00%$%.%@@$H%g0z$�0�$�0�0�$�0�$�$�0� � � � � �0�$�0�00$$!$&$+$0$5$:$A$F$K$P$U$Z$_%t%x0�%�%�%�0�%�$�$0$'*k$0 306'=k0D0R0b0k%r%y0�%�%�%�0�0�%�%�0� � � � �%�%�%�%�%0$!0.%>0C$F%O0T%]0b0j%n%}0�$�%�0�%�0�%�0�%�%�0�%�0�0�0�%�0�$�0�%&$     %04$8%C%I$W$c%w0�0�0�0�%�0�%�%�$f)$h)$j)$l)$n)$p)$r)$t)$v)$x)$z)$|)$~)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)$�)0� � � � � � � � �      
        !          141041:              " $ & ( * , . 0 2 4 6 8 : < > @@ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z$}0�%�$�0�%�$�0�$�0�%�0�$�0�%�%�0�%�$�$�$�%�%�$�%�%�%%%%%0$J0e ~ � � � � �%�%�%�%�'�D%�0�0�$�$�$�$�$�0'k0$'RD0p%~'�D%�0�%�0�%�0�0�0�%�0�%�0�0 0+ %4 %;  ? 'D 0G 0V '\ 'c 0l 0w 0� 0� '� '� 0� 0� '� _'� _0� '� _0� 0�  � '� 0� $� $� $!0
        !          141042: !0&!00!$=!0D!$K!$W!0Z!0c!'l!G0w!0~!'�!0�!0�!$�!'�!0�!'�!7'�!5'�!i0�!'�!E'�!5'"5'"/'"5'"';"'>"5'E"h'H"5'O"='R"5'Y"j'\"5'i"'x"!'�"'�"'�"'�"Q'�"!'�"?'�"40�"'�"'�"'�"!'�"!'�"Q'�"'&#0#'#'#!'##'&#5';#''>#5'`#Y0c#0k#0p#'#<'�#Y0�#0�#'�#M'�#5'�#O'�#5'�#U'�#5'�#'�#5'�#P'�#5'�#W'�#5'�#J'�#5'�#'�#5'�#&'�#5'�#b'�#5@
        !          141043: 0707070064030111241004440000030000030000011777770507310764600004500000014653/newbits/kernel/USRSYS/ldrv/RCS/hs,vhead     1.1;
        !          141044: branch   ;
        !          141045: access   ;
        !          141046: symbols  ;
        !          141047: locks    bin:1.1; strict;
        !          141048: comment  @# @;
        !          141049: 
        !          141050: 
        !          141051: 1.1
        !          141052: date     91.07.15.14.14.33;  author bin;  state Exp;
        !          141053: branches ;
        !          141054: next     ;
        !          141055: 
        !          141056: 
        !          141057: desc
        !          141058: @initial version prov by hal
        !          141059: @
        !          141060: 
        !          141061: 
        !          141062: 
        !          141063: 1.1
        !          141064: log
        !          141065: @Initial revision
        !          141066: @
        !          141067: text
        !          141068: @&��0����v�v�v�Ѓ��VW��6�t;6|Vh��    ��j&�M��k�
        !          141069: ��u���ヿtVh��~       ��j�&����������&��&k�
        !          141070: LJ����LJ�������>t
����P���jjh&h���    ����G$&t�>�uރ>t
����P���k�
        !          141071: LJ����LJ����LJ+���}.���㋇;tG��W�@@ ������LJ����LJ��h�q��+���&s=���㋇�F��~�t)�^��G�F��;;F�ujjj�v��D ���͋^����G�j��     ���_^�VWU��>�t
�v
        !          141072: �v�����>u���_^�VWU��>�t
        !          141073: �v������u        h���   ���_^�VW�i^P�6������uh�������i^P�6�����F��F�;|���^�����
        !          141074: iF�^���j��P���j��@@P�t����@@P�@@���t��!��\�Di�D��^������D��D���(&���)&�|��)&����㋇D�F�h���P����v�W����F���P��@@P����j��P�����6��F��3��_^�VWU��>�t
        !          141075: �6�����_^�VW��~��i�^����|t�D@@P�r��������t�����t�'�r�D�D=&uZV�����F�t;�<�F��DP�'�����L ��t�d���� t�L�v��
���
        !          141076: �d���LV�&���vV����2�_^�VW��~��i�^����|&uJV�%���F��~�t8h�h�j
        !          141077: h����jjh&h������Z*�:�[u̓~�t��N����L���_^�VWU��v
        !          141078: jV�~��i�^�P�����_^�VWU��v
        !          141079: jV�~��i�^�P����_^�VWU���v�v
        !          141080: �~��i�^�P����_^�VWU���v�v
        !          141081: �~��i�^�P����_^�VW��v��X&*�:�Y&t2��Y&*�ȋ�ي�Z&*�PV�)����Y&*�=�rƄY&����Y&�¿���Z*�؊�[*��+���Ǚ.�>���O|9V����F��|+��Z*�ȋ�ًF���\��Z*�=�rƄZ����Z��V�����|tVh�j
        !          141082: ��H&P�,���_^�VW��6��|u�&&�DtL�DP��������t7��&t��t�d����L ��t�� t�L��d��V�"���DP�������t�Dt       jV�M����&t:��X&*�ȋ���F��t�i���^���Z&�Dt��X&��X&*�=&rƄX&�� tC�D u<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�<����[��[*�=&rƄ[��^��;�w����_^�VW��v���F�+���)&t��W�DP������)&����㋇D���t+h��DP����W�t�������P�D@@P�����,&%�=&t=t���
        !          141083: ��W�DP���j�D@@P�t���v��M����_^�VWU��v�4���DP� ������ t<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�����[��[*�=&rƄ[W�����_^�VWU��������;�|�����_^�VW����t��F��F��F�;}?iF�^��>��}t)iF�^��>���(&����狅l�F��F�;F�}�F��F��F�븋F�;t.��.�>������&���~�th��6�����_^�&d��`�VW��~dra�F+�.�6� �uS�F+�RPjh�4�����F���&�F�j6jC�����F�%�Pj@@�����F���Pj@@�����v��&���F���F����F��_^�VW��v�{����F��u�v&�F��F
        !          141084: ��P��v��e&���F��_^�VW���F��~�t!jd�8����:&�F���P�+&���F��_^�d�����`�����܋W+���[XS�`[SSø�`�VWU���_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          141085: ���~�����~�����vh�t����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh�(�������Dž����Dž�_^���`��X��X[SSP�X�VWU��v�~t�~
        !          141086: jjjVh�����
        !          141087: �+��������D�F�D�vh�v
        !          141088: Vh����
        !          141089: W�����_^���`���`���`���`���`���`���`���`���`���`���`���`���`��Ë܋_��Ë܍_VWU��P�V
        !          141090: �F+�+�� ��������;wrw;?r+?w@@��[��]_^���`�ldrv:%d: bad dev
        !          141091: ldrv:%d: dev bsy
        !          141092: ����
        !          141093:     ��    7\�� �       �&��       Y@@�&�`@@:0 dddddddd�,&�&�&X �@@hsload: can't allocate tty's
        !          141094: Kttstart_free_�       Ksleep_Kttopen_main_ttsignal_fclrivec_Z
        !          141095: Kttpoll_hscycle_�hsparam_�Kfree_uexit_�Kttsignal_hsclose_�altclk_in_        Kdefend_kclear_� altclk_out_Q     setivec_�     Kclrivec_sphi_�
        !          141096: ldrvipc_tthup_u_hsioctl_�hsread_7ldrvics_poll_hz_ldrvl_ldrvcon_inb_�        cs_sel_�     Kuexit_nulldev_� outb_�     drvn_altclk_timq_ldrvsel_Kkclear_ttsetgrp_\Ksetivec_xcalledttclose_ttin_ Ktthup_ttout_>con_Kldtimcall_poll_owner_poll_rate_ldrvint_ttioctl_*ttread_Raltsel_vldiv�hswrite_\cprocp_kcall_� timeout_�
        !          141097: Kttsetgrp_Kttclose_hsstart_iKttin_Kttout_HSNUM_alloc_�ucs_vrdiv�hsopen_ wakeup_�Kttioctl_Kttread_spl_�
        !          141098: Ktimeout_HS_PORTS_
        !          141099: hspoll_�ttwrite_zprintf_�   allkp_ldrvpsy_Kalloc_ttstart_pgetcs_�     Kwakeup_hsintr_�sleep_�
        !          141100: ttopen_4hscon_*Kttwrite_Kprintf_ttpoll_H0&'/'$#$*0-05'?'J$Q0T0\'b/$e'h/$k'o/ q'u/ w'~'�P'�'�/'�C'�&'�/'�/$�0�'�9$�'�/'�/'�'�'�&'&'&C0&'#&'-&'4&07&'J&%0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& . 0 2 4 6 8 : < > @@ B$�&'�&O0�&%�&$�&00$
        !          141101: %0$#0($2%;0H0T0^0h0k t y$�$�0�0�0�0�%�0�%�%�0%0,';0?'C1'K0]0j0w0�0�0�0�%�0�%� �%�0&%001%O0S%t0x%�0�%�0�0� /080q ~0�%�0�0�0�0�0050�%�0�0�0�$�00
        !          141102: 00G0T0]0c0r0~0�0�0�%�%�%�%�%�'�10$%!%2$?'\2'a2 g%j0m'q1 |'�20�'�1'�Q'�* �0�0�0�0�0�0&       0#      00      '9      $0<    '?      60E    'X      $0f    0l      's      $'y    60    '�      
        !          141103: '�    *'�    *'�    ''�    *'�    Z'�    *'�    '�    '
        !          141104: '
        !          141105: '
        !          141106: '
        !          141107: C'"
        !          141108: '+
        !          141109: 3'1
        !          141110: )04
        !          141111: ';
        !          141112: 'G
        !          141113: 'R
        !          141114: 'l
        !          141115: 'p
        !          141116: C'v
        !          141117: '}
        !          141118: 0�
        !          141119: '�
        !          141120: '�
        !          141121: '�
        !          141122: '�
        !          141123: *'�
        !          141124: J0�
        !          141125: 0�
        !          141126: 0�
        !          141127: '�
        !          141128: 0'�
        !          141129: J0�
        !          141130: 0'
='*'-'*'!?'$*'+G'.*'5'8*'?@@'B*'I'L*'SH'V*']<'`*'g'j*'q't*'{Y'~*'� '�*'�T'�*@
        !          141131: 0707070064030111231004440000030000030000011777770507310765000005100000015333/newbits/kernel/USRSYS/ldrv/RCS/hs.310,vhead     1.1;
        !          141132: branch   ;
        !          141133: access   ;
        !          141134: symbols  ;
        !          141135: locks    bin:1.1; strict;
        !          141136: comment  @@;
        !          141137: 
        !          141138: 
        !          141139: 1.1
        !          141140: date     91.07.15.14.14.36;  author bin;  state Exp;
        !          141141: branches ;
        !          141142: next     ;
        !          141143: 
        !          141144: 
        !          141145: desc
        !          141146: @initial version prov by hal
        !          141147: @
        !          141148: 
        !          141149: 
        !          141150: 
        !          141151: 1.1
        !          141152: log
        !          141153: @Initial revision
        !          141154: @
        !          141155: text
        !          141156: @&L�����v�v�v�Ѓ��VWU����6�t�;�V�RP�
        !          141157: ���&P�����.�.�&�؃�u���ヿtV�dP��        ��+�P�����N��P��&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P�LP�;
        !          141158: ����G$&t�>Lu܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W�       ������LJ����LJ�ϸP���+��&G��&}5���㋇�F��~�t���ȋ^��G;�u+�PPPS�  ���ҋ^����+�P�Q
        !          141159: ����]_^�VWU��>Nt
�v
        !          141160: �v�N���>u�L]_^�VWU��>Pt
        !          141161: �v�P���Lu
        !          141162: �LP�M
        !          141163: ��]_^�
        !          141164: VWU����v.�&�P�6����� 
�u
�
P������v.�&�P�6 
�����F��F�;v|���^����㋿x.�.� 
��+�P��P����+�P��@@P�����@@P����t��a��\�D��D��^����㋇z�D��D���(&���)&�|��)&����㋇��F���P��P�S���v�W�I���F����P��@@P�7���P��P�'���6"
�F��+���]_^�VWU���6 
����]_^�VWU��P�F%.�.� 
���|t�D@@P���������t�����t�'�r�D�D=&uZV����F�t;�~�F��DP�g�����L ��t�d���� t�L�v��O���
        !          141165: �d���LV�&&���vV�����N��]_^�VWU��P�F%.�.� 
���|&uQV�g���F��~�t?�$
P�BP�
        !          141166: P�$
P����+�PP�&P�$
P������Z*�:�[uƃ~�t��N���L����]_^�VWU��v
        !          141167: +�PV�F%.�.� 
P�5��]_^�VWU��v
        !          141168: +�PV�F%.�.� 
P�7��]_^�VWU���v�v
        !          141169: �F%.�.� 
P����]_^�VWU���v�v
        !          141170: �F%.�.� 
P���]_^�VWU��P�v��X&*�:�Y&t2��Y&*�ȋ�ي�Z&*�PV�`����Y&*�=�rƄY&����Y&�¿���Z*�؊�[*��+���Ǚ.�>���O|9V�;���F��|+��Z*�ȋ�ًF���\��Z*�=�rƄZ����Z��V�4���|tV�P�
        !          141171: P��H&P�^����]_^�VWU��P�6 
�|u�&�DtL�DP�������t7��&t��t�d����L ��t�� t�L��d��V�T���DP��������t�Dt�PV�}����&t:��X&*�ȋ���F��t����^���Z&�Dt��X&��X&*�=&rƄX&�� tC�D u<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�h����[��[*�=&rƄ[��^��;"
w�����]_^�VWU��P�v��F�+���)&t��W�DP�����)&����㋇����t-��P�DP����W�t�����DZ��P�D@@P������,&%�=&t=t���
        !          141172: ��W�DP����P�D@@P����v��u�����]_^�VWU��v�Z���DP�D������ t<��Z*�:�[t0��[*�ȋ�ي�\*�P�t�>����[��[*�=&rƄ[W���]_^�VWU�����6
�6
;4
|�6
�6
]_^�VWU������t��F��F��F�;v}B.�.���> 
�}t,�F�.�.���> 
��(&����狅��F��F�;F�}�F��F��F�뵋F�;t/��.�>��4
���&���~�t�P�6������]_^�^&d��`�VWU����~drm�F+�.�6� �u_�F+�RP�P��4P�����F���&�F��6P�CP�����F�%�P�@@P�����F����P�@@P�����v��&���F���F����F���]_^�VWU����v�i����F��u�&�F��F
        !          141173: ��X��v��o&���F���]_^�VWU�����F��~�t#�dP� ����>&�F���P�/&���F���]_^�d�����`�����܋W+���[XS�`[SSø�`�VWU��]_^��܋W�G�ø�`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          141174: ���~�����~�����v�P�s����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P�&�������Dž����Dž]_^���`��X��X[SSP�X�VWU��v�~t�~
        !          141175: +�PPPV�P�����
        !          141176: �-��������D�F�D�v�P�v
        !          141177: V�P����
        !          141178: W����]_^���`���`���`���`���`���`���`���`���`���`���`���`���`��Ë܋_��Ë܍_VWU��P�V
        !          141179: �F+�+�� ��������;wrw;?r+?w@@��[��]_^���`�ldrv:%d: bad dev
        !          141180: ldrv:%d: dev bsy
        !          141181: ����
        !          141182: 3�*
        !          141183: l��*
        !          141184: *
        !          141185: �& �      Y@@�&�`@@:0 dddddddd�,&�&�&X �@@hsload: can't allocate tty's
        !          141186: Kttstart_ahigh  
        !          141187: free_�   bhigh        Ksleep_Kttopen_main_ttsignal_�clrivec_�
        !          141188: Kttpoll_hscycle_hsparam_�Kfree_uexit_�Kttsignal_hsclose_�altclk_in_y        Kdefend_kclear_ 
        !          141189: altclk_out_�    setivec_H
        !          141190: Kclrivec_sphi_ldrvipc_tthup_�u_hsioctl_�hsread_lldrvics_poll_hz_�drvl_ldrvcon_inb_
        !          141191: 
        !          141192: cs_sel_�    Kuexit_nulldev_*
        !          141193: outb_4
        !          141194: drvn_altclk_timq_ldrvsel_Kkclear_ttsetgrp_�Ksetivec_xcalledttclose_zttin_�Ktthup_ttout_�con_Kldtimcall_poll_owner_poll_rate_ldrvint_ttioctl_�ttread_�altsel_vldiv�hswrite_�cprocp_kcall_
        !          141195: timeout_"Kttsetgrp_Kttclose_hsstart_�Kttin_Kttout_HSNUM_valloc_�ucs_vrdivhsopen_3wakeup_BKttioctl_Kttread_spl_Ktimeout_HS_PORTS_xhspoll_�ttwrite_�printf_>
        !          141196: alow       allkp_ldrvpsy_blow     Kalloc_ttstart_�getcs_
        !          141197: Kwakeup_hsintr_�sleep_
        !          141198: ttopen_�hscon_�L0L1Kttwrite_Kprintf_L22ttpoll_�L380&'1'%%$-010; E'K'V$]0a0j'p1$s'v1$y'}1 '�1 � �'�'�S'�'�1'�E'�('�1'�1$�0�'�;$�'�1'�1 �'&'&'&(',&'0&E06&'A&'K&'R&0V&'l&'0x&0�&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � � � � � � � � � �$ 'R0%$!0%0+$. 3%80;$J0O$Z _%c0q0~0�0�0� � �$�$�0�0�0�0%0%'0* B%F0V'e0i'm3'u0�0�0�0�0�0�0� &%0%" &%.02%@@0D0d �%�0� �%�0� �%�0� �%�0�0, f0o0� �0�%�0�0�0.0;0U0s0�%�0�00$-0A0K0]0�0�0�0�0�0�0�00%"%%%)%/%4'D30K$\ c%i w%}$�'�4'�4 �%�0�'�3 �'�40�'�3'�U'�,  0      0%      03      0D      0V      0_      0�      0�      '�      &0�    '�      80�    '�      &0�    0�      '�      &'�    80�    '�      '
        !          141199: ,'
        !          141200: ,'!
        !          141201: )'$
        !          141202: ,'?
        !          141203: `'B
        !          141204: ,'O
        !          141205: '^
        !          141206: 'j
        !          141207: 'q
        !          141208: '�
        !          141209: '�
        !          141210: E'�
        !          141211: '�
        !          141212: 5'�
        !          141213: +0�
        !          141214: '�
        !          141215: '�
        !          141216: '�
        !          141217: '�
        !          141218: '�
        !          141219: E'�
        !          141220: '�
        !          141221: 0�
        !          141222: '�
        !          141223: '&'','=L0A0I0N']2'eL0i0p'{?'~,'�/'�,'�A'�,'�I'�,'�'�,'�B'�,'� '�,'�J'�,'�>'�,'�'�,'�'�,'�_'�,'�"'�,'CX'F,@
        !          141224: 0707070064030073231004440000030000030000011777770507310765100004500000033570/newbits/kernel/USRSYS/ldrv/RCS/mm,vhead     1.1;
        !          141225: branch   ;
        !          141226: access   ;
        !          141227: symbols  ;
        !          141228: locks    bin:1.1; strict;
        !          141229: comment  @# @;
        !          141230: 
        !          141231: 
        !          141232: 1.1
        !          141233: date     91.07.15.14.14.39;  author bin;  state Exp;
        !          141234: branches ;
        !          141235: next     ;
        !          141236: 
        !          141237: 
        !          141238: desc
        !          141239: @initial version prov by hal
        !          141240: @
        !          141241: 
        !          141242: 
        !          141243: 
        !          141244: 1.1
        !          141245: log
        !          141246: @Initial revision
        !          141247: @
        !          141248: text
        !          141249: @&���H����v�v�v�Ѓ��VW��6�t;6|Vh�����j&�o��k�
        !          141250: ��u���ヿtVh����j�H����������&��&k�
        !          141251: LJ����LJ�������>t
����P���jjh&h��&����G$&t�>�uރ>t
����P���k�
        !          141252: LJ����LJ����LJ+���}.���㋇;tG��W�������LJ����LJ��h���+���&s=���㋇�F��~�t)�^��G�F��I;F�ujjj�v�����͋^����G�j� ���_^�VWU��>�t
�v
        !          141253: �v�����>u���_^�VWU��>�t
        !          141254: �v������u        h������_^�VWU��>�u?jja�����V)N}�h�ja����+�Nu�j`�����h�ja����jMja�����&h�j&����h�\���_^�VWU��j&�I���_^�VWU���F�t��N��t��u��8�vh����X����u��h����V�9����_^�VW�+���}
����LJ� F���F�> +���}9����F���� ���㋿��F��F��F���G���^���=��t  �~�� r��F���_^�VWU�������u���h���V����_^�VWU��j�v
        !          141255: h�/���>t        h����_^�VWU��F
        !          141256: ���CC.;��u.�gMN�������J���v�v
        !          141257: h���V�9���V�v�v
        !          141258: �Q���H�^*��\����9|�:�������#�^)�����\�9��:|������_^�VW��~�u�> ��� sc��P�F
        !          141259: �F
        !          141260: P����F��+���}
����LJ� G��> +���}1���㉷� ��F�F��F
        !          141261: �F
        !          141262: P�<���^���=��t��� r��G���_^�VWU��f
        !          141263: ���F
        !          141264: &t"�>
        !          141265: u�~t      h8�C���>
        !          141266: u�f
        !          141267: ���F
        !          141268: �_^�VW��F��>uhh�    ����&j`����%��F�ja�������
�Pja����Vja�����>&!t=�&!�~��t�C�< �%&���:  t���: t��Vj`�����>(!~�(!��F����CC.;��u.�g���jqv�>,!t�,!�*!&��*!�F�%H���F��u��Ru�: %=u���h*���ǀu��F��tK��5u  �&: ���&�^�;�u        �&: ���t&��u   �&: ���f&��7t�^&�>*!t�������!: �H&�^�;�u  �: �7&��5u   �: &�)&��u   �: �&��7u�>*!t�&��   : �&��9u�6: ������Dt���6:  ���F��t���>u���: &t��`�X�: t,��u��
u��C�
        !          141269: �>��t��t���*�%�&#>: t�: t��0u���
        !          141270: ��0u􊄸*�����t[���t�: t�΀V�U����v��>��&F��~�t.��F�h�j`����&!&�v������,!&��(!�_^�VW��F�+��F-=Dv�c&����.���(�������������������������������������.�O���__________�~�������������� ���>*!t� ��: t� �� ��>*!t�� ��: t�^��1�㋷� ��^��;��.!�,@@uo�F�� t�0��.!�< �V�1��.!�< &�H�N�N+��:  t�&�: t��&�: @@t��>*!t+�����N��Gk���ڋ���t�<t�<�t��F��%�P�s����F��_^�VWU��v�ƻ: �CC.;��uJ.�g
        !          141271: =>ctu`    h       p       P       X       �:  �'�&: ����: @@��&: �����: �>����_^�VWU��v�X*���ƈ�Z�X�X*�=&r�X�_^�VWU��v�
���X&*�:�Y&u���Y&*�ȋ�ي�Z&*����Y&*�=�rƄY&���Y&�>t��.&���;�t��/&���;�u
        !          141272: WV�B���3��bu�>0!u��60!V�#���׃�cu�>0!t�j�
���>0!�f��_^�VW��~�F�h�j`�w
���&!&�v��h���_^�VWU���< ����_^�VW��v�D u2V�����F��|$�F��F�&�F��F��F��F�Ph�����ǃ>2!u�2!Vh�
        !          141273: j
        !          141274: h����_^�VWU����
���>}2�h�jC����h�jB����j
        !          141275: jB���ja���
��>~�uja�g��%��Pja����>t��P�����V�q
���v����vh�
        !          141276: j
        !          141277: h�k
���_^�VWU��> ~�>  ~        �  u��_^�VW��v
        !          141278: �D�F��<uV����u����Dup� t'���F��&jjh&h�����v������ы>�E$E&t&��t�_��F�;Du��6V�7���t+��V�*���|u��� t��V����u��_^�VWU����^�w�O�?t��۽" �V���t�~t���t����%�v�V�F�~+ۊf
        !          141279: �f[�f
        !          141280: �^�v�V�~�V��^���B���J��B���V���)��  X��^���O+O&O]_^�6�c�
        !          141281: %0=0t
�F��F��F�V���!�V��B*��J�
�B*��V��*��B��F��f
        !          141282: �F&�v�v
�^�^+��F�6��n6���f*���:vvK�vVQ�^�^
��.��.�� ����.��Q+����� _�P�Y^����.��~����.���������.��~����.��\I�����r.��~��€�P}�EI�����r�.��~�~u�����+I�����r�.��~*���:v�I�����r�.��~�v�H��v���I�����r�.��~*Ҋ���.����I�����r�.��~����}�O��:v
}*Ҋv
����.���I�����s�Z�.��~����I��~�~����s�?�.��~�����I�<;t!�؀�0��   w9�f�F����FÈF�������I��؀�0��    w�f�F����FÈF�ފ���s���.��~����I��؀�0��      w�f�F����FÈF��<htL<ltX���s���I��؀�0�� w�f�F����FÈF��<hu�<lu��i����€�*��H��~
u6� &�J��~
u6� �:��V��}*Ҁ�Pr�O��Q+Ɋʀ���*�Ѱ �Y��Pr��P��:vv�v�����*���:v
s�v
�&����~u�F&�~u�F&����~u�F�~u�F����:vv�v���€�Pr��P��:vv�v�O���v��*�v
:vr�v�V��*Ҁ�Pr�O�]���:v
}�v
�P�VQ�^����.��.�� �^��.��+�~���.���P� �*Ҋ���.��Y^�����6�&���F<u�^�~<&u�^
�]*Ҋv
����.���^*��8�F<u�^�T<&u*��4*Ҋv
+��^��F��<t7<&t��.��*�*�Q� �P���}�Y��Q����.��+�|� ���Y�u�Q��.�� +�|� ���Y�_�6��g�VQ�^�^��.���΃�.�� ������.+�~����.���P� ��*Ҋ���.��Y^������V��*Ҁ�Pr�O����F
        !          141283: �u��Ѐ�Pr�O����v��*�:vv�v�V��*Ҁ�Pr�O����:v���v�c��V�v���V�v����:v
}�v
�7����Nt
        !          141284: 
�F���F�����F<u��x�<&u����<u�~�t�䈀�&��<u�̀��<u�p�~�u��$w����������
        !          141285: ��<u�~�u��p����������
        !          141286: �뜀�뗁~�u�,|<<�؀��.
        !          141287: �^�,,
        !          141288: |(<�؀�.
        !          141289: �f�,
        !          141290: |<��.��^R�V���Z����F��}*�:Fw�^��}*�:^w:�w
        !          141291: �F
�^��*����v��*�:vv�v�u��F
        !          141292: �u���:vr�v�_��
�
�
�
�
�
�
�
y��
"�
_�
�
�
�
�
�
�
�
�
�
�
�
�
��
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
2;�
�
�
�
{
{
�
�
�
�
�
"�
�
�
�
�
�
�
�
D�
�
�
�
�
�
�
�
�
�
�
�
�
��
�
�
�
��
~
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
{
{
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
�
#S�
�3@@y�
��Y�(���
��
�
�
"D�
�
�
�
�
��
�
�
�
�
���
�
Th�Y�
�
�
�
�
k�
�
�
�
'�
�
�
T�
�
�
�
�
�
�
�
�

        !          141293:  "$&(*,.02468:<>@@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~�����������������@@&�&� �`�@@�� �`        
        !          141294: �
        !          141295: @@�� 
�
`�@@�� �`&@@ `P0p�$ ���!�Ë$ ���)��  �ø�`�U���v�v�P�'��]������`��܋W+�����`�[XS�`[SSø�`�VWU���_^��܋W�G�ø�`���`���`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          141296: ���~�����~�����vh�V����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh�
        !          141297: �������Dž����Dž�_^���`��X��X[SSP�X���`�VWU��v�~t�~
        !          141298: jjjVh����
        !          141299: �+�����|��D�F�D�vh�v
        !          141300: Vh����
        !          141301: W�����_^���`���`���`���`���`���`���`���`���`���`�ldrv:%d: bad dev
        !          141302: ldrv:%d: dev bsy
        !          141303: 
        !          141304: X �I�p���&G��
        !          141305: )�������{[]}\���@@����������~����������������������������������������������������������|��1234567890�'        qwertzuiop�+
�asdfghjkl��^�#yxcvbnm,.���� ����������������-���+�������<��!"$%&/()=?`�QWERTZUIOP�*
�ASDFGHJKL����'YXCVBNM;:���� ����������������-���+�������>��������cccccccccccc*06<BHNTZ`flrx~���������������������������������&    
 ��������������������7?w8?x9?y4?t75?u6?v1?q2?r3?s[@@0?p.?n/_-*&�
��&Kttstart_ismmfunc_     Ksleep_mmtim_Kttopen_main_VIDSLOW_8 clrivec_�mmbeeps_&pollopen_�mm_voff_nint11_�mmcrtsav_ super_�uexit_�mmgo_vinitkeys_�mmwatch_�isuload_Gupdleds_a
        !          141306: Kdefend_nondsig_�isclose_ Kclrivec_setivec_Kpollopen_sphi_�boot_�ldrvipc_u_isioctl_pputchar_
        !          141307: ldrvics_Kint11_isread_Idrvl_ldrvcon_inb_�Kuexit_Ksuper_nulldev_�outb_�drvn_getubd_�timq_isload_�&ldrvsel_Knondsig_istty_agmaptab_`ttsetgrp_�isspecial_zKsetivec_xcalledttclose_VKboot_ttin_`kbunscroll_�
        !          141308: ttout_~con_Kldtimcall_Kputchar_isfunction_ldrvint_ttioctl_jttread_�mmwrite_�islock_Kgetubd_defer_�cprocp_kcall_�timeout_Kttsetgrp_isturbo_�mmstart_�
        !          141309: Kttclose_mmtime_�
        !          141310: Kttin_Kttout_ucs_uds_mm_von_ywakeup_�Kttioctl_isopen_XKttread_spl_�Ktimeout_ispoll_�printf_putubd_ldrvpsy_mmesc_&mmvcnt_  ttstart_�getcs_�Kwakeup_isrint_�sleep_�ttopen_tiscon_�Kprintf_KldeferKputubd_isbusy_0&';'$*$*0-05'?#'J$$Q0T0\'b;$e'h;$k'o; q'u; w'~#'�\'�$'�;'�P'�.'�;'�;$�0�'�F$�'�;'�;'�#'�$'�.'& '&P0&'#& '-&'4&07&'J&,0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � � � � � � � � � � $�&0�&00
00$'+# 005$;0>0O$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�'f$m0t'|$�0�0�$�$�0�$�$�0�0�0�%�%�%�$�%0&$,01$6090@@$T0W$^$d0g y � � � �0�$�0�0�0�$�$�$�$�$�$�$�$�$�$�$�$&$$% %$04%I%Q%`0p%�$�$�0�$�'�i$� �0�'�i0�0�00%%%01%4%>%J0X0^%b%i0l r � � �%�%�%�%�%�0�$�0�%�0�$�%�0%     00%%)0,$/%80=%F0K%T0Y%b%q0t%}0�0�0�%�0�$�0�%�$�%�0�$�%�%�$$%#0/0:0I0T%[0c%l%s$�$�$�$�$�$�$�$�$�$�$�$�$$$$$$
        !          141311: $$$$$$$$$$$ $"$$$&$(0� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �      
        !          141312:              " $ &$)0,%0$609%=$D0G$J0M%Q0W$Z0]%a%q0t%$�$�$�%�%�$�%�%�%�%�%�%�$�0      *       F       H       J       L       N      %R      %Z      %b      %j      'r      C%x    0}      0�      $�      $�      $�      $�      $�      0�      '�      i0�    '�      C0
        !          141313: %*
        !          141314: '1
        !          141315: C%7
        !          141316: 0;
        !          141317: %I
        !          141318: 0Q
        !          141319: %X
        !          141320: 0[
        !          141321: 0h
        !          141322: 0s
        !          141323: %z
        !          141324: 0�
        !          141325: %�
        !          141326: 0�
        !          141327: 0�
        !          141328: 0�
        !          141329: %�
        !          141330: %�
        !          141331:  �
        !          141332: '�
        !          141333: 0�
        !          141334: 0''00#0-05'A'H0O0['b]'h]0m't]0y0� �'�0�$�$�$�0�0�0�$�0�$�$00'F0#0*'60=0J$Y'a0h " '�Q$�$�'
]0
0y
'}
]'�
 �
 �
 �
 �
 �
0�
 �
 �
 �
  - E0K0N ] h w �0� �0�0� �0�0�0 0!0N0Q0z0�0�0�$�0�$�0�0�0�0�000010>0W0~0� � � � � �0�0�'�C0�0� � :0N X0f n0|'�C0� � � � � �0�0�0�0�0 0*00090B0O0R0a0i0u �  0%0R0f0| ~ � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �      
        !          141335:              " $ & ( * , . 0 2 4 6 8 : < > @@ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z | ~ � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �      
        !          141336:              " $ & ( * , . 0 2 4 6 8 : < > @@ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z | ~ � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �      
        !          141337:              " $ & ( * , . 0 2 4 6 8 : < > @@ B D F H J L N P R T V X Z \ ^ ` b d f h j l n p r t v x z |$p${$�'�7'�5'�g0�'�D'�5'�!'�5'�5'�/'�5'�'�5'&f'5'='5'h'5'%'4 '@@'G'V'^P'b 'k?'q40t'{'�'� '� '�P'�'�0�'�'� '�'�5'�''�5'X00'0,';<'BX0E0L'WL'Z5'aN'd5'kT'n5'u'x5'O'�5'�V'�5'�I'�5'�'�5'�&'�5'�a'�5@
        !          141338: 0707070064030111211004440000030000030000011777770507310765500004500000012707/newbits/kernel/USRSYS/ldrv/RCS/ms,vhead     1.1;
        !          141339: branch   ;
        !          141340: access   ;
        !          141341: symbols  ;
        !          141342: locks    bin:1.1; strict;
        !          141343: comment  @# @;
        !          141344: 
        !          141345: 
        !          141346: 1.1
        !          141347: date     91.07.15.14.14.43;  author bin;  state Exp;
        !          141348: branches ;
        !          141349: next     ;
        !          141350: 
        !          141351: 
        !          141352: desc
        !          141353: @initial version prov by hal
        !          141354: @
        !          141355: 
        !          141356: 
        !          141357: 
        !          141358: 1.1
        !          141359: log
        !          141360: @Initial revision
        !          141361: @
        !          141362: text
        !          141363: @&�   �Dx8���v�v�v�Ѓ��VW��6�t;6|Vh�     �-��j&�]      ��k�
        !          141364: ��u���ヿtVh�  ���j�6      �����        ���   ��&��&k�
        !          141365: LJ����LJ�������>t
����P���jjh&h�       �n����G$&t�>�    uރ>t
����P���k�
        !          141366: LJ����LJ����LJ+���}.���㋇;tG��W��������LJ����LJ��h����+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v������͋^����G�j����_^�VWU��>�      t
�v
        !          141367: �v�� ���>u��   �_^�VWU��>�    t
        !          141368: �v�� ����  u       h�      �����_^�VW���      �D
        !          141369: ��     @@�F
        !          141370: ��     @@@@�H
        !          141371: ��     �J
        !          141372: �+�F�h��6J
        !          141373: �,��j�6H
        !          141374: � ��hP�6�   �;���v����+��_^�VWU���6�   ���h��6J
        !          141375: ����j�6H
        !          141376: �����_^�VW��v�����F��>>
        !          141377: t�'P��������h��6J
        !          141378: ���jZ�6F
        !          141379: ����6F
        !          141380: �R��=Zt
        !          141381: ��v���h��6H
        !          141382: �n���6D
        !          141383: �,��h��6H
        !          141384: �W���6D
        !          141385: ���h��6H
        !          141386: �@@���6D
        !          141387: ����h��6H
        !          141388: �)���6D
        !          141389: ����j�6H
        !          141390: ���jh
        !          141391: hT
        !          141392: ���jjh
        !          141393: hf
        !          141394: ���Phb
        !          141395: ���jh 
        !          141396: hj
        !          141397: ���jh$
        !          141398: hn
        !          141399: �w��+����
        !          141400: 
        !          141401: �>
        !          141402: &�v����+��_^�VW���F�j�6H
        !          141403: ���+����>
        !          141404: �v��}��+��_^�VW��g�F��~
        !          141405: |�~
        !          141406: s�v�^
        !          141407: �����  ������v��;���>t����+��_^�VWU��f
        !          141408: ���f
        !          141409: ���
        !          141410: #
        !          141411: 
        !          141412: u�~t        hL
        !          141413: ����
        !          141414: #
        !          141415: 
        !          141416: u�f
        !          141417: ���F
        !          141418: �_^�VWU��jhT
        !          141419: �v�D���>^
        !          141420: u�^
        !          141421: &�>`
        !          141422: u�`
        !          141423: &�_^�VWU��jhb
        !          141424: �v����&
        !          141425: 
        !          141426: ���_^�VWU��j�vhb
        !          141427: �t���&
        !          141428: 
        !          141429: ���_^�VWU��jhj
        !          141430: �v�����_^�VWU��j�vhj
        !          141431: �@@���_^�VWU��j�vhn
        !          141432: �)���&
        !          141433: 
        !          141434: ���_^�VWU��j�vh
        !          141435: 
        !          141436: ����_^�VWU��jh
        !          141437: �v�w���
        !          141438: 
        !          141439: #
        !          141440: ujh�h�h
        !          141441: 
        !          141442: �������
        !          141443: �_^�VW��>>
        !          141444: u����F�h��6H
        !          141445: �����6D
        !          141446: ����F�h��6H
        !          141447: ����6D
        !          141448: �r���F��~����F�%ǘ�F�h��6H
        !          141449: ����6D
        !          141450: �F���F�h��6H
        !          141451: �n���6D
        !          141452: �,���F��~����F�%ǘ�F�j�6H
        !          141453: �C��+��F��F��F��u�F�&�n
        !          141454: %&3F�t�~�tjj�jj&�I&���F� u�F��n
        !          141455: %3F�t�~�tjj�jj�&���F�F�n
        !          141456: �~�u  �~�u���F�&j
        !          141457: �F�&l
        !          141458: �v��A&��;T
        !          141459: �v��2&��;T
        !          141460: ~�f��f��~�t7�F���@@
        !          141461: �F���>^
        !          141462: �@@
        !          141463: �F���>^
        !          141464: b
        !          141465: �F��6X
        !          141466: �6V
        !          141467: P�����b
        !          141468: �~�t7�F���B
        !          141469: �F���>`
        !          141470: �B
        !          141471: �F���>`
        !          141472: d
        !          141473: �F��6\
        !          141474: �6Z
        !          141475: P����d
        !          141476: �b
        !          141477: ;f
        !          141478: u      �d
        !          141479: ;h
        !          141480: t�
        !          141481: 
        !          141482: &jhb
        !          141483: hf
        !          141484: ����
        !          141485: 
        !          141486: #
        !          141487: th
        !          141488: 
        !          141489: �O���>R
        !          141490: t     hL
        !          141491: �����v���&���_^�VWU��k^����p
        !          141492: jhb
        !          141493: kFr
        !          141494: P�N���F
        !          141495:        
        !          141496: 
        !          141497: �_^�VWU��F;F
        !          141498: }�F
        !          141499: ��F;F~�F�F�F�_^�VWU��~}�F����F�_^�VWU��N�      �v
        !          141500: �~��F��]_^Ì���܋W+���[XS�`[SSø�`�VWU����_^�VWU���_^��܋W�G�ø�`���`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          141501: ���~�����~�����vh�R����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`��X��X[SSP�X�VWU��v�~t�~
        !          141502: jjjVh����
        !          141503: �+��������D�F�D�vh�v
        !          141504: Vh����
        !          141505: W�����_^���`���`���`�ldrv:%d: bad dev
        !          141506: ldrv:%d: dev bsy
        !          141507: <
        !          141508: 
        !          141509: i�&&&�44�&=J{����������@@&d@@&d@@&d@@&d@@&dmsunload_=ms_readcrs_�Ksleep_MSPORT_�  main_Kukcopy_Kkucopy_clrivec_�pollopen_HKpollwake_nonedev_&ms_setmick_�uexit_�     ms_setup_JKdefend_Kclrivec_setivec_fKpollopen_ms_wait_sphi_0     ldrvipc_u_msclose_�abs_�ldrvics_drvl_ldrvcon_inb_Kuexit_nulldev_4outb_>drvn_msioctl_�timq_ldrvsel_blkmv�Ksetivec_xcalledms_readmick_�msload_�&con_Kldtimcall_ldrvint_cprocp_kcall_timeout_> ucs_MSIRQ_� wakeup_�     ioctls_�     spl_4     c_range_�Ktimeout_msopen_ims_readbtns_�ms_setcrs_{printf_\ldrvpsy_getcs_mspoll_ms_readstat_Kwakeup_sleep_& ukcopy_�     kucopy_button_ymsintr_PKprintf_pollwake_Rmscon_� 0&'('$$*0-05'?'J$Q0T0\'b($e'h($k'o( q'u( w'~'�9'�'�('�.'�"'�('�($�0�'�+$�'�('�('�'�'�"'&'&.0&'#&'-&'4&07&'J&!0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& �     �       �       �       �       �       �       �       �       �       �       �       �       �       
        !          141510:  
        !          141511:  
        !          141512:  
        !          141513:  
        !          141514: $�&%�&$�&%�&$�&%�&$�&%0%
0%0 "$&0)02$D0G%Q0T%]0`0s$}'�0�0�%�0�%�0�%�0�'�%�0�%�0�%�0�%�0�%�0�%0%0%0%&0)$1%407$A%D0G%N0Q$Y%\0_$g%j0m'u$y$}0�0�%�0�'�$�0�0�$�'�'�0�'�$$"%-00$6$:%R0X%_%f%l%s%�0�$�%�0�$�%�0�%�0�%�0�$�$0$0%$+$/$<0?$H$X0^0a%k0n%u0x%�0�%�0�%�0�%�0�%�0�%�0�%�0�%0.%@@0[%g0v%}%�0�%�0�%�$�%�$�%�%�%�%�0�%�$�%�$&% %
%%0%"%%%)%.%2$8%?%B0E$K$O$T0W%^%d0g0p%�%�%�0�$�'%'' %'-'I'L%'S        'V%']C'`%'m'|'�'�'�'�.'�'�*'�$0�'�'�'�'�'�.'�'        0    '      '    ''    '*    %'Z    40]    0e      0j      'y      )'�    40�    0�      '�      '�    %'�    '�    %'�    ='�    %@
        !          141515: 0707070064030111201004440000030000030000011777770507310765600004600000017470/newbits/kernel/USRSYS/ldrv/RCS/msg,vhead     1.1;
        !          141516: branch   ;
        !          141517: access   ;
        !          141518: symbols  ;
        !          141519: locks    bin:1.1; strict;
        !          141520: comment  @# @;
        !          141521: 
        !          141522: 
        !          141523: 1.1
        !          141524: date     91.07.15.14.14.44;  author bin;  state Exp;
        !          141525: branches ;
        !          141526: next     ;
        !          141527: 
        !          141528: 
        !          141529: desc
        !          141530: @initial version prov by hal
        !          141531: @
        !          141532: 
        !          141533: 
        !          141534: 
        !          141535: 1.1
        !          141536: log
        !          141537: @Initial revision
        !          141538: @
        !          141539: text
        !          141540: @&,��i���v�v�v�Ѓ��VWU����6�t�;�V�2P�Q���&P�����.�.�&�؃�u���ヿtV�DP�!��+�P�Z����.��0��&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P�,P�����G$&t�>,u܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W��
������LJ����LJ�ϸP����+��&G��&}5���㋇�F��~�t���ȋ^��G;�u+�PPPS��
���ҋ^����+�P�%����]_^�VWU��>.t
�v
        !          141541: �v�.���>u�,]_^�VWU��>0t
        !          141542: �v�0���,u
        !          141543: �,P���]_^�
        !          141544: VWU��>pu�&�>pu�]_^�VWU��v�F
        !          141545: -M=v������.��<Dv���DP����P�DP����P�DP���P���PV�����DP���P�DP���P�DP���P��̍DP�s��P�DP�h��P�DP�]��P�DP�R��P���뛍DP�?��P�D
        !          141546: P�4��P�DP�)��P�DP���P�DP���P�DP���P�����P��]_^�VWU���
        !          141547: �>xu�t�>zu�t�>tu+��&�>t�v�t��P�
        !          141548: P�x+�RP�q���F��V��P�:P�t+�RP�V��F�V��F��V��~�    |�~�@@v
�|P��
        !          141549: ���$&�F�P�6�;
        !          141550: ���p�u���F�P+�P�6p�X
        !          141551: ���t.�.:
p�r�z+�RP�xRP�����F��V��~�|)�~��v#��P�g
        !          141552: ���6p��      ���t�p���P�v��v��R
        !          141553: ���
        !          141554: �>
        !          141555: u�6x��P�&
        !          141556: ��뽋6p�F��F�;ts!����D
        !          141557: �D*�D.�D,�D2�D6�D4�F���:�֋6p�x.�.<
r����
        !          141558: ��;rr/�z+�)F�V��F��E�D��|���6t��P�  ���t��]_^�VWU��P�~~�F�.�>>
;ts�>pu������F�.�>>
.�.:
p���t��D�tփ~
        !          141559: t�D
        !          141560: ;FuȋF
        !          141561: =v�����.��Vk�\V��������&u�
�&�*P�vV����|,t*�΃�*�D,;�t�FP�y��
P�FP�����|4t*�΃�2�D4;�t�FP�I��
P�FP����D
        !          141562: ;Fu�,&��$&�>t�;t�&�&�FP����F��>t���>t;Dw��v������F@@@@P�����D�d��FP���%�&  D�F��D��>t�;u��D���t��D�p�G����p�Gt�g��S�k        ���p�0t
�p*P����D�D�D�D
        !          141563: %�=�u�d
        !          141564: �D
        !          141565: �DtV�$     ���|0t
        !          141566: �D*P�z���|8t
        !          141567: �D2P�j���D�>t���+���]_^�VWU��P+��>pu����>pu��&�F%�&�F��t.�.:
p����:��;pvg�D�u�t�E&�U(;T(|�;D&v؋��ԋFF
        !          141568: t̋F�V
        !          141569: ;Tu�;Du��Ft�Ft������D#F�;F�u��
���Fu��׋Nj��u����D�D�D�D�v�D�D�D�D�D �D"�D$���D&�T(���D��D�D�F�
��D�F�V
        !          141570: �D�T�D
        !          141571: ��]_^�VWU��~~�F�.�>>
;ts�F;zw�>pu�����e&�F�.�>>
.�.:
p���D
        !          141572: ;Fu��D�t�V��������u�
���p�t�D;Dwi�Ft�롋D;Dw�L+�PP�&PV��p�O+�PP�&PS�D����G$G&t��t��V��F;D
        !          141573: t��!�F��p��F�E�P�EP�v
        !          141574: �g���v�
        !          141575: �w�u�F
        !          141576: P���;Ft��>t�����p�G��|t�\�?��|�|�F&D�D��G�D���D�T �Dt�d��V�*���|0t
        !          141577: �D*P���+�]_^�VWU����~~�F�.�>>
;ts�>pu�����B�F�.�>>
.�.:
p���D
        !          141578: ;Fu��D�t�V��������&u�
���|�F��~y~�F��F��F�V���؃��F�V�t?�E�U;V|;Fv�~��=��~�t�^��E�U;W|�;Gsމ~��F��F��Ӌ~��F��F��F�V���؃��F�V�)�~x#u�~t�t�E�U;Vu;Ft�~��=���uQ�Ft�����L+�PP�&PV� ����G$G&t���t�����F;D
        !          141579: u����!���F;Es�Fu����F;Ev�E�F�P�v
        !          141580: �EP����v�F
        !          141581: P�
        !          141582: �w�u���;Ft��>t�S��~�t ��^�����D;|u�F��D�E)D�L��G�D���D"�T$�Dt�d��V�����|8t
        !          141583: �D2P�B���6p�D��|�Dt�d��V����p�0t
�p*P����F��]_^�VWU��~~�F�.�>>
;ts�>pu� ��F�.�>>
.�.:
p���D�t�D
        !          141584: ;Ft��m�f
        !          141585: ���F
        !          141586: &t"�|u�~t
        !          141587: �D*P�&���f
        !          141588: ����F�F
        !          141589: t5�D;Dr�~t"�D2��>p�}u�~t
�p*P�E&���f
        !          141590: ���F
        !          141591: ]_^�:
        !          141592: &VWU��v�>u��&�/�;t;Du�D��;Dt;Du�D���D���%�&]_^�VWU���FHFr(;w"��ۋv�~
        !          141593: �N��������F]_^�+�]_^�VWU���FHFr�;w��~�v�N��������F]_^ø�`���`������`�[XS�`[SSø�`�VWU��N�F
        !          141594: �~��F]_^ø�`�VWU���]_^�VWU��]_^���`���`���`���`���`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          141595: ���~�����~�����v�P�%����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P���������Dž����Dž]_^���`�VWU��v�~t�~
        !          141596: +�PPPV�P����
        !          141597: �-����v��D�F�D�v�P�v
        !          141598: V�P�i���
        !          141599: W�d��]_^���`���`��Ë܋_��Ë܍_VWU��P�F�'����F�g��F
        !          141600: �'��֋�[��]_^���`��X��X[SSP�X�ldrv:%d: bad dev
        !          141601: ldrv:%d: dev bsy
        !          141602: �&fXXXffff        
        !          141603: �invalid NMSQID or NMSG kernel variable
        !          141604: invalid NMSG or NMSC kernel variable
        !          141605: could not salloc %u messages
        !          141606: could not kalloc %u message ids
        !          141607: timer_ahigh 
        !          141608: free_bhigh  Ksleep_main_Kukcopy_Kkucopy_clrivec_pollopen_pputuwd_�Kpollwake_Count     Kfree_ipcaccess_@@
nonedev_Xuexit_�NMSC_zKdefend_nondsig_Nsetivec_�Kclrivec_sphi_Kputuwd_Kpollopen_ldrvipc_NMSG_xu_ldrvics_drvl_ldrvcon_Kuexit_msgs_rnulldev_fdrvn_msginit_$timq_umsgget_*ldrvsel_Knondsig_Ksetivec_xcalledsalloc_�msgpoll_zumsgctl_�con_Kldtimcall_NMSQB_vumsgsnd_eldrvint_msqs_pudl_umsgrcv_
        !          141609: msgcon_Vcprocp_kcall_ timeout_nKsalloc_alloc_�
memset_6ucs_uds_NMSQID_twakeup_spl_"getuwd_vlmul�Ktimeout_printf_�alow       allkp_ldrvpsy_blow     Kalloc_ufcopy_�
fucopy_�
getcs_vrmul�Kwakeup_String     sleep_dKgetuwd_kucopy_,ukcopy_�L0�Kprintf_Char     
        !          141610: pollwake_z0&'-'%"$-010; E'K'V$]0a0j'p-$s'v-$y'}- '�- � �'�'�G'�'�-'�<'�&'�-'�-$�0�'�6$�'�-'�- �'&'&'&&',&'0&<06&'A&'K&'R&0V&'l&$0x&0�&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& Z \ ^ ` b d f h j l$0$'01 : < > @@ B0I0T0_0f0n0t0{0�0�0�0�0�0�0�0�0�0�0�0�0&000'$.$5$;$B$H0P$T$\$i0p$�0�$�0�0�'�F0�$�0�$�0�$� �$�$�$�$�0�$0$"0%$,$2070D%J%N$U$X0\$e$q$�$� �$�$�$�$�$�0�$� �$�$'0  !$%0K T V X Z0^'m0q0|0�0�0�0�0�'�0�'�'�'00'0"'&040B0W0i'm's$�$�0�$�$�0�0�0�0'0 $40:$>'E0I$U Z$^$i'�0�0�'�'�'�$'*'.'7'? w${$�$�'�0� � �$�0�'�$�'�$
       0      '%      600    '8      0<    'H      0L    $P      0g      %q      0�      '�      '�    0�    $�      '�      6'�    '�    0�    0�       
        !          141611: $
        !          141612: $"
        !          141613: ')
        !          141614: 00
        !          141615:  9
        !          141616:  >
        !          141617: $B
        !          141618: 0W
        !          141619: 'f
        !          141620: '-010B'I60T'\0`0k'o0s'�0�0�%�0�'�'�0�'6''0&06$=0U$\$e0l �$�$�0� � �$�0�$
$"
0)
'J
'U
'f
'�
3'�
='�
3'�
='�
I')'      
')'Q')'$)'-'0)'O''R)'_'q't)'{'~)'�U'�)'�'�)'�9'�)'�'�'�'�'�'�<'�'�1'�(0�''''1'5<';'B0F'Q'['e'h)'�C0�0�0�'�.'�C0�0�'�'�)'�'�)'N')@
        !          141621: 0707070064030114721004440000030000030000011777770507310766000004500000006146/newbits/kernel/USRSYS/ldrv/RCS/qq,vhead     1.1;
        !          141622: branch   ;
        !          141623: access   ;
        !          141624: symbols  ;
        !          141625: locks    bin:1.1; strict;
        !          141626: comment  @# @;
        !          141627: 
        !          141628: 
        !          141629: 1.1
        !          141630: date     91.07.15.14.14.47;  author bin;  state Exp;
        !          141631: branches ;
        !          141632: next     ;
        !          141633: 
        !          141634: 
        !          141635: desc
        !          141636: @initial version prov by hal
        !          141637: @
        !          141638: 
        !          141639: 
        !          141640: 
        !          141641: 1.1
        !          141642: log
        !          141643: @Initial revision
        !          141644: @
        !          141645: text
        !          141646: @&�D
        !          141647: �$���v�v�v�Ѓ��VWU����6�t�;�V��P�����&P�;����.�.�&�؃�u���ヿtV��P����+�P�����������&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P��P�G����G$&t�>�u܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W�������LJ����LJ�ϸP��&��+��&G��&}5���㋇�F��~�t��&�ȋ^��G;�u+�PPPS����ҋ^����+�P������]_^�VWU��>�t
�v
        !          141648: �v�����>u��]_^�VWU��>�t
        !          141649: �v������u
        !          141650: ��P���]_^�
        !          141651: VWU�������P�P�6��6��&������]_^�VWU���6��6��B��]_^�VWU��]_^�VWU��]_^�VWU��P�v
        !          141652: �|t8�����RP�u���F�VP���=��t�����.�>����‹�]_^�VWU����v
        !          141653: �F�V�J���F��|"�~�}P�F����RP�'&���F��Ћ�]_^�WU���~+�&�]_������`���`�[XS�`[SS�VWU��]_^���`���`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          141654: ���~�����~�����v�P�}����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P�0�������Dž����Dž]_^�WU���~�F&�]_ø�`�VWU��v�~t�~
        !          141655: +�PPPV�P�����
        !          141656: �-�M�����D�F�D�v�P�v
        !          141657: V�P����
        !          141658: W�*��]_^���`���`���`��X��X[SSP�X�ldrv:%d: bad dev
        !          141659: ldrv:%d: dev bsy
        !          141660: GP$Y�$$$�&0$qqcon_�Ksleep_main_clrivec_�uexit_xKdefend_setivec_BKclrivec_sphi_�ldrvipc_u_ldrvics_qqclose_Pdrvl_ldrvcon_Kuexit_nulldev_$drvn_iogetc_timq_ldrvsel_Ksetivec_xcalledqqread_Yffbyte_�con_Kldtimcall_ldrvint_Kiogetc_cprocp_kcall_timeout_ ptov_8ucs_qqwrite_�sfbyte_wakeup_�spl_�vrelse_�Ktimeout_printf_.Kptov_qqopen_Gioputc_ldrvpsy_getcs_Kwakeup_sleep_Kvrelse_Kprintf_Kioputc_0&''%$-010; E'K
'V$]0a0j'p$s'v$y'} '� � �'�
'�,'�'�'�!'�'�'�$�0�'�$�'�'� �'&
'&'&',&'0&!06&'A&'K&  'R&0V&'l&0x&0�&0�&$�&$�&'�&
        !          141661: $�&$�&$�&$�&$�&0�& � � � � � � � � � � �%%%%0 %&%*%7%;0>%i%n%r0w0�%�%� �%�0�%�%�0�'''2'''/1'2'9)'<'I
        !          141662: 'X'd      'k
        !          141663: 'z   '�!'�'�'�0�'�
        !          141664: '�   '�'�'�!'�
        !          141665: '�0�'�   '�'&'';'0?0G0L'['c'0g0n'y'|'�0'�'�.'�@
        !          141666: 0707070064030114711004440000030000030000011777770507310766100004500000007115/newbits/kernel/USRSYS/ldrv/RCS/rm,vhead     1.1;
        !          141667: branch   ;
        !          141668: access   ;
        !          141669: symbols  ;
        !          141670: locks    bin:1.1; strict;
        !          141671: comment  @# @;
        !          141672: 
        !          141673: 
        !          141674: 1.1
        !          141675: date     91.07.15.14.14.48;  author bin;  state Exp;
        !          141676: branches ;
        !          141677: next     ;
        !          141678: 
        !          141679: 
        !          141680: desc
        !          141681: @initial version prov by hal
        !          141682: @
        !          141683: 
        !          141684: 
        !          141685: 
        !          141686: 1.1
        !          141687: log
        !          141688: @Initial revision
        !          141689: @
        !          141690: text
        !          141691: @&�DX�3���v�v�v�Ѓ��VW��6�t;6|Vh�����j&�3��k�
        !          141692: ��u���ヿtVh�����j�����������&��&k�
        !          141693: LJ����LJ�������>t
����P���jjh&h��R����G$&t�>�uރ>t
����P���k�
        !          141694: LJ����LJ����LJ+���}.���㋇;tG��W�������LJ����LJ��h���+���&s=���㋇�F��~�t)�^��G�F��;F�ujjj�v�����͋^����G�j�����_^�VWU��>�t
�v
        !          141695: �v�����>u���_^�VWU��>�t
        !          141696: �v������u        h�����_^�VWU���_^�VW��F��~�}%k^�,�������tk^�,����������F����_^�VW��F%�����k�,����N����+҉F��V���T�F��V��~
        !          141697: u�t0�F�F�t�F�F�t�F��V�;V�u;F�u�F�F�u�F�F�u��o�F�F�td�F�F�u\h0��F��V��       �������������RP�o���D���u��,�F��V���T�E�U�D�T�D*jhRP����D*�_^�VW��~�����k�,����~����+҉F��V���T�F��V��t�F�F�t�F��V�;V�u;F�u�|*u��*�L*�F�F�u�|*t�'��t�{����D�_^�VW��v�D�F�%�����k�,����N�����+҉F��V���U�F�V��t�F��V�;V�u;F�t�L��F��V���������F�V��D��    �ȋ�+�D
        !          141698: T-&��;V�w�r;F�s��D
        !          141699: �T�   ������EU�F��V��|&u�D+�RP�t�t�v��v���D+�RP�v��v��t�t���V�d���_^�VWU��v��%�����k�,���h@@�j&V�v
        !          141700: W�D��
        !          141701: �_^�VWU��v��%�����k�,���h@@�jV�v
        !          141702: W���
        !          141703: �_^���`������`�[XS�`[SS�VWU����_^�VWU���_^���`���`���`���`�VWU����f�~�烽u�~�烽t�'�J�~��F
        !          141704: ���~�����~�����vh�\����>t�~��Dž�~��Dž�_^�VWU��v�����狅;t�&�Vh��������Dž����Dž�_^���`���`�VWU��v�~t�~
        !          141705: jjjVh����
        !          141706: �+�A�����D�F�D�vh�v
        !          141707: Vh����
        !          141708: W� ���_^���`���`��X��X[SSP�X�ldrv:%d: bad dev
        !          141709: ldrv:%d: dev bsy
        !          141710: !
        !          141711: ���&�&Ksleep_main_clrivec_�Kioreq_nonedev_uexit_jKdefend_setivec_@@Kclrivec_sphi_~ldrvipc_u_pclear_ldrvics_drvl_ldrvcon_Kuexit_nulldev_drvn_timq_ldrvsel_Ksetivec_xcalledsalloc_6con_Kldtimcall_Kpclear_ldrvint_cprocp_kcall_�timeout_bdone_�Ksalloc_plrcopy_"ucs_wakeup_tspl_�Ktimeout_Kbdone_printf_,Kplrcopy_ldrvpsy_sfree_getcs_�Kwakeup_sleep_
        !          141712: Kprintf_rmcon_�Ksfree_ioreq_�0&''$$*0-05'?'J$Q0T0\'b$e'h$k'o q'u w'~'�)'�'�'�"'�'�'�$�0�'�$�'�'�'�'�'�'&
'&"0&'#&
'-&
        !          141713: '4&07&'J&0_&0p&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& � � � � � � � � � �%%%0%6'�0�'�0�%'b'z0�%�0�0o0v%�0�%�0�'�&'�'�'�'�''''#('&'-.'0'7 ':'G'V
'b
        !          141714: 'i'x
        !          141715: '�"'�
'�'�0�'�'�
        !          141716: '�
'�
'�"'�'�0�'�
        !          141717: '�
'&0''''0%030;0@@'O'V%0Y0`'k'n'u,'x@
        !          141718: 0707070064030111171004440000030000030000011777770507310766200004600000011744/newbits/kernel/USRSYS/ldrv/RCS/shm,vhead     1.1;
        !          141719: branch   ;
        !          141720: access   ;
        !          141721: symbols  ;
        !          141722: locks    bin:1.1; strict;
        !          141723: comment  @# @;
        !          141724: 
        !          141725: 
        !          141726: 1.1
        !          141727: date     91.07.15.14.14.50;  author bin;  state Exp;
        !          141728: branches ;
        !          141729: next     ;
        !          141730: 
        !          141731: 
        !          141732: desc
        !          141733: @initial version prov by hal
        !          141734: @
        !          141735: 
        !          141736: 
        !          141737: 
        !          141738: 1.1
        !          141739: log
        !          141740: @Initial revision
        !          141741: @
        !          141742: text
        !          141743: @&n   l�����v�v�v�Ѓ��VWU����6�t�;�V�t  P�����&P�   ����.�.�&�؃�u���ヿtV��       P���+�P������p   ��r   ��&��&��.�.�&��LJ����LJ�������>t�Ʊ��P���+�PP�&P�n P�����G$&t�>n   u܃>t�Ʊ��P�����.�.�&��LJ����LJ����LJ+��&G��}+���㋇;u�W�c������LJ����LJ�ϸP�z��+��&G��&}5���㋇�F��~�t��J�ȋ^��G;�u+�PPPS�e���ҋ^����+�P�����]_^�VWU��>p       t
�v
        !          141744: �v�p ���>u�n   ]_^�VWU��>r    t
        !          141745: �v�r ���n  u
        !          141746: �n     P�a��]_^�
        !          141747: VWU��>�      ta��   .�&v��W�6�����u�6�    ��      P������      �/��  .�.x���  .�.x����&��;r�D��+�]_^�VWU����v
        !          141748: �D�F��D�F�;�        r������F�.�.x���E�u�!��W�C������&u�
�ȋE��F�V��F�+ҋ؋ʋD��;V�w�r;F�w��^�����G�F��F��F��t�t�v�P�o���u�o��D+���]_^�VWU����v
        !          141749: �D�F��D�F�;�        r������F�.�.x���E�u�!��W��������tʋE��F�V��F�+ҋ؋ʋD��;V�w�r;F�w��^�����G�F��F��F��t�v�P�t�{���u�v��D+���]_^�VWU��F
        !          141750: =CHt=GHt8��x�FP����P�FP���P�F@@@@P���P�U���=�FP���P�FP���P�FP�x��P�F@@@@P�k��P�&��P�v���]_^�(&VWU��P�F��>t������F;�   r���F.�.����D�t�F
        !          141751: =v�����.���E��V�'������&u�
른&P�vV�����F��|�>t�;t�&�b�v�����F@@@@P����D�d��FP���%�&       D밃>t�;u��D
        !          141752: �~��>�5�|���D���F����F���]_^�VWU��P�F��>t����Z&��  .�.�����&��;s��D�u �~�t�~��E"�U$;T$|�;D"vЉv��ˋFF
        !          141753: tËF�V
        !          141754: ;Tu�;Du��Ft�Ft�늋~���&�D#F;�t�
�q��D;Fr���^��Fu��O��~�u��A��v���+�.�>�����>�@@P�F+�RP�&����tʋF�D�D�D�D�D ���D"�T$�>�E�D���D��D�D�F%�&
��D�F�V
        !          141755: �D�T�FF
        !          141756: u�L��+�.�>���]_^�&VWU��v�>u��&�/�;t;Du�D��;Dt;Du�D���D���%�&]_^�VWU���FHFr(;w"��ۋv�~
        !          141757: �N��������F]_^�+�]_^�VWU���FHFr�;w��~�v�N��������F]_^ø�`������`�[XS�`[SSø�`�VWU���]_^�VWU��]_^���`���`���`�VWU����f�~�烽u�~�烽t�'�K�~��F
        !          141758: ���~�����~�����v�P�[����>t�~��Dž�~��Dž]_^�VWU��v�����狅;t�&�V�P��������Dž����Dž]_^���`���`�VWU��v�~t�~
        !          141759: +�PPPV�P����
        !          141760: �-�C�����D�F�D�v�P�v
        !          141761: V�P����
        !          141762: W� ��]_^���`���`��X��X[SSP�X�ldrv:%d: bad dev
        !          141763: ldrv:%d: dev bsy
        !          141764: ���q,����&�couldn't kalloc %u shared memory ids
        !          141765: timer_Ksleep_main_Kkucopy_clrivec_�putuwd_
        !          141766: ipcaccess_�nonedev_�uexit_L   Kdefend_setivec_Kclrivec_sphi_` Kputuwd_ldrvipc_u_ldrvics_drvl_ldrvcon_Kuexit_nulldev_�shmsegs_drvn_timq_ldrvsel_ushmget_�Ksetivec_xcalledsalloc_ushmctl_zcon_Kldtimcall_ldrvint_NSHMID_�     udl_cprocp_kcall_�timeout_�shmids_shmcon_� Ksalloc_alloc_�ucs_uds_wakeup_V     spl_d     getuwd_�Ktimeout_printf_allkp_ldrvpsy_sfree_�Kalloc_fucopy_�ufcopy_Dgetcs_�Kwakeup_sleep_�Kgetuwd_kucopy_�Kprintf_Ksfree_0&''%$-010; E'K'V$]0a0j'p$s'v$y'} '� � �'�'�2'�'�'�*'�'�'�$�0�'�#$�'�'� �'&'&'&',&'0&*06&'A&'K&'R&     0V&'l&0x&0�&0�&$�&$�&'�&$�&$�&$�&$�&$�&0�& �        �       �       �       �       �       �       �       �       �      $$ '10' &$($+0/$6$= B'F&'I$L Q'U&'`&$�'�0� �'�&'�0�'�'�00$E'K0R Z'^&'k0r'�0�0�'�0&000#020@@0N0[0b0l'�0�$�'� �'�&0� � � � �0�'�0�'�''00#08'G'M']0b'p'�0�$� �'�&'�&0�''0 0+'/03'>0B'L0P'Y& _'g0u'�'�'�#'�'�'�& �'''"'V"'\+'�"'�+'�4'�'�:'�'�'�'�'�'&<''
''(''%'4'@@'G'V'^*'b'k 'q0u'|'�'�'�'�*'�'�0�'�'�'�='�'�&'�'    /0    0      0       '/      '7    /0;    0B      'M      'P    'W    8'Z    @
        !          141767: 0707070064030112201007550000030000030000011777770507310766300003600000000574/newbits/kernel/USRSYS/usrsrc# back up USRSRC directories
        !          141768: TMPFILE=/tmp/usrsrc.$$
        !          141769: rm -f $TMPFILE
        !          141770: cd $USRSRC
        !          141771: for DIR in i8086/drv i8086/drv/tools i8086/ibm_at i8086/src coh ttydrv ker ldrv
        !          141772: do
        !          141773:        for FILE in `ls $USRSRC/$DIR`
        !          141774:        do
        !          141775:                echo $DIR/$FILE >> $TMPFILE
        !          141776:        done
        !          141777: done
        !          141778: echo "$TMPFILE created"
        !          141779: echo -n "Insert 3-1/2\" formatted diskette and press <Enter> "
        !          141780: read JUNK
        !          141781: cpio -ocv < $TMPFILE > /dev/rfva1
        !          141782: rm $TMPFILE
        !          141783: 0707070064030112161007550000030000030000011777770507310766300003600000000516/newbits/kernel/USRSYS/usrsys# back up USRSYS directories
        !          141784: TMPFILE=/tmp/usrsys.$$
        !          141785: rm -f $TMPFILE
        !          141786: cd $USRSYS
        !          141787: for DIR in . ldrv doc confdrv lib
        !          141788: do
        !          141789:        for FILE in `ls $USRSYS/$DIR`
        !          141790:        do
        !          141791:                echo $DIR/$FILE >> $TMPFILE
        !          141792:        done
        !          141793: done
        !          141794: echo "$TMPFILE created"
        !          141795: echo -n "Insert 3-1/2\" formatted diskette and press <Enter> "
        !          141796: read JUNK
        !          141797: cpio -ocv < $TMPFILE > /dev/rfva1
        !          141798: rm $TMPFILE
        !          141799: 0707070064030110611007550000030000030000011777770507310766300003500000002614/newbits/kernel/USRSYS/Build:
        !          141800: :  Build a Coherent executable with a host adapter driver linked in.
        !          141801: :
        !          141802: DRIVERS="rm fl lp mm"
        !          141803: COH_TYPE=fl
        !          141804: HD=""
        !          141805: KB=nkb
        !          141806: for ARG
        !          141807: do
        !          141808:        case $ARG in
        !          141809:        at|aha|ss)
        !          141810:                HD=$ARG
        !          141811:                COH_TYPE=$ARG
        !          141812:                ;;
        !          141813:        kb|nkb)
        !          141814:                KB=$ARG
        !          141815:                ;;
        !          141816:        *)              echo "Usage: $0 { at | ss | aha } { kb | nkb }"
        !          141817:                        exit 0
        !          141818:                        ;;
        !          141819:        esac
        !          141820: done
        !          141821: DRIVERS="$KB $HD $DRIVERS"
        !          141822: echo "Kernel:    /coh.$COH_TYPE"
        !          141823: echo "Devices:   $DRIVERS"
        !          141824: 
        !          141825: : default root/pipe device
        !          141826: BOOTDEV="fva0"
        !          141827: echo "Default root/pipe device is $BOOTDEV."
        !          141828: 
        !          141829: ( cd /usr/src/sys/i8086/drv; make -f Makefile install )        || exit 1
        !          141830: ./config ibm-at $DRIVERS root=$BOOTDEV                 || exit 1
        !          141831: cp coherent /tmp/coh                                   || exit 1
        !          141832: strip /tmp/coh                                         || exit 1
        !          141833: set `ls -s /tmp/coh`
        !          141834: SIZE=$1
        !          141835: rm /tmp/coh                                            || exit 1
        !          141836: echo "Coherent bootable limit is 138 blocks.  This kernel is $SIZE"
        !          141837: if [ $SIZE -gt 138 ] ;then
        !          141838:        echo 
        !          141839:        echo Your Coherent image exceeds the bootable limit of 138 blocks
        !          141840:        echo by `expr $SIZE - 138` 'block(s).'  You will need to decrease the
        !          141841:        echo size of your kernel in order to make it bootable.
        !          141842:        echo
        !          141843:        echo We suggest removing some of the non critical drivers from the
        !          141844:        echo default list of drivers linked into Coherent.  These additional
        !          141845:        echo drivers may then be linked as loadable drivers using the
        !          141846:        echo ldconfig script located in this directory.
        !          141847: fi
        !          141848: mv coherent /coh.$COH_TYPE
        !          141849: chown sys /coh.$COH_TYPE
        !          141850: chgrp sys /coh.$COH_TYPE
        !          141851: chmod 400 /coh.$COH_TYPE
        !          141852: echo "New kernel in /coh.$COH_TYPE"
        !          141853: ls -l /coh.$COH_TYPE
        !          141854: 0707070064030050621006440000000000000000011777770507310766400004200000173363/newbits/kernel/USRSYS/atkernel.o&����      <x-9&��.�  +��d�������d+��d�������`+��d����6�C�����@���.�@���� ��� �!����!���&�!�����!���+����[��f��q�
        !          141855: �|�������������� ��"�$��&�(��*�,��.�0��2�4��6�����������d��������(����4����@����L����&X��&��&d��&��&p��&��&|��&��&���&��&���&��&���&��&���&����O����r��������%���>��u������������������؎м���œ�Ĝ.����+������.Ĝ����+���&��&9u����@;.��r�Ĝ������%��3Ѓ>��t
        !          141856: �������������%��3������������+������+��󫡠�����%��3�����������+�����+������ϸ���������3�%���3«+���׸���������3�%���3«+����+�������3�%��3�™����«+���>�������������3�%���3«+���>������������3�%���3«+��������������3�%���3«+�������������3�%���3«+�������������3�%���3«+�����+���+�+��˹&����;ø�t+��+����Ў؎�&��&��&�
&&����+�а�p��q�����p��q�����+��������������D�D��D+�+����D�T��&��&9u��B6;��}���|��D�ӎێã������G�ʏ���G&鿏���G鴏���G驏���G鞏���G铏��G鈏��G�}�X��G�q���G     �f�X��G
        !          141857: �Z�X��G�N�X�u�G�B�X�i�G
�6��^�G �+��S�G!� ��H�G&@�&���<�G@�&���0�G@�&���$�G@�&����G@�&����G@�&����G@�&����
�G        @�&����
�G
        !          141858: @�&����
�G@�&����
�G@�&����
�G
@�&���
�G@�&���
�G@�&���
�G@+�P�w�>��u��G"�u���G�h���<r� 栰 � �WU��V�~
        !          141859: �N�����]_�VU��V�v
        !          141860: �N������]^�VWU���v�v�v�v�    ������v�v�v
        !          141861: �v�  ���Ǝڋ��N��������ƌ�VP���WP���]_^�VWU���v�v�v�v�M   ������v�v�v
        !          141862: �v�7  ���Ǝڋ��N�N�O����������ƌ�VP�
        !          141863: ��WP�
        !          141864: ���F]_^�VWU���v�v�v
        !          141865: �v�����‹��n�^�N+����PP�h
        !          141866: ��]_^Ë܋GHGs�;̜v��6ʜ�&VWU��+�P�v�v�v����‹��^�v
        !          141867: �N���������PP�
        !          141868: 
        !          141869: ���F]_^��Ë܋GHGrS;̜wM�6ʜ�&VWU��+�P�v�v�v
        !          141870: �2���ڋ��F�~�N���������PP�  ���F]_^��û��+��.�       ��+��d�������d���VWU��v����=u�       �t
���㋇��=�t��'�Z����F
        !          141871: ������|,�h��&�����ރ��&������#�Wh�����j!�������&������#�Wj!�����_^�VWU��v����=u�    �u
        !          141872: Vh��TR������LJ�����|*�h�������ރ��&�����Wh�������u�>uj!�t�����&�����Wj!�j���_^�VW��v�N��|�n�~�^
        !          141873: �F
        !          141874: �V+����&F
        !          141875: V�F+�F
        !          141876: V+����F��V��F
        !          141877: �V+���;V�u;F�t+�����
�F���}1+��~t
        !          141878: ��%
H���%
DP��P��
��j��P�*���~t
        !          141879: ��%
H���%
DPh��
��jh��
���F
        !          141880: �V�������P��������}
����}        ��%�����%������F
        !          141881: PW�X
���F
        !          141882: ��PW�J
��G��|&G�vW�9
���F��PW�+
���v��
���&�_^�VWU��v��}
        !          141883: ��%Pj
        !          141884: �      ��%Ph������_^�VW��v���F���}��%
Pj
        !          141885: ������%��@���%
Ph������%�����W����F�W�����&F��v��i���F���|�f��F��_^�VW��>�u��jj�6v�����~
        !          141886: uj
������F��F�&�F�F��F��F�P�6v��,���_^�VW��v�~
        !          141887: �F�P�v����F��u��&�DP�^���^���F��E�&t��&VW�G���F��u�&�F�D�D�^��G
        !          141888: �D+�RP�t�t����D�T�}u�J&�Dt�@&�E+�DT-&��+���+DT�F�V��~�y�E�      �F�V�%��F��E�U�     �������F�V��~�t��v��F��F�;Ev�E�F��v��v��v�b
�����F��D�F�D�~&t
�v��tW����vV�����Du�~&u+�v��tW������D�^�G�D��G�~&t�D&E�LV�����v��8�F��D�F�D�F�V��D
        !          141889: �T�vV�w���Dt�D)F��F�)E&E�F�&D�&DT�&EU���t�t�H���^��O
        !          141890: �>t h�V[���Dt�D���
        !          141891: �u���DP��\���_^�VWU��v�DA���  ��V�v
        !          141892: ����D&tjh�h�V�Z����W�      ���_^�VW�� �F��F��F�����;6�t6�u�����6����P����u�j�6����P�����6��v��v��L  ���F��V��_^�VW��>��tn����F��F
        !          141893: %���F��V���RP����F��F��V���RP����F��F��V���RP�|��P�v��v����P�v��v��v�hx��S���_^�VW��v�>��u#�D�T��������D�D�T%+҉D�&����F��D�F��|u����D�T�u     h���L���D�F��Dt�v�t�th����K���F��V���RP�����u�v�t�thߛ��K����F��D�T-&��P�v��v�����t�F��V���RP�l���t�F��V���RP�C����D&t�π�Dt��W�F��V���RP���j�F��V���RP����v�����_^�VW��>��u7jj�v
        !          141894: �v����F�V�F�V
        !          141895: ��������������F�V�����F��V��u�F�Ph
���J������F��F��F���F��F�V-&��P�v��v��z���v�F��V���RP�c���v
        !          141896: �F��V���RP�:��h��F��V���RP�#��j�F��V���RP����v�����F��V��_^�VW��>��u!�F+҉F�V��F
        !          141897: +ҹ������F�V��s����F��F
        !          141898: �F��V���RP����%�=�t�v
        !          141899: �vh'���I���F��V���RP����F��F��V���RP����F��F+�&F�V��F��V��_^�VW��>��tc�~
        !          141900: t�F
        !          141901: t�v
        !          141902: hC��aI������F��F
        !          141903: �F��V���RP�6��%=t�v
        !          141904: �vh[��-I��j�F��V���RP�����_^�VW��v�΁�����;�v����N
        !          141905: ����II�N�;�v
        !          141906: Vh����H���F���^��?�
&����_^�VW��F
        !          141907: @��@�F��F��~�r��~�%��;Fu��u       h���H���&u=�%���F��^��&u ;Ft���F���F�+Ǚ.�>0�F�;F�r;F�v�~�u     �%����뚋F���Nj��F���5�
&��v
        !          141908: �EP�G���E�
�F��_���#+��_^�VWU��FHH����r�&u�vh����G���%����_^�����.H��lC����+��ʜ�Ɯ��ێÎӼtRQP�.���Μ���tC��`�v2T�6ΜS�PRQ�؎����W�܋G��@u��P�YZX����[��ρ�,&���P�UG�М��G"�tNT�6Μ�6М�;tPRQ�؎����W�܋G��@u����몃����W�܋G��@u�����������ϻ��G��G��G��G��Ҝ�&Ԝ�Ĝ�g��6Ҝ�6Ԝ�6Μ�6М�PRQ�؎����W�܋G��@u���G"�t�2��eYZX�����М�Μ[���G��G��G��g��ێ�.���М�Μ�Ë܋_;̜v� &�ʜ&�Ë܋_;Ȝv�&�Ɯ&�Ë܋_;̜v���ʜ&�*�Ë܋G�_;̜v���ʜ&�+�Ë܋G�_;Ȝv��6Ɯ+�P����+�S�6ȜRP�����܋G�_��&�R+�P�;���+�Ë܋G�_;̜wp�ʜ&�+�Ë܋GHGrY;̜wSVW�w��O���ʜ��������_^Ë܋GHGr(;̜w"VW�w��O���ʜ����������_^û��+��WU���~�F&�]_�WU���~�F&�]_�WU���~+�&�]_�WU���~&�]_�VWU���v�~
        !          141909: �N����������]_^�VWU���v�~�N����������]_^�WU���~�N+���������]_Ë܋G�g��Ëϋ܋�����ƫ�ū�ī���X��������+�����܋w�����ȭ�譋����P���������&������Y�܋G�_�������+��g���������+Ͼ+������؁�������ȭ�譋����P���������&�Ã>t�VW��+������������+ο+����_^�ÜX�ÜX��X[SSP�X����������6�W+��Ë�6�W6�G�Ë܋_���&�Ë܋G�_���&�Ë܋G�_���&��VW��Ĝ�F��F����F��V��v��v�������؋ʡ�+�щF��t���P�6�9�����>u      h֜��B���t�H����;6r0�D���F��V��D�T�F��V��D�T�F��F��V��� ���_^�VWU��t�H����;6r2�Du�� ��DP�Q���Dt    j&V�s���DP�Q�����_^�VWU��v�t�H����;>r:;ut�� ���EP�DQ��;uu�Et     j&W����E���EP�TQ�����_^�VW��v�v�v
        !          141910: �v������E&u��t�e����MW�����E&�E���F�W�v�����u
�v������+��W�E&tjh�h�W�)N�����v�������Et�}t�E�����W�빁}t��t��&�����_^�VW�+��F��t�H����;6ry�D
        !          141911: �T;VuM;F
        !          141912: uH�D;Fu@�DP�P���D
        !          141913: �T;Vu
;F
        !          141914: u�D;Ft�DP�*P����Du���L&���|u�+D;F�r���+D�F��� ��ug����F��t�H����;6r!�|u�+D;F�r���+D�F��� ���u �&jh�h�h��L���v����f��v��������DP�JO���DtjV�*������D&�F�D�F
        !          141915: �V�D
        !          141916: �TV�
&�����_^�VWU��v�~
        !          141917: t�d����LV�����L&�D�D����V�t�����~
        !          141918: t�D&tjh�h�V�CL����W������_^�VWU��v�|u�d���|&u�Dt�D���Dt�d��V����d��V��L���_^�VWU��v�Du���D�
        !          141919: �d���D���d��V�8���DP�]N���>t�h�L���_^�VWU��v�L �_^�VWU��v�D t�d���_^�VWU��v�~
        !          141920: �=wH����.��Y_q}�vW�t��=��&D�'�vW�t�����vW�t�t
        !          141921: ����ȋ��&D
        !          141922: T�F)D�_^�VWU��v�~
        !          141923: �=wH����.�������v�tW�=��&D�'�v�tW�����v�t�t
        !          141924: W�M���ȋ��&D
        !          141925: T�F)D�_^�VWU��v�|t0�L�<u�\�D��%�������D�DP�������>�t����_^�VWU��v
        !          141926: �|t/�L�<u�|�D�F��F��v�D�DP������>�t����_^�VW�
        !          141927: �v�~
        !          141928: �F�P�v�����F��u�5&�DP�hL���^���F��F��t,�F@t�E�&t�����F�tVW�����F��t�F
&�D�F�D�F�D�t�E�U� �������D
        !          141929: �T�E�D�~�t�D+�RP�t�t����D�T�^��G
        !          141930: ���F�V�v��&���D&tjh�h�V�6I�����v�������~�t�t�t�����^��O
        !          141931: �>t h��I���Dt�|t�D�������t�E+D�F��&EU)E�DP�qK���_^�VW��v�~
        !          141932: �<&t   h��&<���F�R��~���r��^��G�F��u�F���^��t�D�F�;Gr�^��G�W�F�V�^��G+�F�V�F��V��F�+ҋ؋ʋD��;V�w�r;F�w��^��G�W�F��V��^��N�+O��+�F�V��E�U�F��+��_^�VWU���+�;>j�}�<t��t�WG��
        !          141933: ���_^�VW��v�F�PV�&�����t�#Fu���
        !          141934: �v
        !          141935: V�U���_^�VW��v�F�PV�r&�����tV�U���_^�VW��F�P�v�N&�����t       �v
        !          141936: �T���_^�VW��v�~
        !          141937: �F�PV�$&���F��tWV�^��W
        !          141938: ���_^�VW��v�~
        !          141939: �F�PV�����F��tWV�^��W���_^�VW��v�F�PV�������t
�v�v
        !          141940: V�U���_^�VW��v�F�PV������tV�U���_^�VW��v�F�PV�}�����tV�U���_^�VW��v�F�PV�X�����u� � �t�v�v
        !          141941: V�U���F
        !          141942: ��F
        !          141943:  �F
        !          141944: �_^�VW��F�P�v������u����<���_^�VWU��F��%���;j�r        ��+��k�
        !          141945: ����|u�<t�|��_^�VWU�����_^�VWU���_^��VWU�����+��n�.�.�"�F��F��n���F�;r        �v��<����>�>�����]_^Ë�U��n+�9FuH�V���v�^�@�NtC��~u3+ۋ�N;�u�^�^���69t��SRPQ�!FYXZ[�^��������]��Ë�U��N�n+����v�^;�u.�6;�u�������4����^;�u�v��7�v�؈HC��~u�؉^�F�n����]���VWU��v�R��V�����}�W�I��]_^�VWU��>u�&+�PP�&P�P�lD����]_^�VWU��>tr�>t�>t\�6�6��0���uR����T���>�E6=&v�M6�6�6�l6�~
        !          141946: u
        !          141947: �DD&�TF��D@&�TB�F�����t��_^�VW����>T�d|�P�&�R��.T�d�&��>��&�>���&���%�+������(�F��5�Ƌ��tD�5�E�U;u�;u��]��t�E��G�E�v�����W�u
        !          141948: �U�������v���������>t:�+�;6j�},k�
        !          141949: �����uF����F�����P�?����v�������>&�t5�6&�����P��+$�P����� ���;>"�sW���@PW�����>�E$E&t��T�&�>�E"t�e"���&�>t    h�aC���>t$�       �F����;tV�kD����C�v������_^�VWU��>�E2��=��u���j�v
        !          141950: V�@����_^�VWU��>�u2�`����_^�VWU���v
        !          141951: �>�u2�����_^�VWU���v
        !          141952: �>�u2�����_^�VWU���v�v
        !          141953: �>�u2�����_^�VWU���v
        !          141954: �>�u2�����_^�X�P��6�G6�W�����������ϋ�;�t������������;�u��X�P��6�G6�O6�W
        !          141955: ����� ��� �LJ��'������U�싇 ��� ��6"��^���]�VWU��v�>$�u+��V�F
        !          141956: �D�F�D
        !          141957: ������>(�u�6(��6&�W�}�����;6(�uW�n���h*��';��&��7�6&�W�U�������_^�VW��v�7��F��>(�u    P�1����a;6(�t'�>(�;>&�t;5u��;6&�u
        !          141958: �>&���=���v��ˡ(�;&�u�(���(���(��v������6(��(��w
        !          141959: �W���_^�VWU�젿��=&u����P��R������_P�Z1�d��G���u       �G���t�t�t�V,����W�+W���_^�VWU�����F�Dj��RP��D���F�u       hf���2���F�D�6�~�u�u�6�����~�MW�T��j��RP�D���F�u       ht��2���F�D�6�~�u�u�6���jjh�nD���F�u       h���_2���F�D
        !          141960: �*��fO�u   h���C2���T0�_^�VW�"��1�u����&h'��)���F�P�F�P�F�P�v�?�����t֋F�%=
        !          141961: u&�F�F�t�F�F�u�F�F�u��;V�u;F�t��%V����뗋F�V�F�V�RPjj,�F�V�F�V�F�V�RPh8@V�F�P�A���F�V����~�}���K�h�(�:�����u
���v��_D�j
        !          141962: �]�G�W���RPh���z݃��F��E�E6��E8�E<�E&�w�F�W��?���v��o���E�_^�VWU��kF
        !          141963: ����EP�@���F;j�}����u����T�>�u��EP�@��+��_^�VW�6�>�F�P�F�P�F�P�v�������u���F�u��%V�����F�u�f��~�u�F�F�u׋F�F�u��v�v
        !          141964: �F�P�A���F��t��F�=t=t7�t�F֋V�F�V�F�V��F҉Vԋ^��G�WF�V�F�V�F�V��9�F֋V؉F҉V��v��v��6���FʉV̋^��G�WF�V�F�V�F�V̉FΉVЋFҋV��&��%��F҉VԋF΋V��&��%��FΉVЃ~�rw�~��s�~�wr�~��r������F�&�~�})�^���ߋG�F��t�^�����GP�HB���F��ыF��E
        !          141965: �F�=v�����.���,�,Z-R.�.�F֋V�F�V�F�V�F�V�F��V�RPjj,�FދV�F�V�F�V�RPjV�F�P��>���E�~�|�=V�������=u
        !          141966: �YMP�\:��j�T:�'��F֋V�F�V�RP�����F��V��v��v�jj,�FڋV�F�V�F�V�F�V�F�V�RPjV�F�P�V>���E�~�|��v��v֋F֋V�F�V�,��RP�v��v�V�u�^���u�S��v��v��F֋V�,��RP�v��v�V�u�3���u�(��FڋV�F�V�RP�F֋V�F�V�F�V�,��RP�v��v�V�u�����t�&&����F֋V�F�V�RPjj,�F֋V�F�V�F�V�RPjV�F�P�|=���E�~�}���F�V�F�V�RP�F֋V�F�V�,��RP�F�V�F�V�F�V��U��v��v�jj,�v��v�jV�F�P�=���E�~�}�G��v��v��U���F��V��v��v�F֋V�,��RP�F�V�F�V�F�V�RPjV�F�P��<���E�~�}����v��v��F֋V�F�V�,��RP�v��v�V�u��&���u����I�u���&��j
        !          141967: h
        !          141968: �h����+��jV�I���u
        !          141969: �M"�e"��jV�2���u�e"���Dt�D���E�e"���Dt�D���e"���F��~�}�^��㋇��=&t�^���LJ���F����E"@t     Wj
        !          141970: �J��V�����v��v��-*����)+��_^�VW�jr�v�&���t+����6��j&V����u   V������DIt�D%�=�t��
��jjV� ���F��u��%�ŋ^����F��~�&t��S���륋E�F�;l�t
        !          141971: ��%�v���j�v
        !          141972: �EP�*���F��~�}-�F���F
        !          141973: �F��^���^
        !          141974: �w�7��΃��^���W�F��͋E�^��E�^��v�������_^�VWU��v�~y�u      �~u����F�V�裉꣋F�VDT�����~      |�~r���n�^��F���F�F�D
        !          141975: h��v
        !          141976: �W���L
        !          141977: ��H�t����F�V�F�V�[��>�u���+��_^�VW�*�F
        !          141978: �F��F�F��F��F��F��Fڋ^��G�GP�F�@@P�7�&���u+��&�^ڋG&F܋G��&F؋̓��F�;�t�F�볋F�@�����F܋F�F��F֡�&Fց~��~���j�F֙RP�i;���F��t���)F֋^��G���+��G�F�+F։F��F�F�F�F��F��F�+F։F��F�F�F�F�F�HP�v�����F��F��F��v��v�����F��^ڋ���tK�ƃ�P�r�����t9�v��v��[���F��F���GP�~���F�P�v��N���F��F�~�u��j�v��#���F��F��̓��F�;�t�F��r��n�j�v������n��^��O�F�+�P�v������n�j�v������F�^��F�H�(��F�*��F��_^�VW��v�F�&�F��t?�ƃ�P������>�t+��9�t"�F���GP����F��>�u��F��~�u����F��^
        !          141979: &�F��^&�&�_^�VWU��F�V
        !          141980: ��%���_^�VWU��v��s���㋇*����u       ��    +�����_^�VW��v�~
        !          141981: ��%��P������F��ti��@tD��r��     �W���;�u���N���ヿ*�tW�����>�u2����F���*��^��G&��+���s���ヿ*�tG���u�������_^�VW��v�*���R�se�=t����j   �6��݃��F��tM�v
        !          141982: V�����>�t�v��ރ��1�F
        !          141983: �^���G&&�G�G�w�F����-*��.�>D6�������_^�VWU��v��s���㋇*����u��   �.����LJ*��}&u       h���'&���M&u�u���W�ރ��_^�VWU��*���R�s����u�����E&���_^�VWU��+���}���烽*�uF��V�j������_^�VW�����������>�u�^�F���
�F�FP�P߃��F�=/t�6&��&�>�u�^�F���
�F�FP�#߃��F��6(��~�/u$�>�u�^�F���
�F�FP��ރ��F��֍DP�?4���D�~�u�~
        !          141984: ru�6������N��V�
�������~�/t8�~�t2��
        !          141985: �s��G�F���>�u�^�F���
�F�FP�ރ��F��ƒ~�/u$�>�u�^�F���
�F�FP�Zރ��F��ց�
        !          141986: �s��G���D%�=@t���   j&V�C
        !          141987: ���>�t�Y�����|u)�;Z�t!��G�?.u��G�?.u��G�?u  V�y&�����F��F��F��F��F��F��D�T�F�V��~�y�u   �~�u��F�V�F�&�V�RPV�_���F��u����^��G�F��^��G;F�vU�n��^�xK�^���F��u#�~�u�F�F��V��F�V�F��V��F���v������t��F�&�F��F��v�����S���F�~�u�F��V��F�V�~�u&�~�t�%��~
        !          141988: ct���6���F�V��裉��&��~�u1�~
        !          141989: uu�F����6���F��V���V�����v��v��m&��������V�����v��v��T&�����t������_^�VWU��v�>�t$�E;uV����u�DP�1���D��=�؋��_^�VW��^�?u+��+�F@@�����F���G���F���F��:F�u��N�u�&�_^�VWU��+��$���!F�Ft��!�tej�6�������tU�v�>���5��
        !          141990: �����t@�D&�F
        !          141991: �D�t�?���L
        !          141992: �P��R��DL�TN�P��R��DP�TR�P��R��DT�TV�6����&�����_^�VWU��F�������������h��6�������_^�VW�+��r�Ik�X��;6r.�D;F
        !          141993: u�;Ft�|u�t�D;F�s���D�F���X��;6r���Nj��u`h���v�@!���F��~�
        !          141994: }!�^
        !          141995: �t��ÉF튇
        !          141996: ���^�G��F��ً�^��G��6��6��F�Ph����'����+����DP��/���|t
�DP��/���.��F��F
        !          141997: �D�D&�P��DV�k&���u�D�D�DP�/��맋��l�D
        !          141998: t,��F��~�u����^�;wu�F
        !          141999: �G�F����^���׍DP�B/���D;F
        !          142000: t�p��;Ft�f��|}   hƝ� ���D�P��D��_^�VWU��v�|t�|
        !          142001: Vh՝�����Lu�D
        !          142002: u�|uV����DP�/���_^�VWU��v�DP�.��V�����_^�VW�Z�v�~
        !          142003: �r�Ik�X�F��F�;r�^�;u;7t�n�X��F�;s�F��F��^��7�P�'���u+���^��G%�=@u���t�&�_^�VW�F�v�D
        !          142004: �D�F�j&������AA��+�RP�4��܃��F��u+��(&�~��F���%���ȋ^��G��F�j@WP����v��k߃���D�E�D�E�D�E�D�E�U
        !          142005: �D�TRP�ƒ��D�T�D%�=�CC.;��uV.�g
        !          142006:  @`��=�=�=�=�=�E�D�Bj
�EP�DP�5ƒ��0j
        !          142007: �EP�DP�#ƒ��E*�D@�E,�DB�E.�DD�j4�DP����E4�U6�DL�TNRP������DL�TN�E8�U:�DP�TRRP������DP�TR�E<�U>�DT�TVRP�����DT�TV�&�_^�VW�F�vj�4�W���u�&�D�F��|u.�|u(�~�&t"�~�tV�&���D�D�v��4����~��D��D�E�D�E�D�E�D�T�E�U
        !          142008: RP�,����E�U
        !          142009: �D%��>�CC.;��uV.�g
        !          142010:  @`�$?
        !          142011: ??
        !          142012: ??�D�E�Bj
�DP�EP������0j
        !          142013: �DP�EP������D@�E*�DB�E,�DD�E.�j(�EP�J���DL�TN�E4�U6RP�����E4�U6�DP�TR�E8�U:RP�����E8�U:�DT�TV�E<�U>RP�g����E<�U>j&�F�������AA��+�RP�4�Nڃ��F��t7�F���%���ȋ^��G��F�j@PW����^��OS��܃��d
        !          142014: ���_^�VWU��v�r�Ik�X��;>r*�}u��X��;5u��E%�= t��E
        !          142015: t�W�������_^�VW��v�D%�n@�CC.;��t��.�g@�A0A0A��
        !          142016: ~,O����ދG�W�F��V��t��-  PR�v��4�]�����~&O����ދG�W�F��V��t�R�v��4�"�����D�Dj4�DP����L
        !          142017: �P��R��DL�TN�P��R��DP�TR�P��R��DT�TV��D@�DB�DD�
        !          142018: �L��
�F��_^�VWU��v�~
        !          142019: ���D�E�D�E�D�E�D�E�D�E
        !          142020: �E���D�T�E�U�DL�TN�E�U�DP�TR�E�U�DT�TV�E�U�D%�A�CC.;��u,.�g `�A�A�A�D�E�E�E�
        !          142021: �D@��E�U�_^�VWU��v�~
        !          142022: �6��6�V�9����#�;�t ��
+��!��t�|&~V�7���t���޸&�_^�VWU��v�~
        !          142023: u��&�F
        !          142024: ;Du�D����F;Du�D����D%�_^�VWU���6h��6Z��}�����u�Z�%�P�Z���%�Ph��e�����&���&�P��R�j�6Z�������(��u�Z�%�P�Z���%�Ph���)���(��&��>&��E�(�P�a(���_^�VW��vh�6�1Ѓ����u+��j&�~
        !          142025: tj�jV�݃��>�t W��Ѓ���j&jj&V�փ��F��u    V�݃���h�&�EP�^��w�����v��Iك��EP�%���E�u�F
        !          142026: �Eƅ�&���>���_^�VW��v�t�t�H����D�T+���@})����ƉF�������w
        !          142027: �w�����^��G�W
        !          142028: G��+���d}G�����&���&��������&���&���&���&�仃����&���&���&���&�λ�����&���&�_^�VW��v�D&ug�t�����|���&tTjj&�t�\փ��F��P��R����&���&ƅ�&h�&�^��wW�����^��w����j&�v��e׃��v��؃��_^�VWU��v�>�t#;ut�=���E&t�~
        !          142029: t��+�����
        !          142030: Vh��
���_^�VW�j&�v�����F��u+��&�F����F�P��%����&t���F�&��
        !          142031: &�F����&�F��F��F��+�;V�w
        !          142032: s�;F�v�v��v��v�}���t�F��F�&�V���j&�v��v��v�rԃ��F��tڋ^��w���F�;v�s#�<t��@�F���F�;F�s�^��F��F�����v���փ��F�;F�r��ρ�
        !          142033: &�F�+��.�>L��&��&u'Dž�&�F�P�A%��h/��v����������&��&��ߋ�
        !          142034: &�F����&ƅ�&&�F�P�%���v��v�5���F��tC�^�t�v�h=��v����v��������^��G
        !          142035: �F
        !          142036: �G�G���G���G�F��_^�VWU��j&�v��������t:�EP�S$���uƄ�&&��&d}��&��&��ދF
        !          142037: ��
        !          142038: &���&�EP�W$���_^�VW��v�F
        !          142039: Fu���N�t}j&�v�v
        !          142040: �v��҃��F��te����O�~R�^��G�F�����؋�W�F��V��t�R�v�蘸���F��V��u
RP�v�w&���V�v��v��v�v�����v��&Ճ��v�v
        !          142041: �v�K&���_^�VW�j&�v������F��u+����!&�F�
        !          142042: P�H#���F����|u#�DhK��v�>�����F��F���Ƅ�&&�L�\��ދG�W
        !          142043: �F��V��t��|u~�F�;T|-;Ds(�+�;V�rw;F�wj&�v��v��v�у��F��uhX��v�����q��^����D�|@w�h&�DP�EP�����t�DP�]���v��ԃ����&&���&�F��V�;T|�;Ds��+�;V�w�r;F�w��F�
        !          142044: P�n"���F��V��_^�VW�j&�v�����F��u�����F
        !          142045: �V;T|;Ds�+�;Vwr;F
        !          142046: v�F
        !          142047: Phf��v������F�
        !          142048: P��!���|t�|@uY�v�v
        !          142049: �v�\у��F��^��hW����D�h&�EP�DP�����t�EP�^&���^��OS�
Ӄ��D�\�D��ދF
        !          142050: �V�G�W
        !          142051: ���&&���&Ƅ�&&�F�
        !          142052: P�j!���_^�VW�
        !          142053: j&�v�������u     hz������D�T�        �������F��F�=
        !          142054: ~�F�
        !          142055: �F��F�;F�}-�N��^���ދF
        !          142056: �V;Wu;Gu
V����&��F��ˋD@�TB�F��V�V����~�txj&�v��v��v�xσ����ta�F��F�=�~�F���F��F�;F�}=�^���ߋ�W�F��V�RP�0����F��V��F
        !          142057: �V;V�u;F�uW����m��F��W��у�+��_^�VWU��v�~
        !          142058: ��O�t�t�4�䴃���T�����_^�VW�/�>u���6j
        !          142059: �F�Ph
        !          142060: �����tB�t@觴���F��tF�tD蘴���F��P��R�+��RP�~����F�����F�V���F����F��F��6��6��O����F��D2�F�����F��P�S���>�E�U�FՉV��F��F�F��F��F��F�PW�w&���P�J�����_^�VWU��v�D%����ǻ=L�CC.;��ug.�g @`�LOL}LOL�DP������ uj�j&�v
        !          142061: �t�iԃ��DP����%�F
        !          142062: t�0�t�~
        !          142063: u���
        !          142064: �v
        !          142065: V����_^�VWU��v�DP�l���D%��L�CC.;��u<.�g `M�L�L�t��̃��DP�h���t�ԃ��DP�!�V�=��V����_^�VWU��v�~
        !          142066: �}tL�D%�<M�CC.;��u2.�g
        !          142067:  @`�eMRM^M^M^MW�t��Ӄ��WV���WV�/�����_^�VWU��v�~
        !          142068: �L
        !          142069: �P��R��DP�TR�L
        !          142070: �P��R��DT�TV�}t\�D%��M�CC.;��uB.�g
        !          142071:  @`��M�M�M�M�MW�t�Ӄ��#WV�B&��j&�4������t��WV������_^�VW��v
        !          142072: �D�T�        �������F��V��D�T%�&+҉F��^�G%�=`u�&�+��F�^�G�W+DT�F��V��~�u�D+�;V�rw;F�s�D+҉F��V��~�y�u    �~�u��~�tj&�v��v��^�w�Z˃���v��v��v��&���F�~�tY�+F�����+�;V�wr
        !          142073: ;F�v�F���W�^�F�GPV�΃��v��̓��>�u�F�&�V��F���+�)F�V��_��_^�VW��v
        !          142074: �D�T�        �������F��V��D�T%�&+҉F��^�G%�=`u�&�+��F��|u�&�+F���;|s����D���~�u��u�&�+��F�~�uP�v��v��v��&�+�~�t�v��v��^�w��ʃ��j&�v��v��^�w�'ʃ��F��~�u�W�^��F�GPV�=̓��^��O�~�t�^�G%�=t
j�v���˃��       �v��̃��>�uM�F�&�V��F��^��+�DT�D�T;W
}��;Gw����~�t����D�T�^�G�W����_^�VW��v�v�v
        !          142075: V�K���F��V��y+��6�F�F�tj&�v��v��4�CɃ��jjj���Ƀ���h�u�
        !          142076: �����_^�VW��v�F�P�v�v
        !          142077: �+���F��u   ��������n��^����ދG�W�F��V��t�̓��F�;�u�F��V��Pj&�v��v��4�ȃ����u+����4�E�F��n��^����؋�W�F��V�W�:˃��v��v��n�����_^�VW��v�F�P�v�v
        !          142078: �|&���F��u+��i&�F���F��n��^���^���ދG�W�F��V��u)�F�&�v������F��V��t��^���ދF��G�W�̓��F�;�u�&�+��F��~�u&�~t�~�uj&�v��v��v���ǃ����u%�e��v��v��v��hȃ���h�u�+      ���M�~�t����F��E�F�n��^���^���؋�W�F��V�RP�Q����F��V��uc�F�&�v������F��V��u
        !          142079: W��Ƀ�����^���^�F��V��W�F���F�F�^���^��w�7����^��W�MW�Ƀ�����_^�VWU��v�~
        !          142080: |�~
        !          142081: s
        !          142082: �ރ��F�Q�n
        !          142083: �^
        !          142084: ���O�u     ��+��:�F%����F�V
        !          142085: ��������F�V
        !          142086: �n&�^
        !          142087: �uċރ��+lj���_^�VW��>��t����P�vh���a���l&�>��u�b&�>t�X&�~�>"�u�H&j&h�S�6��h ��@���3&�UĉF��>t�vh�S�6��h ���?���v��:��&h�����v��(ă����F��V�����=u��F��V�;Tu;Du�D�TDT�F��V����Duz�D u��D&t׋D
        !          142088: ;DuϋD�F��t�t�v��v��t�t�p����F��V��D�TV�ں���>�}t�Ɯ;F�t�ʜ;F�u�4�;F�u�D��N~�k��>��t
��t�Dtjjj�   j&h�S�6��h ���>��h�%���_^��U���^]�U����vj�F�^��f�]�U��^�GPj�G�^���]�U���v�v�v�v�v�v
        !          142089: �v�Ћ�]�U��+ۊ^�㋏�Qj���t�G�t�^���]Ë�]��U��+ۊ^�㋏�Qj���t�G�t�^���]Ë�]���U��+ۊ^�㋏�Qj���t�G
        !          142090: �t�^���]Ë�]��U��+ۊ^�㋏�Qj���t�G�t�^���]Ë�]��U��^�_       *��㋏�Qj���t�G�t�^���]Ë^�O��]���U��+ۊ^�㋏�Qj���t�G�t�^���]Ë�]��U��+ۊ^�㋏�Qj���t�G�t�^���]Ë�]���U��+ۊ^�㋏�Qj���t�G�t�^���]Ë�]��U��+ۊ^�㋏�Qj���t�G�t�^���]Ë�]�˻�K��F��A��<��7�
        !          142091: �2��-��(��#����������
        !          142092: ����U�싏�Qj���t�^���]�VWU�������.��7
�����6�>��th5��h:�h��h���E��hĞ�<�������thD��*���6���6��hS����������;��u;��t    hW������&h�jh�������u      h�����hR[������tj������u h�����V�{Ѓ�����_^�VW��6�|�D"�t�&�D
        !          142093: �F��u�&�E�U�F��V��^��G�W�F�V�F�V��F�+�RPW����u+��8&�v��v�F��V�EURP�^��w�w�%����D
        !          142094: �v������F�����F򣸣�>*�u��E���+��F�&*��*��F��n��n��F�P�=����u�(�@@��)F��v��&����F��t�F�F�P�F��F�P�����كF��F�P������F��t�F�F�P�v�������q�i�D�F��u�D�F��~�t�F���œ����t�E��Ĝ����~�t�^��G�W-&���+�����t�E�U-&���+�����&�_^�VWU������Ɯ�����ʜ����Ȝ����̜���Ɯ�D��ʜ���D�|�|��_^�VWU��F���F
        !          142095: �����_^�VWU��v�D���F
        !          142096: �D�D
        !          142097: �D&�_^�VWU��v���|���~+��.���t����t����t���t���tށ��t؋F
        !          142098: ����&�_^�VWU��6��6�����P����6�����P�⺃��v����P�Ӻ���&����F
        !          142099: ���6��~
        !          142100: t�~O��Dž���_^�VWU���&�_^�VWU���_^�VWU���&� ����_^�VW��v�~
        !          142101: �F�F��~�t��G�F���F���^���N�u�F�_^�VWU��v�~
        !          142102: �t    ��F�Ou��_^�VWU��>�t        ��&+�����&�_^�VWU���;Fu�&��>�u������&+��_^�VWU��0��0��u�FPhʟ���j
        !          142103: �篃���4�>��0��_^�VWU��F
        !          142104: P�F%�P�F��%�Phԟ����h�������_^�VW��+҉F��V��p��&F�V��>t�����+�&F�V���@@�&����~���+�&F�V�kr�X���~��&F�V��>n����~��&F�V��>t��� �~���&F�V��F��V��&��%��F��V��~�&|�~�r   h�������>Ĝ������+҉F�V�F�+ҋ؋ʋF��V�+��+F�V���>+~��+ң�+F�+F���Ĝ+ҹ������&;6v      h������Ĝ+ҹ������F�V��&��%����+ƣjh��++RP�$�����6V�
        !          142105: ���������
        !          142106: ��bjh�6�6�ʲ���F��V��F���_^�VWU��v
        !          142107: �F%�=wN����.��H^a^e^{^)|���=u8���1+����t�t�t�t���������t�t�DP�ܷ�������_^�VWU��v
        !          142108: �F%�=wO����.���^�^�^�^)|���=u9���2�|���t�t�t�t�?��������t�DP�t袷�������_^�VWU��F
P�6\��������tV�)���D@�DB�DD���_^�VWU���_^�VWU��v�|uV����L
        !          142109: @�_^�VWU��v�D
        !          142110: t�d
        !          142111: ���DDP�'
        !          142112: ���D
        !          142113:  t�d
        !          142114: ���DBP�
        !          142115: ���_^�VW��v�~
        !          142116: �|@uT�D
        !          142117: @t�d
        !          142118: ���F�|u�||:�Et�����L
        !          142119:  �DP�u��jjj�DBP����DP�'����D
        !          142120: @t�|@u�d
        !          142121: ���E�F��>�uj�~�td�|@~^�+DB�F�;F�v�F��F��F�;D@v�D@�F��F��E�DB��E�UWV����E)F��F�&DB�DB=u�DB�F�)D@)F�돋F��E�D
        !          142122: t�|@}�d
        !          142123: ���DDP�����_^�VW��v�~
        !          142124: �E�F��>�t�&�~�u���|}�|u�� �6j�.�����+DD�F�;F�v�F��F��+D@;F�s        �+D@�F��Et�F�;F�u�D
        !          142125: @t����~�t�D
        !          142126: @t,�L
        !          142127: �DP�
        !          142128: ��jjj�DDP�H���DP�      ���N��F��E�DD��E�UWV����E)F��F�&DD�DD=u�DD�F�&D@)F��D
        !          142129:  u�
        !          142130: ��|@�&��d
        !          142131: ���DBP��럋F��E�_^�VWU��>*�uh&�6�Q������t4��&�.�>,�t'�,��*���P�6�'������t
        !          142132: �*���Ƌ��t�2���62�����;�w�2��_^�VWU��v�|u�ƉD�D�2����u�n����uh.�����,��2���E��GR��R�u�\�]��|��D�_^�VWU��v�^�G�G���t#;vt�D���t�} &u
        !          142133: �ERP�����t���_^�VWU��6�DR���t!�E�]�G�؋E�G��DR�2���>2����_^�VW��v�F
        !          142134: �F���F����=%t�u�V&W�è�����F��<lu�F�&F��F�����wc�CC.;��u�.�gDOUXcdoprsux�c)d�dxd�c�cdtd8dGd|dnd�^��F��7뒃~�u1�^��?|�j-�B���j
        !          142135: �^������؃�RP����F��F��^��x�j-����j
        !          142136: �^���W���؃�RP����F����~�uj�[j�^��w�7����݋^���F��^��7띋^���F��F��^��F������u���W裧����~�uj�j��~�uj
        !          142137: �^��+��N�j
        !          142138: �^��w�7�w��_^�VW��F�RP�v
        !          142139: �v�L����F��V��t
�vR�v�������F�RP�v
        !          142140: �v�#�������D��P�!����_^�VWU���6�6�6�6�6����s
        !          142141: �=�}�����_^�VW�jt�6�������u+����E"&�E �E2���~t[�M"�h0@jh����F��~�u    W艮�����F��E�^��w�v�F�P����j�^��G�W���RP�F�P�f���h�i�����E�>0u|���D��=t�D;Er;Eu��̋D�E�\��u�|h�N�����_^�VWU��v�D���t�D�D"t�E
        !          142142: W����h�����D�\�G�D�\�Gh����V衭���_^�VW�j�������u���%&�ӱ�F�蛱�v��ϱ��V�_���u��V�h������>(�t�(��G�>&�t�&��G�+ϋ>�E�D�E�D�E�D�E�D�E2�D2�E0�D0�E$�U&�D$�T&�E(�U*�D(�T*�D6��D:�D8�D<�4��F��F�P�M����v��)������;�tH�t�B��j�\�G�W���RP�F�P讯��V�����䰉F�V�Q���v��ܰ���D��P��R�������&�z�u�+��_^�VW��>jjj�EdP�N,��jjj�ETP�>,���U�>(�t
        !          142143: �6(��tԃ��>&�t
        !          142144: �6&��cԃ����F��N�~&�^���ߋG�F��t�^�����GP�����վ�D��=tI�D;Eu�| &u;t,uV�R&���D;Eu��D&�| u
        !          142145: �6�5&���D"@t�h�%&��뭃>t     h�&���F�EP�E ��&�_^�VW���F��~
        !          142146: &}�^��G$G&t���t腯hȣ�Ʈ���y��F��^��G &�F�G,��G>�F
        !          142147: G6�F��G6�F��F�;F�s����^��G6�F�G:�F�G<�F��%�����u�?�F��E�w�F���v��������^��G6+F
        !          142148: �F��G6�F��F�;F�v+��^��G6�G:�G<�~
        !          142149: &}�G$G&t��t�®hȣ�����_^�VWU���vh�i�k����_^�VW��F��%������腮�F����;�t@�D,;Fu���\��D��G�+D>D6�F�;D6s����D6V����v��G�����v��<����_^�VW��$��F��6��F����=t%�E6)F��E"&t�5&D6�F��E6�E�D�\�7���v��魃��
        !          142150: �;6t<�ɭ�F��6h���߬���uh��\�w������t�[��v�蛭���_^�VW��v�F���}��G6&F��F�;D6s��u��w���5�|�D6)F��F��D6�F��)G6�D �_^�VWU��v�,����<t�D&&jjh@V�i������&W�����_^�VWU��v��|&t�D&�&V�/����_^�VWU��������;u;tN������+���!�&�
        !          142151: �����_^�VW��v
        !          142152: �^����FFu �&+���h������F%�F��>��t=;uu4�E%;F�u)h����W�9&�����u�W�$���^�&�}�=뽋>��t;uu�E%;F�t��=��h�����v�v�v�W&�����u�c�jj�v�v�v�vVW�mă��u
        !          142153: W�.���=��Ft�u�D�^����_^�VW��v��F��L"�F��~�};�^���^��G���u�F���W�a�����t�^���މ�E&u݁d"���փ~�}.�~�~(�N��^���ދG���t�^�����GW�&���ҁd"���F��_^�VWU��v�Dt
        !          142154: �D�D
        !          142155: ���T�D&u     hT��L���D
�P�t�t�8�����uV�������D�E�t�t�u�u�t�t�*������_^�VWU��F%>
&���F�&�V
        !          142156: �f�h������Ft�v
        !          142157: �v�"
        !          142158: �      �v
        !          142159: �v�a  ����h�����u;h��J��h�����Ft�v
        !          142160: �v��  �       �v
        !          142161: �v�"  ����h������t'�|V�����F�u�v
        !          142162: �v�t�t�0������E�F@u<j�6�s������t*�4�t�|�D&�D
        !          142163: &�v
        !          142164: �vV�����u�V����+��_^�VWU��v�|&t�L�L
        !          142165: �kh�����L
        !          142166: �Lth�#��O��\��D��Gh�����|
        !          142167: t     h������D���tW��̃��t�t����V腤��j�#���_^�VW��v�D%�F�h�����F
        !          142168: �V+DT�F��V��F
        !          142169: �V;T|9;Dw4�F
        !          142170: �V�D�T�~�t�F��V�)DTV赟��h�a����&��D��=u     ����E�UEU�F��V����=u     ����E�U�F�V��~�u;+DT;V|.;F
        !          142171: r)�v��v��D�TDTRP�v����F
        !          142172: �V�D�T�f��~�tK�D�TDT+F�V�;V|2;F
        !          142173: r-�F��V�)DT�F
        !          142174: �V�D�T�v��v��t�t�������F�V�+F�V�;V
}�;F
        !          142175: s��~�u:�t�t�v��v��t�t�����v��v��D�TF�V�RP������F��V��F�t�t�F�V�+DTRP�t�t�2����v��v��F�V�+F
        !          142176: VRP�~����F�V�+F
        !          142177: V�D�T���h������D
�P�v�v
        !          142178: �j������tz�~�u.�t�t�u�u�t�t�g����v��v��E�UDTRP�,�t�t�F��V�EURP�t�t�1����v��v��u�u�ᕃ�h����WV�/������v�v
        !          142179: V�����t_�~�u�v��v��F
        !          142180: �VDT+F�V�RP�4�F
        !          142181: �V+F�V�RP�F��V�DTRP�t�t�����v��v��t�t�`����l�+��_^�VWU��v�D���F
        !          142182: +�RPV������u���.�b�u$��+�RPV������t�J�u�6j�=���5��_^�VWU��v�>u
        !          142183: ��+��h�����v�v
        !          142184: ������uh�2�����h�'����D
        !          142185: �DDt�t�t�u�u�t�tj&�&��h�����WV����h������d���L
        !          142186: V�$���V�      �����_^�VW��v�D&u7�>�D�D
        !          142187: �u�e"��觤�F�W�����m��v�蜤���EV�5����_^�VWU��v�>u+��mh�1����t�t������uh�J������D
        !          142188: h�<����t�t�u�u�t�tj&�(���L
        !          142189: �D%���E�D�T�E�UW�N������_^�VW��F�V;b�|Y;`�rSjh�v�v�}���FV;f�|4;d�w.�F
        !          142190: �V;| ;r�F
        !          142191: �VFV;|;v h���5����4��DP�C�����O"�E&�F
        !          142192: �V�E�U�F�V�E�UW蕚���E�U�D�T�FFu���~       |�~@v�@��F�F��F
        !          142193: V%�F��V��F
        !          142194: �V%;V�u;F�t�^
        !          142195: �N����+�+��&+�щF��D&�~t���&�D�^��D�F�V�D
        !          142196: �T�F
        !          142197: �V�D�T�F��D衢�F�V�6^��p����D&tjh�h�V�������v��}����Dt        h������F�&D�&F
        !          142198: V�.�>z�ȋ��&FV�F��)FV����EW�v����DP�!�����g"���_^�VWU��v�~
        !          142199: �}t�u�u�!�����\��D��G�]�7�E�D��w���E�U�D�T�E�U�D�T�E�U�D�TV�����W�M����_^�VW�jh�v
        !          142200: �v�2����F��V��`��b��F��V���F��V�;f�~�|        ;d�r����=t�D�T��d��f��F�V�+F�V�;V�|M;F�rHj�6�������t\�\�?�D�E�|�5�E&�E
        !          142201: &�F�V
        !          142202: �E�U�F��V��E�U���(jh�t�t�y���DT�F��V���t�H�+��_^�VW����F��V�����=t�D�T����F��V�+F�V�;V
        !          142203: |T;FrOj�6�K������tX�\�?�D�E�|�5�E&�E
        !          142204: &�F�V
        !          142205: �E�U�F��V��E�UW�m�������D�TDT�F��V���t�f�+��_^�VW�����F��V��D��=t�D�TDT����F��V��F��V�+F�V�;V
        !          142206: |X;FrSj�6舚�����tV�����<�u�E&�E
        !          142207: &�F�V
        !          142208: �E�U�F��V�+FV
        !          142209: �E�UW視������D�T�F��V���t�[�+��_^�VWU��j0hR��r��+���}u�����G���uF���u
����LJT���������R�&��t��t������R��t��t��t������R������E��V�������X������_^�VWU��vh�d���>��t";uu�E%=uh�u���&�-�=�؋>��t;uu�E%=tԋ=��h�E��+��_^�VW��v�~
        !          142210: �ރ���&+ҋ���������F��V��E(�U*�F�uS�V�uN�F��V�       E$      U&�} &u<��F���]��E��G�+E>E6�F�;E6s����E6W�8����v��Ý���_^�VW��6+��D(�T*����!D$!T&�D$D&t2�F�&�F�G�D$�T&�F�u�V�u�&�F��V��������F��V��؋��_^�VW������u��>N�&+ҋ������������!E$!U&���㋇���F�F�ƣ,��~�t�v�V�߃��Dh֣������E"@t�M"�H���e"���t!��    
        !          142211: ��t��u��t�΀V����_^�VW���G"u!�����
        !          142212: jch��胺���t�
        !          142213: +��$&������ujh���齃����u8�܋D%�=�ujV��Ń��tj&�4�ȃ��u V������V�*ă��I
        !          142214: �������R��>�t�����r��E�F��t�u�������^��G�W�����G�W�F��V��G
        !          142215: �>�uD�F�F�t<�~�   |�~�@v�@��F��F���h�V�Ѓ��F��&��)F�V�뵋^��O
        !          142216: �|�V�/����>�t����&�_^�VWU��h����6��t
�D;F
        !          142217: t�t��h�0����t�D" t�>�D;Et���gh�����F��F
        !          142218: ��F��F���
        !          142219: �&h�"���>tjjh&h�������h����
        !          142220: �_^�VW��6���|&u�    �@&�F���h�H����E��=u�F�      ��E;Du�} &uW���h�J���~�|���>t        �D;tjjh&h�w��넡H=wE����.��K~]~l~u~�~�~�~�~�~�~�6�N����
        !          142221: �~�6�'���>s
        !          142222: ���������\�6�6�h����L�6�6�;����6�6��ۃ��u-���F�  �$�q܃>|��>���F��>&t�������=u��h�����F��_^�VWU��vVj������_^�VWU��6+��|ft%Wjd�Dh�Tj+d�-&�RP言����Vhjjd�F+�RP葀��RP�DdP�!��
        !          142223: ���_^�VW��6�F��F��|ft�Dh�Tj+�F��V�Vh�v
        !          142224: �v�DdP����
        !          142225: �F��V��_^�VWU���w�>|��~t
�F+�PV����L����_^�VWU���v�v
        !          142226: �v�:����_^�VWU��F��P����_^�VWU���2��_^�VW�
        !          142227: �P��R��F��V�kT�
        !          142228: �F��V��F��X��F������j
        !          142229: �v�F�P�����V�闃��_^�VWU����_^�VWU����_^�VWU��"��_^�VWU��>�E�_^�VWU�� ��_^�VWU��>�E0�_^�VWU��6�D�D0�_^�VW��v
        !          142230: ��v���W&�F�h����~~K�>��u� &�} u�}��E;Fu��F�&�u�&&WV�&���tWV���������&���~�}N�F�؉F�>��u���} u�}��E0;Fu��F�&�t�WV�����t
        !          142231: WV�~�������&�̓~u@�>��t~�} u�}���E0;G0u��F�&�t�WV�s���t�WV�1����Ѓ~�uB�>��t8�} u�}��}t��}&t��E"�u��F�&�t����t�WV�������h����~�u��+��_^�VWU��v
        !          142232: ��;Du�&�0� �;Du�~&t�~t�~t�~tۃ>�u����+��_^�VWU�����t�~t�>�M"�  �>�e"��+��_^�VWU��v�>u4�}+���(~�(�>;u4s����t     �>�u4+��_^�VWU�����_^�VWU���_^�VWU��jj�jh�������_^�VWU��v�6 ���F
        !          142233: �"��F�$��F�&��_^�VWU��~u
�>�M"@+���v�v�v
        !          142234: �v�}����_^�VWU��v;6�t�"��t�6��6"��>�u+��_^�VWU��v;6 �t����t�6��6 ��>�u�u+��_^�VW��v�>�~
        !          142235: ����        u���mN�޸&+ҋ���������F��V����㋇���F��~
        !          142236: &u�F� E(      U*����F
        !          142237: ���������F
        !          142238: �����F��V�����!E(!U*�F��V�����!E$!U&�F��_^�VWU���v�Q����_^�VWU��v�,��t�Ɠ��jhP�V�����W輓��+��_^�VWU����_^�VW��6�D@�TB�F��V�DD�TF�F�V��DH�TJ�F��V��DL�TN�F��V�j�v�F�P�a���+��_^�VWU��v���t        V�ܥ��+��_^�VW��>h�����F���D��=u�;�t�D;Eu��D" u��D"t*�d"���L" h�����~tj�v�Y����D��| uQ�D@�TBDHTJ&EHUJ�DD�TFDLTN&ELUN�~t�tP�v�����D�F�h�y��V�-����F��.�v��R�h�^���~�u��
        !          142239: �hj�h�W������_^�VW��v
        !          142240: �Fjr�v�����F��5�~�u+�>���6"��6 �W�ໃ��؋�#�;�t��
W讵��+��_^�VWU��6�� ����6 ��6��"����6"��_^�VWU��v���te�u �>u���S�6蝵����?�>u�jrV�q����u-�>���E%�=�t��W�!�����EP�U���>+��_^�VWU��h&��v�     ��+��_^�VWU��v
        !          142241: jr�v�����uE�>���E%�=@t��W�´���(j&W胺���u��
��EP�����4�ߴ���<�_^�VWU��jr�v赮���uF�6���t�6ԃ��t,�>�t�f
        !          142242: ���d��F
        !          142243: %�    D�L
        !          142244: �P��R��DT�TVV�<���+��_^�VWU��jr�v�W����u7�6�����t#�d��F
        !          142245: �D�F�D�L
        !          142246: �P��R��DT�TVV�����+��_^�VWU��v�{��t
        !          142247: h(�V�����+��_^�VWU���v�I���+��_^�VW��v
        !          142248: �F�jc�v�̭���t�������uj��%�
�P�1������u9�jW�5����tk�E%�ʈ�CC.;��uH.�g @`؈        �؈�F�&jW�>����F��|1�~�tW�T����EP�T���F�����j&�5襻���u�W����_^�VWU���v
        !          142249: �v�[����_^�VW��v�������t�u�F�PV�ܷ��j�v
        !          142250: �F�P�����+��_^�VWU��~|�~}�~�狅*����u��   ��F
        !          142251: =v�����.������J�J�����~}��~}�~�烽*�u�~�牵*��D&�F�g�F�F=|����U�$��Ft��Ft���%=t=t�F��F��F&�t�N�t��N����_^�VW��v�   ������t2�|�E%��F��~� t�~�`t����v�v
        !          142252: �u����+��_^�VWU��jr�v蛫���t��6���D%�=@u����u
        !          142253: V�F�����DP�y���jc�v
        !          142254: �_����tV�h��ۃ>��t���6��������>���;t��W��j�6��躶���u�6�����t�$����6���Ѱ���DP��߃��D�L
        !          142255: �P��R��DT�TVV諰��+��_^�VWU���v�ꨃ����ta�|�E%�=u���L�F=w?����.������͋ۋ�~x*�F
        !          142256: �V�D�T�F
        !          142257: �V��D�T&F
        !          142258: V�؋E�U�����_^�VWU��F
        !          142259: %�����t���tR��`t�� t�Fjc�v�'����u2������t��V�ݯ����v�v
        !          142260: 膭�����tV�¯��+��_^�VW�jr�v�ܩ���t��6��jV�c����u��D�F��D�F��F�%�=`t���}V�k���jr�v
        !          142261: 葩���up�6��jV�����tV�D%�=@t���D�|&�|u���1�>�t�E;F�t�=���v�v��쵃����t�u�L
        !          142262: �DV��+��_^�VW��~wr�~
        !          142263: v���M&�N
        !          142264: k�F���~t;vr;6̜v���)&�F��F
        !          142265: �F��v�~��V�����F��~�}�F��G�~�|�F� �:�^��㋇*����t�]�G%�= u��v�DP�ȇ��P�]�w�H����F��v��DP������~�t�F�F��N����u��~u ��ԋF���~~*�F      �F�.�>���F�RPh�i�v�TP����jjh&�RP�Rڃ��ԃ~~jjj�TP����F�$��t
        !          142266: �������~t���+��_^�
        !          142267: VW��F
        !          142268: %=wz����.�����!�&�jr�v�~����ua�>��VW�  ����u W�2����H�F
        !          142269: t���F
        !          142270: t��VW�����F��|ҍEP�A܃��F���럾뚾����_^�VW�j��σ����t`jV�ӥ�����|H�DjV������F��|"W�v�s����v��F@@P�d����DP�����L�DP�ۃ�W���V�r���+��_^�VWU��j�v�v
        !          142271: �v����_^�VW��v薤�����u+������ȃ~t���#�u��     ���v�v
        !          142272: �����u���Ƌ|�E%��F��~� t
        !          142273: �EP��ڃ��t�E�U�D�T�D�T�裉꣋F
        !          142274: �죋F���t��+���~uh�W蜼���M
        !          142275: &�P��R��EL�UN�
        !          142276: h�W�߼����)F�F+�&DT�~� t
        !          142277: �EP�ڃ��F�_^�VW�jr�v�v����u'�6���F�PV�W���V�+���j�v
        !          142278: �F�P�k���+��_^�VWU��hP��ڃ��6�tV�%����4���=�hP��)ڃ�+��_^�VWU��6$��F%�&�$����_^�VW�jr�v�뤃��t���6��jV�r����u
        !          142279: V蛪�����D�F��D�F�V腪���F�%�=`t����F��^�����t
�E;F�t�~����u���W�n����r�Ik�X��;6r�|~�;F�u���[��X��r�Ik�X��;6r�;F�u�D��X���v�胇���v��֎����^���]�g
        !          142280: ��S�
���W謁��+��_^�VWU��j&�6Z��Q������t�|ƅ�&&���&&���&���&���&�_^�VWU��ju�v解���t��6��jV�.����u��
�j�<�6��W謩���tYj臧��V�7����6��W詧�����tB�|~�L�L
        !          142281: �P��R��DT�TV�D%�=u�|u
�|uV�9̃�V�樃�+��_^�VW�jr�v�����us�6���t�ȃ��tY�L
        !          142282: �P��R��DL�TN�P��R��DP�TR�P��R��DT�TV�~
        !          142283: t'j�F�P�v
        !          142284: ������F��V��DL�TN�F��V��DP�TRV�Z���+��_^�VWU��j&�v�v
        !          142285: �v������_^�VWU��v�~
        !          142286: u;6̜v��F
        !          142287: H��;�w;>̜v+���&�_^�VW��v�<��F��D���t�D���t���v�� ����~tO�F
        !          142288: +��D�T�F�D�F�D
        !          142289: �D%�+������ރ�F����t��w�|�5�v��˃���_^�VW��v调�F��D���t�D���t���v�蔃���~tW�F
        !          142290: FtO��F
        !          142291: V�D�T�F�D�F�D
        !          142292: �D%�+������J��F����t��w�|�5�v��7����_^�VW��F��=u�v�vh��ƃ��>��u��F�F�h���̓��v��v��y���F�F�h&��̓��v��v��y���F�F�h��̓��v��v��yy���F�F�h ��k̓��v��v��^y���F�F�h
��P̓��v��v��Cy���v�v�vh��ƃ���G"�u��F�F�h0��̓��v��v��y���F�F�h4���̃��v��v���x���F�F�h8���̃��v��v���x���F�F�h<���̃��v��v��x���F�F�h@��̃��v��v��x���v�v�v��whD��eŃ�
        !          142293: �F��= t�����F��F��P��~�����>�u
        !          142294: ��%�=�t�F��A&����%�F��~�J}���������Ph֣�F@@P����>�u���&hȣ�[����t���F�<w�6ڣ�6أ�6֣�T����6��6ޣ�6ܣ�6ڣ�6أ�6֣�T���F��V��F�F��F�>�u��F���F�����Pj�R~�����=t��5��F��=
wd����.����ԗۗ�ۗ������&�����F��G�F�
        !          142295: �@�F�
�9�F��2�v�vhs��ă����v�vh�����F�       ��v�vh����Ã��~�u���~�t��F�F�h¢��ʃ��v��v���v���F�F�hǢ��ʃ��v��v��v���F�F�h̢�ʃ��v��v��v���F�F�hѢ�ʃ��v��v��v���F�F�h֢�vʃ��v��v��iv����w�v�vhۢ�Tʃ��v�vh���Eʃ�����6�v��,���_^�+�P�P�P��͋�� /etc/init=WBWGWLWQWVW[W`WeWjWoWtWyW~W�W�W�����������������clrivec: level=%d�����������&& @sel=%x paddr=%X lim=%x flags=%x
        !          142296: vremap: out of gdt's
        !          142297: vremap( faddr=%X, ip=%x ) - not gdt at level 0
        !          142298: vremap( faddr=%X, ip=%x ) - selector is free
        !          142299: ptov:ip=%x: out of gdt's
        !          142300: vtop:ip=%x: sel %x invalid
        !          142301: vrelse: sel %x invalid
        !          142302: vrelse:ip=%x: sel %x already released
        !          142303: Arena %o too smallCorrupt arenaBad free %o
        !          142304: stack overflowbufinit: no space for BUF'sRaw I/O from non user
        !          142305: &t&�&�"�&�&�&�"�"�"�"'&dmalock: driver attempting to doubly lock DMA controller.
        !          142306: eveinit(code)eveinit(data)eveinit()eveinit()fdclose()Inode table overflowcmd=%s time=%lu
        !          142307: ialloc(%p), ipidetach(%p)fsminit: no rootdev(%d,%d)fsminit: no / on rootdev(%d,%d)getment: dev=0x%xOut of inodesInode %u busyOut of spaceBad free listBad block %u (free)bad()�krunch(%d,depth=%d) �U�UGV�UV�V�V�V�"�"W1.2.0.DKCopyright (c) 1982, 1991 by Mark Williams Company
        !          142308: Mark Williams COHERENT Version %s - %s Mode (mem=%u Kbytes)
        !          142309: RealProtectedSerial Number %U
        !          142310: Verification error - call Mark Williams Company at 1-800-MARK-WMS
        !          142311: Cannot allocate user areaCannot create processPanic: %r(%d,%d): %r
        !          142312: Kernel data exceeds 64 KbytesNo alloc space�"�"�",^�^�"�"�"�"�"&out of poll buffers
        !          142313: 0123456789ABCDEFCannot duplicate non shared swapped segmentBad segment countSwapio bad parameterSwapio errorcore&��,���ē��P�(�d������
�&������s���\�M�������V�'>��8�&�&��ǂ8���&�&�&�)�4���2�]�����ۃ&�&������S�&�~���&�&�5�1�΀��n��v�0�&�&�&�&����Parity error: cs=%x ip=%x
        !          142314: ax cs ds es ss system trap: id=%x ip=%x ax=%xax cs ds es ss pid%d: kernel process trap: id=%x, ip=%x ax=%ddouble exception: cs=%x ip=%xinvalid tss: cs=%x ip=%xuser trap: id=%x ip=%x
        !          142315:       ax     cs     ds     es     ss user trap: SEGV id=%x ax=%x pid=%d
        !          142316:       ip=%x sp=%x
        !          142317: @@ukill_�mproto_�XB_DEV     ld_open_�Ucansuper_�Csetrun_�jsav_dsΜtimer_P�sdalloc_�vpfork_ffpopen_:_defqix�EFAULT oops��free_EFAULT     ranupipe_4�ulink_��C_LOAD mountp_aputi_�vprint_!KBCTRL dtkusave�sav_bxМusave_&intflag_unone_&�istat_:Aprocq_tcltfree_main_�Wuseracc_ޓshalloc_[xld_poll_Wisync_&@defend_='waitq_$MAXMEM��uopen_��uaccess_�ufork_,�bad_�Isetacct_-Ksproto_yPFKERN     �PFKERN     �tss_di�umount_\�msize_defqox�bclaim_�clrivec_�      ugetgid_��segadup_�lsegfinm_�spollopen_Hbbufl_UMCSP    putuwd_�halt_llock_!kronflag_h�uwait_(�sexflag_lmap_-Smsync_ADpexit_�guasa_aputp_�etext_smalloc_�wdigtab_D�pollinit_�aowner_�[ISTSIZE_�NBUF_t�upoll_0�segdupd_�sexsread_91DMALCK_$�tss_bpܙseglink_balloc_�Gsendsig_zctclose_�&tabort�tisave�sav_spԜfclear_Upipedev_\�dmaoff_�holebot_int11_�tss_sp0ęsetcdir_$�ugetpgrp_��ld_intr10oWC_BLOCK corebot_l3tol_ltol3_putuwi_&tss_sp1șptret_�}slotsz_�ld_intr11tWidirent_^:uexit_�super_�[nonedev_�"tksave�consave_{dblock_2!tss_sp2̙unull_�ptset_�|ld_intr12yWiclear_K@sav_ssҜsyc�tss_ss0ƙtss_cs�ustat_pollexit_�bld_intr13~Wssalloc_�kactvsig_{getq_+#bufinit_�USIZE &vecs_��tss_ss1ʙtss_ds�ugetpid_��slotp_usync_�ld_intr14�Wltoc_nondsig_�zftoi_F6ctioctl_�&outflag_clrq_�#kclear_�[tss_ss2Ιtss_es�usignal_ۃseginit_|kld_intr15�Widatap_exstack_�1ldefend�'ctread_�&devinit_� a1*�com_usage_mactype_l�setivec_      tss_ipЙtss_axԙualarm2_�ubrk_�uptrace_V�segdupl_�mmfixcon_I[ldrvipc_ vmap_�Pacctip_ialloc_�Dgetment_�Deveinit_�(icodep_bufseqn_ioread_>sphi_Xboot_�tss_pswҙtss_bxڙusetgid_��C_OPEN    icopydm_�<icopymd_U>fn �u_�tss_cx֙nlread_,^ldtimcall_WUDRV_J sbusy_�yidatas_sbl�tss_dxؙtss_si��sysio_Əugetuid_��sigperm_R�pnxgate_relproc_fldrvics_ icodes_cltinit_�"end_putchar_trap_0�pclear_�swapbuf_ C_ULOAD     ldrvcon_@ttsavekpscale_penvsave_{drvl_�CMOSmax_��timeout2_��sigdump_�{C_CLOSE     tusaveinb_pEXTMEMH     trap10�segswap_usetpgrp_΀segsize_�rmsigsin_:[pcsinit_�dC_POLL     ld_block_GVfsminit_nBpexece_I+dclose_
!nulldev_�"dmareq_`swapdev_^�drvn_j�outb_ztrap11�ttyflag_msigint_�Zexlopen_70altclk_timq_blockp_iogetc_getubd_�trap12�holetop_ldrvsel_@fdopen_!5iomapvp_�trap13�coretop_usuload_�ld_intr0=Waread_�Q_canl_cltwant__idle_iNINODE_r�EXTMEML     PIC      gdtmap_��tss_spޙudup_)�seggrow_�o___��xcalledmUld_intr1BWC_IOCTL salloc_ndmaunlock_(bread_
        !          142318: dflag_j"conrest_�splo_\sysitab_��uchdir_
�uexece_�ld_intr2GWinodep_iclose_�Lprocess_%edioctl_�!i8086_f\condev_v�edata_idtmap_��uchmod_��ld_intr3LWdread_X!ffbyte_�swapbot_`�tss_ss�uprofil_2�ld_intr4QWfdaclose_6poll_owner_dev10pvret_�ualarm_'lrdivld_intr5VWfread_
        !          142319: Nctwrite_�&UPASIZE  poll_rate_UPASIZE dev11|usetuid_��segsext_�rsatcopy_Dvmsetuof_�Zldrvint_l�ld_intr6[Wld_xcall_8Ulrremiowrite_�brelease_�rootdev_Z�dev12�gdtsel_��uchroot_1�ucreat_d�segiom_ld_intr7`WC_TIMER     bfree_�Hbflush_�ucl_Ȝdev13�tsave[debflag_�NPOLL_*�nlwrite_�^ld_intr8eWld_close_�Upuload_�*exround_O4iread_Maltsel_dev14�idtsel_��udl_̜uunlink_��version_��ld_intr9jWpclose_C_devmsg_6\excount_�3defer_'msysgen_Wval11      dev15�timeout_�imake_�9envrest_�sas_��argl�cprocp_usload_n�bdone_xffword_dmago_bKBDATA    `trap0[ulseek_s�eprocp_ctopen_t&getupd_�vtop_�trap1frealmode_��scs_œplrcopy_#ptov_�prlcopy_uftime_8�ld_ioctl_�Vfdget_h4defarg�putq_�#kuerr�ageti_�drvmap_�"PICM     !trap2qsds_Ĝkuerr�uclose_P�ld_read_�UKRUNCH_��ifree_�Fkrunch_�Sld_call_AUquantum_ucs_Ɯalloc_?tp_table_vremap_�panic_\trap3|uunique_]�ufcntl_v�vrdivT_LDRV pread_�_fsmount_�Bkfcopy_fkcopy_5unlock_Uktrap4�clock_H$uds_ʜlrmulvrremld_intr�Wbwrite_iprocp_sfbyte_�wakeup_�iNCLIST_n�trap5�umknod_�ugetegid_~�pmake__C_WRITE     imode_1Bctpoll_'swaptop_d�PIT @trap6�clistp_dwrite_�!dmaon_
        !          142320: spl_`trap7�start2uacct_��uioctl_S�schizo_p�NSLOT_�C_POWER   pload_�)dispatch_+jL21#$getuwd_�SPIC     �trap8�uread_��_entry_��fwrite_*Obatflag_kkcopy_f[dpower_�!trap9�dev1vrelse_pevent_a_BFERR idetach_<vread_�Pincopy_�upause_�swapio_[tfddup_�4msetusr_XZldeferb'ldcseg �bsmap_dtime_"setarena_�printf_"cdev3outcopy_
        !          142321: uchown_�unice_ǂsegdq_ldrvpsy_��iwrite_uMallkp_ioputc_KUSZ1  �putubd_Jaidatap_
        !          142322: �stimer_ALLSIZE_p�CMOSA      pdev4(direq_�9ldetach_Z<sfree_obumap_&aicodep_��getuwi_�sfword_�nirqslave_dev54depth_��uumask_5�defunc�utimer_L18$dopen_� dev6@kpcopy_;pkcopy_�ufstat_>�ustime_��utimes_��pts_L19D$aidatas_bctcon_�CMOSD     qdev7Lmsetsys_qZaicodes_dev8Xuutime_8�copyright_Ğbufneed_sleep_�hdev9dld_write_Vdisflag_ttkdone�stand_�$nlcon_�tss_™printn_�dpwrite_�`iopen_Liaccess_�Admalock_�'dpoll_'"kucopy_dukcopy_�clk�cds�ugeteuid_��asize_B_FLAG ld_power_�Viucheck_w<SIDEV     @uumount_M�segmq_indfree_Gldfunc �four"�lbolt_aputc_�SPICM �ulock_��idle_R[ld_time_�Viattach_�:PFLAGS     "PFLAGS     "eoi�tss_ldt�linkq_�pollwake_�bC_READ     
        !          142323: canndaddr_Kftoim_Q9segload_ZL10001�"L2#bsync_ctss_lnk™uwrite_ēutick_��cpid_fdclose_�5fdadupl_�5L3#L10002#ioreq_�upcopy_pucopy_� & s& }& �& �& �& �& �& �& �& �& �& �& �& �& �&     ' 1 ; E O Y c m w � � � �'�G$�$�$�'�&'�&'�&%�$�$� �'�&'&&$$)$/$?'E�'I�0L'O]'S]$V$d$i$m$v$~$�$�$�$�$�'�G$�$$$$)$�$�$�$�'��'&�$$='R�'V�0Y0\0d0g0o0r0z0}0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0000$0$&0)$205$>0A$J0M$V0Y$b0e$n0q$z0}$�0�$�0�$�0�$�0�$�0�$�'�g&0�070M0n0v0�0�0�0�0�00*$.03$70P0s$�$�0�0�%� � �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� ��$"         %      %+      $9      'B      �&0H    0d      0o      0�      $�      0�      $�       �      '�      �&0�    0�      '�      �&0�    0
        !          142324: 0t
        !          142325: 0w
        !          142326: 0�
        !          142327: 0�
        !          142328: 0�
        !          142329: $�
        !          142330: 0�
        !          142331: 0 0.0?0M0V0�0�0�0�0�0�0�$�$�%%$#0&04$T0W0t0�0�0�0�0�0�0�0�0D
0f
0�
0�
0�
0�
0�
0,05'B�&'H�&0K%\%d0l0�0�0�0�0�%�%�$�0�$�0%  0$)$/0I0`0w0�$�0�$�0�$�0�$�0�$00)$<0?0E0^0u0�0�0�0�$�7�<&0$0'$90<$B0N0g0~0�0�0�0�$�$      0 $4070K0b$�$�0�$�0�$�0�0�$ 0#0[0k$r0u �0�0�%�'�$0%3060:$?$E$I _$c$g%m$u0�$�$�0�$�'�g&$�$�'��&0�0�0$%$$ $$$+$/$3$70R'Vg&0`0c$l$p$t �$�$�$�0�$�$�0�$�$�0�$�$�0�$�$0$0$$0)0B$T$[$q$�$�$�%�$�$�$�0�'�E%�%�%$'(E'7E%:%F$�$�$�$�'��'��0�'��'��$�'&�&0'
        !          142332: :':$0$'%:'+:$i'q:'w:0�0�0�$�'�:'�:0�0�0�00,0@0O0Y0f0�0�%�0�%�%�$�'�:'�:00)080@'I�'V�0h$n'v:'|:'��'��'�    '�    0�0�0�0�0�0�0�00-0A0J0f0o0�0�'��'��0�0�'�       '    '             0 W Y [ ]0g0y0� � � � �0�0�0�06%?0|%�0�0�0�%�0�0�0A0S0]0s0~0�'��&'��&0�%�0�$�0 % %
 0 $� $� 0� %� 0!0@!0j!0�!0�!0�!0"06"0x"$�"%�"$�"%�"$�" �"'�"�&'#�&'#0 #'f#'l#'p#&&'v#&&'y#&&0�#0�#'�#0�#'�#0�#0$0
        !          142333: $0$'%$',$&&'9$&&0=$'O$�&'V$�']$T&'d$�'h$T&0k$'v$�&%z$$~$'�$�&'�$'�$'�$g&%�$'�$�%�$$�$$�$$�$$�$'�$�'�$�&'�$�&'%
%%0%'%''%''%''%'')%�0.%'G%''M%'0m%0}%0�%%�%'�%�'�%�$�%$�%0�%0�%0�%%�%%�%%�%%�%0�%%�%%�%0�%0&'&g&0&0&'!&g&'1&
'7&�&'=&�&0@&'G&
0M&'S&g&'Y&�&0_&0e&0k& � � � � � � � � � �  �'{&g&%�&0�&'�&g&0�&'�&g&0�&'�&g&0�&'�&g&0�&''g&0'%-'%1'%5'%9'%?'%C'%I'%N'%R'%Y'%]'%w'%{'%'%�' �'%�'%�'%�'%�'$�'$�'0�'$�'$�'$�'0�'$�'0�'$�'0�'$�'$(0  (0($&(0-($6($<($@($N($T($b($f($l($t($y(0($�($�($�($�($�($�(%�(%�(0�(0�('�(g&0�(0�('�(o&'�(g&')�0)$)0)'+)�'8)�0;)0J)'R)�0X)$e)0h)'u)�'�)�0�)0�)$�)0�)%�)0�)$�)0�)0�)0�)0�)0�)0�)'%*�%4*09*0o*0y*%�*0�* �*0�*%�*0�*%�*0�*0�*0�*0�*$+0+$+%&+%0+0>+'Q+g&0c+0o+%z+0+0�+0�+0,%�,0�,0�,0�, �, �, �, �, �,0'-06-0:-%@-0I-0M-0U-0X-0i-0�-0�-0�-0.0.0C.0M.0P.0�.0�.0�.0�.0�.0�.03/0B/0i/0s/0v/0}/%�/%�/%�/0�/0�/0�/%�/%�/%�/%000000)00/00C00O0%S00Y00d0%00�0%�0%�00�0$�0%�00�071&0.10H10S1%W1%b1%f1%u1%y1%}1%�1%�1%�10�10�1%�10�1%�10320?2${2%�20�2$�2$�20�2030&30830J30W30p30�30�30�30�3%�3%�304%    404%(4%{4%�40�4%�4%�40�4%�4%�4%5%5%+5%/5'A5�&0D50U5%\50e5%�5 �5%�5%�5%�5%�5$�50�50�50�5%�5%6%.6086%N6%T6%Z6%`60x6%�6%�60�6%�6%�60�60�6%�6%�60�6%&707%7%7%,70D7%V70n7%z7%�70�7%�70�7%�7$�70�708080-80:80�80�80�80�80�8%�8%�8%�80�8%9%9090#9%)90,90090<90H90K9'[90j90w9%�9%�90�9%�90�9%�90:0:$(:$,:$5:$9:$B:$F:%P:0S:%g:%k:%q:%s:%w:%}:%�:%�:0�:$�:'�:&'�:&'�:&0�:$�:0�:%      ;%;%0;%4;$;;0>;%E;0K;0R;0b;0h;${;0�;0�;'�;0�;0�;0�;0�;0�;$�;0&<$
        !          142334: <$+<0.<0G<0Q<0g<0n<$�<'�<&'�<&'�<&0�<0�<0=0'=0J=0S=7~=& �= �= �= �= �= �=7�=e7�=e0�=7>&7)>&7C>&0c>0m>0�>0�>7�>& �> ? ? ? ? ?7?f7/?f0O?7c?&7}?&7�?&0�?0�?0�?$@'@&'@&0@@ [@0j@ v@ x@ z@0�@0�@0�@$�@$�@$A$A$
A$A0.A04A �A �A �A �A%�A%�A0�A%B0B%%B$uB$yB0|B$�B$�B$�B0�B$�B$�B$�B0�B%�B$�B$�B$�B0�B%�B%�B%�B%�B0�B'       C�&0C0C0,C%3C0:C0IC0WC0lC0uC0C'�C'�C7�C&7�C&7D&7D&70D&0UD0lD$uD$yD0�D0�D0�D0�D'�D%�D$�D0�D0     E0E0*E07E0bE0sE0�E0�E �E0F$F0F%%F0)F0OF0[F$tF0zF0�F0�F%�F%�F0�F0�F0�F0G0,G7fG&0{G0�G0�G0�G0�G0�G0�G$�G0�G%�G0H0^H$kH0qH0wH0�H0�H0�H0�H0I0
I$;I0AI0GI0QI0lI0I0�I0�I0�I0�I0�I$
        !          142335: J0
J0[J0dJ0yJ0�J7�J&0�J0�J0�J7K&'5K�0;K'?Kg&%HK0KK7WK�7fK�$oK$sK%wK%{K7�K�%�K%�K%�K%�K%�K%�K7�K�%�K'�K�0�K'�K�0�K'L�0      L%L -L GL IL KL ML0TL0lL0vL0�L%�L0�L0�L �L �L �L �L0�L0�L0�L0�L0M0M ,M HM JM LM NM PM0WM0aM0hM%nM$�M$�M$�M$�M �M �M �M �M �M �M0�M0�M0�M0�M%N0�N0�N0�N0�N0�N0O%O0$O0uO0�O0�O0�O0�O0�O0&P01P%8P0eP0mP0vP0�P0�P0�P0�P0�P0Q0Q0RQ0�Q7�Q&0�Q0�Q0�Q0HR0TR0`R0nR0�R7�R&0�R0�R0�R7
S&0!S0'S%aS$�S$�S$�S0�S0�S$�S0�S'�SA0�S%�S0�S �S$�S%�S0�S0�S0&T'TS T$T%T0T0$T0'T'*TS0-T06T'<Td'@Td'IT#'PT#0UT0�T0�T'�Tg&$�T$�T0�T'�TE'�TE0�T$�T'U# U$U%"U0%U'+US0.U �� �� �� �� �� �� �� �� �� �� �� l� n� p� r� t� v� x� z� |� ~� �� �� �� �� �� ��'�U�'�U�0�U'�U�'�U�0�U'�U�'�U�0V'$V�'-V�0EV'VV�'_V�0V'�V�'�V�0�V'�V�'�V�0�V'�V�'�V�0W'W�'#W�0;W'�W�'�W�%�W0�W0�W0�W0�W0�W'�W2$�W$�W$�W$�W$�W0�W$�W0�W$�W$�W$�W0�W$�W$&X$X0X$
X$X$X$X$ X0#X'*X�&07X$CX0FX LX0OX'UX�&0^X'dXo&$kX0nX0uX0{X'�Xg&0�X0�X0�X0�X0�X0
        !          142336: Y%Y%Y%Y0#Y$)Y%2Y%5Y0GY%QY0^Y0zY0�Y0�Y0�Y$�Y%�Y$�Y%�Y%�Y%Z%!Z$&Z%*Z$/Z%2Z$5Z%8Z$;Z%>Z$AZ$GZ%aZ%hZ%kZ%|Z%�Z%�Z%�Z0�Z%�Z0[0[%[%[%"[%2[%A['Y[
0^[%�[%�[%�[%�[%�[%�[%�[%   \%
\$\0\0#\0)\0,\%0\$Q\0T\$Z\0]\'m\�$x\$�\$�\$�\$�\$�\$�\$]0]$]';]�'?]�'C]�'M]�&'Q]�&'W]&']]�'`]�$c]'r]�'v]�'z]�$]0�]$�]'�]d'�]d'�]�'�]'�]�'�]�'�]�'�]�'�]]'�]]'�]d'�]d7�]-&'�]2'�]0�]'�]�&'�]�#�]'�]�)�]'�]�#^'^�)^'^d'^d0^'%^E � � � � � �  � "� $� &� F^ H^ J^ L^%R^%\^0r^0�^%�^ �^ �^ �^ �^%�^%�^0�^0�^%�^$_0_0 _0S_0z_0�_%�_0�_0�_0�_0�_%`0_`0�`%�`0�`0�`%�`'�`g&0�`0�`%4a08a0Qa0aa0ka0qa0�a0�a0�a0�a$�a'�a�&0�a$�a$b$b'b�&0b$"b%0b%6b%Bb%_b0hb$qb0tb%~b'�bg&'�bg&'�bg&0�b'�bg&%c%c0Cc0Gc gc �c �c �c �c �c �c �c �c �c �c �c �c0�c0�c0�c0�c0�c0�c0d0d04d0cd0gd0�d0�d7�d�&0�d7�d�&$�d0�d'�d'�dg&'e'e'e'e'e2'e2'/e�&02e0@e0ee0ue0�e0�e'�e�0�e'�e>'�e>'�e>'�e>'�e'�e'f�0f02f'8f�0;f'Sf�0Vf0]f0of%|f0�f0�f0�f0�f0�f%�f0�f0�f%�f%�f%�f%�f0�f'�fg&0"g0,g05g'<gg&0Hg0eg0lg0rg0yg0�g$�g$�g%�g%�g%�g0�g0�g'�gg&0�g0�g0�g%�g%�g0�g%�g%�g0�g0�g0&h'.h'6h0Oh'iho&0lh'yh�&0|h'�h�&'�h�&0�h'�hE0�h'�hg&0�h0�h%�h0�h0�h'�h�&'.i20Ii0Oi0�i0�i%�i0�i �i0�i'�i20�i'�i�&0j0j0"j02j'9j�&'<j'Hj0uj'|j�&'�j
'�jg&0�j'�jg&%�j0�j0�j'�jg&0�j0�j'�j'�j0*k0@k0Lk'lk
0rk'�k#'�k#'�k#'�k#'�k�&'�k�&'�k�&'�k�&'�k]'�k]'�k�'�k�'�k]'�k]'�kD&'�kD&'�k�'�k�'�k]'�k]'�kD&'�kD&'�kD&'�kD&'�kD&'�kD&'�k#'�kD&'�k#'�k#'�kD&'�k#'�kD&0l' lS0#l'3l#'7l#'LlS0Ol0Vl0bl0fl'zl�&'~l�&'�lS0�l0�l0�l0�l0�l0�l'&mg&0.m0~m$�m0�m0�m0�m0�m'!nS0$n07n0Bn'JnS0Mn0Zn'`nS0cn0vn0�n'�nS0�n0�n0�n'�n�&0�n0�n0�n'oS0o'-oS00o'DoS0Go$So0Vo0fo0ro0yo0�o'�oS0�o0�o'�oS0�o0�o'p#'pd'pd''p#',p�'0p�0mp0p0�p0�p0�p0�p0  q0#q0Kq0eq0}q'�qS0�q0�q0�q0�q0r'rS0r0r0r0#r0qr0�r0�r0�r%�r0�r0�r0�r'�rg&0�r0�r'�rA%�r0s'sS0s0s'sS0!s')sS0,s0Qs'WsS0Zs0bs'hsS0ks0zs0�s'�sg&0�s0�s0�s0�s0�s'�sA'�sS0�s0�s'tS0       t'tS0t01t0Pt$it$qt7�t-&$�t$�t'�td'�td'�t�'�t�$�t0�t'�t�%�t0�t'�tg&0     u0#u$�u0�u$�u0�u0�u0�u$�u0�u v0v0(v02v'9vg&0\v0�v0�v7�v-&$�v$�v'�v�&$�v0�v$�v0�v'w�&$w$w'5w�&08w7�w-&'�w�&0�w'�wd'�wd'�w#'�w#'�w�'�w�'�w�&0�w01x'Nx#0Sx'bx#'ex�'ix�'wx#'�xd'�xd'�x�&0�x0�x'y#0y%$y0'y'9yg&%Ry%Ty%_y%ty%�y%�y%�y0�y'�yS0�y'�y#'�y#'�yS0�y'�y�&'�y�&'zS0z0ez'zz�&0�z0�z'�zg&0{0{'{g&%6{%?{0L{%T{0W{0i{0�{0�{'�{g&%�{%�{0�{$�{0�{0�{0�{%�{0�{0�{0|0|0|0%|%)|%.|%4|%9|%=|0C|%G|0L|%e|%s|%w|%{|%�|%�|%�|0�|%�|%�|0�|0�|%�|0�|'}�0}'
        !          142337: }'}' }�0#}'*}'7}g&%C}'I}�&0L}'U}�&'[}�&'a}�&'g}�&'k}�&'q}�&'w}�&'|}�&0}'�}�&'�}�&0�}'�}�&%�}'�}�&0�}'�}�&'�}g&%�}0�}'�}�0�}'�}'�}0~'~�0       ~0~'~�&'#~�&'/~�&02~':~�& I~ K~ M~ O~ Q~ S~ U~ W~ Y~ [~'_~�&0b~'h~�&'n~�&0q~'w~�&'~�&%�~%�~'�~�&'�~�&0�~'�~�&'�~�&0�~'�~�&'�~�&0�~0�~'�~�&'�~�&'�~�&'�~�&'�~�&%�~%�~'�~�&'�~�&'�~�&'�&00 0'.g&'C''G'7V-& _7m�&0y'�g&'�''�' �0�'�g&%�0�0
�0#�02�$?�$C�$M�$T�$Z�0`�0n�0u�%��%��%��'��g&%��'ŀg&'Հg&%�0��'���0�'
�'�0�05�0:�0F�0L�%P�0T�'f�'j�0o�0��0��%��'��'��'ǁg&0݁0�'��'��0(�01�'9��0<�%I�%[�%h�%��%��0��'��g&'��g&'тg&'�g&0�'��g&%�%$�0'�%<�%D�%J�%P�'c�g&0{�%��0��%��%��'��g&%��0��%Ń%Ƀ'̓g&'�g&%��%�%8�%E�0w�0��0��$��0��0��'��''��''ńg&0&�0�0�'0�g&'3��06�'A�'I�0N�'u��0x�0��0��0˅'ׅ�0څ0�0�'��0��%�0�0�0(�00�09�%C�%G�%K�0O�%`�0e�%w�%z�%}�%��%��%��%��%��0��'���%��'���0��'†�'ʆ�0ӆ%ކ%�0�0��'��%�0�02�%=�%L�0Q�0\�%g�0q�0y�0��%��0��%��$ɇ$͇0ׇ0�%��0��$�$�0&�0:�%A�0E�0Y�0x�0��%��0��0�� �� ҈ Ԉ ֈ0�0��0��%�0�0 �05�0H�0\�0k�%��%��0��0�� �� �� �� �� �� ��0É%҉%މ%��%L�0]�%��0��0��0��%��0Ŋ0͊0ӊ0ڊ0�0��%��%��%�0�%�%�%"�0%�%0�08�%?�0B�0L�$Z�$^�0h�0|�%�� �� �� �� ��%�0�0�%'�%1�06�0D�0Q�0h�0r�%v�0|�0��%��0��0��%��0Č%ڌ%�'�0
�0%�%F�0J�$d�%j�0n�0��0��%��0Ѝ0ݍ0�0�0�0� )�'/�g& 6�'<�g&0C�'P�g&0W�0]�'l�g&0s�0~�%��0�� �� �� �� ��0Ǝ%ю0֎0�0&�0�%-�0=�0L�0^�0o�0~�0��0��0��0��0��0Џ0ޏ%��0�%�0-�%J�%N�%T�%Z�%i�%r�0v�$��$��%��0��%��0��0ΐ%ِ0�0�0��%�0�'�0�0$�%'�0*�%<�%E�0Y�0c�%g�0m�0x�0~�0��%��0��'��%ɑ0͑0ё$ؑ'��&'�&%��$�'
�&'�&0,�05�0K�0R�$f�0i�0��0��%��0��%��%Œ0ɒ0Ւ0ܒ%�0�$&�$�0&�0-�0D�%O�0U�$d�$h�$q�$u�$~�$��0��0��0Փ$�$� �� �� Ġ Ƞ ̠ Р Ԡ ؠ ܠ � � � � � �� �� �� � � � � � � � �  � $� (� ,� 0� 4� 8� <� @� D� H� L� P� T� X� \� `� d� h� l� p� t� x� |� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� ġ ȡ ̡ С ԡ ء ܡ �0�0>�'P�''T�''s��0x�0��0��0ʔ'ޔ''�''��0�0'�$H�0K�$R�0X�$a�0d�0p�$|�0�0��$��0��0��$��0��0��$͕0Е0ܕ$�0�'��g&0��$�0�0�$#�0&�02�$>�0A�0M�$Y�0\�0h�$t�0w�0��'��g&$��0��0��%��0��%ʖ0ߖ$��%��0�%�%�%�0�%)�%5�%9�%=�%I�%M�%Q�%U�%Y�%]�%v�0|�%��0��%��0��0�� �� �� �� �� �� �� — ė Ɨ ȗ ʗ ̗ Η З җ$��0��$�$�0�0)�02�$;�0>�0J�$V�0Y�0e�$q�0t�0��$��0��0��$��0��0��'��g&$ɘ0̘$ؘ0ۘ%�'�g&0�0707070064030053121007440000030000030000011777770507310770100004200000013733/newbits/kernel/USRSYS/config.mwc:
        !          142338: :      configure a Coherent kernel for the AT
        !          142339: :
        !          142340: : usage: config [help]
        !          142341: :       config [stand=fha0]
        !          142342: :       config [stand=fva0]
        !          142343: :       config [stand=fha0] [standard] [root=DRV] [DRV ...]
        !          142344: :       config [stand=fva0] [standard] [root=DRV] [DRV ...]
        !          142345: 
        !          142346: :      initialize variables
        !          142347: :
        !          142348: ATSTANDARD=" fl lp mm "
        !          142349: ATKERNEL=atkernel.o
        !          142350: 
        !          142351: STANDARD="${ATSTANDARD}"
        !          142352: KERNEL="${ATKERNEL}"
        !          142353: LIBS="lib/tty.a lib/support.a"
        !          142354: BUILD=0
        !          142355: DEV=/tmp/dev
        !          142356: PASS1=""
        !          142357: PASS2=""
        !          142358: UNDEF=""
        !          142359: PATCH=""
        !          142360: ROOTDEV=""
        !          142361: INSTALL=""
        !          142362: 
        !          142363: case "$#" in
        !          142364: 0)     /bin/echo
        !          142365:        /bin/echo       "The following can be used as arguments to config:"
        !          142366:        /bin/echo
        !          142367:        /bin/cat doc/*
        !          142368:        exit 0
        !          142369:        ;;
        !          142370: esac
        !          142371: 
        !          142372: for ARG in $*
        !          142373: do
        !          142374:        case "${ARG}" in
        !          142375:        help)
        !          142376:                /bin/echo
        !          142377:                /bin/echo "The following can be used as arguments to config:"
        !          142378:                /bin/echo
        !          142379:                /bin/cat doc/*
        !          142380:                exit 0
        !          142381:                ;;
        !          142382:        ibm-at)
        !          142383:                STANDARD="${ATSTANDARD}"
        !          142384:                KERNEL="${ATKERNEL}"
        !          142385:                ;;
        !          142386:        *)
        !          142387:                PASS1="${PASS1} ${ARG}"
        !          142388:                ;;
        !          142389:        esac
        !          142390: done
        !          142391: 
        !          142392: for ARG in ${PASS1}
        !          142393: do
        !          142394:        case "${ARG}" in
        !          142395:        standard)
        !          142396:                PASS2="${STANDARD} ${PASS2}"
        !          142397:                ;;
        !          142398:        stand\=fha0)
        !          142399:                /etc/umount /dev/fha0 2> /dev/null
        !          142400:                echo -n "Insert 5.25 high capacity floppy into drive 0, press return [y to format]: "
        !          142401:                read x
        !          142402:                case "x$x" in
        !          142403:                xy)     /etc/fdformat -i 6 /dev/fha0 || exit 1 ;;
        !          142404:                esac
        !          142405:                /etc/mkfs  /dev/fha0 2400               || exit 1
        !          142406:                /bin/cp /conf/boot.fha /dev/fha0        || exit 1
        !          142407:                /etc/mount /dev/fha0 /f0                || exit 1
        !          142408:                /bin/mkdir /f0/bin /f0/dev /f0/etc /f0/mnt /f0/tmp || exit 1
        !          142409:                umask 011
        !          142410:                /etc/mknod /f0/dev/null c 0 0           || exit 1
        !          142411:                /bin/ln -f /f0/dev/null /f0/dev/swap    || exit 1
        !          142412:                umask 077
        !          142413:                /etc/mknod /f0/dev/mem  c 0 1           || exit 1
        !          142414:                /etc/mknod /f0/dev/kmem c 0 2           || exit 1
        !          142415:                /bin/chmod 777 /f0/tmp                  || exit 1
        !          142416:                umask 022
        !          142417: 
        !          142418:                /bin/cp /bin/bad /bin/cat /bin/cp /bin/cpdir \
        !          142419:                        /bin/db /bin/dd /bin/df /bin/du \
        !          142420:                        /bin/echo /bin/kill \
        !          142421:                        /bin/ls /bin/mkdir /bin/mv /bin/ncheck \
        !          142422:                        /bin/rm /bin/sh /bin/stty /bin/sync \
        !          142423:                        /bin/time /bin/true /f0/bin || exit 1
        !          142424:                /bin/cp /etc/fsck /etc/init /etc/badscan /etc/clri \
        !          142425:                        /etc/fdisk /etc/mkfs \
        !          142426:                        /etc/mknod /etc/mount /etc/umount /f0/etc || exit 1
        !          142427: 
        !          142428:                DEV=/f0/dev
        !          142429:                :
        !          142430:                : Place a Coherent image out on drive 0.
        !          142431:                : Add a floppy root patched version as a file called 'stand'.
        !          142432:                :
        !          142433:                INSTALL="umask 022; set -e ; /bin/cp coherent /f0 ; \
        !          142434:                        /conf/patch coherent 'rootdev_=makedev(4,14)' ; \
        !          142435:                        /conf/patch coherent 'pipedev_=makedev(4,14)' ; \
        !          142436:                        /bin/cp coherent /f0/stand ; /bin/strip /f0/stand ; \
        !          142437:                        /etc/umount /dev/fha0 ; /bin/df /dev/fha0"
        !          142438: 
        !          142439:                case "$#" in
        !          142440:                1) eval ${INSTALL} ; exit 0 ;;
        !          142441:                esac
        !          142442:                ;;
        !          142443: 
        !          142444:        stand\=fva0)
        !          142445:                /etc/umount /dev/fva0 2> /dev/null
        !          142446:                echo -n "Insert high density 3.5 floppy into drive 0, press return [y to format]: "
        !          142447:                read x
        !          142448:                case "x$x" in
        !          142449:                xy)     /etc/fdformat -i 6 /dev/fva0 || exit 1 ;;
        !          142450:                esac
        !          142451:                /etc/mkfs  /dev/fva0 2880               || exit 1
        !          142452:                /bin/cp /conf/boot.fva /dev/fva0        || exit 1
        !          142453:                /etc/mount /dev/fva0 /f0                || exit 1
        !          142454:                /bin/mkdir /f0/bin /f0/dev /f0/etc /f0/mnt /f0/tmp || exit 1
        !          142455:                umask 011
        !          142456:                /etc/mknod /f0/dev/null c 0 0           || exit 1
        !          142457:                /bin/ln -f /f0/dev/null /f0/dev/swap    || exit 1
        !          142458:                umask 077
        !          142459:                /etc/mknod /f0/dev/mem  c 0 1           || exit 1
        !          142460:                /etc/mknod /f0/dev/kmem c 0 2           || exit 1
        !          142461:                /bin/chmod 777 /f0/tmp                  || exit 1
        !          142462:                umask 022
        !          142463: 
        !          142464:                /bin/cp /bin/bad /bin/cat /bin/cp /bin/cpdir \
        !          142465:                        /bin/db /bin/dd /bin/df /bin/du \
        !          142466:                        /bin/echo /bin/kill \
        !          142467:                        /bin/ls /bin/mkdir /bin/mv /bin/ncheck \
        !          142468:                        /bin/rm /bin/sh /bin/stty /bin/sync \
        !          142469:                        /bin/time /bin/true /f0/bin || exit 1
        !          142470:                /bin/cp /etc/fsck /etc/init /etc/badscan /etc/clri \
        !          142471:                        /etc/fdisk /etc/mkfs \
        !          142472:                        /etc/mknod /etc/mount /etc/umount /f0/etc || exit 1
        !          142473: 
        !          142474:                DEV=/f0/dev
        !          142475:                :
        !          142476:                : Place a Coherent image out on drive 0.
        !          142477:                : Add a floppy root patched version as a file called 'stand'.
        !          142478:                :
        !          142479:                INSTALL="umask 022; set -e ; /bin/cp coherent /f0 ; \
        !          142480:                        /conf/patch coherent 'rootdev_=makedev(4,15)' ; \
        !          142481:                        /conf/patch coherent 'pipedev_=makedev(4,15)' ; \
        !          142482:                        /bin/cp coherent /f0/stand ; /bin/strip /f0/stand ; \
        !          142483:                        /etc/umount /dev/fva0 ; /bin/df /dev/fva0"
        !          142484: 
        !          142485:                case "$#" in
        !          142486:                1) eval ${INSTALL} ; exit 0 ;;
        !          142487:                esac
        !          142488:                ;;
        !          142489: 
        !          142490:        DEV\=*)
        !          142491:                DEV=`/bin/echo "${ARG}" | /bin/sed -e 's/^....//'`
        !          142492:                ;;
        !          142493:        *)
        !          142494:                PASS2="${PASS2} ${ARG}"
        !          142495:                ;;
        !          142496:        esac
        !          142497: done
        !          142498: 
        !          142499: :      get the proper driver information
        !          142500: :
        !          142501: 
        !          142502: for ARG in ${PASS2}
        !          142503: do
        !          142504:        case "$ARG" in
        !          142505: 
        !          142506:        root\=fva0)
        !          142507:                ROOTDEV="makedev(4,15)"
        !          142508:                . confdrv/fl
        !          142509:                ;;
        !          142510:        root\=fha0)
        !          142511:                ROOTDEV="makedev(4,14)"
        !          142512:                . confdrv/fl
        !          142513:                ;;
        !          142514:        root\=*)
        !          142515:                ARG=`/bin/echo "${ARG}" | /bin/sed -e 's/^.....//'`
        !          142516: 
        !          142517:                case "${ARG}" in
        !          142518:                *[0123][abcdx])
        !          142519:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          142520:                        ;;
        !          142521:                *)
        !          142522:                        FILE="${ARG}"
        !          142523:                        ;;
        !          142524:                esac
        !          142525: 
        !          142526:                if /bin/test -r confdrv/${FILE}
        !          142527:                then
        !          142528:                        . confdrv/${FILE}
        !          142529:                        ROOTDEV="${MAKEDEV}"
        !          142530: /bin/echo "'confdrv/${FILE}' executing"
        !          142531:                else
        !          142532:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          142533:                        exit 1
        !          142534:                fi
        !          142535:                ;;
        !          142536: 
        !          142537:        swap)
        !          142538:                ;;
        !          142539: 
        !          142540:        swap\=*)
        !          142541:                ARG=`/bin/echo "${ARG}" | /bin/sed -e 's/^.....//'`
        !          142542: 
        !          142543:                case "${ARG}" in
        !          142544:                *[0123][abcdx])
        !          142545:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          142546:                        if [ -d "${DEV-/dev}" ]
        !          142547:                        then
        !          142548:                                /bin/ln -f ${DEV-/dev}/${ARG} ${DEV-/dev}/swap
        !          142549:                        fi
        !          142550:                        ;;
        !          142551:                *)
        !          142552:                        FILE="${ARG}"
        !          142553:                        ;;
        !          142554:                esac
        !          142555: 
        !          142556:                if /bin/test -r confdrv/${FILE}
        !          142557:                then
        !          142558:                        . confdrv/${FILE}
        !          142559:                        PATCH="${PATCH} swapdev_=${MAKEDEV}"
        !          142560:                        /bin/echo "Swap device will be ${DEV-/dev}/${ARG}"
        !          142561:                        /bin/echo "See documentation before enabling"
        !          142562:                else
        !          142563:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          142564:                        exit 1
        !          142565:                fi
        !          142566:                ;;
        !          142567: 
        !          142568:        *\=*)
        !          142569:                PATCH="${PATCH} ${ARG}"
        !          142570:                ;;
        !          142571: 
        !          142572:        *)
        !          142573:                case "${ARG}" in
        !          142574:                *[0123][abcdx])
        !          142575:                        FILE=`/bin/echo "${ARG}" | /bin/sed -e 's/..$//'`
        !          142576:                        ;;
        !          142577:                *)
        !          142578:                        FILE="${ARG}"
        !          142579:                        ;;
        !          142580:                esac
        !          142581: 
        !          142582:                if /bin/test -r confdrv/${FILE}
        !          142583:                then
        !          142584:                        . confdrv/${FILE}
        !          142585:                        case "${ROOTDEV}" in
        !          142586:                        ?*)     ;;
        !          142587:                        *)      ROOTDEV="${MAKEDEV}" ;;
        !          142588:                        esac
        !          142589:                else
        !          142590:                        /bin/echo "'confdrv/${FILE}' does not exist"
        !          142591:                        exit 1
        !          142592:                fi
        !          142593:                ;;
        !          142594:        esac
        !          142595: done
        !          142596: ROOTDEV="${ROOTDEV-makedev(4,14)}"
        !          142597: 
        !          142598: :      include stub drivers
        !          142599: :
        !          142600: UNDEF="${UNDEF} ${LIBS}"
        !          142601: 
        !          142602: :      make the proper root and pipe devices
        !          142603: :
        !          142604: PATCH="${PATCH} rootdev_=${ROOTDEV} pipedev_=${ROOTDEV}"
        !          142605: 
        !          142606: set -ex
        !          142607: :
        !          142608: :      create a kernel with the desired device drivers
        !          142609: :
        !          142610: /bin/ld -i -x -o coherent ${KERNEL} ${UNDEF} -lc
        !          142611: :
        !          142612: :      enable the desired device drivers
        !          142613: :
        !          142614: /conf/patch coherent ALLSIZE_=16384 NBUF_=32 NCLIST_=24 ${PATCH}
        !          142615: /bin/chmod 644 coherent
        !          142616: /bin/chown sys coherent
        !          142617: /bin/chgrp sys coherent
        !          142618: /bin/sync
        !          142619: :
        !          142620: eval ${INSTALL}
        !          142621: 0707070064030110571007550000030000030000011777770507310770200003700000001165/newbits/kernel/USRSYS/newkers# newkers - copy kernels to floppy
        !          142622: VOL=${1-foo}
        !          142623: case $VOL in
        !          142624: f0 | 5)
        !          142625:        VOL=f0
        !          142626:        PATCH="rootdev_=0x40E"
        !          142627:        ;;
        !          142628: f1 | 3)
        !          142629:        PATCH="rootdev_=0x40F"
        !          142630:        VOL=f1
        !          142631:        ;;
        !          142632: *)
        !          142633:        echo "Usage: $0 { f0 | 5 | f1 | 3 }"
        !          142634:        exit 0
        !          142635: esac
        !          142636: echo -n "Place boot diskette in $1 drive and press <Enter> "
        !          142637: read JUNK
        !          142638: mount $VOL || exit 1
        !          142639: cp /coh.at /$VOL/begin
        !          142640: ln -f /$VOL/begin /$VOL/coherent
        !          142641: chmog 400 sys sys /$VOL/coherent       
        !          142642: /conf/patch /$VOL/coherent $PATCH pipedev_=0x883 ronflag_=1 || exit 1
        !          142643: cp /coh.ss /$VOL/coherent.ss
        !          142644: chmog 400 sys sys /$VOL/coherent.ss
        !          142645: cp /coh.aha /$VOL/coherent.aha
        !          142646: chmog 400 sys sys /$VOL/coherent.aha
        !          142647: ls -l /$VOL/begin /$VOL/coh*
        !          142648: umount $VOL
        !          142649: 0707070064030027041004440000030000030000011777770507310770300002400000015076/newbits/Makefile,vhead     1.1;
        !          142650: access   ;
        !          142651: symbols  ;
        !          142652: locks    ;
        !          142653: comment  @@;
        !          142654: 
        !          142655: 
        !          142656: 1.1
        !          142657: date     91.03.12.21.05.34;  author bin;  state Exp;
        !          142658: branches ;
        !          142659: next   ;
        !          142660: 
        !          142661: 
        !          142662: desc
        !          142663: @provided by stevesf. uses SRCPATH. designed to make all
        !          142664: executables. I haven't had time to look at it so It's here until
        !          142665: I do...
        !          142666: @
        !          142667: 
        !          142668: 
        !          142669: 
        !          142670: 1.1
        !          142671: log
        !          142672: @Initial revision
        !          142673: @
        !          142674: text
        !          142675: @# /usr/src/cmd/Makefile 2/20/91
        !          142676: # Makefile for COHERENT commands.
        !          142677: # Preliminary, does not yet make most subdirectories.
        !          142678: 
        !          142679: # Commands in /bin compiled from single sources.
        !          142680: BIN=\
        !          142681:        ac\
        !          142682:        ar\
        !          142683:        at\
        !          142684:        bad\
        !          142685:        banner\
        !          142686:        basename\
        !          142687:        c\
        !          142688:        cal\
        !          142689:        calendar\
        !          142690:        cat\
        !          142691:        chgrp\
        !          142692:        chmod\
        !          142693:        chown\
        !          142694:        cmp\
        !          142695:        col\
        !          142696:        comm\
        !          142697:        conv\
        !          142698:        cp\
        !          142699:        cpdir\
        !          142700:        crypt\
        !          142701:        date\
        !          142702:        dd\
        !          142703:        deroff\
        !          142704:        df\
        !          142705:        du\
        !          142706:        echo\
        !          142707:        egrep\
        !          142708:        epson\
        !          142709:        expr\
        !          142710:        factor\
        !          142711:        file\
        !          142712:        fixstack\
        !          142713:        fnkey\
        !          142714:        from\
        !          142715:        grep\
        !          142716:        help\
        !          142717:        join\
        !          142718:        kill\
        !          142719:        lc\
        !          142720:        ln\
        !          142721:        look\
        !          142722:        ls\
        !          142723:        m4\
        !          142724:        man\
        !          142725:        mesg\
        !          142726:        mkdir\
        !          142727:        msg\
        !          142728:        mv\
        !          142729:        newgrp\
        !          142730:        nm\
        !          142731:        od\
        !          142732:        pr\
        !          142733:        prep\
        !          142734:        prof\
        !          142735:        pwd\
        !          142736:        quot\
        !          142737:        ranlib\
        !          142738:        rev\
        !          142739:        rm\
        !          142740:        rmdir\
        !          142741:        sa\
        !          142742:        scat\
        !          142743:        size\
        !          142744:        sleep\
        !          142745:        sort\
        !          142746:        split\
        !          142747:        strings\
        !          142748:        strip\
        !          142749:        stty\
        !          142750:        sum\
        !          142751:        sync\
        !          142752:        tail\
        !          142753:        tar\
        !          142754:        tee\
        !          142755:        time\
        !          142756:        touch\
        !          142757:        tr\
        !          142758:        tty\
        !          142759:        typo\
        !          142760:        uniq\
        !          142761:        wc\
        !          142762:        who\
        !          142763:        write\
        !          142764:        yes
        !          142765: 
        !          142766: # Commands in /bin built by making subdirectories.
        !          142767: BIN2=\
        !          142768:        awk\
        !          142769:        check\
        !          142770:        dcheck\
        !          142771:        diff\
        !          142772:        dos\
        !          142773:        dump\
        !          142774:        dumpdate\
        !          142775:        dumpdir\
        !          142776:        ed\
        !          142777:        hp\
        !          142778:        hpr\
        !          142779:        hpskip\
        !          142780:        icheck\
        !          142781:        lex\
        !          142782:        lpr\
        !          142783:        lpskip\
        !          142784:        ncheck\
        !          142785:        restor\
        !          142786:        sed\
        !          142787:        tsort\
        !          142788:        yacc
        !          142789: 
        !          142790: # Shell scripts in /bin, the source is the executable.
        !          142791: BINSH=\
        !          142792:        diff3\
        !          142793:        false\
        !          142794:        mount\
        !          142795:        phone\
        !          142796:        shutdown\
        !          142797:        spell\
        !          142798:        true\
        !          142799:        umount
        !          142800: 
        !          142801: # Commands in /bin not yet included.
        !          142802: BINMISSING=\
        !          142803:        as\
        !          142804:        bc\
        !          142805:        cc\
        !          142806:        compress\
        !          142807:        db\
        !          142808:        dc\
        !          142809:        find\
        !          142810:        head\
        !          142811:        ld\
        !          142812:        login\
        !          142813:        mail\
        !          142814:        make\
        !          142815:        msgs\
        !          142816:        nroff\
        !          142817:        passwd\
        !          142818:        ps\
        !          142819:        rmail\
        !          142820:        sh\
        !          142821:        su\
        !          142822:        test\
        !          142823:        troff\
        !          142824:        uncompress\
        !          142825:        units\
        !          142826:        zcat
        !          142827: 
        !          142828: # Commands in /etc compiled from single sources.
        !          142829: ETC=\
        !          142830:        accton\
        !          142831:        cron\
        !          142832:        mkfs\
        !          142833:        mknod\
        !          142834:        mount\
        !          142835:        umount\
        !          142836:        update\
        !          142837:        wall
        !          142838: 
        !          142839: # Commands in /etc built from subdirectories.
        !          142840: ETC2=\
        !          142841:        clri
        !          142842: 
        !          142843: # Commands in /usr/lib compiled from single sources.
        !          142844: USRLIB=\
        !          142845:        atrun
        !          142846: 
        !          142847: # Commands in /usr/lib built from subdirectories.
        !          142848: USRLIB2=\
        !          142849:        diff3\
        !          142850:        diffh\
        !          142851:        hpd\
        !          142852:        lpd
        !          142853: 
        !          142854: # Objects built from subdirectories but not currently distributed.
        !          142855: EXTRA=\
        !          142856:        prps
        !          142857: 
        !          142858: # Sources in /usr/src/cmd but executables not currently distributed.
        !          142859: UNUSED=\
        !          142860:        connect.c\
        !          142861:        detab.c\
        !          142862:        learn.c\
        !          142863:        load.c\
        !          142864:        mf.c\
        !          142865:        mkproto.c\
        !          142866:        more.c\
        !          142867:        uload.c
        !          142868: 
        !          142869: # Primary target.
        !          142870: all:   $(BIN) $(ETC) $(USRLIB)
        !          142871:        make SRCPATH=$(SRCPATH)/awk
        !          142872:        make SRCPATH=$(SRCPATH)/check
        !          142873:        make SRCPATH=$(SRCPATH)/diff
        !          142874:        make SRCPATH=$(SRCPATH)/dos
        !          142875:        make SRCPATH=$(SRCPATH)/dump
        !          142876:        make SRCPATH=$(SRCPATH)/ed
        !          142877:        make SRCPATH=$(SRCPATH)/grep
        !          142878:        make SRCPATH=$(SRCPATH)/lex
        !          142879:        make SRCPATH=$(SRCPATH)/lpr
        !          142880:        make SRCPATH=$(SRCPATH)/sed
        !          142881:        make SRCPATH=$(SRCPATH)/tsort
        !          142882:        make SRCPATH=$(SRCPATH)/yacc
        !          142883:        : /usr/src/cmd done.
        !          142884: 
        !          142885: # Secondary targets.
        !          142886: # The actions would not be necessary if make could deal with null extensions.
        !          142887: ac:    ac.c
        !          142888:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142889: accton:        accton.c
        !          142890:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142891: ar:    ar.c
        !          142892:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142893: at:    at.c
        !          142894:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142895: atrun: atrun.c
        !          142896:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142897: bad:   bad.c
        !          142898:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142899: banner:        banner.c
        !          142900:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142901: basename:      basename.c
        !          142902:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142903: c:     c.c
        !          142904:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142905: cal:   cal.c
        !          142906:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142907: calendar:      calendar.c
        !          142908:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142909: cat:   cat.c
        !          142910:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142911: chgrp: chgrp.c
        !          142912:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142913: chmod: chmod.c
        !          142914:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142915: chown: chown.c
        !          142916:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142917: cmp:   cmp.c
        !          142918:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142919: col:   col.c
        !          142920:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142921: comm:  comm.c
        !          142922:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142923: conv:  conv.o
        !          142924:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142925: conv.o:        conv.y
        !          142926: cp:    cp.c
        !          142927:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142928: cpdir: cpdir.c
        !          142929:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142930: cron:  cron.c
        !          142931:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142932: crypt: crypt.c
        !          142933:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142934: date:  date.c
        !          142935:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142936: dd:    dd.c
        !          142937:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142938: deroff:        deroff.c
        !          142939:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142940: df:    df.c
        !          142941:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142942: du:    du.c
        !          142943:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142944: echo:  echo.c
        !          142945:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142946: egrep: egrep.c
        !          142947:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142948: epson: i8086/epson.c
        !          142949:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142950: expr:  expr.o
        !          142951:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142952: expr.o:        expr.y
        !          142953: factor:        factor.c
        !          142954:        $(CC) $(LDFLAGS) -o $@@ $? -lm
        !          142955: file:  file.c
        !          142956:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142957: fixstack:      fixstack.c
        !          142958:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142959: fnkey: i8086/fnkey.c
        !          142960:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142961: from:  from.c
        !          142962:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142963: help:  help.c
        !          142964:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142965: join:  join.c
        !          142966:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142967: kill:  kill.c
        !          142968:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142969: lc:    lc.c
        !          142970:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142971: ln:    ln.c
        !          142972:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142973: look:  look.c
        !          142974:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142975: # N.B. cmd/ls.c is old source, current is in cmd/skut/ls.c.
        !          142976: ls:    skut/ls.c
        !          142977:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142978: m4:    m4.c
        !          142979:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142980: man:   man.c
        !          142981:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142982: mesg:  mesg.c
        !          142983:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142984: mkdir: mkdir.c
        !          142985:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142986: mkfs:  mkfs.c
        !          142987:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142988: mknod: mknod.c
        !          142989:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142990: mount: mount.c
        !          142991:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142992: msg:   msg.c
        !          142993:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142994: mv:    mv.c
        !          142995:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142996: newgrp:        newgrp.c
        !          142997:        $(CC) $(LDFLAGS) -o $@@ $?
        !          142998: nm:    nm.c
        !          142999:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143000: od:    od.c
        !          143001:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143002: pr:    pr.c
        !          143003:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143004: prep:  prep.c
        !          143005:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143006: prof:  prof.c
        !          143007:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143008: pwd:   pwd.c
        !          143009:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143010: quot:  quot.c
        !          143011:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143012: ranlib:        ranlib.c
        !          143013:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143014: rev:   rev.c
        !          143015:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143016: rm:    rm.c
        !          143017:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143018: rmdir: rmdir.c
        !          143019:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143020: sa:    sa.c
        !          143021:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143022: scat:  scat.c
        !          143023:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143024: size:  size.c
        !          143025:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143026: sleep: sleep.c
        !          143027:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143028: sort:  sort.c
        !          143029:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143030: split: split.c
        !          143031:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143032: strings:       strings.c
        !          143033:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143034: strip: strip.c
        !          143035:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143036: stty:  stty.c
        !          143037:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143038: sum:   sum.c
        !          143039:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143040: sync:  sync.c
        !          143041:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143042: tail:  tail.c
        !          143043:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143044: tar:   tar.c
        !          143045:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143046: tee:   tee.c
        !          143047:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143048: time:  time.c
        !          143049:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143050: touch: touch.c
        !          143051:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143052: tr:    tr.c
        !          143053:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143054: tty:   tty.c
        !          143055:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143056: typo:  typo.c
        !          143057:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143058: umount:        umount.c
        !          143059:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143060: uniq:  uniq.c
        !          143061:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143062: update:        update.c
        !          143063:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143064: wall:  wall.c
        !          143065:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143066: wc:    wc.c
        !          143067:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143068: who:   who.c
        !          143069:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143070: write: write.c
        !          143071:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143072: yes:   yes.c
        !          143073:        $(CC) $(LDFLAGS) -o $@@ $?
        !          143074: 
        !          143075: # Etc.
        !          143076: clean:
        !          143077:        rm *.o
        !          143078: stripall:
        !          143079:        strip $(BIN) $(BIN2) $(ETC) $(ETC2) $(USRLIB) $(USRLIB2)
        !          143080: 
        !          143081: # end of /usr/src/cmd/Makefile
        !          143082: @
        !          143083: 0707070000000000000000000000000000000000010000000000000000000001300000000527TRAILER!!!

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.